From 449cc186d5b8117d74ba22d6173497d00939f5f1 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sat, 28 Apr 2012 17:53:17 +0200 Subject: Source files split into modules --- src/ClassFILE.cpp | 425 -- src/DirectX.ico | Bin 1078 -> 0 bytes src/accents.txt | 5 - src/app/README.txt | 3 + src/app/d3dapp.cpp | 2452 +++++++++++ src/app/d3dapp.h | 168 + src/app/joystick.cpp | 245 ++ src/app/joystick.h | 31 + src/auto.cpp | 461 --- src/auto.h | 114 - src/autobase.cpp | 1459 ------- src/autobase.h | 122 - src/autoconvert.cpp | 546 --- src/autoconvert.h | 82 - src/autoderrick.cpp | 605 --- src/autoderrick.h | 84 - src/autodestroyer.cpp | 397 -- src/autodestroyer.h | 76 - src/autoegg.cpp | 375 -- src/autoegg.h | 83 - src/autoenergy.cpp | 665 --- src/autoenergy.h | 83 - src/autofactory.cpp | 961 ----- src/autofactory.h | 85 - src/autoflag.cpp | 178 - src/autoflag.h | 58 - src/autohuston.cpp | 315 -- src/autohuston.h | 77 - src/autoinfo.cpp | 537 --- src/autoinfo.h | 80 - src/autojostle.cpp | 167 - src/autojostle.h | 60 - src/autokid.cpp | 222 - src/autokid.h | 59 - src/autolabo.cpp | 629 --- src/autolabo.h | 87 - src/automush.cpp | 362 -- src/automush.h | 73 - src/autonest.cpp | 291 -- src/autonest.h | 73 - src/autonuclear.cpp | 504 --- src/autonuclear.h | 80 - src/autopara.cpp | 347 -- src/autopara.h | 77 - src/autoportico.cpp | 446 -- src/autoportico.h | 81 - src/autoradar.cpp | 326 -- src/autoradar.h | 76 - src/autorepair.cpp | 362 -- src/autorepair.h | 76 - src/autoresearch.cpp | 627 --- src/autoresearch.h | 82 - src/autoroot.cpp | 135 - src/autoroot.h | 56 - src/autosafe.cpp | 636 --- src/autosafe.h | 86 - src/autostation.cpp | 387 -- src/autostation.h | 68 - src/autotower.cpp | 561 --- src/autotower.h | 86 - src/blitz.cpp | 471 --- src/blitz.h | 84 - src/brain.cpp | 3000 -------------- src/brain.h | 220 - src/bug.txt | 94 - src/bug1.txt | 68 - src/button.cpp | 248 -- src/button.h | 58 - src/camera.cpp | 2109 ---------- src/camera.h | 271 -- src/cbottoken.cpp | 521 --- src/cbottoken.h | 39 - src/ceebot.ini | 66 - src/check.cpp | 168 - src/check.h | 48 - src/cloud.cpp | 332 -- src/cloud.h | 90 - src/cmdtoken.cpp | 978 ----- src/cmdtoken.h | 67 - src/colobot.ini | 75 - src/color.cpp | 226 -- src/color.h | 58 - src/common/README.txt | 3 + src/common/event.cpp | 91 + src/common/event.h | 636 +++ src/common/global.h | 64 + src/common/iman.cpp | 165 + src/common/iman.h | 58 + src/common/language.h | 51 + src/common/metafile.cpp | 418 ++ src/common/metafile.h | 78 + src/common/misc.cpp | 443 ++ src/common/misc.h | 240 ++ src/common/modfile.cpp | 697 ++++ src/common/modfile.h | 119 + src/common/profile.cpp | 116 + src/common/profile.h | 36 + src/common/restext.cpp | 3663 +++++++++++++++++ src/common/restext.h | 159 + src/common/struct.h | 73 + src/compass.cpp | 176 - src/compass.h | 52 - src/control.cpp | 876 ---- src/control.h | 137 - src/cur00001.cur | Bin 326 -> 0 bytes src/cur00002.cur | Bin 326 -> 0 bytes src/cur00003.cur | Bin 326 -> 0 bytes src/cursor1.cur | Bin 326 -> 0 bytes src/cursorha.cur | Bin 326 -> 0 bytes src/cursorsc.cur | Bin 326 -> 0 bytes src/d3dapp.cpp | 2452 ----------- src/d3dapp.h | 168 - src/d3dengine.cpp | 5727 -------------------------- src/d3dengine.h | 686 ---- src/d3denum.cpp | 621 --- src/d3denum.h | 136 - src/d3dframe.cpp | 623 --- src/d3dframe.h | 142 - src/d3dmath.cpp | 343 -- src/d3dmath.h | 97 - src/d3dres.h | 59 - src/d3dtextr.cpp | 1080 ----- src/d3dtextr.h | 80 - src/d3dutil.cpp | 327 -- src/d3dutil.h | 114 - src/dd.cpp | 175 - src/displayinfo.cpp | 1222 ------ src/displayinfo.h | 92 - src/displaytext.cpp | 615 --- src/displaytext.h | 96 - src/edit.cpp | 3318 --------------- src/edit.h | 255 -- src/editvalue.cpp | 380 -- src/editvalue.h | 85 - src/event.cpp | 91 - src/event.h | 636 --- src/gauge.cpp | 159 - src/gauge.h | 52 - src/global.h | 64 - src/graphics/README.txt | 5 + src/graphics/common/blitz.cpp | 471 +++ src/graphics/common/blitz.h | 84 + src/graphics/common/camera.cpp | 2109 ++++++++++ src/graphics/common/camera.h | 271 ++ src/graphics/common/cloud.cpp | 332 ++ src/graphics/common/cloud.h | 90 + src/graphics/common/light.cpp | 503 +++ src/graphics/common/light.h | 113 + src/graphics/common/mainmovie.cpp | 249 ++ src/graphics/common/mainmovie.h | 80 + src/graphics/common/model.cpp | 3228 +++++++++++++++ src/graphics/common/model.h | 137 + src/graphics/common/particule.cpp | 4373 ++++++++++++++++++++ src/graphics/common/particule.h | 339 ++ src/graphics/common/planet.cpp | 248 ++ src/graphics/common/planet.h | 79 + src/graphics/common/pyro.cpp | 2486 ++++++++++++ src/graphics/common/pyro.h | 175 + src/graphics/common/terrain.cpp | 2270 +++++++++++ src/graphics/common/terrain.h | 214 + src/graphics/common/text.cpp | 1881 +++++++++ src/graphics/common/text.h | 113 + src/graphics/common/water.cpp | 835 ++++ src/graphics/common/water.h | 134 + src/graphics/d3d/d3dengine.cpp | 5727 ++++++++++++++++++++++++++ src/graphics/d3d/d3dengine.h | 686 ++++ src/graphics/d3d/d3denum.cpp | 621 +++ src/graphics/d3d/d3denum.h | 136 + src/graphics/d3d/d3dframe.cpp | 623 +++ src/graphics/d3d/d3dframe.h | 142 + src/graphics/d3d/d3dtextr.cpp | 1080 +++++ src/graphics/d3d/d3dtextr.h | 80 + src/graphics/d3d/d3dutil.cpp | 327 ++ src/graphics/d3d/d3dutil.h | 114 + src/group.cpp | 646 --- src/group.h | 48 - src/image.cpp | 157 - src/image.h | 52 - src/iman.cpp | 165 - src/iman.h | 58 - src/interface.cpp | 607 --- src/interface.h | 93 - src/joystick.cpp | 245 -- src/joystick.h | 31 - src/key.cpp | 290 -- src/key.h | 54 - src/label.cpp | 95 - src/label.h | 48 - src/language.h | 51 - src/light.cpp | 503 --- src/light.h | 113 - src/list.cpp | 870 ---- src/list.h | 117 - src/maindialog.cpp | 6937 -------------------------------- src/maindialog.h | 256 -- src/mainmap.cpp | 404 -- src/mainmap.h | 68 - src/mainmovie.cpp | 249 -- src/mainmovie.h | 80 - src/mainshort.cpp | 376 -- src/mainshort.h | 61 - src/map.cpp | 1342 ------ src/map.h | 141 - src/math/README.txt | 3 + src/math/d3dmath.cpp | 343 ++ src/math/d3dmath.h | 97 + src/math/math3d.cpp | 1035 +++++ src/math/math3d.h | 106 + src/math3d.cpp | 1035 ----- src/math3d.h | 106 - src/metafile.cpp | 418 -- src/metafile.h | 78 - src/micent2.txt | 13 - src/misc.cpp | 443 -- src/misc.h | 240 -- src/mixer.txt | 486 --- src/model.cpp | 3228 --------------- src/model.h | 137 - src/modfile.cpp | 697 ---- src/modfile.h | 119 - src/motion.cpp | 257 -- src/motion.h | 94 - src/motionant.cpp | 901 ----- src/motionant.h | 80 - src/motionbee.cpp | 663 --- src/motionbee.h | 73 - src/motionhuman.cpp | 1799 --------- src/motionhuman.h | 102 - src/motionmother.cpp | 543 --- src/motionmother.h | 67 - src/motionspider.cpp | 789 ---- src/motionspider.h | 78 - src/motiontoto.cpp | 886 ---- src/motiontoto.h | 81 - src/motionvehicle.cpp | 2091 ---------- src/motionvehicle.h | 82 - src/motionworm.cpp | 380 -- src/motionworm.h | 75 - src/object.cpp | 7607 ----------------------------------- src/object.h | 781 ---- src/object/README.txt | 3 + src/object/auto/auto.cpp | 461 +++ src/object/auto/auto.h | 114 + src/object/auto/autobase.cpp | 1459 +++++++ src/object/auto/autobase.h | 122 + src/object/auto/autoconvert.cpp | 546 +++ src/object/auto/autoconvert.h | 82 + src/object/auto/autoderrick.cpp | 605 +++ src/object/auto/autoderrick.h | 84 + src/object/auto/autodestroyer.cpp | 397 ++ src/object/auto/autodestroyer.h | 76 + src/object/auto/autoegg.cpp | 375 ++ src/object/auto/autoegg.h | 83 + src/object/auto/autoenergy.cpp | 665 +++ src/object/auto/autoenergy.h | 83 + src/object/auto/autofactory.cpp | 961 +++++ src/object/auto/autofactory.h | 85 + src/object/auto/autoflag.cpp | 178 + src/object/auto/autoflag.h | 58 + src/object/auto/autohuston.cpp | 315 ++ src/object/auto/autohuston.h | 77 + src/object/auto/autoinfo.cpp | 537 +++ src/object/auto/autoinfo.h | 80 + src/object/auto/autojostle.cpp | 167 + src/object/auto/autojostle.h | 60 + src/object/auto/autokid.cpp | 222 + src/object/auto/autokid.h | 59 + src/object/auto/autolabo.cpp | 629 +++ src/object/auto/autolabo.h | 87 + src/object/auto/automush.cpp | 362 ++ src/object/auto/automush.h | 73 + src/object/auto/autonest.cpp | 291 ++ src/object/auto/autonest.h | 73 + src/object/auto/autonuclear.cpp | 504 +++ src/object/auto/autonuclear.h | 80 + src/object/auto/autopara.cpp | 347 ++ src/object/auto/autopara.h | 77 + src/object/auto/autoportico.cpp | 446 ++ src/object/auto/autoportico.h | 81 + src/object/auto/autoradar.cpp | 326 ++ src/object/auto/autoradar.h | 76 + src/object/auto/autorepair.cpp | 362 ++ src/object/auto/autorepair.h | 76 + src/object/auto/autoresearch.cpp | 627 +++ src/object/auto/autoresearch.h | 82 + src/object/auto/autoroot.cpp | 135 + src/object/auto/autoroot.h | 56 + src/object/auto/autosafe.cpp | 636 +++ src/object/auto/autosafe.h | 86 + src/object/auto/autostation.cpp | 387 ++ src/object/auto/autostation.h | 68 + src/object/auto/autotower.cpp | 561 +++ src/object/auto/autotower.h | 86 + src/object/brain.cpp | 3000 ++++++++++++++ src/object/brain.h | 220 + src/object/motion/motion.cpp | 257 ++ src/object/motion/motion.h | 94 + src/object/motion/motionant.cpp | 901 +++++ src/object/motion/motionant.h | 80 + src/object/motion/motionbee.cpp | 663 +++ src/object/motion/motionbee.h | 73 + src/object/motion/motionhuman.cpp | 1799 +++++++++ src/object/motion/motionhuman.h | 102 + src/object/motion/motionmother.cpp | 543 +++ src/object/motion/motionmother.h | 67 + src/object/motion/motionspider.cpp | 789 ++++ src/object/motion/motionspider.h | 78 + src/object/motion/motiontoto.cpp | 886 ++++ src/object/motion/motiontoto.h | 81 + src/object/motion/motionvehicle.cpp | 2091 ++++++++++ src/object/motion/motionvehicle.h | 82 + src/object/motion/motionworm.cpp | 380 ++ src/object/motion/motionworm.h | 75 + src/object/object.cpp | 7607 +++++++++++++++++++++++++++++++++++ src/object/object.h | 781 ++++ src/object/robotmain.cpp | 7031 ++++++++++++++++++++++++++++++++ src/object/robotmain.h | 463 +++ src/object/task/task.cpp | 109 + src/object/task/task.h | 89 + src/object/task/taskadvance.cpp | 159 + src/object/task/taskadvance.h | 59 + src/object/task/taskbuild.cpp | 822 ++++ src/object/task/taskbuild.h | 93 + src/object/task/taskfire.cpp | 398 ++ src/object/task/taskfire.h | 61 + src/object/task/taskfireant.cpp | 227 ++ src/object/task/taskfireant.h | 72 + src/object/task/taskflag.cpp | 321 ++ src/object/task/taskflag.h | 66 + src/object/task/taskgoto.cpp | 2352 +++++++++++ src/object/task/taskgoto.h | 167 + src/object/task/taskgungoal.cpp | 161 + src/object/task/taskgungoal.h | 57 + src/object/task/taskinfo.cpp | 233 ++ src/object/task/taskinfo.h | 57 + src/object/task/taskmanager.cpp | 291 ++ src/object/task/taskmanager.h | 77 + src/object/task/taskmanip.cpp | 1398 +++++++ src/object/task/taskmanip.h | 109 + src/object/task/taskpen.cpp | 304 ++ src/object/task/taskpen.h | 77 + src/object/task/taskrecover.cpp | 431 ++ src/object/task/taskrecover.h | 75 + src/object/task/taskreset.cpp | 345 ++ src/object/task/taskreset.h | 73 + src/object/task/tasksearch.cpp | 334 ++ src/object/task/tasksearch.h | 79 + src/object/task/taskshield.cpp | 573 +++ src/object/task/taskshield.h | 94 + src/object/task/taskspiderexplo.cpp | 124 + src/object/task/taskspiderexplo.h | 53 + src/object/task/tasktake.cpp | 612 +++ src/object/task/tasktake.h | 85 + src/object/task/taskterraform.cpp | 429 ++ src/object/task/taskterraform.h | 72 + src/object/task/taskturn.cpp | 147 + src/object/task/taskturn.h | 55 + src/object/task/taskwait.cpp | 89 + src/object/task/taskwait.h | 53 + src/old/DirectX.ico | Bin 0 -> 1078 bytes src/old/README.txt | 3 + src/old/accents.txt | 5 + src/old/bug.txt | 94 + src/old/bug1.txt | 68 + src/old/ceebot.ini | 66 + src/old/colobot.ini | 75 + src/old/cur00001.cur | Bin 0 -> 326 bytes src/old/cur00002.cur | Bin 0 -> 326 bytes src/old/cur00003.cur | Bin 0 -> 326 bytes src/old/cursor1.cur | Bin 0 -> 326 bytes src/old/cursorha.cur | Bin 0 -> 326 bytes src/old/cursorsc.cur | Bin 0 -> 326 bytes src/old/d3dres.h | 59 + src/old/micent2.txt | 13 + src/old/mixer.txt | 486 +++ src/old/patch16.txt | 10 + src/old/readme.txt | 872 ++++ src/old/resource.h | 55 + src/old/t.txt | 11 + src/old/tracks.txt | 17 + src/old/traduc.txt | 151 + src/old/version.txt | 108 + src/old/winmain.aps | Bin 0 -> 40696 bytes src/old/winmain.rc | 265 ++ src/particule.cpp | 4373 -------------------- src/particule.h | 339 -- src/patch16.txt | 10 - src/physics.cpp | 3885 ------------------ src/physics.h | 248 -- src/physics/README.txt | 3 + src/physics/physics.cpp | 3885 ++++++++++++++++++ src/physics/physics.h | 248 ++ src/planet.cpp | 248 -- src/planet.h | 79 - src/profile.cpp | 116 - src/profile.h | 36 - src/pyro.cpp | 2486 ------------ src/pyro.h | 175 - src/readme.txt | 872 ---- src/resource.h | 55 - src/restext.cpp | 3663 ----------------- src/restext.h | 159 - src/robotmain.cpp | 7031 -------------------------------- src/robotmain.h | 463 --- src/script.cpp | 3777 ----------------- src/script.h | 118 - src/script/ClassFILE.cpp | 425 ++ src/script/cbottoken.cpp | 521 +++ src/script/cbottoken.h | 39 + src/script/cmdtoken.cpp | 978 +++++ src/script/cmdtoken.h | 67 + src/script/dd.cpp | 175 + src/script/script.cpp | 3777 +++++++++++++++++ src/script/script.h | 118 + src/scroll.cpp | 471 --- src/scroll.h | 84 - src/shortcut.cpp | 243 -- src/shortcut.h | 50 - src/slider.cpp | 582 --- src/slider.h | 84 - src/sound.cpp | 1658 -------- src/sound.h | 245 -- src/sound/README.txt | 3 + src/sound/sound.cpp | 1658 ++++++++ src/sound/sound.h | 245 ++ src/struct.h | 73 - src/studio.cpp | 1667 -------- src/studio.h | 117 - src/t.txt | 11 - src/target.cpp | 285 -- src/target.h | 50 - src/task.cpp | 109 - src/task.h | 89 - src/taskadvance.cpp | 159 - src/taskadvance.h | 59 - src/taskbuild.cpp | 822 ---- src/taskbuild.h | 93 - src/taskfire.cpp | 398 -- src/taskfire.h | 61 - src/taskfireant.cpp | 227 -- src/taskfireant.h | 72 - src/taskflag.cpp | 321 -- src/taskflag.h | 66 - src/taskgoto.cpp | 2352 ----------- src/taskgoto.h | 167 - src/taskgungoal.cpp | 161 - src/taskgungoal.h | 57 - src/taskinfo.cpp | 233 -- src/taskinfo.h | 57 - src/taskmanager.cpp | 291 -- src/taskmanager.h | 77 - src/taskmanip.cpp | 1398 ------- src/taskmanip.h | 109 - src/taskpen.cpp | 304 -- src/taskpen.h | 77 - src/taskrecover.cpp | 431 -- src/taskrecover.h | 75 - src/taskreset.cpp | 345 -- src/taskreset.h | 73 - src/tasksearch.cpp | 334 -- src/tasksearch.h | 79 - src/taskshield.cpp | 573 --- src/taskshield.h | 94 - src/taskspiderexplo.cpp | 124 - src/taskspiderexplo.h | 53 - src/tasktake.cpp | 612 --- src/tasktake.h | 85 - src/taskterraform.cpp | 429 -- src/taskterraform.h | 72 - src/taskturn.cpp | 147 - src/taskturn.h | 55 - src/taskwait.cpp | 89 - src/taskwait.h | 53 - src/terrain.cpp | 2270 ----------- src/terrain.h | 214 - src/text.cpp | 1881 --------- src/text.h | 113 - src/tracks.txt | 17 - src/traduc.txt | 151 - src/ui/README.txt | 3 + src/ui/button.cpp | 248 ++ src/ui/button.h | 58 + src/ui/check.cpp | 168 + src/ui/check.h | 48 + src/ui/color.cpp | 226 ++ src/ui/color.h | 58 + src/ui/compass.cpp | 176 + src/ui/compass.h | 52 + src/ui/control.cpp | 876 ++++ src/ui/control.h | 137 + src/ui/displayinfo.cpp | 1222 ++++++ src/ui/displayinfo.h | 92 + src/ui/displaytext.cpp | 615 +++ src/ui/displaytext.h | 96 + src/ui/edit.cpp | 3318 +++++++++++++++ src/ui/edit.h | 255 ++ src/ui/editvalue.cpp | 380 ++ src/ui/editvalue.h | 85 + src/ui/gauge.cpp | 159 + src/ui/gauge.h | 52 + src/ui/group.cpp | 646 +++ src/ui/group.h | 48 + src/ui/image.cpp | 157 + src/ui/image.h | 52 + src/ui/interface.cpp | 607 +++ src/ui/interface.h | 93 + src/ui/key.cpp | 290 ++ src/ui/key.h | 54 + src/ui/label.cpp | 95 + src/ui/label.h | 48 + src/ui/list.cpp | 870 ++++ src/ui/list.h | 117 + src/ui/maindialog.cpp | 6937 ++++++++++++++++++++++++++++++++ src/ui/maindialog.h | 256 ++ src/ui/mainmap.cpp | 404 ++ src/ui/mainmap.h | 68 + src/ui/mainshort.cpp | 376 ++ src/ui/mainshort.h | 61 + src/ui/map.cpp | 1342 ++++++ src/ui/map.h | 141 + src/ui/scroll.cpp | 471 +++ src/ui/scroll.h | 84 + src/ui/shortcut.cpp | 243 ++ src/ui/shortcut.h | 50 + src/ui/slider.cpp | 582 +++ src/ui/slider.h | 84 + src/ui/studio.cpp | 1667 ++++++++ src/ui/studio.h | 117 + src/ui/target.cpp | 285 ++ src/ui/target.h | 50 + src/ui/window.cpp | 1622 ++++++++ src/ui/window.h | 148 + src/version.txt | 108 - src/water.cpp | 835 ---- src/water.h | 134 - src/window.cpp | 1622 -------- src/window.h | 148 - src/winmain.aps | Bin 40696 -> 0 bytes src/winmain.rc | 265 -- 539 files changed, 137030 insertions(+), 137001 deletions(-) delete mode 100644 src/ClassFILE.cpp delete mode 100644 src/DirectX.ico delete mode 100644 src/accents.txt create mode 100644 src/app/README.txt create mode 100644 src/app/d3dapp.cpp create mode 100644 src/app/d3dapp.h create mode 100644 src/app/joystick.cpp create mode 100644 src/app/joystick.h delete mode 100644 src/auto.cpp delete mode 100644 src/auto.h delete mode 100644 src/autobase.cpp delete mode 100644 src/autobase.h delete mode 100644 src/autoconvert.cpp delete mode 100644 src/autoconvert.h delete mode 100644 src/autoderrick.cpp delete mode 100644 src/autoderrick.h delete mode 100644 src/autodestroyer.cpp delete mode 100644 src/autodestroyer.h delete mode 100644 src/autoegg.cpp delete mode 100644 src/autoegg.h delete mode 100644 src/autoenergy.cpp delete mode 100644 src/autoenergy.h delete mode 100644 src/autofactory.cpp delete mode 100644 src/autofactory.h delete mode 100644 src/autoflag.cpp delete mode 100644 src/autoflag.h delete mode 100644 src/autohuston.cpp delete mode 100644 src/autohuston.h delete mode 100644 src/autoinfo.cpp delete mode 100644 src/autoinfo.h delete mode 100644 src/autojostle.cpp delete mode 100644 src/autojostle.h delete mode 100644 src/autokid.cpp delete mode 100644 src/autokid.h delete mode 100644 src/autolabo.cpp delete mode 100644 src/autolabo.h delete mode 100644 src/automush.cpp delete mode 100644 src/automush.h delete mode 100644 src/autonest.cpp delete mode 100644 src/autonest.h delete mode 100644 src/autonuclear.cpp delete mode 100644 src/autonuclear.h delete mode 100644 src/autopara.cpp delete mode 100644 src/autopara.h delete mode 100644 src/autoportico.cpp delete mode 100644 src/autoportico.h delete mode 100644 src/autoradar.cpp delete mode 100644 src/autoradar.h delete mode 100644 src/autorepair.cpp delete mode 100644 src/autorepair.h delete mode 100644 src/autoresearch.cpp delete mode 100644 src/autoresearch.h delete mode 100644 src/autoroot.cpp delete mode 100644 src/autoroot.h delete mode 100644 src/autosafe.cpp delete mode 100644 src/autosafe.h delete mode 100644 src/autostation.cpp delete mode 100644 src/autostation.h delete mode 100644 src/autotower.cpp delete mode 100644 src/autotower.h delete mode 100644 src/blitz.cpp delete mode 100644 src/blitz.h delete mode 100644 src/brain.cpp delete mode 100644 src/brain.h delete mode 100644 src/bug.txt delete mode 100644 src/bug1.txt delete mode 100644 src/button.cpp delete mode 100644 src/button.h delete mode 100644 src/camera.cpp delete mode 100644 src/camera.h delete mode 100644 src/cbottoken.cpp delete mode 100644 src/cbottoken.h delete mode 100644 src/ceebot.ini delete mode 100644 src/check.cpp delete mode 100644 src/check.h delete mode 100644 src/cloud.cpp delete mode 100644 src/cloud.h delete mode 100644 src/cmdtoken.cpp delete mode 100644 src/cmdtoken.h delete mode 100644 src/colobot.ini delete mode 100644 src/color.cpp delete mode 100644 src/color.h create mode 100644 src/common/README.txt create mode 100644 src/common/event.cpp create mode 100644 src/common/event.h create mode 100644 src/common/global.h create mode 100644 src/common/iman.cpp create mode 100644 src/common/iman.h create mode 100644 src/common/language.h create mode 100644 src/common/metafile.cpp create mode 100644 src/common/metafile.h create mode 100644 src/common/misc.cpp create mode 100644 src/common/misc.h create mode 100644 src/common/modfile.cpp create mode 100644 src/common/modfile.h create mode 100644 src/common/profile.cpp create mode 100644 src/common/profile.h create mode 100644 src/common/restext.cpp create mode 100644 src/common/restext.h create mode 100644 src/common/struct.h delete mode 100644 src/compass.cpp delete mode 100644 src/compass.h delete mode 100644 src/control.cpp delete mode 100644 src/control.h delete mode 100644 src/cur00001.cur delete mode 100644 src/cur00002.cur delete mode 100644 src/cur00003.cur delete mode 100644 src/cursor1.cur delete mode 100644 src/cursorha.cur delete mode 100644 src/cursorsc.cur delete mode 100644 src/d3dapp.cpp delete mode 100644 src/d3dapp.h delete mode 100644 src/d3dengine.cpp delete mode 100644 src/d3dengine.h delete mode 100644 src/d3denum.cpp delete mode 100644 src/d3denum.h delete mode 100644 src/d3dframe.cpp delete mode 100644 src/d3dframe.h delete mode 100644 src/d3dmath.cpp delete mode 100644 src/d3dmath.h delete mode 100644 src/d3dres.h delete mode 100644 src/d3dtextr.cpp delete mode 100644 src/d3dtextr.h delete mode 100644 src/d3dutil.cpp delete mode 100644 src/d3dutil.h delete mode 100644 src/dd.cpp delete mode 100644 src/displayinfo.cpp delete mode 100644 src/displayinfo.h delete mode 100644 src/displaytext.cpp delete mode 100644 src/displaytext.h delete mode 100644 src/edit.cpp delete mode 100644 src/edit.h delete mode 100644 src/editvalue.cpp delete mode 100644 src/editvalue.h delete mode 100644 src/event.cpp delete mode 100644 src/event.h delete mode 100644 src/gauge.cpp delete mode 100644 src/gauge.h delete mode 100644 src/global.h create mode 100644 src/graphics/README.txt create mode 100644 src/graphics/common/blitz.cpp create mode 100644 src/graphics/common/blitz.h create mode 100644 src/graphics/common/camera.cpp create mode 100644 src/graphics/common/camera.h create mode 100644 src/graphics/common/cloud.cpp create mode 100644 src/graphics/common/cloud.h create mode 100644 src/graphics/common/light.cpp create mode 100644 src/graphics/common/light.h create mode 100644 src/graphics/common/mainmovie.cpp create mode 100644 src/graphics/common/mainmovie.h create mode 100644 src/graphics/common/model.cpp create mode 100644 src/graphics/common/model.h create mode 100644 src/graphics/common/particule.cpp create mode 100644 src/graphics/common/particule.h create mode 100644 src/graphics/common/planet.cpp create mode 100644 src/graphics/common/planet.h create mode 100644 src/graphics/common/pyro.cpp create mode 100644 src/graphics/common/pyro.h create mode 100644 src/graphics/common/terrain.cpp create mode 100644 src/graphics/common/terrain.h create mode 100644 src/graphics/common/text.cpp create mode 100644 src/graphics/common/text.h create mode 100644 src/graphics/common/water.cpp create mode 100644 src/graphics/common/water.h create mode 100644 src/graphics/d3d/d3dengine.cpp create mode 100644 src/graphics/d3d/d3dengine.h create mode 100644 src/graphics/d3d/d3denum.cpp create mode 100644 src/graphics/d3d/d3denum.h create mode 100644 src/graphics/d3d/d3dframe.cpp create mode 100644 src/graphics/d3d/d3dframe.h create mode 100644 src/graphics/d3d/d3dtextr.cpp create mode 100644 src/graphics/d3d/d3dtextr.h create mode 100644 src/graphics/d3d/d3dutil.cpp create mode 100644 src/graphics/d3d/d3dutil.h delete mode 100644 src/group.cpp delete mode 100644 src/group.h delete mode 100644 src/image.cpp delete mode 100644 src/image.h delete mode 100644 src/iman.cpp delete mode 100644 src/iman.h delete mode 100644 src/interface.cpp delete mode 100644 src/interface.h delete mode 100644 src/joystick.cpp delete mode 100644 src/joystick.h delete mode 100644 src/key.cpp delete mode 100644 src/key.h delete mode 100644 src/label.cpp delete mode 100644 src/label.h delete mode 100644 src/language.h delete mode 100644 src/light.cpp delete mode 100644 src/light.h delete mode 100644 src/list.cpp delete mode 100644 src/list.h delete mode 100644 src/maindialog.cpp delete mode 100644 src/maindialog.h delete mode 100644 src/mainmap.cpp delete mode 100644 src/mainmap.h delete mode 100644 src/mainmovie.cpp delete mode 100644 src/mainmovie.h delete mode 100644 src/mainshort.cpp delete mode 100644 src/mainshort.h delete mode 100644 src/map.cpp delete mode 100644 src/map.h create mode 100644 src/math/README.txt create mode 100644 src/math/d3dmath.cpp create mode 100644 src/math/d3dmath.h create mode 100644 src/math/math3d.cpp create mode 100644 src/math/math3d.h delete mode 100644 src/math3d.cpp delete mode 100644 src/math3d.h delete mode 100644 src/metafile.cpp delete mode 100644 src/metafile.h delete mode 100644 src/micent2.txt delete mode 100644 src/misc.cpp delete mode 100644 src/misc.h delete mode 100644 src/mixer.txt delete mode 100644 src/model.cpp delete mode 100644 src/model.h delete mode 100644 src/modfile.cpp delete mode 100644 src/modfile.h delete mode 100644 src/motion.cpp delete mode 100644 src/motion.h delete mode 100644 src/motionant.cpp delete mode 100644 src/motionant.h delete mode 100644 src/motionbee.cpp delete mode 100644 src/motionbee.h delete mode 100644 src/motionhuman.cpp delete mode 100644 src/motionhuman.h delete mode 100644 src/motionmother.cpp delete mode 100644 src/motionmother.h delete mode 100644 src/motionspider.cpp delete mode 100644 src/motionspider.h delete mode 100644 src/motiontoto.cpp delete mode 100644 src/motiontoto.h delete mode 100644 src/motionvehicle.cpp delete mode 100644 src/motionvehicle.h delete mode 100644 src/motionworm.cpp delete mode 100644 src/motionworm.h delete mode 100644 src/object.cpp delete mode 100644 src/object.h create mode 100644 src/object/README.txt create mode 100644 src/object/auto/auto.cpp create mode 100644 src/object/auto/auto.h create mode 100644 src/object/auto/autobase.cpp create mode 100644 src/object/auto/autobase.h create mode 100644 src/object/auto/autoconvert.cpp create mode 100644 src/object/auto/autoconvert.h create mode 100644 src/object/auto/autoderrick.cpp create mode 100644 src/object/auto/autoderrick.h create mode 100644 src/object/auto/autodestroyer.cpp create mode 100644 src/object/auto/autodestroyer.h create mode 100644 src/object/auto/autoegg.cpp create mode 100644 src/object/auto/autoegg.h create mode 100644 src/object/auto/autoenergy.cpp create mode 100644 src/object/auto/autoenergy.h create mode 100644 src/object/auto/autofactory.cpp create mode 100644 src/object/auto/autofactory.h create mode 100644 src/object/auto/autoflag.cpp create mode 100644 src/object/auto/autoflag.h create mode 100644 src/object/auto/autohuston.cpp create mode 100644 src/object/auto/autohuston.h create mode 100644 src/object/auto/autoinfo.cpp create mode 100644 src/object/auto/autoinfo.h create mode 100644 src/object/auto/autojostle.cpp create mode 100644 src/object/auto/autojostle.h create mode 100644 src/object/auto/autokid.cpp create mode 100644 src/object/auto/autokid.h create mode 100644 src/object/auto/autolabo.cpp create mode 100644 src/object/auto/autolabo.h create mode 100644 src/object/auto/automush.cpp create mode 100644 src/object/auto/automush.h create mode 100644 src/object/auto/autonest.cpp create mode 100644 src/object/auto/autonest.h create mode 100644 src/object/auto/autonuclear.cpp create mode 100644 src/object/auto/autonuclear.h create mode 100644 src/object/auto/autopara.cpp create mode 100644 src/object/auto/autopara.h create mode 100644 src/object/auto/autoportico.cpp create mode 100644 src/object/auto/autoportico.h create mode 100644 src/object/auto/autoradar.cpp create mode 100644 src/object/auto/autoradar.h create mode 100644 src/object/auto/autorepair.cpp create mode 100644 src/object/auto/autorepair.h create mode 100644 src/object/auto/autoresearch.cpp create mode 100644 src/object/auto/autoresearch.h create mode 100644 src/object/auto/autoroot.cpp create mode 100644 src/object/auto/autoroot.h create mode 100644 src/object/auto/autosafe.cpp create mode 100644 src/object/auto/autosafe.h create mode 100644 src/object/auto/autostation.cpp create mode 100644 src/object/auto/autostation.h create mode 100644 src/object/auto/autotower.cpp create mode 100644 src/object/auto/autotower.h create mode 100644 src/object/brain.cpp create mode 100644 src/object/brain.h create mode 100644 src/object/motion/motion.cpp create mode 100644 src/object/motion/motion.h create mode 100644 src/object/motion/motionant.cpp create mode 100644 src/object/motion/motionant.h create mode 100644 src/object/motion/motionbee.cpp create mode 100644 src/object/motion/motionbee.h create mode 100644 src/object/motion/motionhuman.cpp create mode 100644 src/object/motion/motionhuman.h create mode 100644 src/object/motion/motionmother.cpp create mode 100644 src/object/motion/motionmother.h create mode 100644 src/object/motion/motionspider.cpp create mode 100644 src/object/motion/motionspider.h create mode 100644 src/object/motion/motiontoto.cpp create mode 100644 src/object/motion/motiontoto.h create mode 100644 src/object/motion/motionvehicle.cpp create mode 100644 src/object/motion/motionvehicle.h create mode 100644 src/object/motion/motionworm.cpp create mode 100644 src/object/motion/motionworm.h create mode 100644 src/object/object.cpp create mode 100644 src/object/object.h create mode 100644 src/object/robotmain.cpp create mode 100644 src/object/robotmain.h create mode 100644 src/object/task/task.cpp create mode 100644 src/object/task/task.h create mode 100644 src/object/task/taskadvance.cpp create mode 100644 src/object/task/taskadvance.h create mode 100644 src/object/task/taskbuild.cpp create mode 100644 src/object/task/taskbuild.h create mode 100644 src/object/task/taskfire.cpp create mode 100644 src/object/task/taskfire.h create mode 100644 src/object/task/taskfireant.cpp create mode 100644 src/object/task/taskfireant.h create mode 100644 src/object/task/taskflag.cpp create mode 100644 src/object/task/taskflag.h create mode 100644 src/object/task/taskgoto.cpp create mode 100644 src/object/task/taskgoto.h create mode 100644 src/object/task/taskgungoal.cpp create mode 100644 src/object/task/taskgungoal.h create mode 100644 src/object/task/taskinfo.cpp create mode 100644 src/object/task/taskinfo.h create mode 100644 src/object/task/taskmanager.cpp create mode 100644 src/object/task/taskmanager.h create mode 100644 src/object/task/taskmanip.cpp create mode 100644 src/object/task/taskmanip.h create mode 100644 src/object/task/taskpen.cpp create mode 100644 src/object/task/taskpen.h create mode 100644 src/object/task/taskrecover.cpp create mode 100644 src/object/task/taskrecover.h create mode 100644 src/object/task/taskreset.cpp create mode 100644 src/object/task/taskreset.h create mode 100644 src/object/task/tasksearch.cpp create mode 100644 src/object/task/tasksearch.h create mode 100644 src/object/task/taskshield.cpp create mode 100644 src/object/task/taskshield.h create mode 100644 src/object/task/taskspiderexplo.cpp create mode 100644 src/object/task/taskspiderexplo.h create mode 100644 src/object/task/tasktake.cpp create mode 100644 src/object/task/tasktake.h create mode 100644 src/object/task/taskterraform.cpp create mode 100644 src/object/task/taskterraform.h create mode 100644 src/object/task/taskturn.cpp create mode 100644 src/object/task/taskturn.h create mode 100644 src/object/task/taskwait.cpp create mode 100644 src/object/task/taskwait.h create mode 100644 src/old/DirectX.ico create mode 100644 src/old/README.txt create mode 100644 src/old/accents.txt create mode 100644 src/old/bug.txt create mode 100644 src/old/bug1.txt create mode 100644 src/old/ceebot.ini create mode 100644 src/old/colobot.ini create mode 100644 src/old/cur00001.cur create mode 100644 src/old/cur00002.cur create mode 100644 src/old/cur00003.cur create mode 100644 src/old/cursor1.cur create mode 100644 src/old/cursorha.cur create mode 100644 src/old/cursorsc.cur create mode 100644 src/old/d3dres.h create mode 100644 src/old/micent2.txt create mode 100644 src/old/mixer.txt create mode 100644 src/old/patch16.txt create mode 100644 src/old/readme.txt create mode 100644 src/old/resource.h create mode 100644 src/old/t.txt create mode 100644 src/old/tracks.txt create mode 100644 src/old/traduc.txt create mode 100644 src/old/version.txt create mode 100644 src/old/winmain.aps create mode 100644 src/old/winmain.rc delete mode 100644 src/particule.cpp delete mode 100644 src/particule.h delete mode 100644 src/patch16.txt delete mode 100644 src/physics.cpp delete mode 100644 src/physics.h create mode 100644 src/physics/README.txt create mode 100644 src/physics/physics.cpp create mode 100644 src/physics/physics.h delete mode 100644 src/planet.cpp delete mode 100644 src/planet.h delete mode 100644 src/profile.cpp delete mode 100644 src/profile.h delete mode 100644 src/pyro.cpp delete mode 100644 src/pyro.h delete mode 100644 src/readme.txt delete mode 100644 src/resource.h delete mode 100644 src/restext.cpp delete mode 100644 src/restext.h delete mode 100644 src/robotmain.cpp delete mode 100644 src/robotmain.h delete mode 100644 src/script.cpp delete mode 100644 src/script.h create mode 100644 src/script/ClassFILE.cpp create mode 100644 src/script/cbottoken.cpp create mode 100644 src/script/cbottoken.h create mode 100644 src/script/cmdtoken.cpp create mode 100644 src/script/cmdtoken.h create mode 100644 src/script/dd.cpp create mode 100644 src/script/script.cpp create mode 100644 src/script/script.h delete mode 100644 src/scroll.cpp delete mode 100644 src/scroll.h delete mode 100644 src/shortcut.cpp delete mode 100644 src/shortcut.h delete mode 100644 src/slider.cpp delete mode 100644 src/slider.h delete mode 100644 src/sound.cpp delete mode 100644 src/sound.h create mode 100644 src/sound/README.txt create mode 100644 src/sound/sound.cpp create mode 100644 src/sound/sound.h delete mode 100644 src/struct.h delete mode 100644 src/studio.cpp delete mode 100644 src/studio.h delete mode 100644 src/t.txt delete mode 100644 src/target.cpp delete mode 100644 src/target.h delete mode 100644 src/task.cpp delete mode 100644 src/task.h delete mode 100644 src/taskadvance.cpp delete mode 100644 src/taskadvance.h delete mode 100644 src/taskbuild.cpp delete mode 100644 src/taskbuild.h delete mode 100644 src/taskfire.cpp delete mode 100644 src/taskfire.h delete mode 100644 src/taskfireant.cpp delete mode 100644 src/taskfireant.h delete mode 100644 src/taskflag.cpp delete mode 100644 src/taskflag.h delete mode 100644 src/taskgoto.cpp delete mode 100644 src/taskgoto.h delete mode 100644 src/taskgungoal.cpp delete mode 100644 src/taskgungoal.h delete mode 100644 src/taskinfo.cpp delete mode 100644 src/taskinfo.h delete mode 100644 src/taskmanager.cpp delete mode 100644 src/taskmanager.h delete mode 100644 src/taskmanip.cpp delete mode 100644 src/taskmanip.h delete mode 100644 src/taskpen.cpp delete mode 100644 src/taskpen.h delete mode 100644 src/taskrecover.cpp delete mode 100644 src/taskrecover.h delete mode 100644 src/taskreset.cpp delete mode 100644 src/taskreset.h delete mode 100644 src/tasksearch.cpp delete mode 100644 src/tasksearch.h delete mode 100644 src/taskshield.cpp delete mode 100644 src/taskshield.h delete mode 100644 src/taskspiderexplo.cpp delete mode 100644 src/taskspiderexplo.h delete mode 100644 src/tasktake.cpp delete mode 100644 src/tasktake.h delete mode 100644 src/taskterraform.cpp delete mode 100644 src/taskterraform.h delete mode 100644 src/taskturn.cpp delete mode 100644 src/taskturn.h delete mode 100644 src/taskwait.cpp delete mode 100644 src/taskwait.h delete mode 100644 src/terrain.cpp delete mode 100644 src/terrain.h delete mode 100644 src/text.cpp delete mode 100644 src/text.h delete mode 100644 src/tracks.txt delete mode 100644 src/traduc.txt create mode 100644 src/ui/README.txt create mode 100644 src/ui/button.cpp create mode 100644 src/ui/button.h create mode 100644 src/ui/check.cpp create mode 100644 src/ui/check.h create mode 100644 src/ui/color.cpp create mode 100644 src/ui/color.h create mode 100644 src/ui/compass.cpp create mode 100644 src/ui/compass.h create mode 100644 src/ui/control.cpp create mode 100644 src/ui/control.h create mode 100644 src/ui/displayinfo.cpp create mode 100644 src/ui/displayinfo.h create mode 100644 src/ui/displaytext.cpp create mode 100644 src/ui/displaytext.h create mode 100644 src/ui/edit.cpp create mode 100644 src/ui/edit.h create mode 100644 src/ui/editvalue.cpp create mode 100644 src/ui/editvalue.h create mode 100644 src/ui/gauge.cpp create mode 100644 src/ui/gauge.h create mode 100644 src/ui/group.cpp create mode 100644 src/ui/group.h create mode 100644 src/ui/image.cpp create mode 100644 src/ui/image.h create mode 100644 src/ui/interface.cpp create mode 100644 src/ui/interface.h create mode 100644 src/ui/key.cpp create mode 100644 src/ui/key.h create mode 100644 src/ui/label.cpp create mode 100644 src/ui/label.h create mode 100644 src/ui/list.cpp create mode 100644 src/ui/list.h create mode 100644 src/ui/maindialog.cpp create mode 100644 src/ui/maindialog.h create mode 100644 src/ui/mainmap.cpp create mode 100644 src/ui/mainmap.h create mode 100644 src/ui/mainshort.cpp create mode 100644 src/ui/mainshort.h create mode 100644 src/ui/map.cpp create mode 100644 src/ui/map.h create mode 100644 src/ui/scroll.cpp create mode 100644 src/ui/scroll.h create mode 100644 src/ui/shortcut.cpp create mode 100644 src/ui/shortcut.h create mode 100644 src/ui/slider.cpp create mode 100644 src/ui/slider.h create mode 100644 src/ui/studio.cpp create mode 100644 src/ui/studio.h create mode 100644 src/ui/target.cpp create mode 100644 src/ui/target.h create mode 100644 src/ui/window.cpp create mode 100644 src/ui/window.h delete mode 100644 src/version.txt delete mode 100644 src/water.cpp delete mode 100644 src/water.h delete mode 100644 src/window.cpp delete mode 100644 src/window.h delete mode 100644 src/winmain.aps delete mode 100644 src/winmain.rc diff --git a/src/ClassFILE.cpp b/src/ClassFILE.cpp deleted file mode 100644 index ef98e14..0000000 --- a/src/ClassFILE.cpp +++ /dev/null @@ -1,425 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - - - -// Static variables - -static CBotClass* m_pClassFILE; -static CBotProgram* m_pFuncFile; -static int m_CompteurFileOpen = 0; -static char* m_filesDir; - - - -// Prepares a file name. - -void PrepareFilename(CBotString &filename) -{ - int pos; - - pos = filename.ReverseFind('\\'); - if ( pos > 0 ) - { - filename = filename.Mid(pos+1); // Remove files with - } - - pos = filename.ReverseFind('/'); - if ( pos > 0 ) - { - filename = filename.Mid(pos+1); // also with / - } - - pos = filename.ReverseFind(':'); - if ( pos > 0 ) - { - filename = filename.Mid(pos+1); // also removes the drive letter C: - } - - filename = CBotString(m_filesDir) + CBotString("\\") + filename; -} - - -// constructor of the class -// get the filename as a parameter - -// execution -BOOL rfconstruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) -{ - CBotString mode; - - // accepts no parameters - if ( pVar == NULL ) return TRUE; - - // must be a character string - if ( pVar->GivType() != CBotTypString ) { Exception = CBotErrBadString; return FALSE; } - - CBotString filename = pVar->GivValString(); - PrepareFilename(filename); - - // there may be a second parameter - pVar = pVar->GivNext(); - if ( pVar != NULL ) - { - // recover mode - mode = pVar->GivValString(); - if ( mode != "r" && mode != "w" ) { Exception = CBotErrBadParam; return FALSE; } - - // no third parameter - if ( pVar->GivNext() != NULL ) { Exception = CBotErrOverParam; return FALSE; } - } - - // saves the file name - pVar = pThis->GivItem("filename"); - pVar->SetValString(filename); - - if ( ! mode.IsEmpty() ) - { - // opens the requested file - FILE* pFile = fopen( filename, mode ); - if ( pFile == NULL ) { Exception = CBotErrFileOpen; return FALSE; } - - m_CompteurFileOpen ++; - - // save the channel file - pVar = pThis->GivItem("handle"); - pVar->SetValInt((long)pFile); - } - - return TRUE; -} - -// compilation -CBotTypResult cfconstruct (CBotVar* pThis, CBotVar* &pVar) -{ - // accepts no parameters - if ( pVar == NULL ) return CBotTypResult( 0 ); - - // must be a character string - if ( pVar->GivType() != CBotTypString ) - return CBotTypResult( CBotErrBadString ); - - // there may be a second parameter - pVar = pVar->GivNext(); - if ( pVar != NULL ) - { - // which must be a string - if ( pVar->GivType() != CBotTypString ) - return CBotTypResult( CBotErrBadString ); - // no third parameter - if ( pVar->GivNext() != NULL ) return CBotTypResult( CBotErrOverParam ); - } - - // the result is void (constructor) - return CBotTypResult( 0 ); -} - - -// destructor of the class - -// execution -BOOL rfdestruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) -{ - // retrieve the item "handle" - pVar = pThis->GivItem("handle"); - - // don't open? no problem :) - if ( pVar->GivInit() != IS_DEF) return TRUE; - - FILE* pFile= (FILE*)pVar->GivValInt(); - fclose(pFile); - m_CompteurFileOpen --; - - pVar->SetInit(IS_NAN); - - return TRUE; -} - - -// process FILE :: open -// get the r/w mode as a parameter - -// execution -BOOL rfopen (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) -{ - // there must be a parameter - if ( pVar == NULL ) { Exception = CBotErrLowParam; return FALSE; } - - // which must be a character string - if ( pVar->GivType() != CBotTypString ) { Exception = CBotErrBadString; return FALSE; } - - // There may be a second parameter - if ( pVar->GivNext() != NULL ) - { - // if the first parameter is the file name - CBotString filename = pVar->GivValString(); - PrepareFilename(filename); - - // saves the file name - CBotVar* pVar2 = pThis->GivItem("filename"); - pVar2->SetValString(filename); - - // next parameter is the mode - pVar = pVar -> GivNext(); - } - - CBotString mode = pVar->GivValString(); - if ( mode != "r" && mode != "w" ) { Exception = CBotErrBadParam; return FALSE; } - - // no third parameter - if ( pVar->GivNext() != NULL ) { Exception = CBotErrOverParam; return FALSE; } - - // retrieve the item "handle" - pVar = pThis->GivItem("handle"); - - // which must not be initialized - if ( pVar->GivInit() == IS_DEF) { Exception = CBotErrFileOpen; return FALSE; } - - // file contains the name - pVar = pThis->GivItem("filename"); - CBotString filename = pVar->GivValString(); - - PrepareFilename(filename); // if the name was h.filename attribute = "..."; - - // opens the requested file - FILE* pFile = fopen( filename, mode ); - if ( pFile == NULL ) - { - pResult->SetValInt(FALSE); - return TRUE; - } - - m_CompteurFileOpen ++; - - // Registered the channel file - pVar = pThis->GivItem("handle"); - pVar->SetValInt((long)pFile); - - pResult->SetValInt(TRUE); - return TRUE; -} - -// compilation -CBotTypResult cfopen (CBotVar* pThis, CBotVar* &pVar) -{ - // there must be a parameter - if ( pVar == NULL ) return CBotTypResult( CBotErrLowParam ); - - // which must be a string - if ( pVar->GivType() != CBotTypString ) - return CBotTypResult( CBotErrBadString ); - - // there may be a second parameter - pVar = pVar->GivNext(); - if ( pVar != NULL ) - { - // which must be a string - if ( pVar->GivType() != CBotTypString ) - return CBotTypResult( CBotErrBadString ); - - // no third parameter - if ( pVar->GivNext() != NULL ) return CBotTypResult( CBotErrOverParam ); - } - - // the result is bool - return CBotTypResult(CBotTypBoolean); -} - - -// process FILE :: close - -// execeution -BOOL rfclose (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) -{ - // it shouldn't be any parameters - if ( pVar != NULL ) return CBotErrOverParam; - - // retrieve the item "handle" - pVar = pThis->GivItem("handle"); - - if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return FALSE; } - - FILE* pFile= (FILE*)pVar->GivValInt(); - fclose(pFile); - m_CompteurFileOpen --; - - pVar->SetInit(IS_NAN); - - return TRUE; -} - -// compilation -CBotTypResult cfclose (CBotVar* pThis, CBotVar* &pVar) -{ - // it shouldn't be any parameters - if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam ); - - // function returns a result "void" - return CBotTypResult( 0 ); -} - -// process FILE :: writeln - -// execution -BOOL rfwrite (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) -{ - // there must be a parameter - if ( pVar == NULL ) { Exception = CBotErrLowParam; return FALSE; } - - // which must be a character string - if ( pVar->GivType() != CBotTypString ) { Exception = CBotErrBadString; return FALSE; } - - CBotString param = pVar->GivValString(); - - // retrieve the item "handle" - pVar = pThis->GivItem("handle"); - - if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return FALSE; } - - FILE* pFile= (FILE*)pVar->GivValInt(); - - int res = fputs(param+CBotString("\n"), pFile); - - // if an error occurs generate an exception - if ( res < 0 ) { Exception = CBotErrWrite; return FALSE; } - - return TRUE; -} - -// compilation -CBotTypResult cfwrite (CBotVar* pThis, CBotVar* &pVar) -{ - // there must be a parameter - if ( pVar == NULL ) return CBotTypResult( CBotErrLowParam ); - - // which must be a character string - if ( pVar->GivType() != CBotTypString ) return CBotTypResult( CBotErrBadString ); - - // no other parameter - if ( pVar->GivNext() != NULL ) return CBotTypResult( CBotErrOverParam ); - - // the function returns a void result - return CBotTypResult( 0 ); -} - -// process FILE :: readln - -// execution -BOOL rfread (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) -{ - // it shouldn't be any parameters - if ( pVar != NULL ) { Exception = CBotErrOverParam; return FALSE; } - - // retrieve the item "handle" - pVar = pThis->GivItem("handle"); - - if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return FALSE; } - - FILE* pFile= (FILE*)pVar->GivValInt(); - - char chaine[2000]; - int i; - for ( i = 0 ; i < 2000 ; i++ ) chaine[i] = 0; - - fgets(chaine, 1999, pFile); - - for ( i = 0 ; i < 2000 ; i++ ) if (chaine[i] == '\n') chaine[i] = 0; - - // if an error occurs generate an exception - if ( ferror(pFile) ) { Exception = CBotErrRead; return FALSE; } - - pResult->SetValString( chaine ); - - return TRUE; -} - -// compilation -CBotTypResult cfread (CBotVar* pThis, CBotVar* &pVar) -{ - // it should not be any parameter - if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam ); - - // function returns a result "string" - return CBotTypResult( CBotTypString ); -} -// process FILE :: readln - - -// execution -BOOL rfeof (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) -{ - // it should not be any parameter - if ( pVar != NULL ) { Exception = CBotErrOverParam; return FALSE; } - - // retrieve the item "handle" - pVar = pThis->GivItem("handle"); - - if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return FALSE; } - - FILE* pFile= (FILE*)pVar->GivValInt(); - - pResult->SetValInt( feof( pFile ) ); - - return TRUE; -} - -// compilation -CBotTypResult cfeof (CBotVar* pThis, CBotVar* &pVar) -{ - // it shouldn't be any parameter - if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam ); - - // the function returns a boolean result - return CBotTypResult( CBotTypBoolean ); -} - - - - - -void InitClassFILE() -{ -// create a class for file management -// the use is as follows: -// file canal( "NomFichier.txt" ) -// canal.open( "r" ); // open for read -// s = canal.readln( ); // reads a line -// canal.close(); // close the file - - // create the class FILE - m_pClassFILE = new CBotClass("file", NULL); - // adds the component ".filename" - m_pClassFILE->AddItem("filename", CBotTypString); - // adds the component ".handle" - m_pClassFILE->AddItem("handle", CBotTypInt, PR_PRIVATE); - - // define a constructor and a destructor - m_pClassFILE->AddFunction("file", rfconstruct, cfconstruct ); - m_pClassFILE->AddFunction("~file", rfdestruct, NULL ); - - // end of the methods associated - m_pClassFILE->AddFunction("open", rfopen, cfopen ); - m_pClassFILE->AddFunction("close", rfclose, cfclose ); - m_pClassFILE->AddFunction("writeln", rfwrite, cfwrite ); - m_pClassFILE->AddFunction("readln", rfread, cfread ); - m_pClassFILE->AddFunction("eof", rfeof, cfeof ); - - m_pFuncFile = new CBotProgram( ); - CBotStringArray ListFonctions; - m_pFuncFile->Compile( "public file openfile(string name, string mode) {return new file(name, mode);}", ListFonctions); - m_pFuncFile->SetIdent(-2); // restoreState in special identifier for this function -} - diff --git a/src/DirectX.ico b/src/DirectX.ico deleted file mode 100644 index 9752f54..0000000 Binary files a/src/DirectX.ico and /dev/null differ diff --git a/src/accents.txt b/src/accents.txt deleted file mode 100644 index 9473b1b..0000000 --- a/src/accents.txt +++ /dev/null @@ -1,5 +0,0 @@ -!"#$%&'()*+,-./0123456789:;<=>? -@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^ -_abcdefghijklmnopqrstuvwxyz{|}~ -ÁÀÂÄÃÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜ -áàâäãçéèêëíìîïñóòôöõúùûü diff --git a/src/app/README.txt b/src/app/README.txt new file mode 100644 index 0000000..50e273f --- /dev/null +++ b/src/app/README.txt @@ -0,0 +1,3 @@ +src/app + +Contains the main class of the application and joystick module (to be incorporated into application module once using SDL). diff --git a/src/app/d3dapp.cpp b/src/app/d3dapp.cpp new file mode 100644 index 0000000..a1d5c6a --- /dev/null +++ b/src/app/d3dapp.cpp @@ -0,0 +1,2452 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "struct.h" +#include "d3dtextr.h" +#include "d3dengine.h" +#include "language.h" +#include "event.h" +#include "profile.h" +#include "iman.h" +#include "restext.h" +#include "math3d.h" +#include "joystick.h" +#include "robotmain.h" +#include "sound.h" +#include "d3dapp.h" + +// fix for "MSH_MOUSEWHEEL undefined" error +#ifdef UNICODE +#define MSH_MOUSEWHEEL L"MSWHEEL_ROLLMSG" +#else +#define MSH_MOUSEWHEEL "MSWHEEL_ROLLMSG" +#endif + + +#define AUDIO_TRACK 13 // total number of audio tracks on the CD +#define MAX_STEP 0.2f // maximum time for a step + +#define WINDOW_DX (640+6) // dimensions in windowed mode +#define WINDOW_DY (480+25) + +#define USE_THREAD FALSE // TRUE does not work! +#define TIME_THREAD 0.02f + + + + +// Limit the use of the controls keyboard & joystick. + +float AxeLimit(float value) +{ + if ( value < -1.0f ) value = -1.0f; + if ( value > 1.0f ) value = 1.0f; + return value; +} + + +// Entry point to the program. Initializes everything, and goes into a +// message-processing loop. Idle time is used to render the scene. + +INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) +{ + Error err; + char string[100]; + + CD3DApplication d3dApp; // single instance of the application + + err = d3dApp.CheckMistery(strCmdLine); + if ( err != ERR_OK ) + { + GetResource(RES_ERR, err, string); +#if _NEWLOOK + MessageBox( NULL, string, _T("CeeBot"), MB_ICONERROR|MB_OK ); +#else + MessageBox( NULL, string, _T("COLOBOT"), MB_ICONERROR|MB_OK ); +#endif + return 0; + } + + if ( FAILED(d3dApp.Create(hInst, strCmdLine)) ) + { + return 0; + } + + return d3dApp.Run(); // execution of all +} + + +// Internal variables and function prototypes. + +enum APPMSGTYPE { MSG_NONE, MSGERR_APPMUSTEXIT, MSGWARN_SWITCHEDTOSOFTWARE }; + +static INT CALLBACK AboutProc( HWND, UINT, WPARAM, LPARAM ); +static LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ); + +static CD3DApplication* g_pD3DApp; + + + +// Constructor. + +CD3DApplication::CD3DApplication() +{ + int i; + + m_iMan = new(CInstanceManager); + m_event = new CEvent(m_iMan); + + m_pD3DEngine = 0; + m_pRobotMain = 0; + m_pSound = 0; + m_pFramework = 0; + m_instance = 0; + m_hWnd = 0; + m_pDD = 0; + m_pD3D = 0; + m_pD3DDevice = 0; + + m_CDpath[0] = 0; + + m_pddsRenderTarget = 0; + m_pddsDepthBuffer = 0; + + m_keyState = 0; + m_axeKey = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_axeJoy = D3DVECTOR(0.0f, 0.0f, 0.0f); + + m_vidMemTotal = 0; + m_bActive = FALSE; + m_bActivateApp = FALSE; + m_bReady = FALSE; + m_bJoystick = FALSE; + m_aTime = 0.0f; + + for ( i=0 ; i<32 ; i++ ) + { + m_bJoyButton[i] = FALSE; + } + +#if _NEWLOOK + m_strWindowTitle = _T("CeeBot"); +#else + m_strWindowTitle = _T("COLOBOT"); +#endif + m_bAppUseZBuffer = TRUE; + m_bAppUseStereo = TRUE; + m_bShowStats = FALSE; + m_bDebugMode = FALSE; + m_bAudioState = TRUE; + m_bAudioTrack = TRUE; + m_bNiceMouse = FALSE; + m_bSetupMode = TRUE; + m_fnConfirmDevice = 0; + + ResetKey(); + + g_pD3DApp = this; + + // Request event sent by Logitech. + m_mshMouseWheel = RegisterWindowMessage(MSH_MOUSEWHEEL); + + _mkdir("files\\"); +} + + +// Destructor. + +CD3DApplication::~CD3DApplication() +{ + delete m_iMan; +} + + + +// Returns the path of the CD. + +char* CD3DApplication::RetCDpath() +{ + return m_CDpath; +} + +// Reads the information in the registry. + +Error CD3DApplication::RegQuery() +{ + FILE* file = NULL; + HKEY key; + LONG i; + DWORD type, len; + char filename[100]; + +#if _NEWLOOK + #if _TEEN + i = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Epsitec\\CeeBot-Teen\\Setup", + #else + i = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Epsitec\\CeeBot-A\\Setup", + #endif +#else + i = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Epsitec\\Colobot\\Setup", +#endif + 0, KEY_READ, &key); + if ( i != ERROR_SUCCESS ) return ERR_INSTALL; + + type = REG_SZ; + len = sizeof(m_CDpath); + i = RegQueryValueEx(key, "CDpath", NULL, &type, (LPBYTE)m_CDpath, &len); + if ( i != ERROR_SUCCESS || type != REG_SZ ) return ERR_INSTALL; + + filename[0] = m_CDpath[0]; + filename[1] = ':'; + filename[2] = '\\'; + filename[3] = 0; + i = GetDriveType(filename); + if ( i != DRIVE_CDROM ) return ERR_NOCD; + + strcat(filename, "install.ini"); + file = fopen(filename, "rb"); // install.ini file exist? + if ( file == NULL ) return ERR_NOCD; + fclose(file); + + return ERR_OK; +} + +// Checks for audio tracks on the CD. + +Error CD3DApplication::AudioQuery() +{ + MCI_OPEN_PARMS mciOpenParms; + MCI_STATUS_PARMS mciStatusParms; + DWORD dwReturn; + UINT deviceID; + char device[10]; + + // Open the device by specifying the device and filename. + // MCI will attempt to choose the MIDI mapper as the output port. + memset(&mciOpenParms, 0, sizeof(MCI_OPEN_PARMS)); + mciOpenParms.lpstrDeviceType = (LPCTSTR)MCI_DEVTYPE_CD_AUDIO; + if ( m_CDpath[0] == 0 ) + { + dwReturn = mciSendCommand(NULL, + MCI_OPEN, + MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID, + (DWORD)(LPVOID)&mciOpenParms); + } + else + { + device[0] = m_CDpath[0]; + device[1] = ':'; + device[2] = 0; + mciOpenParms.lpstrElementName = device; + dwReturn = mciSendCommand(NULL, + MCI_OPEN, + MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_OPEN_ELEMENT, + (DWORD)(LPVOID)&mciOpenParms); + } + if ( dwReturn != 0 ) + { + return ERR_NOCD; + } + + // The device opened successfully; get the device ID. + deviceID = mciOpenParms.wDeviceID; + + memset(&mciStatusParms, 0, sizeof(MCI_STATUS_PARMS)); + mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; + dwReturn = mciSendCommand(deviceID, + MCI_STATUS, + MCI_WAIT|MCI_STATUS_ITEM, + (DWORD)&mciStatusParms); + if ( dwReturn != 0 ) + { + mciSendCommand(deviceID, MCI_CLOSE, 0, NULL); + return ERR_NOCD; + } + + if ( mciStatusParms.dwReturn != AUDIO_TRACK ) + { + mciSendCommand(deviceID, MCI_CLOSE, 0, NULL); + return ERR_NOCD; + } + + mciSendCommand(deviceID, MCI_CLOSE, 0, NULL); + return ERR_OK; +} + +// Checks for the key. + +Error CD3DApplication::CheckMistery(char *strCmdLine) +{ + if ( strstr(strCmdLine, "-debug") != 0 ) + { + m_bShowStats = TRUE; + SetDebugMode(TRUE); + } + + if ( strstr(strCmdLine, "-audiostate") != 0 ) + { + m_bAudioState = FALSE; + } + + if ( strstr(strCmdLine, "-audiotrack") != 0 ) + { + m_bAudioTrack = FALSE; + } + + m_CDpath[0] = 0; +#if _FULL + if ( strstr(strCmdLine, "-nocd") == 0 && !m_bDebugMode ) + { + Error err; + + err = RegQuery(); + if ( err != ERR_OK ) return err; + + //?err = AudioQuery(); + //?if ( err != ERR_OK ) return err; + } +#endif +#if _SCHOOL & _EDU + if ( strstr(strCmdLine, "-nosetup") != 0 ) + { + m_bSetupMode = FALSE; + } + m_bAudioTrack = FALSE; +#endif +#if _SCHOOL & _PERSO + Error err = RegQuery(); + if ( err != ERR_OK ) return err; + m_bAudioTrack = FALSE; +#endif +#if _SCHOOL & _CEEBOTDEMO + m_bAudioTrack = FALSE; +#endif +#if _NET + m_bAudioTrack = FALSE; +#endif +#if _DEMO + m_bAudioTrack = FALSE; +#endif + + return ERR_OK; +} + + +// Returns the total amount of video memory for textures. + +int CD3DApplication::GetVidMemTotal() +{ + return m_vidMemTotal; +} + +BOOL CD3DApplication::IsVideo8MB() +{ + if ( m_vidMemTotal == 0 ) return FALSE; + return (m_vidMemTotal <= 8388608L); // 8 Mb or less (2 ^ 23)? +} + +BOOL CD3DApplication::IsVideo32MB() +{ + if ( m_vidMemTotal == 0 ) return FALSE; + return (m_vidMemTotal > 16777216L); // more than 16 Mb (2 ^ 24)? +} + + +void CD3DApplication::SetShowStat(BOOL bShow) +{ + m_bShowStats = bShow; +} + +BOOL CD3DApplication::RetShowStat() +{ + return m_bShowStats; +} + + +void CD3DApplication::SetDebugMode(BOOL bMode) +{ + m_bDebugMode = bMode; + D3DTextr_SetDebugMode(m_bDebugMode); +} + +BOOL CD3DApplication::RetDebugMode() +{ + return m_bDebugMode; +} + +BOOL CD3DApplication::RetSetupMode() +{ + return m_bSetupMode; +} + + + + +// Son process of time management. + +DWORD WINAPI ThreadRoutine(LPVOID) +{ + Event event; + float time; + int ms, start, end, delay; + + ms = (int)(TIME_THREAD*1000.0f); + time = 0.0f; + while ( TRUE ) + { + start = timeGetTime(); + + g_pD3DApp->m_pD3DEngine->FrameMove(TIME_THREAD); + + ZeroMemory(&event, sizeof(Event)); + event.event = EVENT_FRAME; + event.rTime = TIME_THREAD; + event.axeX = AxeLimit(g_pD3DApp->m_axeKey.x + g_pD3DApp->m_axeJoy.x); + event.axeY = AxeLimit(g_pD3DApp->m_axeKey.y + g_pD3DApp->m_axeJoy.y); + event.axeZ = AxeLimit(g_pD3DApp->m_axeKey.z + g_pD3DApp->m_axeJoy.z); + event.keyState = g_pD3DApp->m_keyState; + + if ( g_pD3DApp->m_pRobotMain != 0 ) + { + g_pD3DApp->m_pRobotMain->EventProcess(event); + } + + end = timeGetTime(); + + delay = ms-(end-start); + if ( delay > 0 ) + { + Sleep(delay); // waiting 20ms-used + } + time += TIME_THREAD; + } + return 0; +} + + +// Called during device intialization, this code checks the device +// for some minimum set of capabilities. + +HRESULT CD3DApplication::ConfirmDevice( DDCAPS* pddDriverCaps, + D3DDEVICEDESC7* pd3dDeviceDesc ) +{ +//? if( pd3dDeviceDesc->wMaxVertexBlendMatrices < 2 ) +//? return E_FAIL; + + return S_OK; +} + +// Create the application. + +HRESULT CD3DApplication::Create( HINSTANCE hInst, TCHAR* strCmdLine ) +{ + HRESULT hr; + char deviceName[100]; + char modeName[100]; + int iValue; + DWORD style; + BOOL bFull, b3D; + + m_instance = hInst; + + InitCurrentDirectory(); + + // Enumerate available D3D devices. The callback is used so the app can + // confirm/reject each enumerated device depending on its capabilities. + if( FAILED( hr = D3DEnum_EnumerateDevices( m_fnConfirmDevice ) ) ) + { + DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); + return hr; + } + + if( FAILED( hr = D3DEnum_SelectDefaultDevice( &m_pDeviceInfo ) ) ) + { + DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); + return hr; + } + + if ( !m_bDebugMode ) + { + m_pDeviceInfo->bWindowed = FALSE; // full screen + } + if ( GetProfileInt("Device", "FullScreen", bFull) ) + { + m_pDeviceInfo->bWindowed = !bFull; + } + + // Create the 3D engine. + if( (m_pD3DEngine = new CD3DEngine(m_iMan, this)) == NULL ) + { + DisplayFrameworkError( D3DENUMERR_ENGINE, MSGERR_APPMUSTEXIT ); + return E_OUTOFMEMORY; + } + SetEngine(m_pD3DEngine); + + // Initialize the app's custom scene stuff + if( FAILED( hr = m_pD3DEngine->OneTimeSceneInit() ) ) + { + DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); + return hr; + } + + // Create a new CD3DFramework class. This class does all of our D3D + // initialization and manages the common D3D objects. + if( (m_pFramework = new CD3DFramework7()) == NULL ) + { + DisplayFrameworkError( E_OUTOFMEMORY, MSGERR_APPMUSTEXIT ); + return E_OUTOFMEMORY; + } + + // Create the sound instance. + if( (m_pSound = new CSound(m_iMan)) == NULL ) + { + DisplayFrameworkError( D3DENUMERR_SOUND, MSGERR_APPMUSTEXIT ); + return E_OUTOFMEMORY; + } + + // Create the robot application. + if( (m_pRobotMain = new CRobotMain(m_iMan)) == NULL ) + { + DisplayFrameworkError( D3DENUMERR_ROBOT, MSGERR_APPMUSTEXIT ); + return E_OUTOFMEMORY; + } + + // Register the window class + WNDCLASS wndClass = { 0, WndProc, 0, 0, hInst, + LoadIcon( hInst, MAKEINTRESOURCE(IDI_MAIN_ICON) ), + LoadCursor( NULL, IDC_ARROW ), + (HBRUSH)GetStockObject(WHITE_BRUSH), + NULL, _T("D3D Window") }; + RegisterClass( &wndClass ); + + // Create the render window + style = WS_CAPTION|WS_VISIBLE; + if ( m_bDebugMode ) style |= WS_SYSMENU; // close box + m_hWnd = CreateWindow( _T("D3D Window"), m_strWindowTitle, +//? WS_OVERLAPPEDWINDOW|WS_VISIBLE, + style, CW_USEDEFAULT, CW_USEDEFAULT, + WINDOW_DX, WINDOW_DY, 0L, +//? LoadMenu( hInst, MAKEINTRESOURCE(IDR_MENU) ), + NULL, + hInst, 0L ); + UpdateWindow( m_hWnd ); + + if ( !GetProfileInt("Setup", "Sound3D", b3D) ) + { + b3D = TRUE; + } + m_pSound->SetDebugMode(m_bDebugMode); + m_pSound->Create(m_hWnd, b3D); + m_pSound->CacheAll(); + m_pSound->SetState(m_bAudioState); + m_pSound->SetAudioTrack(m_bAudioTrack); + m_pSound->SetCDpath(m_CDpath); + + // Initialize the 3D environment for the app + if( FAILED( hr = Initialize3DEnvironment() ) ) + { + DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); + Cleanup3DEnvironment(); + return E_FAIL; + } + + // Change the display device driver. + GetProfileString("Device", "Name", deviceName, 100); + GetProfileString("Device", "Mode", modeName, 100); + GetProfileInt("Device", "FullScreen", bFull); + if ( deviceName[0] != 0 && modeName[0] != 0 && bFull ) + { + ChangeDevice(deviceName, modeName, bFull); + } + + // First execution? + if ( !GetProfileInt("Setup", "ObjectDirty", iValue) ) + { + m_pD3DEngine->FirstExecuteAdapt(TRUE); + } + + // Creates the file colobot.ini at the first execution. + m_pRobotMain->CreateIni(); + +#if _DEMO + m_pRobotMain->ChangePhase(PHASE_NAME); +#else +#if _NET | _SCHOOL + m_pRobotMain->ChangePhase(PHASE_WELCOME2); +#else +#if _FRENCH + m_pRobotMain->ChangePhase(PHASE_WELCOME2); +#endif +#if _ENGLISH + m_pRobotMain->ChangePhase(PHASE_WELCOME2); +#endif +#if _GERMAN + m_pRobotMain->ChangePhase(PHASE_WELCOME2); +#endif +#if _WG + m_pRobotMain->ChangePhase(PHASE_WELCOME1); +#endif +#if _POLISH + m_pRobotMain->ChangePhase(PHASE_WELCOME1); +#endif +#endif +#endif + m_pD3DEngine->TimeInit(); + +#if USE_THREAD + m_thread = CreateThread(NULL, 0, ThreadRoutine, this, 0, &m_threadId); + SetThreadPriority(m_thread, THREAD_PRIORITY_ABOVE_NORMAL); +#endif + + // The app is ready to go + m_bReady = TRUE; + + return S_OK; +} + + +// Message-processing loop. Idle time is used to render the scene. + +INT CD3DApplication::Run() +{ + // Load keyboard accelerators + HACCEL hAccel = LoadAccelerators( NULL, MAKEINTRESOURCE(IDR_MAIN_ACCEL) ); + + // Now we're ready to recieve and process Windows messages. + BOOL bGotMsg; + MSG msg; + PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE ); + + while( WM_QUIT != msg.message ) + { + // Use PeekMessage() if the app is active, so we can use idle time to + // render the scene. Else, use GetMessage() to avoid eating CPU time. + if( m_bActive ) + bGotMsg = PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ); + else + bGotMsg = GetMessage( &msg, NULL, 0U, 0U ); + + if( bGotMsg ) + { + // Translate and dispatch the message + if( TranslateAccelerator( m_hWnd, hAccel, &msg ) == 0 ) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + } + else + { + // Render a frame during idle time (no messages are waiting) + if( m_bActive && m_bReady ) + { + Event event; + + while ( m_event->GetEvent(event) ) + { + if ( event.event == EVENT_QUIT ) + { +//? SendMessage( m_hWnd, WM_CLOSE, 0, 0 ); + m_pSound->StopMusic(); + Cleanup3DEnvironment(); + PostQuitMessage(0); + return msg.wParam; + } + m_pRobotMain->EventProcess(event); + } + + if ( !RetNiceMouse() ) + { + SetMouseType(m_pD3DEngine->RetMouseType()); + } + + if( FAILED( Render3DEnvironment() ) ) + DestroyWindow( m_hWnd ); + } + } + } + + return msg.wParam; +} + + + +// Conversion of the position of the mouse. +// x: 0=left, 1=right +// y: 0=down, 1=up + +FPOINT CD3DApplication::ConvPosToInterface(HWND hWnd, LPARAM lParam) +{ + POINT cpos; + FPOINT pos; + float px, py, w, h; + + cpos.x = (short)LOWORD(lParam); + cpos.y = (short)HIWORD(lParam); + + if ( !m_pDeviceInfo->bWindowed ) + { + ClientToScreen(hWnd, &cpos); + } + + px = (float)cpos.x; + py = (float)cpos.y; + w = (float)m_ddsdRenderTarget.dwWidth; + h = (float)m_ddsdRenderTarget.dwHeight; + + pos.x = px/w; + pos.y = 1.0f-py/h; + + return pos; +} + +// Physically moves the mouse. + +void CD3DApplication::SetMousePos(FPOINT pos) +{ + POINT p; + + pos.y = 1.0f-pos.y; + + pos.x *= m_ddsdRenderTarget.dwWidth; + pos.y *= m_ddsdRenderTarget.dwHeight; + + p.x = (int)pos.x; + p.y = (int)pos.y; + ClientToScreen(m_hWnd, &p); + + SetCursorPos(p.x, p.y); +} + +// Choosing the type of cursor for the mouse. + +void CD3DApplication::SetMouseType(D3DMouse type) +{ + HCURSOR hc; + + if ( type == D3DMOUSEHAND ) + { + hc = LoadCursor(m_instance, MAKEINTRESOURCE(IDC_CURSORHAND)); + } + else if ( type == D3DMOUSECROSS ) + { + hc = LoadCursor(NULL, IDC_CROSS); + } + else if ( type == D3DMOUSEEDIT ) + { + hc = LoadCursor(NULL, IDC_IBEAM); + } + else if ( type == D3DMOUSENO ) + { + hc = LoadCursor(NULL, IDC_NO); + } + else if ( type == D3DMOUSEMOVE ) + { + hc = LoadCursor(NULL, IDC_SIZEALL); + } + else if ( type == D3DMOUSEMOVEH ) + { + hc = LoadCursor(NULL, IDC_SIZEWE); + } + else if ( type == D3DMOUSEMOVEV ) + { + hc = LoadCursor(NULL, IDC_SIZENS); + } + else if ( type == D3DMOUSEMOVED ) + { + hc = LoadCursor(NULL, IDC_SIZENESW); + } + else if ( type == D3DMOUSEMOVEI ) + { + hc = LoadCursor(NULL, IDC_SIZENWSE); + } + else if ( type == D3DMOUSEWAIT ) + { + hc = LoadCursor(NULL, IDC_WAIT); + } + else if ( type == D3DMOUSESCROLLL ) + { + hc = LoadCursor(m_instance, MAKEINTRESOURCE(IDC_CURSORSCROLLL)); + } + else if ( type == D3DMOUSESCROLLR ) + { + hc = LoadCursor(m_instance, MAKEINTRESOURCE(IDC_CURSORSCROLLR)); + } + else if ( type == D3DMOUSESCROLLU ) + { + hc = LoadCursor(m_instance, MAKEINTRESOURCE(IDC_CURSORSCROLLU)); + } + else if ( type == D3DMOUSESCROLLD ) + { + hc = LoadCursor(m_instance, MAKEINTRESOURCE(IDC_CURSORSCROLLD)); + } + else if ( type == D3DMOUSETARGET ) + { + hc = LoadCursor(m_instance, MAKEINTRESOURCE(IDC_CURSORTARGET)); + } + else + { + hc = LoadCursor(NULL, IDC_ARROW); + } + + if ( hc != NULL ) + { + SetCursor(hc); + } +} + +// Choice of mode for the mouse. + +void CD3DApplication::SetNiceMouse(BOOL bNice) +{ + if ( bNice == m_bNiceMouse ) return; + m_bNiceMouse = bNice; + + if ( m_bNiceMouse ) + { + ShowCursor(FALSE); // hides the ugly windows mouse + SetCursor(NULL); + } + else + { + ShowCursor(TRUE); // shows the ugly windows mouse + SetCursor(LoadCursor(NULL, IDC_ARROW)); + } +} + +// Whether to use the mouse pretty shaded. + +BOOL CD3DApplication::RetNiceMouse() +{ + if ( m_pDeviceInfo->bWindowed ) return FALSE; + if ( !m_pDeviceInfo->bHardware ) return FALSE; + + return m_bNiceMouse; +} + +// Indicates whether it is possible to use the mouse pretty shaded. + +BOOL CD3DApplication::RetNiceMouseCap() +{ + if ( m_pDeviceInfo->bWindowed ) return FALSE; + if ( !m_pDeviceInfo->bHardware ) return FALSE; + + return TRUE; +} + + +// Static msg handler which passes messages to the application class. + +LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + if ( g_pD3DApp != 0 ) + { + Event event; + short move; + + ZeroMemory(&event, sizeof(Event)); + +#if 0 + if ( uMsg == WM_KEYDOWN || + uMsg == WM_CHAR || + uMsg == WM_XBUTTONDOWN || + uMsg == WM_XBUTTONUP ) + { + char s[100]; + sprintf(s, "event: %d %d %d\n", uMsg, wParam, lParam); + OutputDebugString(s); + } +#endif + + if ( uMsg == WM_LBUTTONDOWN ) event.event = EVENT_LBUTTONDOWN; + if ( uMsg == WM_RBUTTONDOWN ) event.event = EVENT_RBUTTONDOWN; + if ( uMsg == WM_LBUTTONUP ) event.event = EVENT_LBUTTONUP; + if ( uMsg == WM_RBUTTONUP ) event.event = EVENT_RBUTTONUP; + if ( uMsg == WM_MOUSEMOVE ) event.event = EVENT_MOUSEMOVE; + if ( uMsg == WM_KEYDOWN ) event.event = EVENT_KEYDOWN; + if ( uMsg == WM_KEYUP ) event.event = EVENT_KEYUP; + if ( uMsg == WM_CHAR ) event.event = EVENT_CHAR; + + if ( uMsg == WM_XBUTTONUP ) + { + if ( (wParam>>16) == XBUTTON1 ) event.event = EVENT_HYPER_PREV; + if ( (wParam>>16) == XBUTTON2 ) event.event = EVENT_HYPER_NEXT; + } + + event.param = wParam; + event.axeX = AxeLimit(g_pD3DApp->m_axeKey.x + g_pD3DApp->m_axeJoy.x); + event.axeY = AxeLimit(g_pD3DApp->m_axeKey.y + g_pD3DApp->m_axeJoy.y); + event.axeZ = AxeLimit(g_pD3DApp->m_axeKey.z + g_pD3DApp->m_axeJoy.z); + event.keyState = g_pD3DApp->m_keyState; + + if ( uMsg == WM_LBUTTONDOWN || + uMsg == WM_RBUTTONDOWN || + uMsg == WM_LBUTTONUP || + uMsg == WM_RBUTTONUP || + uMsg == WM_MOUSEMOVE ) // mouse event? + { + event.pos = g_pD3DApp->ConvPosToInterface(hWnd, lParam); + g_pD3DApp->m_mousePos = event.pos; + g_pD3DApp->m_pD3DEngine->SetMousePos(event.pos); + } + + if ( uMsg == WM_MOUSEWHEEL ) // mouse wheel? + { + event.event = EVENT_KEYDOWN; + event.pos = g_pD3DApp->m_mousePos; + move = HIWORD(wParam); + if ( move/WHEEL_DELTA > 0 ) event.param = VK_WHEELUP; + if ( move/WHEEL_DELTA < 0 ) event.param = VK_WHEELDOWN; + } + if ( g_pD3DApp->m_mshMouseWheel != 0 && + uMsg == g_pD3DApp->m_mshMouseWheel ) // Logitech mouse wheel? + { + event.event = EVENT_KEYDOWN; + event.pos = g_pD3DApp->m_mousePos; + move = LOWORD(wParam); + if ( move/WHEEL_DELTA > 0 ) event.param = VK_WHEELUP; + if ( move/WHEEL_DELTA < 0 ) event.param = VK_WHEELDOWN; + } + + if ( event.event == EVENT_KEYDOWN || + event.event == EVENT_KEYUP || + event.event == EVENT_CHAR ) + { + if ( event.param == 0 ) + { + event.event = EVENT_NULL; + } + } + + if ( g_pD3DApp->m_pRobotMain != 0 && event.event != 0 ) + { + g_pD3DApp->m_pRobotMain->EventProcess(event); +//? if ( !g_pD3DApp->RetNiceMouse() ) +//? { +//? g_pD3DApp->SetMouseType(g_pD3DApp->m_pD3DEngine->RetMouseType()); +//? } + } + if ( g_pD3DApp->m_pD3DEngine != 0 ) + { + g_pD3DApp->m_pD3DEngine->MsgProc( hWnd, uMsg, wParam, lParam ); + } + return g_pD3DApp->MsgProc( hWnd, uMsg, wParam, lParam ); + } + + return DefWindowProc( hWnd, uMsg, wParam, lParam ); +} + + +// Minimal message proc function for the about box. + +BOOL CALLBACK AboutProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM ) +{ + if( WM_COMMAND == uMsg ) + if( IDOK == LOWORD(wParam) || IDCANCEL == LOWORD(wParam) ) + EndDialog( hWnd, TRUE ); + + return WM_INITDIALOG == uMsg ? TRUE : FALSE; +} + + + +// Ignore keypresses. + +void CD3DApplication::FlushPressKey() +{ + m_keyState = 0; + m_axeKey = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_axeJoy = D3DVECTOR(0.0f, 0.0f, 0.0f); +} + +// Resets the default keys. + +void CD3DApplication::ResetKey() +{ + int i; + + for ( i=0 ; i<50 ; i++ ) + { + m_key[i][0] = 0; + m_key[i][1] = 0; + } + m_key[KEYRANK_LEFT ][0] = VK_LEFT; + m_key[KEYRANK_RIGHT ][0] = VK_RIGHT; + m_key[KEYRANK_UP ][0] = VK_UP; + m_key[KEYRANK_DOWN ][0] = VK_DOWN; + m_key[KEYRANK_GUP ][0] = VK_SHIFT; + m_key[KEYRANK_GDOWN ][0] = VK_CONTROL; + m_key[KEYRANK_CAMERA ][0] = VK_SPACE; + m_key[KEYRANK_CAMERA ][1] = VK_BUTTON2; + m_key[KEYRANK_DESEL ][0] = VK_NUMPAD0; + m_key[KEYRANK_DESEL ][1] = VK_BUTTON6; + m_key[KEYRANK_ACTION ][0] = VK_RETURN; + m_key[KEYRANK_ACTION ][1] = VK_BUTTON1; + m_key[KEYRANK_NEAR ][0] = VK_ADD; + m_key[KEYRANK_NEAR ][1] = VK_BUTTON5; + m_key[KEYRANK_AWAY ][0] = VK_SUBTRACT; + m_key[KEYRANK_AWAY ][1] = VK_BUTTON4; + m_key[KEYRANK_NEXT ][0] = VK_TAB; + m_key[KEYRANK_NEXT ][1] = VK_BUTTON3; + m_key[KEYRANK_HUMAN ][0] = VK_HOME; + m_key[KEYRANK_HUMAN ][1] = VK_BUTTON7; + m_key[KEYRANK_QUIT ][0] = VK_ESCAPE; + m_key[KEYRANK_HELP ][0] = VK_F1; + m_key[KEYRANK_PROG ][0] = VK_F2; + m_key[KEYRANK_CBOT ][0] = VK_F3; + m_key[KEYRANK_VISIT ][0] = VK_DECIMAL; + m_key[KEYRANK_SPEED10][0] = VK_F4; + m_key[KEYRANK_SPEED15][0] = VK_F5; + m_key[KEYRANK_SPEED20][0] = VK_F6; +// m_key[KEYRANK_SPEED30][0] = VK_F7; +} + +// Modifies a button. + +void CD3DApplication::SetKey(int keyRank, int option, int key) +{ + if ( keyRank < 0 || + keyRank >= 50 ) return; + + if ( option < 0 || + option >= 2 ) return; + + m_key[keyRank][option] = key; +} + +// Gives a hint. + +int CD3DApplication::RetKey(int keyRank, int option) +{ + if ( keyRank < 0 || + keyRank >= 50 ) return 0; + + if ( option < 0 || + option >= 2 ) return 0; + + return m_key[keyRank][option]; +} + + + +// Use the joystick or keyboard. + +void CD3DApplication::SetJoystick(BOOL bEnable) +{ + m_bJoystick = bEnable; + + if ( m_bJoystick ) // joystick ? + { + if ( !InitDirectInput(m_instance, m_hWnd) ) // initialise joystick + { + m_bJoystick = FALSE; + } + else + { + SetAcquire(TRUE); + SetTimer(m_hWnd, 0, 1000/30, NULL); + } + } + else // keyboard? + { + KillTimer(m_hWnd, 0); + SetAcquire(FALSE); + FreeDirectInput(); + } +} + +BOOL CD3DApplication::RetJoystick() +{ + return m_bJoystick; +} + + +// Message handling function. + +LRESULT CD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, + LPARAM lParam ) +{ + HRESULT hr; + DIJOYSTATE js; + int i; + + // The F10 key sends another message to activate + // menu in standard Windows applications! + if ( uMsg == WM_SYSKEYDOWN && wParam == VK_F10 ) + { + uMsg = WM_KEYDOWN; + } + if ( uMsg == WM_SYSKEYUP && wParam == VK_F10 ) + { + uMsg = WM_KEYUP; + } + + // Mange event "menu" sent by Alt or F10. + if ( uMsg == WM_SYSCOMMAND && wParam == SC_KEYMENU ) + { + return 0; + } + + if ( uMsg == WM_KEYDOWN || uMsg == WM_KEYUP ) + { + if ( GetKeyState(VK_SHIFT) & 0x8000 ) + { + m_keyState |= KS_SHIFT; + } + else + { + m_keyState &= ~KS_SHIFT; + } + + if ( GetKeyState(VK_CONTROL) & 0x8000 ) + { + m_keyState |= KS_CONTROL; + } + else + { + m_keyState &= ~KS_CONTROL; + } + } + + switch( uMsg ) + { + case WM_KEYDOWN: + if ( wParam == m_key[KEYRANK_UP ][0] ) m_axeKey.y = 1.0f; + if ( wParam == m_key[KEYRANK_UP ][1] ) m_axeKey.y = 1.0f; + if ( wParam == m_key[KEYRANK_DOWN ][0] ) m_axeKey.y = -1.0f; + if ( wParam == m_key[KEYRANK_DOWN ][1] ) m_axeKey.y = -1.0f; + if ( wParam == m_key[KEYRANK_LEFT ][0] ) m_axeKey.x = -1.0f; + if ( wParam == m_key[KEYRANK_LEFT ][1] ) m_axeKey.x = -1.0f; + if ( wParam == m_key[KEYRANK_RIGHT][0] ) m_axeKey.x = 1.0f; + if ( wParam == m_key[KEYRANK_RIGHT][1] ) m_axeKey.x = 1.0f; + if ( wParam == m_key[KEYRANK_GUP ][0] ) m_axeKey.z = 1.0f; + if ( wParam == m_key[KEYRANK_GUP ][1] ) m_axeKey.z = 1.0f; + if ( wParam == m_key[KEYRANK_GDOWN][0] ) m_axeKey.z = -1.0f; + if ( wParam == m_key[KEYRANK_GDOWN][1] ) m_axeKey.z = -1.0f; + if ( wParam == m_key[KEYRANK_NEAR ][0] ) m_keyState |= KS_NUMPLUS; + if ( wParam == m_key[KEYRANK_NEAR ][1] ) m_keyState |= KS_NUMPLUS; + if ( wParam == m_key[KEYRANK_AWAY ][0] ) m_keyState |= KS_NUMMINUS; + if ( wParam == m_key[KEYRANK_AWAY ][1] ) m_keyState |= KS_NUMMINUS; + if ( wParam == VK_PRIOR ) m_keyState |= KS_PAGEUP; + if ( wParam == VK_NEXT ) m_keyState |= KS_PAGEDOWN; +//? if ( wParam == VK_SHIFT ) m_keyState |= KS_SHIFT; +//? if ( wParam == VK_CONTROL ) m_keyState |= KS_CONTROL; + if ( wParam == VK_NUMPAD8 ) m_keyState |= KS_NUMUP; + if ( wParam == VK_NUMPAD2 ) m_keyState |= KS_NUMDOWN; + if ( wParam == VK_NUMPAD4 ) m_keyState |= KS_NUMLEFT; + if ( wParam == VK_NUMPAD6 ) m_keyState |= KS_NUMRIGHT; + break; + + case WM_KEYUP: + if ( wParam == m_key[KEYRANK_UP ][0] ) m_axeKey.y = 0.0f; + if ( wParam == m_key[KEYRANK_UP ][1] ) m_axeKey.y = 0.0f; + if ( wParam == m_key[KEYRANK_DOWN ][0] ) m_axeKey.y = 0.0f; + if ( wParam == m_key[KEYRANK_DOWN ][1] ) m_axeKey.y = 0.0f; + if ( wParam == m_key[KEYRANK_LEFT ][0] ) m_axeKey.x = 0.0f; + if ( wParam == m_key[KEYRANK_LEFT ][1] ) m_axeKey.x = 0.0f; + if ( wParam == m_key[KEYRANK_RIGHT][0] ) m_axeKey.x = 0.0f; + if ( wParam == m_key[KEYRANK_RIGHT][1] ) m_axeKey.x = 0.0f; + if ( wParam == m_key[KEYRANK_GUP ][0] ) m_axeKey.z = 0.0f; + if ( wParam == m_key[KEYRANK_GUP ][1] ) m_axeKey.z = 0.0f; + if ( wParam == m_key[KEYRANK_GDOWN][0] ) m_axeKey.z = 0.0f; + if ( wParam == m_key[KEYRANK_GDOWN][1] ) m_axeKey.z = 0.0f; + if ( wParam == m_key[KEYRANK_NEAR ][0] ) m_keyState &= ~KS_NUMPLUS; + if ( wParam == m_key[KEYRANK_NEAR ][1] ) m_keyState &= ~KS_NUMPLUS; + if ( wParam == m_key[KEYRANK_AWAY ][0] ) m_keyState &= ~KS_NUMMINUS; + if ( wParam == m_key[KEYRANK_AWAY ][1] ) m_keyState &= ~KS_NUMMINUS; + if ( wParam == VK_PRIOR ) m_keyState &= ~KS_PAGEUP; + if ( wParam == VK_NEXT ) m_keyState &= ~KS_PAGEDOWN; +//? if ( wParam == VK_SHIFT ) m_keyState &= ~KS_SHIFT; +//? if ( wParam == VK_CONTROL ) m_keyState &= ~KS_CONTROL; + if ( wParam == VK_NUMPAD8 ) m_keyState &= ~KS_NUMUP; + if ( wParam == VK_NUMPAD2 ) m_keyState &= ~KS_NUMDOWN; + if ( wParam == VK_NUMPAD4 ) m_keyState &= ~KS_NUMLEFT; + if ( wParam == VK_NUMPAD6 ) m_keyState &= ~KS_NUMRIGHT; + break; + + case WM_LBUTTONDOWN: + m_keyState |= KS_MLEFT; + break; + + case WM_RBUTTONDOWN: + m_keyState |= KS_MRIGHT; + break; + + case WM_LBUTTONUP: + m_keyState &= ~KS_MLEFT; + break; + + case WM_RBUTTONUP: + m_keyState &= ~KS_MRIGHT; + break; + + case WM_PAINT: + // Handle paint messages when the app is not ready + if( m_pFramework && !m_bReady ) + { + if( m_pDeviceInfo->bWindowed ) + m_pFramework->ShowFrame(); + else + m_pFramework->FlipToGDISurface( TRUE ); + } + break; + + case WM_MOVE: + // If in windowed mode, move the Framework's window + if( m_pFramework && m_bActive && m_bReady && m_pDeviceInfo->bWindowed ) + m_pFramework->Move( (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam) ); + break; + + case WM_SIZE: + // Check to see if we are losing our window... + if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam ) + { + m_bActive = FALSE; + } + else + { + m_bActive = TRUE; + } +//? char s[100]; +//? sprintf(s, "WM_SIZE %d %d %d\n", m_bActive, m_bReady, m_pDeviceInfo->bWindowed); +//? OutputDebugString(s); + + // A new window size will require a new backbuffer + // size, so the 3D structures must be changed accordingly. + if( m_bActive && m_bReady && m_pDeviceInfo->bWindowed ) + { + m_bReady = FALSE; + +//? OutputDebugString("WM_SIZE Change3DEnvironment\n"); + if( FAILED( hr = Change3DEnvironment() ) ) + return 0; + + m_bReady = TRUE; + } + break; + + case WM_TIMER: + if ( m_bActivateApp && m_bJoystick ) + { + if ( UpdateInputState(js) ) + { + m_axeJoy.x = js.lX/1000.0f+js.lRz/1000.0f; // tourner + m_axeJoy.y = -js.lY/1000.0f; // avancer + m_axeJoy.z = -js.rglSlider[0]/1000.0f; // monter + + m_axeJoy.x = Neutral(m_axeJoy.x, 0.2f); + m_axeJoy.y = Neutral(m_axeJoy.y, 0.2f); + m_axeJoy.z = Neutral(m_axeJoy.z, 0.2f); + +//? char s[100]; +//? sprintf(s, "x=%d y=%d z=% x=%d y=%d z=%d\n", js.lX,js.lY,js.lZ,js.lRx,js.lRy,js.lRz); +//? OutputDebugString(s); + + for ( i=0 ; i<32 ; i++ ) + { + if ( js.rgbButtons[i] != 0 && !m_bJoyButton[i] ) + { + m_bJoyButton[i] = TRUE; + PostMessage(m_hWnd, WM_KEYDOWN, VK_BUTTON1+i, 0); + } + if ( js.rgbButtons[i] == 0 && m_bJoyButton[i] ) + { + m_bJoyButton[i] = FALSE; + PostMessage(m_hWnd, WM_KEYUP, VK_BUTTON1+i, 0); + } + } + } + else + { + OutputDebugString("UpdateInputState error\n"); + } + } + break; + + case WM_ACTIVATE: + if( LOWORD(wParam) == WA_INACTIVE ) + { + m_bActivateApp = FALSE; + } + else + { + m_bActivateApp = TRUE; + } + + if ( m_bActivateApp && m_bJoystick ) + { + SetAcquire(TRUE); // re-enables the joystick + } + break; + + case MM_MCINOTIFY: + if ( wParam == MCI_NOTIFY_SUCCESSFUL ) + { + OutputDebugString("Event MM_MCINOTIFY\n"); + m_pSound->SuspendMusic(); + m_pSound->RestartMusic(); + } + break; + + case WM_SETCURSOR: + // Prevent a cursor in fullscreen mode + if( m_bActive && m_bReady && !m_pDeviceInfo->bWindowed ) + { +//? SetCursor(NULL); + return 1; + } + break; + + case WM_ENTERMENULOOP: + // Pause the app when menus are displayed + Pause(TRUE); + break; + case WM_EXITMENULOOP: + Pause(FALSE); + break; + + case WM_ENTERSIZEMOVE: + // Halt frame movement while the app is sizing or moving + m_pD3DEngine->TimeEnterGel(); + break; + case WM_EXITSIZEMOVE: + m_pD3DEngine->TimeExitGel(); + break; + + case WM_NCHITTEST: + // Prevent the user from selecting the menu in fullscreen mode + if( !m_pDeviceInfo->bWindowed ) + return HTCLIENT; + + break; + + case WM_POWERBROADCAST: + switch( wParam ) + { + case PBT_APMQUERYSUSPEND: + // At this point, the app should save any data for open + // network connections, files, etc.., and prepare to go into + // a suspended mode. + return OnQuerySuspend( (DWORD)lParam ); + + case PBT_APMRESUMESUSPEND: + // At this point, the app should recover any data, network + // connections, files, etc.., and resume running from when + // the app was suspended. + return OnResumeSuspend( (DWORD)lParam ); + } + break; + + case WM_SYSCOMMAND: + // Prevent moving/sizing and power loss in fullscreen mode + switch( wParam ) + { + case SC_MOVE: + case SC_SIZE: + case SC_MAXIMIZE: + case SC_MONITORPOWER: + if( FALSE == m_pDeviceInfo->bWindowed ) + return 1; + break; + } + break; + + case WM_COMMAND: + switch( LOWORD(wParam) ) + { + case IDM_CHANGEDEVICE: + // Display the device-selection dialog box. + if( m_bActive && m_bReady ) + { + Pause(TRUE); + + if( SUCCEEDED( D3DEnum_UserChangeDevice( &m_pDeviceInfo ) ) ) + { + if( FAILED( hr = Change3DEnvironment() ) ) + return 0; + } + Pause(FALSE); + } + return 0; + + case IDM_ABOUT: + // Display the About box + Pause(TRUE); + DialogBox( (HINSTANCE)GetWindowLong( hWnd, GWL_HINSTANCE ), + MAKEINTRESOURCE(IDD_ABOUT), hWnd, AboutProc ); + Pause(FALSE); + return 0; + + case IDM_EXIT: + // Recieved key/menu command to exit app + SendMessage( hWnd, WM_CLOSE, 0, 0 ); + return 0; + } + break; + + case WM_GETMINMAXINFO: + ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100; + ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100; + break; + + case WM_CLOSE: + DestroyWindow( hWnd ); + return 0; + + case WM_DESTROY: + Cleanup3DEnvironment(); + PostQuitMessage(0); + return 0; + } + + return DefWindowProc( hWnd, uMsg, wParam, lParam ); +} + + +// Enumeration function to report valid pixel formats for z-buffers. + +HRESULT WINAPI EnumZBufferFormatsCallback(DDPIXELFORMAT* pddpf, + VOID* pContext) +{ + DDPIXELFORMAT* pddpfOut = (DDPIXELFORMAT*)pContext; + + char s[100]; + sprintf(s, "EnumZBufferFormatsCallback %d\n", pddpf->dwRGBBitCount); + OutputDebugString(s); + + if( pddpfOut->dwRGBBitCount == pddpf->dwRGBBitCount ) + { + (*pddpfOut) = (*pddpf); + return D3DENUMRET_CANCEL; + } + + return D3DENUMRET_OK; +} + +// Internal function called by Create() to make and attach a zbuffer +// to the renderer. + +HRESULT CD3DApplication::CreateZBuffer(GUID* pDeviceGUID) +{ + HRESULT hr; + + // Check if the device supports z-bufferless hidden surface removal. If so, + // we don't really need a z-buffer + D3DDEVICEDESC7 ddDesc; + m_pD3DDevice->GetCaps( &ddDesc ); + if( ddDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR ) + return S_OK; + + // Get z-buffer dimensions from the render target + DDSURFACEDESC2 ddsd; + ddsd.dwSize = sizeof(ddsd); + m_pddsRenderTarget->GetSurfaceDesc( &ddsd ); + + // Setup the surface desc for the z-buffer. + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT; + ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY; + ddsd.ddpfPixelFormat.dwSize = 0; // Tag the pixel format as unitialized + + // Get an appropiate pixel format from enumeration of the formats. On the + // first pass, we look for a zbuffer dpeth which is equal to the frame + // buffer depth (as some cards unfornately require this). + m_pD3D->EnumZBufferFormats( *pDeviceGUID, EnumZBufferFormatsCallback, + (VOID*)&ddsd.ddpfPixelFormat ); + if( 0 == ddsd.ddpfPixelFormat.dwSize ) + { + // Try again, just accepting any 16-bit zbuffer + ddsd.ddpfPixelFormat.dwRGBBitCount = 16; + m_pD3D->EnumZBufferFormats( *pDeviceGUID, EnumZBufferFormatsCallback, + (VOID*)&ddsd.ddpfPixelFormat ); + + if( 0 == ddsd.ddpfPixelFormat.dwSize ) + { + DEBUG_MSG( _T("Device doesn't support requested zbuffer format") ); + return D3DFWERR_NOZBUFFER; + } + } + + // Create and attach a z-buffer + if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsDepthBuffer, NULL ) ) ) + { + DEBUG_MSG( _T("Error: Couldn't create a ZBuffer surface") ); + if( hr != DDERR_OUTOFVIDEOMEMORY ) + return D3DFWERR_NOZBUFFER; + DEBUG_MSG( _T("Error: Out of video memory") ); + return DDERR_OUTOFVIDEOMEMORY; + } + + if( FAILED( m_pddsRenderTarget->AddAttachedSurface( m_pddsDepthBuffer ) ) ) + { + DEBUG_MSG( _T("Error: Couldn't attach zbuffer to render surface") ); + return D3DFWERR_NOZBUFFER; + } + + // Finally, this call rebuilds internal structures + if( FAILED( m_pD3DDevice->SetRenderTarget( m_pddsRenderTarget, 0L ) ) ) + { + DEBUG_MSG( _T("Error: SetRenderTarget() failed after attaching zbuffer!") ); + return D3DFWERR_NOZBUFFER; + } + + return S_OK; +} + +// Initializes the sample framework, then calls the app-specific function +// to initialize device specific objects. This code is structured to +// handled any errors that may occur duing initialization. + +HRESULT CD3DApplication::Initialize3DEnvironment() +{ + HRESULT hr; + DDSCAPS2 ddsCaps2; + DWORD dwFrameworkFlags = 0L; + DWORD dwTotal; + DWORD dwFree; + + dwFrameworkFlags |= ( !m_pDeviceInfo->bWindowed ? D3DFW_FULLSCREEN : 0L ); + dwFrameworkFlags |= ( m_pDeviceInfo->bStereo ? D3DFW_STEREO : 0L ); + dwFrameworkFlags |= ( m_bAppUseZBuffer ? D3DFW_ZBUFFER : 0L ); + + // Initialize the D3D framework + if( SUCCEEDED( hr = m_pFramework->Initialize( m_hWnd, + m_pDeviceInfo->pDriverGUID, m_pDeviceInfo->pDeviceGUID, + &m_pDeviceInfo->ddsdFullscreenMode, dwFrameworkFlags ) ) ) + { + m_pDD = m_pFramework->GetDirectDraw(); + m_pD3D = m_pFramework->GetDirect3D(); + m_pD3DDevice = m_pFramework->GetD3DDevice(); + + m_pD3DEngine->SetD3DDevice(m_pD3DDevice); + + m_pddsRenderTarget = m_pFramework->GetRenderSurface(); + + m_ddsdRenderTarget.dwSize = sizeof(m_ddsdRenderTarget); + m_pddsRenderTarget->GetSurfaceDesc( &m_ddsdRenderTarget ); + + // Request the amount of video memory. + ZeroMemory(&ddsCaps2, sizeof(ddsCaps2)); + ddsCaps2.dwCaps = DDSCAPS_TEXTURE; + dwTotal = 0; + hr = m_pDD->GetAvailableVidMem(&ddsCaps2, &dwTotal, &dwFree); + m_vidMemTotal = dwTotal; + + // Let the app run its startup code which creates the 3d scene. + if( SUCCEEDED( hr = m_pD3DEngine->InitDeviceObjects() ) ) + { +//? CreateZBuffer(m_pDeviceInfo->pDeviceGUID); + return S_OK; + } + else + { + DeleteDeviceObjects(); + m_pFramework->DestroyObjects(); + } + } + + // If we get here, the first initialization passed failed. If that was with a + // hardware device, try again using a software rasterizer instead. + if( m_pDeviceInfo->bHardware ) + { + // Try again with a software rasterizer + DisplayFrameworkError( hr, MSGWARN_SWITCHEDTOSOFTWARE ); + D3DEnum_SelectDefaultDevice( &m_pDeviceInfo, D3DENUM_SOFTWAREONLY ); + return Initialize3DEnvironment(); + } + + return hr; +} + + +// Handles driver, device, and/or mode changes for the app. + +HRESULT CD3DApplication::Change3DEnvironment() +{ +#if 0 + HRESULT hr; + static BOOL bOldWindowedState = TRUE; + static DWORD dwSavedStyle; + static RECT rcSaved; + + // Release all scene objects that will be re-created for the new device + DeleteDeviceObjects(); + + // Release framework objects, so a new device can be created + if( FAILED( hr = m_pFramework->DestroyObjects() ) ) + { + DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); + SendMessage( m_hWnd, WM_CLOSE, 0, 0 ); + return hr; + } + + // Check if going from fullscreen to windowed mode, or vice versa. + if( bOldWindowedState != m_pDeviceInfo->bWindowed ) + { + if( m_pDeviceInfo->bWindowed ) + { + // Coming from fullscreen mode, so restore window properties + SetWindowLong( m_hWnd, GWL_STYLE, dwSavedStyle ); + SetWindowPos( m_hWnd, HWND_NOTOPMOST, rcSaved.left, rcSaved.top, + ( rcSaved.right - rcSaved.left ), + ( rcSaved.bottom - rcSaved.top ), SWP_SHOWWINDOW ); + } + else + { + // Going to fullscreen mode, save/set window properties as needed + dwSavedStyle = GetWindowLong( m_hWnd, GWL_STYLE ); + GetWindowRect( m_hWnd, &rcSaved ); + SetWindowLong( m_hWnd, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE ); + } + + bOldWindowedState = m_pDeviceInfo->bWindowed; + } + + // Inform the framework class of the driver change. It will internally + // re-create valid surfaces, a d3ddevice, etc. + if( FAILED( hr = Initialize3DEnvironment() ) ) + { + DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); + SendMessage( m_hWnd, WM_CLOSE, 0, 0 ); + return hr; + } + + return S_OK; +#else + HRESULT hr; + + // Release all scene objects that will be re-created for the new device + DeleteDeviceObjects(); + + // Release framework objects, so a new device can be created + if( FAILED( hr = m_pFramework->DestroyObjects() ) ) + { + DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); + SendMessage( m_hWnd, WM_CLOSE, 0, 0 ); + return hr; + } + + if( m_pDeviceInfo->bWindowed ) + { + SetWindowPos(m_hWnd, HWND_NOTOPMOST, 10, 10, WINDOW_DX, WINDOW_DY, SWP_SHOWWINDOW); + } + + // Inform the framework class of the driver change. It will internally + // re-create valid surfaces, a d3ddevice, etc. + if( FAILED( hr = Initialize3DEnvironment() ) ) + { + DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); + SendMessage( m_hWnd, WM_CLOSE, 0, 0 ); + return hr; + } + + m_pD3DEngine->ChangeLOD(); + + if( m_pDeviceInfo->bWindowed ) + { + SetNiceMouse(FALSE); // hides the ugly windows mouse + } + + return S_OK; +#endif +} + + + +// Evolved throughout the game + +void CD3DApplication::StepSimul(float rTime) +{ + Event event; + + if ( m_pRobotMain == 0 ) return; + + ZeroMemory(&event, sizeof(Event)); + event.event = EVENT_FRAME; // funny bug release "Maximize speed"! + event.rTime = rTime; + event.axeX = AxeLimit(m_axeKey.x + m_axeJoy.x); + event.axeY = AxeLimit(m_axeKey.y + m_axeJoy.y); + event.axeZ = AxeLimit(m_axeKey.z + m_axeJoy.z); + event.keyState = m_keyState; + +//?char s[100]; +//?sprintf(s, "StepSimul %.3f\n", event.rTime); +//?OutputDebugString(s); + m_pRobotMain->EventProcess(event); +} + + +// Draws the scene. + +HRESULT CD3DApplication::Render3DEnvironment() +{ + HRESULT hr; + float rTime; + + // Check the cooperative level before rendering + if( FAILED( hr = m_pDD->TestCooperativeLevel() ) ) + { + switch( hr ) + { + case DDERR_EXCLUSIVEMODEALREADYSET: + case DDERR_NOEXCLUSIVEMODE: + OutputDebugString("DDERR_EXCLUSIVEMODEALREADYSET\n"); + // Do nothing because some other app has exclusive mode + return S_OK; + + case DDERR_WRONGMODE: + OutputDebugString("DDERR_WRONGMODE\n"); + // The display mode changed on us. Resize accordingly + if( m_pDeviceInfo->bWindowed ) + return Change3DEnvironment(); + break; + } + return hr; + } + + // Get the relative time, in seconds + rTime = m_pD3DEngine->TimeGet(); + if ( rTime > MAX_STEP ) rTime = MAX_STEP; // never more than 0.5s! + m_aTime += rTime; + +#if !USE_THREAD + if( FAILED( hr = m_pD3DEngine->FrameMove(rTime) ) ) + return hr; + + // FrameMove (animate) the scene + StepSimul(rTime); +#endif + + // Render the scene. + if( FAILED( hr = m_pD3DEngine->Render() ) ) + return hr; + + DrawSuppl(); + + // Show the frame rate, etc. + if( m_bShowStats ) + ShowStats(); + + // Show the frame on the primary surface. + if( FAILED( hr = m_pFramework->ShowFrame() ) ) + { + if( DDERR_SURFACELOST != hr ) + return hr; + + m_pFramework->RestoreSurfaces(); + m_pD3DEngine->RestoreSurfaces(); + } + + return S_OK; +} + + +// Cleanup scene objects + +VOID CD3DApplication::Cleanup3DEnvironment() +{ + m_bActive = FALSE; + m_bReady = FALSE; + + if( m_pFramework ) + { + DeleteDeviceObjects(); + SAFE_DELETE( m_pFramework ); + + m_pD3DEngine->FinalCleanup(); + } + + D3DEnum_FreeResources(); +//? FreeDirectInput(); +} + +// Called when the app is exitting, or the device is being changed, +// this function deletes any device dependant objects. + +VOID CD3DApplication::DeleteDeviceObjects() +{ + if( m_pFramework ) + { + m_pD3DEngine->DeleteDeviceObjects(); + SAFE_RELEASE( m_pddsDepthBuffer ); + } +} + + + +// Called in to toggle the pause state of the app. This function +// brings the GDI surface to the front of the display, so drawing +// output like message boxes and menus may be displayed. + +VOID CD3DApplication::Pause( BOOL bPause ) +{ + static DWORD dwAppPausedCount = 0L; + + dwAppPausedCount += ( bPause ? +1 : -1 ); + m_bReady = ( dwAppPausedCount ? FALSE : TRUE ); + + // Handle the first pause request (of many, nestable pause requests) + if( bPause && ( 1 == dwAppPausedCount ) ) + { + // Get a surface for the GDI + if( m_pFramework ) + m_pFramework->FlipToGDISurface( TRUE ); + + // Stop the scene from animating + m_pD3DEngine->TimeEnterGel(); + } + + if( 0 == dwAppPausedCount ) + { + // Restart the scene + m_pD3DEngine->TimeExitGel(); + } +} + + +// Called when the app receives a PBT_APMQUERYSUSPEND message, meaning +// the computer is about to be suspended. At this point, the app should +// save any data for open network connections, files, etc.., and prepare +// to go into a suspended mode. + +LRESULT CD3DApplication::OnQuerySuspend( DWORD dwFlags ) +{ + OutputDebugString("OnQuerySuspend\n"); + Pause(TRUE); + return TRUE; +} + + +// Called when the app receives a PBT_APMRESUMESUSPEND message, meaning +// the computer has just resumed from a suspended state. At this point, +// the app should recover any data, network connections, files, etc.., +// and resume running from when the app was suspended. + +LRESULT CD3DApplication::OnResumeSuspend( DWORD dwData ) +{ + OutputDebugString("OnResumeSuspend\n"); + Pause(FALSE); + return TRUE; +} + + +// Draw all the additional graphic elements. + +void CD3DApplication::DrawSuppl() +{ + HDC hDC; + FPOINT p1, p2; + POINT list[3]; + RECT rect; + HPEN hPen; + HGDIOBJ old; + FPOINT pos; + float d; + int nbOut; + + if ( FAILED(m_pddsRenderTarget->GetDC(&hDC)) ) return; + + // Displays the selection rectangle. + if ( m_pD3DEngine->GetHilite(p1, p2) ) + { + nbOut = 0; + if ( p1.x < 0.0f || p1.x > 1.0f ) nbOut ++; + if ( p1.y < 0.0f || p1.y > 1.0f ) nbOut ++; + if ( p2.x < 0.0f || p2.x > 1.0f ) nbOut ++; + if ( p2.y < 0.0f || p2.y > 1.0f ) nbOut ++; + if ( nbOut <= 2 ) + { +#if 0 + time = Mod(m_aTime, 0.5f); + if ( time < 0.25f ) d = time*4.0f; + else d = (2.0f-time*4.0f); +#endif +#if 0 + time = Mod(m_aTime, 0.5f); + if ( time < 0.4f ) d = time/0.4f; + else d = 1.0f-(time-0.4f)/0.1f; +#endif +#if 1 + d = 0.5f+sinf(m_aTime*6.0f)*0.5f; +#endif + d *= (p2.x-p1.x)*0.1f; + p1.x += d; + p1.y += d; + p2.x -= d; + p2.y -= d; + + hPen = CreatePen(PS_SOLID, 1, RGB(255,255,0)); // yellow + old = SelectObject(hDC, hPen); + + rect.left = (int)(p1.x*m_ddsdRenderTarget.dwWidth); + rect.right = (int)(p2.x*m_ddsdRenderTarget.dwWidth); + rect.top = (int)((1.0f-p2.y)*m_ddsdRenderTarget.dwHeight); + rect.bottom = (int)((1.0f-p1.y)*m_ddsdRenderTarget.dwHeight); + + list[0].x = rect.left; + list[0].y = rect.top+(rect.bottom-rect.top)/5; + list[1].x = rect.left; + list[1].y = rect.top; + list[2].x = rect.left+(rect.right-rect.left)/5; + list[2].y = rect.top; + Polyline(hDC, list, 3); + + list[0].x = rect.right; + list[0].y = rect.top+(rect.bottom-rect.top)/5; + list[1].x = rect.right; + list[1].y = rect.top; + list[2].x = rect.right+(rect.left-rect.right)/5; + list[2].y = rect.top; + Polyline(hDC, list, 3); + + list[0].x = rect.left; + list[0].y = rect.bottom+(rect.top-rect.bottom)/5; + list[1].x = rect.left; + list[1].y = rect.bottom; + list[2].x = rect.left+(rect.right-rect.left)/5; + list[2].y = rect.bottom; + Polyline(hDC, list, 3); + + list[0].x = rect.right; + list[0].y = rect.bottom+(rect.top-rect.bottom)/5; + list[1].x = rect.right; + list[1].y = rect.bottom; + list[2].x = rect.right+(rect.left-rect.right)/5; + list[2].y = rect.bottom; + Polyline(hDC, list, 3); + + if ( old != 0 ) SelectObject(hDC, old); + DeleteObject(hPen); + } + } + + m_pddsRenderTarget->ReleaseDC(hDC); +} + +// Shows frame rate and dimensions of the rendering device. + +VOID CD3DApplication::ShowStats() +{ + static FLOAT fFPS = 0.0f; + static FLOAT fLastTime = 0.0f; + static DWORD dwFrames = 0L; + + // Keep track of the time lapse and frame count + FLOAT fTime = timeGetTime() * 0.001f; // Get current time in seconds + ++dwFrames; + + // Update the frame rate once per second + if( fTime - fLastTime > 1.0f ) + { + fFPS = dwFrames / (fTime - fLastTime); + fLastTime = fTime; + dwFrames = 0L; + } + + int t = m_pD3DEngine->RetStatisticTriangle(); + + // Setup the text buffer to write out dimensions + TCHAR buffer[100]; + sprintf( buffer, _T("%7.02f fps T=%d (%dx%dx%d)"), fFPS, t, + m_ddsdRenderTarget.dwWidth, m_ddsdRenderTarget.dwHeight, + m_ddsdRenderTarget.ddpfPixelFormat.dwRGBBitCount ); + OutputText( 400, 2, buffer ); + + int x, y, i; + if ( m_pD3DEngine->GetSpriteCoord(x, y) ) + { + OutputText( x, y, "+" ); + } + + for ( i=0 ; i<10 ; i++ ) + { + char* info = m_pD3DEngine->RetInfoText(i); + x = 50; + y = m_ddsdRenderTarget.dwHeight-20-i*20; + OutputText( x, y, info ); + } +} + + +// Draws text on the window. + +VOID CD3DApplication::OutputText( DWORD x, DWORD y, TCHAR* str ) +{ + HDC hDC; + + // Get a DC for the surface. Then, write out the buffer + if( m_pddsRenderTarget ) + { + if( SUCCEEDED( m_pddsRenderTarget->GetDC(&hDC) ) ) + { + SetTextColor( hDC, RGB(255,255,0) ); + SetBkMode( hDC, TRANSPARENT ); + ExtTextOut( hDC, x, y, 0, NULL, str, lstrlen(str), NULL ); + m_pddsRenderTarget->ReleaseDC(hDC); + } + } +} + + + + +// Defines a function that allocates memory for and initializes +// members within a BITMAPINFOHEADER structure + +PBITMAPINFO CD3DApplication::CreateBitmapInfoStruct(HBITMAP hBmp) +{ + BITMAP bmp; + PBITMAPINFO pbmi; + WORD cClrBits; + + // Retrieve the bitmap's color format, width, and height. + if ( !GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp) ) + return 0; + + // Convert the color format to a count of bits. + cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); + + if ( cClrBits == 1 ) cClrBits = 1; + else if ( cClrBits <= 4 ) cClrBits = 4; + else if ( cClrBits <= 8 ) cClrBits = 8; + else if ( cClrBits <= 16 ) cClrBits = 16; + else if ( cClrBits <= 24 ) cClrBits = 24; + else cClrBits = 32; + + // Allocate memory for the BITMAPINFO structure. (This structure + // contains a BITMAPINFOHEADER structure and an array of RGBQUAD data + // structures.) + if ( cClrBits != 24 ) + { + pbmi = (PBITMAPINFO)LocalAlloc(LPTR, + sizeof(BITMAPINFOHEADER) + + sizeof(RGBQUAD) * (2^cClrBits)); + } + // There is no RGBQUAD array for the 24-bit-per-pixel format. + else + { + pbmi = (PBITMAPINFO)LocalAlloc(LPTR, + sizeof(BITMAPINFOHEADER)); + } + + // Initialize the fields in the BITMAPINFO structure. + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biWidth = bmp.bmWidth; + pbmi->bmiHeader.biHeight = bmp.bmHeight; + pbmi->bmiHeader.biPlanes = bmp.bmPlanes; + pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel; + if ( cClrBits < 24 ) + pbmi->bmiHeader.biClrUsed = 2^cClrBits; + + // If the bitmap is not compressed, set the BI_RGB flag. + pbmi->bmiHeader.biCompression = BI_RGB; + + // Compute the number of bytes in the array of color + // indices and store the result in biSizeImage. + pbmi->bmiHeader.biSizeImage = (pbmi->bmiHeader.biWidth + 7) /8 + * pbmi->bmiHeader.biHeight + * cClrBits; + + // Set biClrImportant to 0, indicating that all of the + // device colors are important. + pbmi->bmiHeader.biClrImportant = 0; + + return pbmi; +} + +// Defines a function that initializes the remaining structures, +// retrieves the array of palette indices, opens the file, copies +// the data, and closes the file. + +BOOL CD3DApplication::CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC) +{ + FILE* file; // file handle + BITMAPFILEHEADER hdr; // bitmap file-header + PBITMAPINFOHEADER pbih; // bitmap info-header + LPBYTE lpBits; // memory pointer + DWORD dwTotal; // total count of bytes + + pbih = (PBITMAPINFOHEADER)pbi; + lpBits = (LPBYTE)GlobalAlloc(GMEM_FIXED, pbih->biSizeImage); + if ( !lpBits ) return FALSE; + + // Retrieve the color table (RGBQUAD array) and the bits + // (array of palette indices) from the DIB. + if ( !GetDIBits(hDC, hBMP, 0, (WORD)pbih->biHeight, + lpBits, pbi, DIB_RGB_COLORS) ) + return FALSE; + + // Create the .BMP file. + file = fopen(pszFile, "wb"); + if ( file == NULL ) return FALSE; + + hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" + + // Compute the size of the entire file. + hdr.bfSize = (DWORD)(sizeof(BITMAPFILEHEADER) + + pbih->biSize + pbih->biClrUsed + * sizeof(RGBQUAD) + pbih->biSizeImage); + + hdr.bfReserved1 = 0; + hdr.bfReserved2 = 0; + + // Compute the offset to the array of color indices. + hdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + + pbih->biSize + pbih->biClrUsed + * sizeof (RGBQUAD); + + // Copy the BITMAPFILEHEADER into the .BMP file. + fwrite(&hdr, sizeof(BITMAPFILEHEADER), 1, file); + + // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. + fwrite(pbih, sizeof(BITMAPINFOHEADER)+pbih->biClrUsed*sizeof(RGBQUAD), 1, file); + + // Copy the array of color indices into the .BMP file. + dwTotal = pbih->biSizeImage; + fwrite(lpBits, dwTotal, 1, file); + + // Close the .BMP file. + fclose(file); + + // Free memory. + GlobalFree((HGLOBAL)lpBits); + return TRUE; +} + +// Write a file. BMP screenshot. + +BOOL CD3DApplication::WriteScreenShot(char *filename, int width, int height) +{ + D3DVIEWPORT7 vp; + HDC hDC; + HDC hDCImage; + HBITMAP hb; + PBITMAPINFO info; + int dx, dy; + + m_pD3DDevice->GetViewport(&vp); + dx = vp.dwWidth; + dy = vp.dwHeight; + + if ( FAILED(m_pddsRenderTarget->GetDC(&hDC)) ) return FALSE; + + hDCImage = CreateCompatibleDC(hDC); + if ( hDCImage == 0 ) + { + m_pddsRenderTarget->ReleaseDC(hDC); + return FALSE; + } + + hb = CreateCompatibleBitmap(hDC, width, height); + if ( hb == 0 ) + { + DeleteDC(hDCImage); + m_pddsRenderTarget->ReleaseDC(hDC); + return FALSE; + } + + SelectObject(hDCImage, hb); + StretchBlt(hDCImage, 0, 0, width, height, hDC, 0, 0, dx, dy, SRCCOPY); + + info = CreateBitmapInfoStruct(hb); + if ( info == 0 ) + { + DeleteObject(hb); + DeleteDC(hDCImage); + m_pddsRenderTarget->ReleaseDC(hDC); + return FALSE; + } + + CreateBMPFile(filename, info, hb, hDCImage); + + DeleteObject(hb); + DeleteDC(hDCImage); + m_pddsRenderTarget->ReleaseDC(hDC); + return TRUE; +} + + +// Initializes an hDC on the rendering surface. + +BOOL CD3DApplication::GetRenderDC(HDC &hDC) +{ + if ( FAILED(m_pddsRenderTarget->GetDC(&hDC)) ) return FALSE; + return TRUE; +} + +// Frees the hDC of the rendering surface. + +BOOL CD3DApplication::ReleaseRenderDC(HDC &hDC) +{ + m_pddsRenderTarget->ReleaseDC(hDC); + return TRUE; +} + + + + +// Perform the list of all graphics devices available. +// For the device selected, lists the full screen modes +// possible. +// buf* --> nom1<0> nom2<0> <0> + +BOOL CD3DApplication::EnumDevices(char *bufDevices, int lenDevices, + char *bufModes, int lenModes, + int &totalDevices, int &selectDevices, + int &totalModes, int &selectModes) +{ + D3DEnum_DeviceInfo* pDeviceList; + D3DEnum_DeviceInfo* pDevice; + DDSURFACEDESC2* pddsdMode; + DWORD numDevices, device, mode; + int len; + char text[100]; + + D3DEnum_GetDevices(&pDeviceList, &numDevices); + + selectDevices = -1; + selectModes = -1; + totalModes = 0; + for( device=0 ; devicestrDesc)+1; + if ( len >= lenDevices ) break; // bufDevices full! + strcpy(bufDevices, pDevice->strDesc); + bufDevices += len; + lenDevices -= len; + + if ( pDevice == m_pDeviceInfo ) // select device ? + { + selectDevices = device; + + for( mode=0 ; modedwNumModes ; mode++ ) + { + pddsdMode = &pDevice->pddsdModes[mode]; + + sprintf(text, "%ld x %ld x %ld", + pddsdMode->dwWidth, + pddsdMode->dwHeight, + pddsdMode->ddpfPixelFormat.dwRGBBitCount); + + len = strlen(text)+1; + if ( len >= lenModes ) break; // bufModes full ! + strcpy(bufModes, text); + bufModes += len; + lenModes -= len; + + if ( mode == m_pDeviceInfo->dwCurrentMode ) // select mode ? + { + selectModes = mode; + } + } + bufModes[0] = 0; + totalModes = pDevice->dwNumModes; + } + } + bufDevices[0] = 0; + totalDevices = numDevices; + + return TRUE; +} + +// Indicates whether it is in full screen mode. + +BOOL CD3DApplication::RetFullScreen() +{ + return !m_pDeviceInfo->bWindowed; +} + +// Change the graphics mode. + +BOOL CD3DApplication::ChangeDevice(char *deviceName, char *modeName, + BOOL bFull) +{ + D3DEnum_DeviceInfo* pDeviceList; + D3DEnum_DeviceInfo* pDevice; + DDSURFACEDESC2* pddsdMode; + DWORD numDevices, device, mode; + HRESULT hr; + char text[100]; + + D3DEnum_GetDevices(&pDeviceList, &numDevices); + + for( device=0 ; devicestrDesc, deviceName) == 0 ) // device found ? + { + for( mode=0 ; modedwNumModes ; mode++ ) + { + pddsdMode = &pDevice->pddsdModes[mode]; + + sprintf(text, "%ld x %ld x %ld", + pddsdMode->dwWidth, + pddsdMode->dwHeight, + pddsdMode->ddpfPixelFormat.dwRGBBitCount); + + if ( strcmp(text, modeName) == 0 ) // mode found ? + { + m_pDeviceInfo = pDevice; + pDevice->bWindowed = !bFull; + pDevice->dwCurrentMode = mode; + pDevice->ddsdFullscreenMode = pDevice->pddsdModes[mode]; + + m_bReady = FALSE; + + if ( FAILED( hr = Change3DEnvironment() ) ) + { + return FALSE; + } + + SetProfileString("Device", "Name", deviceName); + SetProfileString("Device", "Mode", modeName); + SetProfileInt("Device", "FullScreen", bFull); + m_bReady = TRUE; + return TRUE; + } + } + } + } + + return FALSE; +} + + + +// Displays error messages in a message box. + +VOID CD3DApplication::DisplayFrameworkError( HRESULT hr, DWORD dwType ) +{ + TCHAR strMsg[512]; + + switch( hr ) + { + case D3DENUMERR_ENGINE: + lstrcpy( strMsg, _T("Could not create 3D Engine application!") ); + break; + case D3DENUMERR_ROBOT: + lstrcpy( strMsg, _T("Could not create Robot application!") ); + break; + case D3DENUMERR_NODIRECTDRAW: + lstrcpy( strMsg, _T("Could not create DirectDraw!") ); + break; + case D3DENUMERR_NOCOMPATIBLEDEVICES: + lstrcpy( strMsg, _T("Could not find any compatible Direct3D\n" + "devices.") ); + break; + case D3DENUMERR_SUGGESTREFRAST: + lstrcpy( strMsg, _T("Could not find any compatible devices.\n\n" + "Try enabling the reference rasterizer using\n" + "EnableRefRast.reg.") ); + break; + case D3DENUMERR_ENUMERATIONFAILED: + lstrcpy( strMsg, _T("Enumeration failed. Your system may be in an\n" + "unstable state and need to be rebooted") ); + break; + case D3DFWERR_INITIALIZATIONFAILED: + lstrcpy( strMsg, _T("Generic initialization error.\n\nEnable " + "debug output for detailed information.") ); + break; + case D3DFWERR_NODIRECTDRAW: + lstrcpy( strMsg, _T("No DirectDraw") ); + break; + case D3DFWERR_NODIRECT3D: + lstrcpy( strMsg, _T("No Direct3D") ); + break; + case D3DFWERR_INVALIDMODE: + lstrcpy( strMsg, _T("COLOBOT requires a 16-bit (or higher) " + "display mode\nto run in a window.\n\nPlease " + "switch your desktop settings accordingly.") ); + break; + case D3DFWERR_COULDNTSETCOOPLEVEL: + lstrcpy( strMsg, _T("Could not set Cooperative Level") ); + break; + case D3DFWERR_NO3DDEVICE: + lstrcpy( strMsg, _T("Could not create the Direct3DDevice object.") ); + + if( MSGWARN_SWITCHEDTOSOFTWARE == dwType ) + lstrcat( strMsg, _T("\nThe 3D hardware chipset may not support" + "\nrendering in the current display mode.") ); + break; + case D3DFWERR_NOZBUFFER: + lstrcpy( strMsg, _T("No ZBuffer") ); + break; + case D3DFWERR_INVALIDZBUFFERDEPTH: + lstrcpy( strMsg, _T("Invalid Z-buffer depth. Try switching modes\n" + "from 16- to 32-bit (or vice versa)") ); + break; + case D3DFWERR_NOVIEWPORT: + lstrcpy( strMsg, _T("No Viewport") ); + break; + case D3DFWERR_NOPRIMARY: + lstrcpy( strMsg, _T("No primary") ); + break; + case D3DFWERR_NOCLIPPER: + lstrcpy( strMsg, _T("No Clipper") ); + break; + case D3DFWERR_BADDISPLAYMODE: + lstrcpy( strMsg, _T("Bad display mode") ); + break; + case D3DFWERR_NOBACKBUFFER: + lstrcpy( strMsg, _T("No backbuffer") ); + break; + case D3DFWERR_NONZEROREFCOUNT: + lstrcpy( strMsg, _T("A DDraw object has a non-zero reference\n" + "count (meaning it was not properly cleaned up)." ) ); + break; + case D3DFWERR_NORENDERTARGET: + lstrcpy( strMsg, _T("No render target") ); + break; + case E_OUTOFMEMORY: + lstrcpy( strMsg, _T("Not enough memory!") ); + break; + case DDERR_OUTOFVIDEOMEMORY: + lstrcpy( strMsg, _T("There was insufficient video memory " + "to use the\nhardware device.") ); + break; + default: + lstrcpy( strMsg, _T("Generic application error.\n\nEnable " + "debug output for detailed information.") ); + } + + if( MSGERR_APPMUSTEXIT == dwType ) + { + lstrcat( strMsg, _T("\n\nCOLOBOT will now exit.") ); + MessageBox( NULL, strMsg, m_strWindowTitle, MB_ICONERROR|MB_OK ); + } + else + { + if( MSGWARN_SWITCHEDTOSOFTWARE == dwType ) + lstrcat( strMsg, _T("\n\nSwitching to software rasterizer.") ); + MessageBox( NULL, strMsg, m_strWindowTitle, MB_ICONWARNING|MB_OK ); + } +} + + diff --git a/src/app/d3dapp.h b/src/app/d3dapp.h new file mode 100644 index 0000000..6f28cda --- /dev/null +++ b/src/app/d3dapp.h @@ -0,0 +1,168 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// d3dapp.h + + +#ifndef _D3DAPP_H +#define _D3DAPP_H + +#define D3D_OVERLOADS + +#include + +#include "d3dengine.h" +#include "d3dframe.h" +#include "d3denum.h" +#include "d3dutil.h" +#include "d3dres.h" +#include "misc.h" +#include "struct.h" + + +class CInstanceManager; +class CEvent; +class CRobotMain; +class CSound; + + + +class CD3DApplication +{ +public: + CD3DApplication(); + ~CD3DApplication(); + +protected: + LRESULT OnQuerySuspend( DWORD dwFlags ); + LRESULT OnResumeSuspend( DWORD dwData ); + +public: + Error RegQuery(); + Error AudioQuery(); + Error CheckMistery(char *strCmdLine); + int GetVidMemTotal(); + BOOL IsVideo8MB(); + BOOL IsVideo32MB(); + HRESULT Create( HINSTANCE, TCHAR* ); + INT Run(); + LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + VOID Pause( BOOL bPause ); + FPOINT ConvPosToInterface(HWND hWnd, LPARAM lParam); + void SetMousePos(FPOINT pos); + void StepSimul(float rTime); + char* RetCDpath(); + + void SetShowStat(BOOL bShow); + BOOL RetShowStat(); + void SetDebugMode(BOOL bMode); + BOOL RetDebugMode(); + BOOL RetSetupMode(); + + BOOL EnumDevices(char *bufDevices, int lenDevices, char *bufModes, int lenModes, int &totalDevices, int &selectDevices, int &totalModes, int &selectModes); + BOOL RetFullScreen(); + BOOL ChangeDevice(char *device, char *mode, BOOL bFull); + + void FlushPressKey(); + void ResetKey(); + void SetKey(int keyRank, int option, int key); + int RetKey(int keyRank, int option); + + void SetJoystick(BOOL bEnable); + BOOL RetJoystick(); + + void SetMouseType(D3DMouse type); + void SetNiceMouse(BOOL bNice); + BOOL RetNiceMouse(); + BOOL RetNiceMouseCap(); + + BOOL WriteScreenShot(char *filename, int width, int height); + + BOOL GetRenderDC(HDC &hDC); + BOOL ReleaseRenderDC(HDC &hDC); + PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp); + BOOL CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC); + +protected: + HRESULT ConfirmDevice( DDCAPS* pddDriverCaps, D3DDEVICEDESC7* pd3dDeviceDesc ); + HRESULT Initialize3DEnvironment(); + HRESULT Change3DEnvironment(); + HRESULT CreateZBuffer(GUID* pDeviceGUID); + HRESULT Render3DEnvironment(); + VOID Cleanup3DEnvironment(); + VOID DeleteDeviceObjects(); + VOID DisplayFrameworkError( HRESULT, DWORD ); + + void InitText(); + void DrawSuppl(); + VOID ShowStats(); + VOID OutputText( DWORD x, DWORD y, TCHAR* str ); + +protected: + CInstanceManager* m_iMan; + CEvent* m_event; + + HINSTANCE m_instance; + HWND m_hWnd; + D3DEnum_DeviceInfo* m_pDeviceInfo; + LPDIRECTDRAW7 m_pDD; + LPDIRECT3D7 m_pD3D; + LPDIRECT3DDEVICE7 m_pD3DDevice; + LPDIRECTDRAWSURFACE7 m_pddsRenderTarget; + DDSURFACEDESC2 m_ddsdRenderTarget; + LPDIRECTDRAWSURFACE7 m_pddsDepthBuffer; + + HANDLE m_thread; + DWORD m_threadId; + + char m_CDpath[100]; + + CD3DFramework7* m_pFramework; + BOOL m_bActive; + BOOL m_bActivateApp; + BOOL m_bReady; + BOOL m_bJoystick; + + DWORD m_vidMemTotal; + TCHAR* m_strWindowTitle; + BOOL m_bAppUseZBuffer; + BOOL m_bAppUseStereo; + BOOL m_bShowStats; + BOOL m_bDebugMode; + BOOL m_bAudioState; + BOOL m_bAudioTrack; + BOOL m_bNiceMouse; + BOOL m_bSetupMode; + HRESULT (*m_fnConfirmDevice)(DDCAPS*, D3DDEVICEDESC7*); + +public: + CD3DEngine* m_pD3DEngine; + CRobotMain* m_pRobotMain; + CSound* m_pSound; + + int m_keyState; + D3DVECTOR m_axeKey; + D3DVECTOR m_axeJoy; + BOOL m_bJoyButton[32]; + FPOINT m_mousePos; + DWORD m_mshMouseWheel; + + float m_aTime; + DWORD m_key[50][2]; +}; + + +#endif // _D3DAPP_H diff --git a/src/app/joystick.cpp b/src/app/joystick.cpp new file mode 100644 index 0000000..609a1fb --- /dev/null +++ b/src/app/joystick.cpp @@ -0,0 +1,245 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// joystick.cpp + +#define STRICT +#define DIRECTINPUT_VERSION 0x0700 + +#include +#include +#include + +#include "joystick.h" + + + + +// Global variables. + +LPDIRECTINPUT7 g_pDI = NULL; +LPDIRECTINPUTDEVICE2 g_pJoystick = NULL; +DIDEVCAPS g_diDevCaps; + + + + + +// Called once for each enumerated joystick. If we find one, create a +// device interface on it so we can play with it. + +BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, + VOID* pContext ) +{ + HRESULT hr; + + // Obtain an interface to the enumerated joystick. + hr = g_pDI->CreateDeviceEx( pdidInstance->guidInstance, IID_IDirectInputDevice2, + (VOID**)&g_pJoystick, NULL ); + + // If it failed, then we can't use this joystick. (Maybe the user unplugged + // it while we were in the middle of enumerating it.) + if( FAILED(hr) ) + return DIENUM_CONTINUE; + + + // Stop enumeration. Note: we're just taking the first joystick we get. You + // could store all the enumerated joysticks and let the user pick. + return DIENUM_STOP; +} + + +// Callback function for enumerating the axes on a joystick. + +BOOL CALLBACK EnumAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, + VOID* pContext ) +{ + DIPROPRANGE diprg; + diprg.diph.dwSize = sizeof(DIPROPRANGE); + diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); + diprg.diph.dwHow = DIPH_BYOFFSET; + diprg.diph.dwObj = pdidoi->dwOfs; // Specify the enumerated axis + diprg.lMin = -1000; + diprg.lMax = +1000; + + // Set the range for the axis + if( FAILED( g_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) ) + return DIENUM_STOP; + +#ifndef __MINGW32__ // FIXME Doesn't work under MinGW + // Set the UI to reflect what axes the joystick supports + switch( pdidoi->dwOfs ) + { + case DIJOFS_X: + OutputDebugString("EnumAxesCallback -x\n"); + break; + case DIJOFS_Y: + OutputDebugString("EnumAxesCallback -y\n"); + break; + case DIJOFS_Z: + OutputDebugString("EnumAxesCallback -z\n"); + break; + case DIJOFS_RX: + OutputDebugString("EnumAxesCallback -rx\n"); + break; + case DIJOFS_RY: + OutputDebugString("EnumAxesCallback -ry\n"); + break; + case DIJOFS_RZ: + OutputDebugString("EnumAxesCallback -rz\n"); + break; + case DIJOFS_SLIDER(0): + OutputDebugString("EnumAxesCallback -s0\n"); + break; + case DIJOFS_SLIDER(1): + OutputDebugString("EnumAxesCallback -s1\n"); + break; + } +#endif + + return DIENUM_CONTINUE; +} + + +// Initialize the DirectInput variables. + +BOOL InitDirectInput(HINSTANCE hInst, HWND hWnd) +{ + HRESULT hr; + + // Register with the DirectInput subsystem and get a pointer + // to a IDirectInput interface we can use. +#ifndef __MINGW32__ // FIXME Doesn't work under MinGW + hr = DirectInputCreateEx( hInst, DIRECTINPUT_VERSION,IID_IDirectInput7, (LPVOID*)&g_pDI, NULL ); + if( FAILED(hr) ) return FALSE; +#else + return FALSE; +#endif + + // Look for a simple joystick we can use for this sample program. + hr = g_pDI->EnumDevices( DIDEVTYPE_JOYSTICK, EnumJoysticksCallback, + NULL, DIEDFL_ATTACHEDONLY ); + if( FAILED(hr) ) return FALSE; + + // Make sure we got a joystick + if( NULL == g_pJoystick ) + { +//? MessageBox( NULL, "Joystick not found", "DInput Sample", +//? MB_ICONERROR | MB_OK ); + return FALSE; + } + + // Set the data format to "simple joystick" - a predefined data format + // + // A data format specifies which controls on a device we are interested in, + // and how they should be reported. This tells DInput that we will be + // passing a DIJOYSTATE structure to IDirectInputDevice::GetDeviceState(). + hr = g_pJoystick->SetDataFormat( &c_dfDIJoystick ); + if( FAILED(hr) ) return FALSE; + + // Set the cooperative level to let DInput know how this device should + // interact with the system and with other DInput applications. + hr = g_pJoystick->SetCooperativeLevel( hWnd, DISCL_EXCLUSIVE|DISCL_FOREGROUND ); + if( FAILED(hr) ) return FALSE; + + // Determine how many axis the joystick has (so we don't error out setting + // properties for unavailable axis) + g_diDevCaps.dwSize = sizeof(DIDEVCAPS); + hr = g_pJoystick->GetCapabilities(&g_diDevCaps); + if( FAILED(hr) ) return FALSE; + + + // Enumerate the axes of the joyctick and set the range of each axis. Note: + // we could just use the defaults, but we're just trying to show an example + // of enumerating device objects (axes, buttons, etc.). + g_pJoystick->EnumObjects( EnumAxesCallback, (VOID*)g_pJoystick, DIDFT_AXIS ); + + return TRUE; +} + +// Acquire or unacquire the keyboard, depending on if the app is active +// Input device must be acquired before the GetDeviceState is called. + +BOOL SetAcquire(BOOL bActive) +{ + if ( g_pJoystick ) + { + if( bActive ) g_pJoystick->Acquire(); + else g_pJoystick->Unacquire(); + } + return TRUE; +} + + +// Get the input device's state and display it. + +BOOL UpdateInputState( DIJOYSTATE &js ) +{ + HRESULT hr; + + if ( g_pJoystick ) + { + do + { + // Poll the device to read the current state + hr = g_pJoystick->Poll(); + if ( FAILED(hr) ) return FALSE; + + // Get the input's device state + hr = g_pJoystick->GetDeviceState( sizeof(DIJOYSTATE), &js ); + + if( hr == DIERR_INPUTLOST ) + { + // DInput is telling us that the input stream has been + // interrupted. We aren't tracking any state between polls, so + // we don't have any special reset that needs to be done. We + // just re-acquire and try again. + hr = g_pJoystick->Acquire(); + if ( FAILED(hr) ) return FALSE; + } + } + while ( DIERR_INPUTLOST == hr ); + if ( FAILED(hr) ) return FALSE; + } + return TRUE; +} + + +// Initialize the DirectInput variables. + +BOOL FreeDirectInput() +{ + // Unacquire and release any DirectInputDevice objects. + if( NULL != g_pJoystick ) + { + // Unacquire the device one last time just in case + // the app tried to exit while the device is still acquired. + g_pJoystick->Unacquire(); + g_pJoystick->Release(); + g_pJoystick = NULL; + } + + + // Release any DirectInput objects. + if( g_pDI ) + { + g_pDI->Release(); + g_pDI = NULL; + } + + return TRUE; +} + diff --git a/src/app/joystick.h b/src/app/joystick.h new file mode 100644 index 0000000..4b465e0 --- /dev/null +++ b/src/app/joystick.h @@ -0,0 +1,31 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// joystick.h + +#ifndef _JOYSTICK_H_ +#define _JOYSTICK_H_ + + + +extern BOOL InitDirectInput(HINSTANCE hInst, HWND hWnd); +extern BOOL SetAcquire(BOOL bActive); +extern BOOL UpdateInputState(DIJOYSTATE &js); +extern BOOL FreeDirectInput(); + + + +#endif //_JOYSTICK_H_ diff --git a/src/auto.cpp b/src/auto.cpp deleted file mode 100644 index 9711423..0000000 --- a/src/auto.cpp +++ /dev/null @@ -1,461 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "light.h" -#include "terrain.h" -#include "water.h" -#include "cloud.h" -#include "planet.h" -#include "blitz.h" -#include "camera.h" -#include "object.h" -#include "modfile.h" -#include "interface.h" -#include "button.h" -#include "list.h" -#include "label.h" -#include "gauge.h" -#include "window.h" -#include "robotmain.h" -#include "displaytext.h" -#include "sound.h" -#include "cmdtoken.h" -#include "auto.h" - - - - -// Object's constructor. - -CAuto::CAuto(CInstanceManager* iMan, CObject* object) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_AUTO, this, 100); - - m_object = object; - m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - m_cloud = (CCloud*)m_iMan->SearchInstance(CLASS_CLOUD); - m_planet = (CPlanet*)m_iMan->SearchInstance(CLASS_PLANET); - m_blitz = (CBlitz*)m_iMan->SearchInstance(CLASS_BLITZ); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - - m_type = m_object->RetType(); - m_time = 0.0f; - m_lastUpdateTime = 0.0f; - m_bMotor = FALSE; - m_progressTime = 0.0f; - m_progressTotal = 1.0f; - - Init(); -} - -// Object's destructor. - -CAuto::~CAuto() -{ - m_iMan->DeleteInstance(CLASS_AUTO, this); -} - - -// Destroys the object. - -void CAuto::DeleteObject(BOOL bAll) -{ -} - - -// Initialize the object. - -void CAuto::Init() -{ - m_bBusy = FALSE; -} - -// Starts the object. - -void CAuto::Start(int param) -{ -} - - -// Give a type. - -BOOL CAuto::SetType(ObjectType type) -{ - return FALSE; -} - -// Gives a value. - -BOOL CAuto::SetValue(int rank, float value) -{ - return FALSE; -} - -// Gives the string. - -BOOL CAuto::SetString(char *string) -{ - return FALSE; -} - - -// Management of an event. - -BOOL CAuto::EventProcess(const Event &event) -{ - if ( event.event == EVENT_FRAME && - !m_engine->RetPause() ) - { - m_time += event.rTime; - UpdateInterface(event.rTime); - } - - if ( !m_object->RetSelect() ) // robot not selected? - { - return TRUE; - } - - return TRUE; -} - -// Indicates whether the controller has finished its activity. - -Error CAuto::IsEnded() -{ - return ERR_CONTINUE; -} - -// Stops the controller - -BOOL CAuto::Abort() -{ - return FALSE; -} - - -// Creates all the interface when the object is selected. - -BOOL CAuto::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, dim, ddim; - float ox, oy, sx, sy; - char name[100]; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw != 0 ) - { - pw->Flush(); // destroys the window buttons - m_interface->DeleteControl(EVENT_WINDOW0); // destroys the window - } - - if ( !bSelect ) return TRUE; - - pos.x = 0.0f; - pos.y = 0.0f; - dim.x = 540.0f/640.0f; -//? dim.y = 70.0f/480.0f; - dim.y = 86.0f/480.0f; - m_interface->CreateWindows(pos, dim, 3, EVENT_WINDOW0); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - m_object->GetTooltipName(name); - pos.x = 0.0f; - pos.y = 64.0f/480.0f; - ddim.x = 540.0f/640.0f; - ddim.y = 16.0f/480.0f; - pw->CreateLabel(pos, ddim, 0, EVENT_LABEL0, name); - - dim.x = 33.0f/640.0f; - dim.y = 33.0f/480.0f; - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*7.0f; - pos.y = oy+sy*0.6f; - ddim.x = 160.0f/640.0f; - ddim.y = 26.0f/480.0f; - pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GPROGRESS); - - if ( m_type != OBJECT_BASE && - m_type != OBJECT_SAFE && - m_type != OBJECT_HUSTON ) - { - pos.x = ox+sx*2.1f; - pos.y = oy+sy*0; - ddim.x = dim.x*0.6f; - ddim.y = dim.y*0.6f; - pw->CreateButton(pos, ddim, 12, EVENT_OBJECT_DELETE); - } - -#if 0 - pos.x = ox+sx*12.4f; - pos.y = oy+sy*1; - pw->CreateButton(pos, dim, 63, EVENT_OBJECT_BHELP); - - pos.x = ox+sx*12.4f; - pos.y = oy+sy*0; - pw->CreateButton(pos, dim, 19, EVENT_OBJECT_HELP); - - if ( m_main->RetSceneSoluce() ) - { - pos.x = ox+sx*13.4f; - pos.y = oy+sy*1; - pw->CreateButton(pos, dim, 20, EVENT_OBJECT_SOLUCE); - } - - pos.x = ox+sx*13.4f; - pos.y = oy+sy*0; - pw->CreateButton(pos, dim, 10, EVENT_OBJECT_DESELECT); -#else - pos.x = ox+sx*12.3f; - pos.y = oy+sy*-0.1f; - ddim.x = dim.x*1.0f; - ddim.y = dim.y*2.1f; - pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue background - - pos.x = ox+sx*12.3f; - pos.y = oy+sy*1; - pw->CreateGroup(pos, dim, 19, EVENT_NULL); // sign SatCom - - pos.x = ox+sx*12.4f; - pos.y = oy+sy*0.5f; - ddim.x = dim.x*0.8f; - ddim.y = dim.y*0.5f; - pw->CreateButton(pos, ddim, 18, EVENT_OBJECT_BHELP); - pos.y = oy+sy*0.0f; - pw->CreateButton(pos, ddim, 19, EVENT_OBJECT_HELP); - - pos.x = ox+sx*13.4f; - pos.y = oy+sy*0; - pw->CreateButton(pos, dim, 10, EVENT_OBJECT_DESELECT); -#endif - - pos.x = ox+sx*14.9f; - pos.y = oy+sy*0; - ddim.x = 14.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGauge(pos, ddim, 3, EVENT_OBJECT_GSHIELD); - - UpdateInterface(); - m_lastUpdateTime = 0.0f; - UpdateInterface(0.0f); - - return TRUE; -} - -// Change the state of a button interface. - -void CAuto::CheckInterface(CWindow *pw, EventMsg event, BOOL bState) -{ - CControl* control; - - control = pw->SearchControl(event); - if ( control == 0 ) return; - - control->SetState(STATE_CHECK, bState); -} - -// Change the state of a button interface. - -void CAuto::EnableInterface(CWindow *pw, EventMsg event, BOOL bState) -{ - CControl* control; - - control = pw->SearchControl(event); - if ( control == 0 ) return; - - control->SetState(STATE_ENABLE, bState); -} - -// Change the state of a button interface. - -void CAuto::VisibleInterface(CWindow *pw, EventMsg event, BOOL bState) -{ - CControl* control; - - control = pw->SearchControl(event); - if ( control == 0 ) return; - - control->SetState(STATE_VISIBLE, bState); -} - -// Change the state of a button interface. - -void CAuto::DeadInterface(CWindow *pw, EventMsg event, BOOL bState) -{ - CControl* control; - - control = pw->SearchControl(event); - if ( control == 0 ) return; - - control->SetState(STATE_DEAD, !bState); -} - -// Change the state of a button interface. - -void CAuto::UpdateInterface() -{ - CWindow* pw; - - if ( !m_object->RetSelect() ) return; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; - - VisibleInterface(pw, EVENT_OBJECT_GPROGRESS, m_bBusy); -} - -// Updates the state of all buttons on the interface, -// following the time that elapses ... - -void CAuto::UpdateInterface(float rTime) -{ - CWindow* pw; - CGauge* pg; - - if ( m_time < m_lastUpdateTime+0.1f ) return; - m_lastUpdateTime = m_time; - - if ( !m_object->RetSelect() ) return; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; - - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GSHIELD); - if ( pg != 0 ) - { - pg->SetLevel(m_object->RetShield()); - } - - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GPROGRESS); - if ( pg != 0 ) - { - pg->SetLevel(m_progressTime); - } -} - - -// Returns an error due the state of the automation. - -Error CAuto::RetError() -{ - return ERR_OK; -} - - -// Management of the occupation. - -BOOL CAuto::RetBusy() -{ - return m_bBusy; -} - -void CAuto::SetBusy(BOOL bBusy) -{ - m_bBusy = bBusy; -} - -void CAuto::InitProgressTotal(float total) -{ - m_progressTime = 0.0f; - m_progressTotal = total; -} - -void CAuto::EventProgress(float rTime) -{ - m_progressTime += rTime/m_progressTotal; -} - - -// Engine management. - -BOOL CAuto::RetMotor() -{ - return m_bMotor; -} - -void CAuto::SetMotor(BOOL bMotor) -{ - m_bMotor = bMotor; -} - - -// Saves all parameters of the controller. - -BOOL CAuto::Write(char *line) -{ - char name[100]; - - sprintf(name, " aType=%d", m_type); - strcat(line, name); - - sprintf(name, " aBusy=%d", m_bBusy); - strcat(line, name); - - sprintf(name, " aTime=%.2f", m_time); - strcat(line, name); - - sprintf(name, " aProgressTime=%.2f", m_progressTime); - strcat(line, name); - - sprintf(name, " aProgressTotal=%.2f", m_progressTotal); - strcat(line, name); - - return FALSE; -} - -// Return all settings to the controller. - -BOOL CAuto::Read(char *line) -{ - m_type = (ObjectType)OpInt(line, "aType", OBJECT_NULL); - m_bBusy = OpInt(line, "aBusy", 0); - m_time = OpFloat(line, "aTime", 0.0f); - m_progressTime = OpFloat(line, "aProgressTime", 0.0f); - m_progressTotal = OpFloat(line, "aProgressTotal", 0.0f); - - return FALSE; -} - diff --git a/src/auto.h b/src/auto.h deleted file mode 100644 index 4cc9389..0000000 --- a/src/auto.h +++ /dev/null @@ -1,114 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// auto.h - -#ifndef _AUTO_H_ -#define _AUTO_H_ - - -#include "object.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CLight; -class CTerrain; -class CWater; -class CCloud; -class CPlanet; -class CBlitz; -class CCamera; -class CObject; -class CInterface; -class CRobotMain; -class CDisplayText; -class CWindow; -class CSound; - - - - -class CAuto -{ -public: - CAuto(CInstanceManager* iMan, CObject* object); - ~CAuto(); - - virtual void DeleteObject(BOOL bAll=FALSE); - - virtual void Init(); - virtual void Start(int param); - virtual BOOL EventProcess(const Event &event); - virtual Error IsEnded(); - virtual BOOL Abort(); - - virtual BOOL SetType(ObjectType type); - virtual BOOL SetValue(int rank, float value); - virtual BOOL SetString(char *string); - - virtual BOOL CreateInterface(BOOL bSelect); - virtual Error RetError(); - - virtual BOOL RetBusy(); - virtual void SetBusy(BOOL bBuse); - virtual void InitProgressTotal(float total); - virtual void EventProgress(float rTime); - - virtual BOOL RetMotor(); - virtual void SetMotor(BOOL bMotor); - - virtual BOOL Write(char *line); - virtual BOOL Read(char *line); - -protected: - void CheckInterface(CWindow *pw, EventMsg event, BOOL bState); - void EnableInterface(CWindow *pw, EventMsg event, BOOL bState); - void VisibleInterface(CWindow *pw, EventMsg event, BOOL bState); - void DeadInterface(CWindow *pw, EventMsg event, BOOL bState); - void UpdateInterface(); - void UpdateInterface(float rTime); - -protected: - CInstanceManager* m_iMan; - CEvent* m_event; - CD3DEngine* m_engine; - CParticule* m_particule; - CLight* m_light; - CTerrain* m_terrain; - CWater* m_water; - CCloud * m_cloud; - CPlanet * m_planet; - CBlitz* m_blitz; - CCamera* m_camera; - CInterface* m_interface; - CRobotMain* m_main; - CDisplayText* m_displayText; - CObject* m_object; - CSound* m_sound; - - ObjectType m_type; - BOOL m_bBusy; - BOOL m_bMotor; - float m_time; - float m_lastUpdateTime; - float m_progressTime; - float m_progressTotal; -}; - - -#endif //_AUTO_H_ diff --git a/src/autobase.cpp b/src/autobase.cpp deleted file mode 100644 index fada8d5..0000000 --- a/src/autobase.cpp +++ /dev/null @@ -1,1459 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "language.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "terrain.h" -#include "cloud.h" -#include "planet.h" -#include "blitz.h" -#include "camera.h" -#include "object.h" -#include "physics.h" -#include "interface.h" -#include "button.h" -#include "window.h" -#include "displaytext.h" -#include "robotmain.h" -#include "sound.h" -#include "auto.h" -#include "autobase.h" - - - -#define BASE_LAND_TIME 7.5f // hard landing -#define BASE_TAKO_TIME 10.0f // hard landing -#define BASE_DOOR_TIME 6.0f // time opening / closing -#define BASE_DOOR_TIME2 2.0f // time opening / closing suppl. -#define BASE_PORTICO_TIME_MOVE 16.0f // gate advance time -#define BASE_PORTICO_TIME_DOWN 4.0f // gate length down -#define BASE_PORTICO_TIME_OPEN 4.0f // gate opening duration -#define BASE_TRANSIT_TIME 15.0f // transit duration - - - - -// Object's constructor. - -CAutoBase::CAutoBase(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - m_fogStart = m_engine->RetFogStart(); - m_deepView = m_engine->RetDeepView(); - Init(); - m_phase = ABP_WAIT; - m_soundChannel = -1; -} - -// Object's destructor. - -CAutoBase::~CAutoBase() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoBase::DeleteObject(BOOL bAll) -{ - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } - - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoBase::Init() -{ - m_bOpen = FALSE; - m_time = 0.0f; - m_lastParticule = 0.0f; - m_lastMotorParticule = 0.0f; - - m_pos = m_object->RetPosition(0); - m_lastPos = m_pos; - - m_phase = ABP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; -} - - -// Start the object. - -void CAutoBase::Start(int param) -{ - m_phase = ABP_START; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - - m_param = param; -} - - -// Management of an event. - -BOOL CAutoBase::EventProcess(const Event &event) -{ - D3DMATRIX* mat; - Event newEvent; - CObject* pObj; - D3DVECTOR pos, speed, vibCir, iPos; - FPOINT dim, p; - Error err; - float angle, dist, time, h, len, vSpeed; - int i, max; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - -begin: - iPos = m_object->RetPosition(0); - - if ( m_phase == ABP_START ) - { - if ( m_param != PARAM_STOP && // not placed on the ground? - m_param != PARAM_FIXSCENE ) - { - FreezeCargo(TRUE); // freeze whole cargo - } - - if ( m_param == PARAM_STOP ) // raises the ground? - { - m_phase = ABP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - - for ( i=0 ; i<8 ; i++ ) - { - m_object->SetAngleZ(1+i, PI/2.0f-124.0f*PI/180.0f); - m_object->SetAngleX(10+i, -10.0f*PI/180.0f); - m_object->SetAngleX(18+i, 10.0f*PI/180.0f); - m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, -11.5f)); - m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, 11.5f)); - } - - pObj = m_main->RetSelectObject(); - m_main->SelectObject(pObj); - m_camera->SetObject(pObj); - if ( pObj == 0 ) - { - m_camera->SetType(CAMERA_BACK); - } - else - { - m_camera->SetType(pObj->RetCameraType()); - m_camera->SetDist(pObj->RetCameraDist()); - } - - m_main->StartMusic(); - } - - if ( m_param == PARAM_FIXSCENE ) // raises the ground? - { - m_phase = ABP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - - for ( i=0 ; i<8 ; i++ ) - { - m_object->SetAngleZ(1+i, PI/2.0f-124.0f*PI/180.0f); - m_object->SetAngleX(10+i, -10.0f*PI/180.0f); - m_object->SetAngleX(18+i, 10.0f*PI/180.0f); - m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, -11.5f)); - m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, 11.5f)); - } - } - - if ( m_param == PARAM_LANDING ) // Landing? - { - m_phase = ABP_LAND; - m_progress = 0.0f; - m_speed = 1.0f/BASE_LAND_TIME; - - m_main->SetMovieLock(TRUE); // blocks everything until the end of the landing - m_bMotor = TRUE; // lights the jet engine - - m_camera->SetType(CAMERA_SCRIPT); - - pos = m_pos; - pos.x -= 150.0f; - m_terrain->MoveOnFloor(pos); - pos.y += 10.0f; - m_camera->SetScriptEye(pos); - m_posSound = pos; - - pos = m_object->RetPosition(0); - pos.y += 300.0f+50.0f; - m_camera->SetScriptLookat(pos); - - m_camera->FixCamera(); - m_engine->SetFocus(2.0f); - - m_engine->SetFogStart(0.9f); - - if ( m_soundChannel == -1 ) - { - m_soundChannel = m_sound->Play(SOUND_FLY, m_posSound, 0.3f, 2.0f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, BASE_LAND_TIME, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 2.0f, SOPER_STOP); - } - - m_main->StartMusic(); - } - - if ( m_param == PARAM_PORTICO ) // gate on the porch? - { - pos = m_object->RetPosition(0); - m_finalPos = pos; - pos.z += BASE_PORTICO_TIME_MOVE*5.0f; // back - pos.y += 10.0f; // rises (the gate) - m_object->SetPosition(0, pos); - MoveCargo(); // all cargo moves - - m_phase = ABP_PORTICO_MOVE; - m_progress = 0.0f; - m_speed = 1.0f/BASE_PORTICO_TIME_MOVE; - - m_main->StartMusic(); - } - - if ( m_param == PARAM_TRANSIT1 || - m_param == PARAM_TRANSIT2 || - m_param == PARAM_TRANSIT3 ) // transit in space? - { - m_phase = ABP_TRANSIT_MOVE; - m_progress = 0.0f; - m_speed = 1.0f/BASE_TRANSIT_TIME; - - m_object->SetAngleZ(0, -PI/2.0f); - pos = m_object->RetPosition(0); - pos.y += 10000.0f; // in space - m_finalPos = pos; - m_object->SetPosition(0, pos); - - m_main->SetMovieLock(TRUE); // blocks everything until the end of the landing - m_bMotor = TRUE; // lights the jet engine - - m_camera->SetType(CAMERA_SCRIPT); - pos.x += 1000.0f; - pos.z -= 60.0f; - pos.y += 80.0f; - m_camera->SetScriptEye(pos); - m_posSound = pos; - m_camera->FixCamera(); - m_engine->SetFocus(1.0f); - - BeginTransit(); - - mat = m_object->RetWorldMatrix(0); - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 10.0f; - dim.y = dim.x; - pos = D3DVECTOR(42.0f, -2.0f, 17.0f); - pos = Transform(*mat, pos); - m_partiChannel[0] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); - pos = D3DVECTOR(17.0f, -2.0f, 42.0f); - pos = Transform(*mat, pos); - m_partiChannel[1] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); - pos = D3DVECTOR(42.0f, -2.0f, -17.0f); - pos = Transform(*mat, pos); - m_partiChannel[2] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); - pos = D3DVECTOR(17.0f, -2.0f, -42.0f); - pos = Transform(*mat, pos); - m_partiChannel[3] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); - pos = D3DVECTOR(-42.0f, -2.0f, 17.0f); - pos = Transform(*mat, pos); - m_partiChannel[4] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); - pos = D3DVECTOR(-17.0f, -2.0f, 42.0f); - pos = Transform(*mat, pos); - m_partiChannel[5] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); - pos = D3DVECTOR(-42.0f, -2.0f, -17.0f); - pos = Transform(*mat, pos); - m_partiChannel[6] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); - pos = D3DVECTOR(-17.0f, -2.0f, -42.0f); - pos = Transform(*mat, pos); - m_partiChannel[7] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); - - if ( m_soundChannel == -1 ) - { - m_soundChannel = m_sound->Play(SOUND_FLY, m_posSound, 0.0f, 1.2f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, BASE_TRANSIT_TIME*0.55f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.8f, BASE_TRANSIT_TIME*0.45f, SOPER_STOP); - } - } - } - - if ( event.event == EVENT_UPDINTERFACE ) - { - if ( m_object->RetSelect() ) CreateInterface(TRUE); - } - - if ( event.event == EVENT_OBJECT_BTAKEOFF ) - { - err = CheckCloseDoor(); - if ( err != ERR_OK ) - { - m_displayText->DisplayError(err, m_object); - return FALSE; - } - - err = m_main->CheckEndMission(FALSE); - if ( err != ERR_OK ) - { - m_displayText->DisplayError(err, m_object); - return FALSE; - } - - FreezeCargo(TRUE); // freeze whole cargo - m_main->SetMovieLock(TRUE); // blocks everything until the end - m_main->DeselectAll(); - - m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); - m_event->AddEvent(newEvent); - - m_camera->SetType(CAMERA_SCRIPT); - - pos = m_pos; - pos.x -= 110.0f; - m_terrain->MoveOnFloor(pos); - pos.y += 10.0f; - m_camera->SetScriptEye(pos); - m_posSound = pos; - - pos = m_object->RetPosition(0); - pos.y += 50.0f; - m_camera->SetScriptLookat(pos); - - m_engine->SetFocus(1.0f); - - m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.3f, 1.5f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.5f, BASE_DOOR_TIME2, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.5f, 0.5f, SOPER_STOP); - - m_phase = ABP_CLOSE2; - m_progress = 0.0f; - m_speed = 1.0f/BASE_DOOR_TIME2; - return TRUE; - } - - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_phase == ABP_WAIT ) return TRUE; - - m_progress += event.rTime*m_speed; - - if ( m_phase == ABP_LAND ) - { - if ( m_progress < 1.0f ) - { - pos = m_pos; - pos.y += powf(1.0f-m_progress, 2.0f)*300.0f; - m_object->SetPosition(0, pos); - MoveCargo(); // all cargo moves - - vibCir.z = sinf(m_time*PI* 2.01f)*(PI/150.0f)+ - sinf(m_time*PI* 2.51f)*(PI/200.0f)+ - sinf(m_time*PI*19.01f)*(PI/400.0f); - vibCir.x = sinf(m_time*PI* 2.03f)*(PI/150.0f)+ - sinf(m_time*PI* 2.52f)*(PI/200.0f)+ - sinf(m_time*PI*19.53f)*(PI/400.0f); - vibCir.y = 0.0f; - vibCir *= Min(1.0f, (1.0f-m_progress)*3.0f); - m_object->SetCirVibration(vibCir); - - pos = m_pos; - pos.x -= 150.0f; - m_terrain->MoveOnFloor(pos); - pos.y += 10.0f; - m_camera->SetScriptEye(pos); - - pos = m_object->RetPosition(0); - pos.y += 50.0f; - m_camera->SetScriptLookat(pos); - - m_engine->SetFocus(1.0f+(1.0f-m_progress)); - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) - { - m_lastParticule = m_time; - - // Dust thrown to the ground. - pos = m_pos; - pos.x += (Rand()-0.5f)*10.0f; - pos.z += (Rand()-0.5f)*10.0f; - angle = Rand()*(PI*2.0f); - dist = m_progress*50.0f; - p = RotatePoint(angle, dist); - speed.x = p.x; - speed.z = p.y; - speed.y = 0.0f; - dim.x = (Rand()*15.0f+15.0f)*m_progress; - dim.y = dim.x; - if ( dim.x >= 1.0f ) - { - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 2.0f); - } - - // Particles are ejected from the jet engine. - pos = m_object->RetPosition(0); - pos.y += 6.0f; - h = m_terrain->RetFloorHeight(pos)/300.0f; - speed.x = (Rand()-0.5f)*(80.0f-50.0f*h); - speed.z = (Rand()-0.5f)*(80.0f-50.0f*h); - speed.y = -(Rand()*(h+1.0f)*40.0f+(h+1.0f)*40.0f); - dim.x = Rand()*2.0f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 2.0f, 10.0f, 2.0f); - - // Black smoke from the jet engine. - if ( m_progress > 0.8f ) - { - pos = m_pos; - pos.x += (Rand()-0.5f)*8.0f; - pos.z += (Rand()-0.5f)*8.0f; - pos.y += 3.0f; - speed.x = (Rand()-0.5f)*8.0f; - speed.z = (Rand()-0.5f)*8.0f; - speed.y = 0.0f; - dim.x = Rand()*4.0f+4.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 2.0f); - } - } - } - else - { - m_bMotor = FALSE; // put out the reactor - - m_object->SetPosition(0, m_pos); // setting down - m_object->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); - MoveCargo(); // all cargo moves - - // Impact with the ground. - max = (int)(50.0f*m_engine->RetParticuleDensity()); - for ( i=0 ; iCreateParticule(pos, speed, dim, PARTICRASH, time, 0.0f, 2.0f); - } - -//? m_camera->StartEffect(CE_CRASH, m_pos, 1.0f); - m_camera->StartEffect(CE_EXPLO, m_pos, 2.0f); - m_engine->SetFocus(1.0f); - m_sound->Play(SOUND_BOUM, m_posSound, 0.6f, 0.5f); - - m_phase = ABP_OPENWAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - if ( m_phase == ABP_OPENWAIT ) - { - if ( m_progress < 1.0f ) - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) - { - m_lastParticule = m_time; - - // Black smoke from the reactor. - pos = m_pos; - pos.x += (Rand()-0.5f)*8.0f; - pos.z += (Rand()-0.5f)*8.0f; - pos.y += 3.0f; - speed.x = (Rand()-0.5f)*8.0f; - speed.z = (Rand()-0.5f)*8.0f; - speed.y = 0.0f; - dim.x = Rand()*4.0f+4.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 2.0f); - } - } - else - { - m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.0f, 0.3f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.3f, 1.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.0f, BASE_DOOR_TIME-1.5f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 1.0f, SOPER_STOP); - - m_phase = ABP_OPEN; - m_progress = 0.0f; - m_speed = 1.0f/BASE_DOOR_TIME; - } - } - - if ( m_phase == ABP_OPEN ) - { - if ( m_progress < 1.0f ) - { - angle = -m_progress*124.0f*PI/180.0f; - for ( i=0 ; i<8 ; i++ ) - { - m_object->SetAngleZ(1+i, PI/2.0f+angle); - } - - if ( m_param != PARAM_PORTICO ) - { - angle = m_progress*PI*2.0f; - p = RotatePoint(angle, -150.0f); - pos = m_pos; - pos.x += p.x; - pos.z += p.y; - m_terrain->MoveOnFloor(pos); - pos.y += 10.0f; - pos.y += m_progress*40.0f; - m_camera->SetScriptEye(pos); - - m_engine->SetFogStart(0.9f-(0.9f-m_fogStart)*m_progress); - } - } - else - { - for ( i=0 ; i<8 ; i++ ) - { - m_object->SetAngleZ(1+i, PI/2.0f-124.0f*PI/180.0f); - } - - // Clash the doors with the ground. - max = (int)(20.0f*m_engine->RetParticuleDensity()); - for ( i=0 ; iCreateParticule(pos, speed, dim, PARTICRASH, time, 0.0f, 2.0f); - } - - m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.3f, 1.5f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.5f, BASE_DOOR_TIME2, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.5f, 0.5f, SOPER_STOP); - - m_phase = ABP_OPEN2; - m_progress = 0.0f; - m_speed = 1.0f/BASE_DOOR_TIME2; - } - } - - if ( m_phase == ABP_OPEN2 ) - { - if ( m_progress < 1.0f ) - { - len = 7.0f-m_progress*(7.0f+11.5f); - for ( i=0 ; i<8 ; i++ ) - { - m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, len)); - m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, -len)); - m_object->SetAngleX(10+i, -10.0f*PI/180.0f*m_progress); - m_object->SetAngleX(18+i, 10.0f*PI/180.0f*m_progress); - } - - if ( m_param != PARAM_PORTICO ) - { - angle = m_progress*PI/2.0f; - p = RotatePoint(angle, -150.0f); - pos = m_pos; - pos.x += p.x; - pos.z += p.y; - m_terrain->MoveOnFloor(pos); - pos.y += 10.0f; - pos.y += m_progress*40.0f; - m_camera->SetScriptEye(pos); - - m_engine->SetFogStart(0.9f-(0.9f-m_fogStart)*m_progress); - } - } - else - { - for ( i=0 ; i<8 ; i++ ) - { - m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, -11.5f)); - m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, 11.5f)); - m_object->SetAngleX(10+i, -10.0f*PI/180.0f); - m_object->SetAngleX(18+i, 10.0f*PI/180.0f); - } - - m_phase = ABP_LDWAIT; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - if ( m_phase == ABP_LDWAIT ) - { - if ( m_progress >= 1.0f ) - { - FreezeCargo(FALSE); // frees all cargo - - if ( m_param != PARAM_PORTICO ) - { - m_main->SetMovieLock(FALSE); // you can play! - - pObj = m_main->RetSelectObject(); - m_main->SelectObject(pObj); - m_camera->SetObject(pObj); - if ( pObj == 0 ) - { - m_camera->SetType(CAMERA_BACK); - } - else - { - m_camera->SetType(pObj->RetCameraType()); - m_camera->SetDist(pObj->RetCameraDist()); - } - m_sound->Play(SOUND_BOUM, m_object->RetPosition(0)); - m_soundChannel = -1; - - m_engine->SetFogStart(m_fogStart); - } - - m_bOpen = TRUE; - m_phase = ABP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - if ( m_phase == ABP_CLOSE2 ) - { - if ( m_progress < 1.0f ) - { - len = 7.0f-(1.0f-m_progress)*(7.0f+11.5f); - for ( i=0 ; i<8 ; i++ ) - { - m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, len)); - m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, -len)); - m_object->SetAngleX(10+i, -10.0f*PI/180.0f*(1.0f-m_progress)); - m_object->SetAngleX(18+i, 10.0f*PI/180.0f*(1.0f-m_progress)); - } - } - else - { - for ( i=0 ; i<8 ; i++ ) - { - m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, 7.0f)); - m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, -7.0f)); - m_object->SetAngleX(10+i, 0.0f); - m_object->SetAngleX(18+i, 0.0f); - } - - m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.0f, 0.3f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.3f, 1.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.0f, BASE_DOOR_TIME-1.5f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 1.0f, SOPER_STOP); - - m_phase = ABP_CLOSE; - m_progress = 0.0f; - m_speed = 1.0f/BASE_DOOR_TIME; - } - } - - if ( m_phase == ABP_CLOSE ) - { - if ( m_progress < 1.0f ) - { - angle = -(1.0f-m_progress)*124.0f*PI/180.0f; - for ( i=0 ; i<8 ; i++ ) - { - m_object->SetAngleZ(1+i, PI/2.0f+angle); - } - } - else - { - for ( i=0 ; i<8 ; i++ ) - { - m_object->SetAngleZ(1+i, PI/2.0f); - } - m_bMotor = TRUE; // lights the jet engine - - // Shock of the closing doors. - max = (int)(20.0f*m_engine->RetParticuleDensity()); - for ( i=0 ; iCreateParticule(pos, speed, dim, PARTICRASH, time); - } - m_sound->Play(SOUND_BOUM, m_object->RetPosition(0)); - - m_soundChannel = -1; - m_bOpen = FALSE; - m_phase = ABP_TOWAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - if ( m_phase == ABP_TOWAIT ) - { - if ( m_progress < 1.0f ) - { - if ( m_soundChannel == -1 ) - { - m_soundChannel = m_sound->Play(SOUND_FLY, m_posSound, 0.0f, 0.5f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 2.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.3f, 2.0f, BASE_TAKO_TIME, SOPER_STOP); - } - - vibCir.z = sinf(m_time*PI*19.01f)*(PI/400.0f); - vibCir.x = sinf(m_time*PI*19.53f)*(PI/400.0f); - vibCir.y = 0.0f; - vibCir *= m_progress*1.0f; - m_object->SetCirVibration(vibCir); - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - // Particles are ejected from the reactor. - pos = m_object->RetPosition(0); - pos.y += 6.0f; - speed.x = (Rand()-0.5f)*160.0f; - speed.z = (Rand()-0.5f)*160.0f; - speed.y = -(Rand()*10.0f+10.0f); - dim.x = Rand()*2.0f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 2.0f, 10.0f, 2.0f); - } - - m_engine->SetFogStart(m_fogStart+(0.9f-m_fogStart)*m_progress); - } - else - { - m_engine->SetFogStart(0.9f); - - m_phase = ABP_TAKEOFF; - m_progress = 0.0f; - m_speed = 1.0f/BASE_TAKO_TIME; - } - } - - if ( m_phase == ABP_TAKEOFF ) - { - if ( m_progress < 1.0f ) - { - pos = m_pos; - pos.y += powf(m_progress, 2.0f)*600.0f; - m_object->SetPosition(0, pos); - MoveCargo(); // all cargo moves - - vibCir.z = sinf(m_time*PI*19.01f)*(PI/400.0f); - vibCir.x = sinf(m_time*PI*19.53f)*(PI/400.0f); - vibCir.y = 0.0f; - m_object->SetCirVibration(vibCir); - - pos = m_pos; - pos.x -= 110.0f+m_progress*250.0f; - m_terrain->MoveOnFloor(pos); - pos.y += 10.0f; - m_camera->SetScriptEye(pos); - - pos = m_object->RetPosition(0); - pos.y += 50.0f; - m_camera->SetScriptLookat(pos); - - m_engine->SetFocus(1.0f+m_progress); - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) - { - m_lastParticule = m_time; - - // Dust thrown to the ground. - pos = m_pos; - pos.x += (Rand()-0.5f)*10.0f; - pos.z += (Rand()-0.5f)*10.0f; - angle = Rand()*(PI*2.0f); - dist = (1.0f-m_progress)*50.0f; - p = RotatePoint(angle, dist); - speed.x = p.x; - speed.z = p.y; - speed.y = 0.0f; - dim.x = (Rand()*10.0f+10.0f)*(1.0f-m_progress); - dim.y = dim.x; - if ( dim.x >= 1.0f ) - { - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 2.0f); - } - - // Particles are ejected from the reactor. - pos = m_object->RetPosition(0); - pos.y += 6.0f; - speed.x = (Rand()-0.5f)*40.0f; - speed.z = (Rand()-0.5f)*40.0f; - time = 5.0f+150.0f*m_progress; - speed.y = -(Rand()*time+time); - time = 2.0f+m_progress*12.0f; - dim.x = Rand()*time+time; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 2.0f, 10.0f, 2.0f); - - // Black smoke from the reactor. - pos = m_object->RetPosition(0); - pos.y += 3.0f; - speed.x = (Rand()-0.5f)*10.0f*(4.0f-m_progress*3.0f); - speed.z = (Rand()-0.5f)*10.0f*(4.0f-m_progress*3.0f); - speed.y = 0.0f; - dim.x = Rand()*20.0f+20.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 10.0f, 0.0f, 2.0f); - } - } - else - { - m_soundChannel = -1; - m_event->MakeEvent(newEvent, EVENT_WIN); - m_event->AddEvent(newEvent); - - m_phase = ABP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - if ( m_phase == ABP_PORTICO_MOVE ) // advance of the gate? - { - if ( m_progress < 1.0f ) - { - pos = m_object->RetPosition(0); - pos.z -= event.rTime*5.0f; - m_object->SetPosition(0, pos); - MoveCargo(); // all cargo moves - } - else - { - m_phase = ABP_PORTICO_WAIT1; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - if ( m_phase == ABP_PORTICO_WAIT1 ) // expectation the gate? - { - if ( m_progress >= 1.0f ) - { - m_phase = ABP_PORTICO_DOWN; - m_progress = 0.0f; - m_speed = 1.0f/BASE_PORTICO_TIME_DOWN; - } - } - - if ( m_phase == ABP_PORTICO_DOWN ) // down the gate? - { - if ( m_progress < 1.0f ) - { - pos = m_object->RetPosition(0); - pos.y -= event.rTime*(10.0f/BASE_PORTICO_TIME_DOWN); - m_object->SetPosition(0, pos); - MoveCargo(); // all cargo moves - } - else - { - // Impact with the ground. - max = (int)(50.0f*m_engine->RetParticuleDensity()); - for ( i=0 ; iCreateParticule(pos, speed, dim, PARTICRASH, time, 0.0f, 2.0f); - } - - m_phase = ABP_PORTICO_WAIT2; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - if ( m_phase == ABP_PORTICO_WAIT2 ) // expectation the gate? - { - if ( m_progress >= 1.0f ) - { - m_phase = ABP_PORTICO_OPEN; - m_progress = 0.0f; - m_speed = 1.0f/BASE_PORTICO_TIME_OPEN; - } - } - - if ( m_phase == ABP_PORTICO_OPEN ) // opening the gate? - { - if ( m_progress < 1.0f ) - { - } - else - { - m_phase = ABP_OPEN; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - if ( m_phase == ABP_TRANSIT_MOVE ) // transit in space? - { - if ( m_progress < 1.0f ) - { - pos = m_object->RetPosition(0); - pos.x += event.rTime*(2000.0f/BASE_TRANSIT_TIME); - m_object->SetPosition(0, pos); - pos.x += 60.0f; - m_camera->SetScriptLookat(pos); - } - else - { - m_object->SetAngleZ(0, 0.0f); - - m_param = PARAM_LANDING; - m_phase = ABP_START; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - - EndTransit(); - - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.8f, 0.01f, SOPER_STOP); - m_soundChannel = -1; - } - goto begin; - } - } - - if ( m_bMotor ) - { - if ( m_lastMotorParticule+m_engine->ParticuleAdapt(0.02f) <= m_time ) - { - m_lastMotorParticule = m_time; - - mat = m_object->RetWorldMatrix(0); - - if ( event.rTime == 0.0f ) - { - vSpeed = 0.0f; - } - else - { - pos = m_object->RetPosition(0); - if ( m_phase == ABP_TRANSIT_MOVE ) - { - vSpeed = (pos.x-iPos.x)/event.rTime; - } - else - { - vSpeed = (pos.y-iPos.y)/event.rTime; - } - if ( vSpeed < 0.0f ) vSpeed *= 1.5f; - } - - pos = D3DVECTOR(0.0f, 6.0f, 0.0f); - speed.x = (Rand()-0.5f)*4.0f; - speed.z = (Rand()-0.5f)*4.0f; - speed.y = vSpeed*0.8f-(8.0f+Rand()*6.0f); - speed += pos; - pos = Transform(*mat, pos); - speed = Transform(*mat, speed); - speed -= pos; - - dim.x = 4.0f+Rand()*4.0f; - dim.y = dim.x; - - m_particule->CreateParticule(pos, speed, dim, PARTIBASE, 3.0f, 0.0f, 0.0f); - - if ( m_phase == ABP_TRANSIT_MOVE ) - { - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 12.0f; - dim.y = dim.x; - pos = D3DVECTOR(0.0f, 7.0f, 0.0f); - pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; - pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 1.0f, 0.0f, 0.0f); - - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 4.0f; - dim.y = dim.x; - pos = D3DVECTOR(42.0f, 0.0f, 17.0f); - pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; - pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); - pos = D3DVECTOR(17.0f, 0.0f, 42.0f); - pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; - pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); - pos = D3DVECTOR(42.0f, 0.0f, -17.0f); - pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; - pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); - pos = D3DVECTOR(17.0f, 0.0f, -42.0f); - pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; - pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); - pos = D3DVECTOR(-42.0f, 0.0f, 17.0f); - pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; - pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); - pos = D3DVECTOR(-17.0f, 0.0f, 42.0f); - pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; - pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); - pos = D3DVECTOR(-42.0f, 0.0f, -17.0f); - pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; - pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); - pos = D3DVECTOR(-17.0f, 0.0f, -42.0f); - pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; - pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); - - pos = D3DVECTOR(42.0f, -2.0f, 17.0f); - pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[0], pos); - pos = D3DVECTOR(17.0f, -2.0f, 42.0f); - pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[1], pos); - pos = D3DVECTOR(42.0f, -2.0f, -17.0f); - pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[2], pos); - pos = D3DVECTOR(17.0f, -2.0f, -42.0f); - pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[3], pos); - pos = D3DVECTOR(-42.0f, -2.0f, 17.0f); - pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[4], pos); - pos = D3DVECTOR(-17.0f, -2.0f, 42.0f); - pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[5], pos); - pos = D3DVECTOR(-42.0f, -2.0f, -17.0f); - pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[6], pos); - pos = D3DVECTOR(-17.0f, -2.0f, -42.0f); - pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[7], pos); - } - } - } - - if ( m_soundChannel != -1 ) - { - pos = m_engine->RetEyePt(); - m_sound->Position(m_soundChannel, pos); - } - - return TRUE; -} - -// Stops the controller. - -BOOL CAutoBase::Abort() -{ - Event newEvent; - CObject* pObj; - int i; - - if ( m_phase == ABP_TRANSIT_MOVE ) // transit ? - { - m_object->SetAngleZ(0, 0.0f); - - m_param = PARAM_LANDING; - m_phase = ABP_START; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - - EndTransit(); - - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.8f, 0.01f, SOPER_STOP); - m_soundChannel = -1; - } - return TRUE; - } - - if ( m_param == PARAM_PORTICO ) // gate on the porch? - { - m_object->SetPosition(0, m_finalPos); - MoveCargo(); // all cargo moves - - for ( i=0 ; i<8 ; i++ ) - { - m_object->SetAngleZ(1+i, PI/2.0f-124.0f*PI/180.0f); - m_object->SetAngleX(10+i, -10.0f*PI/180.0f); - m_object->SetAngleX(18+i, 10.0f*PI/180.0f); - m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, -11.5f)); - m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, 11.5f)); - } - } - else - { - if ( m_phase == ABP_LAND || - m_phase == ABP_OPENWAIT || - m_phase == ABP_OPEN || - m_phase == ABP_OPEN2 ) // Landing? - { - m_bMotor = FALSE; // put out the jet engine - m_bOpen = TRUE; - - m_object->SetPosition(0, m_pos); // setting down - m_object->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); - MoveCargo(); // all cargo moves - for ( i=0 ; i<8 ; i++ ) - { - m_object->SetAngleZ(1+i, PI/2.0f-124.0f*PI/180.0f); - m_object->SetAngleX(10+i, -10.0f*PI/180.0f); - m_object->SetAngleX(18+i, 10.0f*PI/180.0f); - m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, -11.5f)); - m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, 11.5f)); - } - - m_main->SetMovieLock(FALSE); // you can play! - - pObj = m_main->RetSelectObject(); - m_main->SelectObject(pObj); - m_camera->SetObject(pObj); - if ( pObj == 0 ) - { - m_camera->SetType(CAMERA_BACK); - } - else - { - m_camera->SetType(pObj->RetCameraType()); - m_camera->SetDist(pObj->RetCameraDist()); - } - - m_engine->SetFogStart(m_fogStart); - } - - if ( m_phase == ABP_CLOSE2 || - m_phase == ABP_CLOSE || - m_phase == ABP_TOWAIT || - m_phase == ABP_TAKEOFF ) // off? - { - m_event->MakeEvent(newEvent, EVENT_WIN); - m_event->AddEvent(newEvent); - } - } - - m_object->SetAngleZ(0, 0.0f); - FreezeCargo(FALSE); // frees all cargo - - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } - - m_phase = ABP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - - return TRUE; -} - - -// Returns an error due the state of the automation. - -Error CAutoBase::RetError() -{ - return ERR_OK; -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoBase::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, dim, ddim; - float ox, oy, sx, sy; - float sleep, delay, magnetic, progress; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - dim.x = 33.0f/640.0f; - dim.y = 33.0f/480.0f; - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - ddim.x = dim.x*1.5f; - ddim.y = dim.y*1.5f; - -//? pos.x = ox+sx*7.25f; -//? pos.y = oy+sy*0.25f; -//? pw->CreateButton(pos, ddim, 63, EVENT_OBJECT_BHELP); - - pos.x = ox+sx*8.00f; - pos.y = oy+sy*0.25f; - pw->CreateButton(pos, ddim, 28, EVENT_OBJECT_BTAKEOFF); - - if ( m_blitz->GetStatus(sleep, delay, magnetic, progress) ) - { - pos.x = ox+sx*10.2f; - pos.y = oy+sy*0.5f; - ddim.x = dim.x*1.0f; - ddim.y = dim.y*1.0f; - pw->CreateButton(pos, ddim, 41, EVENT_OBJECT_LIMIT); - } - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 100, EVENT_OBJECT_TYPE); - - UpdateInterface(); - - return TRUE; -} - -// Updates the status of all interface buttons. - -void CAutoBase::UpdateInterface() -{ - CWindow* pw; - - if ( !m_object->RetSelect() ) return; - - CAuto::UpdateInterface(); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); -} - - -// Freeze or frees all cargo. - -void CAutoBase::FreezeCargo(BOOL bFreeze) -{ - CObject* pObj; - CPhysics* physics; - D3DVECTOR oPos; - float dist; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - pObj->SetCargo(FALSE); - - if ( pObj == m_object ) continue; // yourself? - if ( pObj->RetTruck() != 0 ) continue; // transport object? - - oPos = pObj->RetPosition(0); - dist = Length2d(m_pos, oPos); - if ( dist < 32.0f ) - { - if ( bFreeze ) - { - pObj->SetCargo(TRUE); - } - - physics = pObj->RetPhysics(); - if ( physics != 0 ) - { - physics->SetFreeze(bFreeze); - } - } - } -} - -// All cargo moves vertically with the ship. - -void CAutoBase::MoveCargo() -{ - CObject* pObj; - D3DVECTOR oPos, sPos; - int i; - - sPos = m_object->RetPosition(0); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetCargo() ) continue; - - oPos = pObj->RetPosition(0); - oPos.y = sPos.y+30.0f; - oPos.y += pObj->RetCharacter()->height; - oPos.x += sPos.x-m_lastPos.x; - oPos.z += sPos.z-m_lastPos.z; - pObj->SetPosition(0, oPos); - } - - m_lastPos = sPos; -} - - -// Checks whether it is possible to close the doors. - -Error CAutoBase::CheckCloseDoor() -{ - CObject* pObj; - D3DVECTOR oPos; - ObjectType type; - float oRad, dist; - int i, j; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj == m_object ) continue; // yourself? - if ( !pObj->RetActif() ) continue; // inactive? - - type = pObj->RetType(); - if ( type == OBJECT_PORTICO ) continue; - - j = 0; - while ( pObj->GetCrashSphere(j++, oPos, oRad) ) - { - dist = Length2d(m_pos, oPos); - if ( dist+oRad > 32.0f && - dist-oRad < 72.0f ) - { - return ERR_BASE_DLOCK; - } - - if ( type == OBJECT_HUMAN && - dist+oRad > 32.0f ) - { - return ERR_BASE_DHUMAN; - } - } - } - return ERR_OK; -} - - -// Start a transit. - -void CAutoBase::BeginTransit() -{ - BOOL bFull, bQuarter; - - if ( m_param == PARAM_TRANSIT2 ) - { - strcpy(m_bgBack, "back01.tga"); // clouds orange / blue - } - else if ( m_param == PARAM_TRANSIT3 ) - { - strcpy(m_bgBack, "back22.tga"); // blueberries clouds - } - else - { -#if _DEMO - strcpy(m_bgBack, "back46b.tga"); // paintings -#else - strcpy(m_bgBack, "back46.tga"); // paintings -#endif - } - - m_engine->SetFogStart(0.9f); // hardly any fog - m_engine->SetDeepView(2000.0f); // we see very far - m_engine->ApplyChange(); - - m_engine->RetBackground(m_bgName, m_bgUp, m_bgDown, m_bgCloudUp, m_bgCloudDown, bFull, bQuarter); - m_engine->FreeTexture(m_bgName); - - m_engine->SetBackground(m_bgBack, 0x00000000, 0x00000000, 0x00000000, 0x00000000); - m_engine->LoadTexture(m_bgBack); - - m_cloud->SetEnable(FALSE); // cache clouds - m_planet->SetMode(1); -} - -// End of a transit. - -void CAutoBase::EndTransit() -{ - m_engine->SetFogStart(m_fogStart); // gives initial fog - m_engine->SetDeepView(m_deepView); // gives initial depth - m_engine->ApplyChange(); - - m_engine->FreeTexture(m_bgBack); - - m_engine->SetBackground(m_bgName, m_bgUp, m_bgDown, m_bgCloudUp, m_bgCloudDown); - m_engine->LoadTexture(m_bgName); - - m_cloud->SetEnable(TRUE); // gives the clouds - m_planet->SetMode(0); - - m_main->StartMusic(); -} - diff --git a/src/autobase.h b/src/autobase.h deleted file mode 100644 index 7e0093a..0000000 --- a/src/autobase.h +++ /dev/null @@ -1,122 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autobase.h - -#ifndef _AUTOBASE_H_ -#define _AUTOBASE_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -#define PARAM_STOP 0 // run=0 -> stops and open -#define PARAM_LANDING 1 // run=1 -> landing -#define PARAM_PORTICO 2 // run=2 -> gate on the ground -#define PARAM_FIXSCENE 3 // run=3 -> open and stops to win / lost -#define PARAM_TRANSIT1 11 // run=11 -> transit in space -#define PARAM_TRANSIT2 12 // run=12 -> transit in space -#define PARAM_TRANSIT3 13 // run=13 -> transit in space - - -enum AutoBasePhase -{ - ABP_WAIT = 1, // expected - ABP_START = 2, // start-up - - ABP_LAND = 3, // landing - ABP_OPENWAIT = 4, // wait before opening - ABP_OPEN = 5, // opens the gate - ABP_OPEN2 = 6, // opens supplements - ABP_LDWAIT = 7, // expected - - ABP_CLOSE2 = 8, // closes supplements - ABP_CLOSE = 9, // closes gate - ABP_TOWAIT = 10, // wait before takeoff - ABP_TAKEOFF = 11, // take-off - - ABP_PORTICO_MOVE = 12, // gate advance - ABP_PORTICO_WAIT1= 13, // gate expected - ABP_PORTICO_DOWN = 14, // gate down - ABP_PORTICO_WAIT2= 15, // gate expected - ABP_PORTICO_OPEN = 16, // gate opens - - ABP_TRANSIT_MOVE = 17, // transit - moving -}; - - - -class CAutoBase : public CAuto -{ -public: - CAutoBase(CInstanceManager* iMan, CObject* object); - ~CAutoBase(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - void Start(int param); - BOOL EventProcess(const Event &event); - BOOL Abort(); - Error RetError(); - - BOOL CreateInterface(BOOL bSelect); - -protected: - void UpdateInterface(); - void FreezeCargo(BOOL bFreeze); - void MoveCargo(); - Error CheckCloseDoor(); - void BeginTransit(); - void EndTransit(); - -protected: - AutoBasePhase m_phase; - BOOL m_bOpen; - float m_progress; - float m_speed; - float m_lastParticule; - float m_lastMotorParticule; - float m_fogStart; - float m_deepView; - D3DVECTOR m_pos; - D3DVECTOR m_posSound; - D3DVECTOR m_finalPos; - D3DVECTOR m_lastPos; - int m_param; - int m_soundChannel; - int m_partiChannel[8]; - - char m_bgBack[100]; - char m_bgName[100]; - D3DCOLOR m_bgUp; - D3DCOLOR m_bgDown; - D3DCOLOR m_bgCloudUp; - D3DCOLOR m_bgCloudDown; -}; - - -#endif //_AUTOBASE_H_ diff --git a/src/autoconvert.cpp b/src/autoconvert.cpp deleted file mode 100644 index ae213e3..0000000 --- a/src/autoconvert.cpp +++ /dev/null @@ -1,546 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "light.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "interface.h" -#include "button.h" -#include "window.h" -#include "sound.h" -#include "displaytext.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autoconvert.h" - - - - -// Object's constructor. - -CAutoConvert::CAutoConvert(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - Init(); - m_phase = ACP_STOP; - m_bResetDelete = FALSE; - m_soundChannel = -1; -} - -// Object's destructor. - -CAutoConvert::~CAutoConvert() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoConvert::DeleteObject(BOOL bAll) -{ - CObject* fret; - - if ( !bAll ) - { - fret = SearchStone(OBJECT_STONE); - if ( fret != 0 ) - { - fret->DeleteObject(); // destroy the stone - delete fret; - } - } - - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } - - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoConvert::Init() -{ - m_phase = ACP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - m_time = 0.0f; - m_timeVirus = 0.0f; - m_lastParticule = 0.0f; - - CAuto::Init(); -} - - -// Management of an event. - -BOOL CAutoConvert::EventProcess(const Event &event) -{ - CObject* fret; - D3DVECTOR pos, speed; - FPOINT dim, c, p; - float angle; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_speed; - m_timeVirus -= event.rTime; - - if ( m_object->RetVirusMode() ) // contaminated by a virus? - { - if ( m_timeVirus <= 0.0f ) - { - m_timeVirus = 0.1f+Rand()*0.3f; - - angle = (Rand()-0.5f)*0.3f; - m_object->SetAngleY(1, angle); - m_object->SetAngleY(2, angle); - m_object->SetAngleY(3, angle+PI); - - m_object->SetAngleX(2, -PI*0.35f*(0.8f+Rand()*0.2f)); - m_object->SetAngleX(3, -PI*0.35f*(0.8f+Rand()*0.2f)); - } - return TRUE; - } - - EventProgress(event.rTime); - - if ( m_phase == ACP_STOP ) return TRUE; - - if ( m_phase == ACP_WAIT ) - { - if ( m_progress >= 1.0f ) - { - fret = SearchStone(OBJECT_STONE); // Has stone transformed? - if ( fret == 0 || SearchVehicle() ) - { - m_phase = ACP_WAIT; // still waiting ... - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - else - { - fret->SetLock(TRUE); // stone usable - - SetBusy(TRUE); - InitProgressTotal(3.0f+10.0f+1.5f); - UpdateInterface(); - - m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.0f); - m_bSoundClose = FALSE; - - m_phase = ACP_CLOSE; - m_progress = 0.0f; - m_speed = 1.0f/3.0f; - } - } - } - - if ( m_phase == ACP_CLOSE ) - { - if ( m_progress < 1.0f ) - { - if ( m_progress >= 0.8f && !m_bSoundClose ) - { - m_bSoundClose = TRUE; - m_sound->Play(SOUND_CLOSE, m_object->RetPosition(0), 1.0f, 0.8f); - } - angle = -PI*0.35f*(1.0f-Bounce(m_progress, 0.85f, 0.05f)); - m_object->SetAngleX(2, angle); - m_object->SetAngleX(3, angle); - } - else - { - m_object->SetAngleX(2, 0.0f); - m_object->SetAngleX(3, 0.0f); - - m_soundChannel = m_sound->Play(SOUND_CONVERT, m_object->RetPosition(0), 0.0f, 0.25f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.25f, 0.5f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.00f, 4.5f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.25f, 4.5f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.25f, 0.5f, SOPER_STOP); - - m_phase = ACP_ROTATE; - m_progress = 0.0f; - m_speed = 1.0f/10.0f; - } - } - - if ( m_phase == ACP_ROTATE ) - { - if ( m_progress < 1.0f ) - { - if ( m_progress < 0.5f ) - { - angle = powf((m_progress*2.0f)*5.0f, 2.0f); // accelerates - } - else - { - angle = -powf((2.0f-m_progress*2.0f)*5.0f, 2.0f); // slows - } - m_object->SetAngleY(1, angle); - m_object->SetAngleY(2, angle); - m_object->SetAngleY(3, angle+PI); - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_object->RetPosition(0); - c.x = pos.x; - c.y = pos.z; - p.x = c.x; - p.y = c.y+6.0f; - p = RotatePoint(c, Rand()*PI*2.0f, p); - pos.x = p.x; - pos.z = p.y; - pos.y += 1.0f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = Rand()*2.0f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 1.0f, 0.0f, 0.0f); - } - } - else - { - m_object->SetAngleY(1, 0.0f); - m_object->SetAngleY(2, 0.0f); - m_object->SetAngleY(3, PI); - - fret = SearchStone(OBJECT_STONE); - if ( fret != 0 ) - { - m_bResetDelete = ( fret->RetResetCap() != RESET_NONE ); - fret->DeleteObject(); // destroy the stone - delete fret; - } - - CreateMetal(); // Create the metal - m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.5f); - - m_phase = ACP_OPEN; - m_progress = 0.0f; - m_speed = 1.0f/1.5f; - } - } - - if ( m_phase == ACP_OPEN ) - { - if ( m_progress < 1.0f ) - { - angle = -PI*0.35f*Bounce(m_progress, 0.7f, 0.2f); - m_object->SetAngleX(2, angle); - m_object->SetAngleX(3, angle); - - if ( m_progress < 0.9f && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_object->RetPosition(0); - pos.x += (Rand()-0.5f)*6.0f; - pos.z += (Rand()-0.5f)*6.0f; - pos.y += Rand()*4.0f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = Rand()*4.0f+3.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); - } - } - else - { - m_soundChannel = -1; - m_object->SetAngleX(2, -PI*0.35f); - m_object->SetAngleX(3, -PI*0.35f); - - SetBusy(FALSE); - UpdateInterface(); - - m_phase = ACP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - return TRUE; -} - -// Returns an error due the state of the automation. - -Error CAutoConvert::RetError() -{ - if ( m_object->RetVirusMode() ) - { - return ERR_BAT_VIRUS; - } - - if ( m_phase == ACP_WAIT ) return ERR_CONVERT_EMPTY; - return ERR_OK; -} - -// Cancels the current transformation. - -BOOL CAutoConvert::Abort() -{ - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } - - m_object->SetAngleY(1, 0.0f); - m_object->SetAngleY(2, 0.0f); - m_object->SetAngleY(3, PI); - m_object->SetAngleX(2, -PI*0.35f); - m_object->SetAngleX(3, -PI*0.35f); - - m_phase = ACP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - - SetBusy(FALSE); - UpdateInterface(); - - return TRUE; -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoConvert::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 103, EVENT_OBJECT_TYPE); - - return TRUE; -} - - -// Saves all parameters of the controller. - -BOOL CAutoConvert::Write(char *line) -{ - char name[100]; - - if ( m_phase == ACP_STOP || - m_phase == ACP_WAIT ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller. - -BOOL CAutoConvert::Read(char *line) -{ - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoConvertPhase)OpInt(line, "aPhase", ACP_WAIT); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - - m_lastParticule = 0.0f; - - return TRUE; -} - - -// Searches for the object before or during processing. - -CObject* CAutoConvert::SearchStone(ObjectType type) -{ - CObject* pObj; - D3DVECTOR cPos, oPos; - ObjectType oType; - float dist; - int i; - - cPos = m_object->RetPosition(0); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - oType = pObj->RetType(); - if ( oType != type ) continue; - if ( pObj->RetTruck() != 0 ) continue; - - oPos = pObj->RetPosition(0); - dist = Length(oPos, cPos); - - if ( dist <= 5.0f ) return pObj; - } - - return 0; -} - -// Search if a vehicle is too close. - -BOOL CAutoConvert::SearchVehicle() -{ - CObject* pObj; - D3DVECTOR cPos, oPos; - ObjectType type; - float oRadius, dist; - int i; - - cPos = m_object->RetPosition(0); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type != OBJECT_HUMAN && - type != OBJECT_MOBILEfa && - type != OBJECT_MOBILEta && - type != OBJECT_MOBILEwa && - type != OBJECT_MOBILEia && - type != OBJECT_MOBILEfc && - type != OBJECT_MOBILEtc && - type != OBJECT_MOBILEwc && - type != OBJECT_MOBILEic && - type != OBJECT_MOBILEfi && - type != OBJECT_MOBILEti && - type != OBJECT_MOBILEwi && - type != OBJECT_MOBILEii && - type != OBJECT_MOBILEfs && - type != OBJECT_MOBILEts && - type != OBJECT_MOBILEws && - type != OBJECT_MOBILEis && - type != OBJECT_MOBILErt && - type != OBJECT_MOBILErc && - type != OBJECT_MOBILErr && - type != OBJECT_MOBILErs && - type != OBJECT_MOBILEsa && - type != OBJECT_MOBILEtg && - type != OBJECT_MOBILEft && - type != OBJECT_MOBILEtt && - type != OBJECT_MOBILEwt && - type != OBJECT_MOBILEit && - type != OBJECT_MOBILEdr && - type != OBJECT_METAL && - type != OBJECT_URANIUM && - type != OBJECT_POWER && - type != OBJECT_ATOMIC && - type != OBJECT_BULLET && - type != OBJECT_BBOX && - type != OBJECT_TNT && - type != OBJECT_MOTHER && - type != OBJECT_ANT && - type != OBJECT_SPIDER && - type != OBJECT_BEE && - type != OBJECT_WORM ) continue; - - if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; - dist = Length(oPos, cPos)-oRadius; - - if ( dist < 8.0f ) return TRUE; - } - - return FALSE; -} - -// Creates an object metal. - -void CAutoConvert::CreateMetal() -{ - D3DVECTOR pos; - float angle; - CObject* fret; - - pos = m_object->RetPosition(0); - angle = m_object->RetAngleY(0); - - fret = new CObject(m_iMan); - if ( !fret->CreateResource(pos, angle, OBJECT_METAL) ) - { - delete fret; - m_displayText->DisplayError(ERR_TOOMANY, m_object); - return; - } - - if ( m_bResetDelete ) - { - fret->SetResetCap(RESET_DELETE); - } - - m_displayText->DisplayError(INFO_CONVERT, m_object); -} - diff --git a/src/autoconvert.h b/src/autoconvert.h deleted file mode 100644 index 2e35e24..0000000 --- a/src/autoconvert.h +++ /dev/null @@ -1,82 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autoconvert.h - -#ifndef _AUTOCONVERT_H_ -#define _AUTOCONVERT_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoConvertPhase -{ - ACP_STOP = 1, - ACP_WAIT = 2, - ACP_CLOSE = 3, // close the cover - ACP_ROTATE = 4, // turn the cover - ACP_OPEN = 5, // opens the cover -}; - - - -class CAutoConvert : public CAuto -{ -public: - CAutoConvert(CInstanceManager* iMan, CObject* object); - ~CAutoConvert(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - BOOL Abort(); - - BOOL CreateInterface(BOOL bSelect); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - CObject* SearchStone(ObjectType type); - BOOL SearchVehicle(); - void CreateMetal(); - -protected: - AutoConvertPhase m_phase; - float m_progress; - float m_speed; - float m_timeVirus; - float m_lastParticule; - BOOL m_bResetDelete; - BOOL m_bSoundClose; - int m_soundChannel; -}; - - -#endif //_AUTOCONVERT_H_ diff --git a/src/autoderrick.cpp b/src/autoderrick.cpp deleted file mode 100644 index d2541c5..0000000 --- a/src/autoderrick.cpp +++ /dev/null @@ -1,605 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "interface.h" -#include "button.h" -#include "window.h" -#include "sound.h" -#include "displaytext.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autoderrick.h" - - - -#define DERRICK_DELAY 10.0f // duration of the extraction -#define DERRICK_DELAYu 30.0f // same, but for uranium - - - - -// Object's constructor. - -CAutoDerrick::CAutoDerrick(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - Init(); - m_phase = ADP_WAIT; // paused until the first Init () - m_soundChannel = -1; -} - -// Object's destructor. - -CAutoDerrick::~CAutoDerrick() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoDerrick::DeleteObject(BOOL bAll) -{ - CObject* fret; - - if ( !bAll ) - { - fret = SearchFret(); - if ( fret != 0 && fret->RetLock() ) - { - fret->DeleteObject(); - delete fret; - } - } - - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } - - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoDerrick::Init() -{ - D3DMATRIX* mat; - D3DVECTOR pos; - TerrainRes res; - - pos = m_object->RetPosition(0); - res = m_terrain->RetResource(pos); - - if ( res == TR_STONE || - res == TR_URANIUM || - res == TR_KEYa || - res == TR_KEYb || - res == TR_KEYc || - res == TR_KEYd ) - { - m_type = OBJECT_FRET; - if ( res == TR_STONE ) m_type = OBJECT_STONE; - if ( res == TR_URANIUM ) m_type = OBJECT_URANIUM; - if ( res == TR_KEYa ) m_type = OBJECT_KEYa; - if ( res == TR_KEYb ) m_type = OBJECT_KEYb; - if ( res == TR_KEYc ) m_type = OBJECT_KEYc; - if ( res == TR_KEYd ) m_type = OBJECT_KEYd; - - m_phase = ADP_EXCAVATE; - m_progress = 0.0f; - m_speed = 1.0f/(m_type==OBJECT_URANIUM?DERRICK_DELAYu:DERRICK_DELAY); - } - else - { - m_phase = ADP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f; - } - - m_time = 0.0f; - m_timeVirus = 0.0f; - m_lastParticule = 0.0f; - m_lastTrack = 0.0f; - - pos = D3DVECTOR(7.0f, 0.0f, 0.0f); - mat = m_object->RetWorldMatrix(0); - pos = Transform(*mat, pos); - m_terrain->MoveOnFloor(pos); - m_fretPos = pos; -} - - -// Management of an event. - -BOOL CAutoDerrick::EventProcess(const Event &event) -{ - CObject* fret; - D3DVECTOR pos, speed; - FPOINT dim; - float angle, duration, factor; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_phase == ADP_WAIT ) return TRUE; - - m_progress += event.rTime*m_speed; - m_timeVirus -= event.rTime; - - if ( m_object->RetVirusMode() ) // contaminated by a virus? - { - if ( m_timeVirus <= 0.0f ) - { - m_timeVirus = 0.1f+Rand()*0.3f; - - pos.x = 0.0f; - pos.z = 0.0f; - pos.y = -2.0f*Rand(); - m_object->SetPosition(1, pos); // up / down the drill - - m_object->SetAngleY(1, Rand()*0.5f); // rotates the drill - } - return TRUE; - } - - if ( m_phase == ADP_EXCAVATE ) - { - if ( m_soundChannel == -1 ) - { - if ( m_type == OBJECT_URANIUM ) - { - factor = DERRICK_DELAYu/DERRICK_DELAY; - } - else - { - factor = 1.0f; - } - m_soundChannel = m_sound->Play(SOUND_DERRICK, m_object->RetPosition(0), 1.0f, 0.5f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 4.0f*factor, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.3f, 6.0f*factor, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 1.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 4.0f, SOPER_STOP); - } - - if ( m_progress >= 6.0f/16.0f && // penetrates into the ground? - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_object->RetPosition(0); - speed.x = (Rand()-0.5f)*10.0f; - speed.z = (Rand()-0.5f)*10.0f; - speed.y = Rand()*5.0f; - dim.x = Rand()*3.0f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); - } - - if ( m_progress >= 6.0f/16.0f && // penetrates into the ground? - m_lastTrack+m_engine->ParticuleAdapt(0.5f) <= m_time ) - { - m_lastTrack = m_time; - - pos = m_object->RetPosition(0); - speed.x = (Rand()-0.5f)*12.0f; - speed.z = (Rand()-0.5f)*12.0f; - speed.y = Rand()*10.0f+10.0f; - dim.x = 0.6f; - dim.y = dim.x; - pos.y += dim.y; - duration = Rand()*2.0f+2.0f; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK5, - duration, Rand()*10.0f+15.0f, - duration*0.2f, 1.0f); - } - - if ( m_progress < 1.0f ) - { - pos.x = 0.0f; - pos.z = 0.0f; - pos.y = -m_progress*16.0f; - m_object->SetPosition(1, pos); // down the drill - - angle = m_object->RetAngleY(1); - angle += event.rTime*8.0f; - m_object->SetAngleY(1, angle); // rotates the drill - } - else - { - m_phase = ADP_ASCEND; - m_progress = 0.0f; - m_speed = 1.0f/5.0f; - } - } - - if ( m_phase == ADP_ASCEND ) - { - if ( m_progress <= 7.0f/16.0f && - m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_object->RetPosition(0); - speed.x = (Rand()-0.5f)*10.0f; - speed.z = (Rand()-0.5f)*10.0f; - speed.y = Rand()*5.0f; - dim.x = Rand()*3.0f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); - } - - if ( m_progress <= 4.0f/16.0f && - m_lastTrack+m_engine->ParticuleAdapt(1.0f) <= m_time ) - { - m_lastTrack = m_time; - - pos = m_object->RetPosition(0); - speed.x = (Rand()-0.5f)*12.0f; - speed.z = (Rand()-0.5f)*12.0f; - speed.y = Rand()*10.0f+10.0f; - dim.x = 0.6f; - dim.y = dim.x; - pos.y += dim.y; - duration = Rand()*2.0f+2.0f; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK5, - duration, Rand()*10.0f+15.0f, - duration*0.2f, 1.0f); - } - - if ( m_progress < 1.0f ) - { - pos.x = 0.0f; - pos.z = 0.0f; - pos.y = -(1.0f-m_progress)*16.0f; - m_object->SetPosition(1, pos); // back the drill - - angle = m_object->RetAngleY(1); - angle -= event.rTime*2.0f; - m_object->SetAngleY(1, angle); // rotates the drill - } - else - { - m_soundChannel = -1; - m_bSoundFall = FALSE; - - m_phase = ADP_EXPORT; - m_progress = 0.0f; - m_speed = 1.0f/5.0f; - } - } - - if ( m_phase == ADP_ISFREE ) - { - if ( m_progress >= 1.0f ) - { - m_bSoundFall = FALSE; - - m_phase = ADP_EXPORT; - m_progress = 0.0f; - m_speed = 1.0f/5.0f; - } - } - - if ( m_phase == ADP_EXPORT ) - { - if ( m_progress == 0.0f ) - { - if ( SearchFree(m_fretPos) ) - { - angle = m_object->RetAngleY(0); - CreateFret(m_fretPos, angle, m_type, 16.0f); - } - else - { - m_phase = ADP_ISFREE; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - return TRUE; - } - } - - fret = SearchFret(); - - if ( fret != 0 && - m_progress <= 0.5f && - m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) - { - m_lastParticule = m_time; - - if ( m_progress < 0.3f ) - { - pos = fret->RetPosition(0); - pos.x += (Rand()-0.5f)*5.0f; - pos.z += (Rand()-0.5f)*5.0f; - pos.y += (Rand()-0.5f)*5.0f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 3.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFIRE, 1.0f, 0.0f, 0.0f); - } - else - { - pos = fret->RetPosition(0); - pos.x += (Rand()-0.5f)*5.0f; - pos.z += (Rand()-0.5f)*5.0f; - pos.y += Rand()*2.5f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f); - } - } - - if ( m_progress < 1.0f ) - { - if ( fret != 0 ) - { - pos = fret->RetPosition(0); - pos.y -= event.rTime*20.0f; // grave - if ( !m_bSoundFall && pos.y < m_fretPos.y ) - { - m_sound->Play(SOUND_BOUM, m_fretPos); - m_bSoundFall = TRUE; - } - if ( pos.y < m_fretPos.y ) - { - pos.y = m_fretPos.y; - fret->SetLock(FALSE); // object usable - } - fret->SetPosition(0, pos); - } - } - else - { - if ( ExistKey() ) // key already exists? - { - m_phase = ADP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/10.0f; - } - else - { - m_phase = ADP_EXCAVATE; - m_progress = 0.0f; - m_speed = 1.0f/(m_type==OBJECT_URANIUM?DERRICK_DELAYu:DERRICK_DELAY); - } - } - } - - return TRUE; -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoDerrick::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 109, EVENT_OBJECT_TYPE); - - return TRUE; -} - - -// Saves all parameters of the controller. - -BOOL CAutoDerrick::Write(char *line) -{ - char name[100]; - - if ( m_phase == ADP_WAIT ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller. - -BOOL CAutoDerrick::Read(char *line) -{ - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoDerrickPhase)OpInt(line, "aPhase", ADP_WAIT); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - - m_lastParticule = 0.0f; - - return TRUE; -} - - -// Seeks the subject cargo. - -CObject* CAutoDerrick::SearchFret() -{ - CObject* pObj; - D3DVECTOR oPos; - ObjectType type; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type == OBJECT_DERRICK ) continue; - - oPos = pObj->RetPosition(0); - - if ( oPos.x == m_fretPos.x && - oPos.z == m_fretPos.z ) return pObj; - } - - return 0; -} - -// Seeks if a site is free. - -BOOL CAutoDerrick::SearchFree(D3DVECTOR pos) -{ - CObject* pObj; - D3DVECTOR sPos; - ObjectType type; - float sRadius, distance; - int i, j; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type == OBJECT_DERRICK ) continue; - - j = 0; - while ( pObj->GetCrashSphere(j++, sPos, sRadius) ) - { - distance = Length(sPos, pos); - distance -= sRadius; - if ( distance < 2.0f ) return FALSE; // location occupied - } - } - - return TRUE; // location free -} - -// Create a transportable object. - -void CAutoDerrick::CreateFret(D3DVECTOR pos, float angle, ObjectType type, - float height) -{ - CObject* fret; - - fret = new CObject(m_iMan); - if ( !fret->CreateResource(pos, angle, type) ) - { - delete fret; - m_displayText->DisplayError(ERR_TOOMANY, m_object); - return; - } - fret->SetLock(TRUE); // object not yet usable - - if ( m_object->RetResetCap() == RESET_MOVE ) - { - fret->SetResetCap(RESET_DELETE); - } - - pos = fret->RetPosition(0); - pos.y += height; - fret->SetPosition(0, pos); -} - -// Look if there is already a key. - -BOOL CAutoDerrick::ExistKey() -{ - CObject* pObj; - ObjectType type; - int i; - - if ( m_type != OBJECT_KEYa && - m_type != OBJECT_KEYb && - m_type != OBJECT_KEYc && - m_type != OBJECT_KEYd ) return FALSE; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type == m_type ) return TRUE; - } - - return FALSE; -} - - -// Returns an error due the state of the automaton. - -Error CAutoDerrick::RetError() -{ - if ( m_object->RetVirusMode() ) - { - return ERR_BAT_VIRUS; - } - - if ( m_phase == ADP_WAIT ) return ERR_DERRICK_NULL; - return ERR_OK; -} - - diff --git a/src/autoderrick.h b/src/autoderrick.h deleted file mode 100644 index 6c9293d..0000000 --- a/src/autoderrick.h +++ /dev/null @@ -1,84 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autoderrick.h - -#ifndef _AUTODERRICK_H_ -#define _AUTODERRICK_H_ - - -#include "object.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - - -enum AutoDerrickPhase -{ - ADP_WAIT = 1, - ADP_EXCAVATE = 2, // down the drill - ADP_ASCEND = 3, // up the drill - ADP_EXPORT = 4, // exports matter - ADP_ISFREE = 5, // expected material loss -}; - - - -class CAutoDerrick : public CAuto -{ -public: - CAutoDerrick(CInstanceManager* iMan, CObject* object); - ~CAutoDerrick(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - - BOOL CreateInterface(BOOL bSelect); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - CObject* SearchFret(); - BOOL SearchFree(D3DVECTOR pos); - void CreateFret(D3DVECTOR pos, float angle, ObjectType type, float height); - BOOL ExistKey(); - -protected: - AutoDerrickPhase m_phase; - float m_progress; - float m_speed; - float m_timeVirus; - float m_lastParticule; - float m_lastTrack; - D3DVECTOR m_fretPos; - int m_soundChannel; - BOOL m_bSoundFall; -}; - - -#endif //_AUTODERRICK_H_ diff --git a/src/autodestroyer.cpp b/src/autodestroyer.cpp deleted file mode 100644 index 11dc0ba..0000000 --- a/src/autodestroyer.cpp +++ /dev/null @@ -1,397 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "light.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "physics.h" -#include "pyro.h" -#include "sound.h" -#include "interface.h" -#include "button.h" -#include "window.h" -#include "robotmain.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autodestroyer.h" - - - - -// Object's constructor. - -CAutoDestroyer::CAutoDestroyer(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - Init(); - m_phase = ADEP_WAIT; // paused until the first Init () -} - -// Destructive of the object. - -CAutoDestroyer::~CAutoDestroyer() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoDestroyer::DeleteObject(BOOL bAll) -{ - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoDestroyer::Init() -{ - m_phase = ADEP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/0.5f; - - m_time = 0.0f; - m_timeVirus = 0.0f; - m_lastParticule = 0.0f; - - CAuto::Init(); -} - - -// Management of an event. - -BOOL CAutoDestroyer::EventProcess(const Event &event) -{ - CObject* scrap; - CPyro* pyro; - D3DVECTOR pos, speed; - FPOINT dim; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_speed; - m_timeVirus -= event.rTime; - - if ( m_object->RetVirusMode() ) // contaminated by a virus? - { - if ( m_timeVirus <= 0.0f ) - { - m_timeVirus = 0.1f+Rand()*0.3f; - } - return TRUE; - } - - if ( m_phase == ADEP_WAIT ) - { - if ( m_progress >= 1.0f ) - { - scrap = SearchPlastic(); - if ( scrap == 0 ) - { - m_phase = ADEP_WAIT; // still waiting ... - m_progress = 0.0f; - m_speed = 1.0f/0.5f; - } - else - { - scrap->SetLock(TRUE); // usable waste -//? scrap->SetTruck(m_object); // usable waste - - if ( SearchVehicle() ) - { - m_phase = ADEP_WAIT; // still waiting ... - m_progress = 0.0f; - m_speed = 1.0f/0.5f; - } - else - { - m_sound->Play(SOUND_PSHHH2, m_object->RetPosition(0), 1.0f, 1.0f); - - m_phase = ADEP_DOWN; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - m_bExplo = FALSE; - } - } - } - } - - if ( m_phase == ADEP_DOWN ) - { - if ( m_progress >= 0.3f-0.05f && !m_bExplo ) - { - scrap = SearchPlastic(); - if ( scrap != 0 ) - { - pyro = new CPyro(m_iMan); - pyro->Create(PT_FRAGT, scrap); - } - m_bExplo = TRUE; - } - - if ( m_progress < 1.0f ) - { - pos = D3DVECTOR(0.0f, -10.0f, 0.0f); - pos.y = -Bounce(m_progress, 0.3f)*10.0f; - m_object->SetPosition(1, pos); - } - else - { - m_object->SetPosition(1, D3DVECTOR(0.0f, -10.0f, 0.0f)); - m_sound->Play(SOUND_REPAIR, m_object->RetPosition(0)); - - m_phase = ADEP_REPAIR; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - if ( m_phase == ADEP_REPAIR ) - { - if ( m_progress < 1.0f ) - { - } - else - { - m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 0.8f); - - m_phase = ADEP_UP; - m_progress = 0.0f; - m_speed = 1.0f/3.0f; - } - } - - if ( m_phase == ADEP_UP ) - { - if ( m_progress < 1.0f ) - { - pos = D3DVECTOR(0.0f, -10.0f, 0.0f); - pos.y = -(1.0f-m_progress)*10.0f; - m_object->SetPosition(1, pos); - } - else - { - m_object->SetPosition(1, D3DVECTOR(0.0f, 0.0f, 0.0f)); - - m_phase = ADEP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/0.5f; - } - } - - return TRUE; -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoDestroyer::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 106, EVENT_OBJECT_TYPE); - - return TRUE; -} - - -// Seeks plate waste in the destroyer. - -CObject* CAutoDestroyer::SearchPlastic() -{ - CObject* pObj; - D3DVECTOR sPos, oPos; - ObjectType type; - float dist; - int i; - - sPos = m_object->RetPosition(0); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type != OBJECT_SCRAP4 && - type != OBJECT_SCRAP5 ) continue; - - oPos = pObj->RetPosition(0); - dist = Length(oPos, sPos); - if ( dist <= 5.0f ) return pObj; - } - - return 0; -} - -// Seeks if one vehicle is too close. - -BOOL CAutoDestroyer::SearchVehicle() -{ - CObject* pObj; - D3DVECTOR cPos, oPos; - ObjectType type; - float oRadius, dist; - int i; - - cPos = m_object->RetPosition(0); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type != OBJECT_HUMAN && - type != OBJECT_MOBILEfa && - type != OBJECT_MOBILEta && - type != OBJECT_MOBILEwa && - type != OBJECT_MOBILEia && - type != OBJECT_MOBILEfc && - type != OBJECT_MOBILEtc && - type != OBJECT_MOBILEwc && - type != OBJECT_MOBILEic && - type != OBJECT_MOBILEfi && - type != OBJECT_MOBILEti && - type != OBJECT_MOBILEwi && - type != OBJECT_MOBILEii && - type != OBJECT_MOBILEfs && - type != OBJECT_MOBILEts && - type != OBJECT_MOBILEws && - type != OBJECT_MOBILEis && - type != OBJECT_MOBILErt && - type != OBJECT_MOBILErc && - type != OBJECT_MOBILErr && - type != OBJECT_MOBILErs && - type != OBJECT_MOBILEsa && - type != OBJECT_MOBILEtg && - type != OBJECT_MOBILEft && - type != OBJECT_MOBILEtt && - type != OBJECT_MOBILEwt && - type != OBJECT_MOBILEit && - type != OBJECT_MOBILEdr && - type != OBJECT_MOTHER && - type != OBJECT_ANT && - type != OBJECT_SPIDER && - type != OBJECT_BEE && - type != OBJECT_WORM ) continue; - - if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; - dist = Length(oPos, cPos)-oRadius; - - if ( dist < 20.0f ) return TRUE; - } - - return FALSE; -} - - -// Returns an error due the state of the automation. - -Error CAutoDestroyer::RetError() -{ - if ( m_object->RetVirusMode() ) - { - return ERR_BAT_VIRUS; - } - - return ERR_OK; -} - - -// Saves all parameters of the controller. - -BOOL CAutoDestroyer::Write(char *line) -{ - char name[100]; - - if ( m_phase == ADEP_WAIT ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller. - -BOOL CAutoDestroyer::Read(char *line) -{ - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoDestroyerPhase)OpInt(line, "aPhase", ADEP_WAIT); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - - m_lastParticule = 0.0f; - - return TRUE; -} - - diff --git a/src/autodestroyer.h b/src/autodestroyer.h deleted file mode 100644 index a69f832..0000000 --- a/src/autodestroyer.h +++ /dev/null @@ -1,76 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autodestroyer.h - -#ifndef _AUTODESTROYER_H_ -#define _AUTODESTROYER_H_ - - -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoDestroyerPhase -{ - ADEP_WAIT = 1, // expected metal - ADEP_DOWN = 2, // down the cover - ADEP_REPAIR = 3, // built the vehicle - ADEP_UP = 4, // up the cover -}; - - - -class CAutoDestroyer : public CAuto -{ -public: - CAutoDestroyer(CInstanceManager* iMan, CObject* object); - ~CAutoDestroyer(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - - BOOL CreateInterface(BOOL bSelect); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - CObject* SearchPlastic(); - BOOL SearchVehicle(); - -protected: - AutoDestroyerPhase m_phase; - float m_progress; - float m_speed; - float m_timeVirus; - float m_lastParticule; - BOOL m_bExplo; -}; - - -#endif //_AUTODESTROYER_H_ diff --git a/src/autoegg.cpp b/src/autoegg.cpp deleted file mode 100644 index 6e57fcc..0000000 --- a/src/autoegg.cpp +++ /dev/null @@ -1,375 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "pyro.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autoegg.h" - - - -// Object's constructor. - -CAutoEgg::CAutoEgg(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - m_type = OBJECT_NULL; - m_value = 0.0f; - m_string[0] = 0; - - m_param = 0; - m_phase = AEP_NULL; - Init(); -} - -// Object's destructor. - -CAutoEgg::~CAutoEgg() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoEgg::DeleteObject(BOOL bAll) -{ - CObject* alien; - - CAuto::DeleteObject(bAll); - - if ( !bAll ) - { - alien = SearchAlien(); - if ( alien != 0 ) - { - // Probably the intended action - // Original code: ( alien->RetZoom(0) == 1.0f ) - if ( alien->RetZoomY(0) == 1.0f ) - { - alien->SetLock(FALSE); - alien->SetActivity(TRUE); // the insect is active - } - else - { - alien->DeleteObject(); - delete alien; - } - } - } -} - - -// Initialize the object. - -void CAutoEgg::Init() -{ - CObject* alien; - - alien = SearchAlien(); - if ( alien == 0 ) - { - m_phase = AEP_NULL; - m_progress = 0.0f; - m_speed = 1.0f/5.0f; - m_time = 0.0f; - return; - } - - m_phase = AEP_INCUB; - m_progress = 0.0f; - m_speed = 1.0f/5.0f; - m_time = 0.0f; - - m_type = alien->RetType(); - - if ( m_type == OBJECT_ANT || - m_type == OBJECT_SPIDER || - m_type == OBJECT_BEE ) - { - alien->SetZoom(0, 0.2f); - } - if ( m_type == OBJECT_WORM ) - { - alien->SetZoom(0, 0.01f); // invisible ! - } - alien->SetLock(TRUE); - alien->SetActivity(FALSE); -} - - -// Gives a value. - -BOOL CAutoEgg::SetType(ObjectType type) -{ - m_type = type; - return TRUE; -} - -// Gives a value. - -BOOL CAutoEgg::SetValue(int rank, float value) -{ - if ( rank != 0 ) return FALSE; - m_value = value; - return TRUE; -} - -// Gives the string. - -BOOL CAutoEgg::SetString(char *string) -{ - strcpy(m_string, string); - return TRUE; -} - - -// Start object. - -void CAutoEgg::Start(int param) -{ - if ( m_type == OBJECT_NULL ) return; - if ( m_value == 0.0f ) return; - - m_phase = AEP_DELAY; - m_progress = 0.0f; - m_speed = 1.0f/m_value; - - m_param = param; -} - - -// Management of an event. - -BOOL CAutoEgg::EventProcess(const Event &event) -{ - CObject* alien; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_phase == AEP_NULL ) return TRUE; - - if ( m_phase == AEP_DELAY ) - { - m_progress += event.rTime*m_speed; - if ( m_progress < 1.0f ) return TRUE; - - alien = new CObject(m_iMan); - if ( !alien->CreateInsect(m_object->RetPosition(0), m_object->RetAngleY(0), m_type) ) - { - delete alien; - m_phase = AEP_DELAY; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - return TRUE; - } - alien->SetActivity(FALSE); - alien->ReadProgram(0, m_string); - alien->RunProgram(0); - Init(); - } - - alien = SearchAlien(); - if ( alien == 0 ) return TRUE; - alien->SetActivity(FALSE); - - m_progress += event.rTime*m_speed; - - if ( m_phase == AEP_ZOOM ) - { - if ( m_type == OBJECT_ANT || - m_type == OBJECT_SPIDER || - m_type == OBJECT_BEE ) - { - alien->SetZoom(0, 0.2f+m_progress*0.8f); // Others push - } - } - - return TRUE; -} - -// Indicates whether the controller has completed its activity. - -Error CAutoEgg::IsEnded() -{ - CObject* alien; - CPyro* pyro; - - if ( m_phase == AEP_DELAY ) - { - return ERR_CONTINUE; - } - - alien = SearchAlien(); - if ( alien == 0 ) return ERR_STOP; - - if ( m_phase == AEP_INCUB ) - { - if ( m_progress < 1.0f ) return ERR_CONTINUE; - - m_phase = AEP_ZOOM; - m_progress = 0.0f; - m_speed = 1.0f/5.0f; - } - - if ( m_phase == AEP_ZOOM ) - { - if ( m_progress < 1.0f ) return ERR_CONTINUE; - - pyro = new CPyro(m_iMan); - pyro->Create(PT_EGG, m_object); // exploding egg - - alien->SetZoom(0, 1.0f); // this is a big boy now - - m_phase = AEP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/3.0f; - } - - if ( m_phase == AEP_WAIT ) - { - if ( m_progress < 1.0f ) return ERR_CONTINUE; - - alien->SetLock(FALSE); - alien->SetActivity(TRUE); // the insect is active - } - - return ERR_STOP; -} - - -// Returns an error due the state of the automation. - -Error CAutoEgg::RetError() -{ - return ERR_OK; -} - - -// Seeking the insect that starts in the egg. - -CObject* CAutoEgg::SearchAlien() -{ - CObject* pObj; - CObject* pBest; - D3DVECTOR cPos, oPos; - ObjectType type; - float dist, min; - int i; - - cPos = m_object->RetPosition(0); - min = 100000.0f; - pBest = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj->RetTruck() != 0 ) continue; - - type = pObj->RetType(); - if ( type != OBJECT_ANT && - type != OBJECT_BEE && - type != OBJECT_SPIDER && - type != OBJECT_WORM ) continue; - - oPos = pObj->RetPosition(0); - dist = Length2d(oPos, cPos); - if ( dist < 8.0f && dist < min ) - { - min = dist; - pBest = pObj; - } - } - return pBest; -} - - -// Saves all parameters of the controller. - -BOOL CAutoEgg::Write(char *line) -{ - char name[100]; - - if ( m_phase == AEP_NULL ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.5f", m_speed); - strcat(line, name); - - sprintf(name, " aParamType=%s", GetTypeObject(m_type)); - strcat(line, name); - - sprintf(name, " aParamValue1=%.2f", m_value); - strcat(line, name); - - sprintf(name, " aParamString=\"%s\"", m_string); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller. - -BOOL CAutoEgg::Read(char *line) -{ - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoEggPhase)OpInt(line, "aPhase", AEP_NULL); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - m_type = OpTypeObject(line, "aParamType", OBJECT_NULL); - m_value = OpFloat(line, "aParamValue1", 0.0f); - OpString(line, "aParamString", m_string); - - return TRUE; -} - diff --git a/src/autoegg.h b/src/autoegg.h deleted file mode 100644 index 4340a9b..0000000 --- a/src/autoegg.h +++ /dev/null @@ -1,83 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autoegg.h - -#ifndef _AUTOEGG_H_ -#define _AUTOEGG_H_ - - -#include "object.h" -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoEggPhase -{ - AEP_NULL = 0, - AEP_DELAY = 1, - AEP_INCUB = 3, - AEP_ZOOM = 4, - AEP_WAIT = 5, -}; - - - -class CAutoEgg : public CAuto -{ -public: - CAutoEgg(CInstanceManager* iMan, CObject* object); - ~CAutoEgg(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - void Start(int param); - BOOL EventProcess(const Event &event); - Error IsEnded(); - Error RetError(); - - BOOL SetType(ObjectType type); - BOOL SetValue(int rank, float value); - BOOL SetString(char *string); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - CObject* SearchAlien(); - -protected: - ObjectType m_type; - float m_value; - char m_string[100]; - int m_param; - AutoEggPhase m_phase; - float m_progress; - float m_speed; -}; - - -#endif //_AUTOEGG_H_ diff --git a/src/autoenergy.cpp b/src/autoenergy.cpp deleted file mode 100644 index 023a185..0000000 --- a/src/autoenergy.cpp +++ /dev/null @@ -1,665 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "light.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "interface.h" -#include "button.h" -#include "gauge.h" -#include "window.h" -#include "displaytext.h" -#include "sound.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autoenergy.h" - - - -#define ENERGY_POWER 0.4f // Necessary energy for a battery -#define ENERGY_DELAY 12.0f // processing time - - - - -// Object's constructor. - -CAutoEnergy::CAutoEnergy(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - m_partiSphere = -1; - Init(); -} - -// Object's destructor. - -CAutoEnergy::~CAutoEnergy() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoEnergy::DeleteObject(BOOL bAll) -{ - CObject* fret; - - if ( m_partiSphere != -1 ) - { - m_particule->DeleteParticule(m_partiSphere); - m_partiSphere = -1; - } - - if ( !bAll ) - { - fret = SearchMetal(); - if ( fret != 0 ) - { - fret->DeleteObject(); // destroys the metal - delete fret; - } - - fret = SearchPower(); - if ( fret != 0 ) - { - fret->DeleteObject(); // destroys the cell - delete fret; - } - } - - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoEnergy::Init() -{ - m_time = 0.0f; - m_timeVirus = 0.0f; - m_lastUpdateTime = 0.0f; - m_lastParticule = 0.0f; - - m_phase = AENP_WAIT; // waiting ... - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - - CAuto::Init(); -} - - -// Management of an event. - -BOOL CAutoEnergy::EventProcess(const Event &event) -{ - CObject* fret; - D3DVECTOR pos, ppos, speed; - FPOINT dim, c, p; - TerrainRes res; - float big; - BOOL bGO; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_speed; - m_timeVirus -= event.rTime; - - if ( m_object->RetVirusMode() ) // contaminated by a virus? - { - if ( m_timeVirus <= 0.0f ) - { - m_timeVirus = 0.1f+Rand()*0.3f; - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - pos = m_object->RetPosition(0); - pos.y += 10.0f; - speed.x = (Rand()-0.5f)*10.0f; - speed.z = (Rand()-0.5f)*10.0f; - speed.y = -7.0f; - dim.x = Rand()*0.5f+0.5f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ, 1.0f, 0.0f, 0.0f); - } - } - return TRUE; - } - - UpdateInterface(event.rTime); - EventProgress(event.rTime); - - big = m_object->RetEnergy(); - - res = m_terrain->RetResource(m_object->RetPosition(0)); - if ( res == TR_POWER ) - { - big += event.rTime*0.01f; // recharges the big pile - } - - if ( m_phase == AENP_WAIT ) - { - if ( m_progress >= 1.0f ) - { - bGO = FALSE; - fret = SearchMetal(); // transform metal? - if ( fret != 0 ) - { - if ( fret->RetType() == OBJECT_METAL ) - { - if ( big > ENERGY_POWER ) bGO = TRUE; - } - else - { - if ( !SearchVehicle() ) bGO = TRUE; - } - } - - if ( bGO ) - { - if ( fret->RetType() == OBJECT_METAL ) - { - fret->SetLock(TRUE); // usable metal - CreatePower(); // creates the battery - } - - SetBusy(TRUE); - InitProgressTotal(ENERGY_DELAY); - CAuto::UpdateInterface(); - - pos = m_object->RetPosition(0); - pos.y += 4.0f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 3.0f; - dim.y = dim.x; - m_partiSphere = m_particule->CreateParticule(pos, speed, dim, PARTISPHERE1, ENERGY_DELAY, 0.0f, 0.0f); - - m_phase = AENP_CREATE; - m_progress = 0.0f; - m_speed = 1.0f/ENERGY_DELAY; - } - else - { - if ( rand()%3 == 0 && big > 0.01f ) - { - m_phase = AENP_BLITZ; - m_progress = 0.0f; - m_speed = 1.0f/Rand()*1.0f+1.0f; - } - else - { - m_phase = AENP_WAIT; // still waiting ... - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - } - } - - if ( m_phase == AENP_BLITZ ) - { - if ( m_progress < 1.0f && big > 0.01f ) - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - pos = m_object->RetPosition(0); - pos.y += 10.0f; - speed.x = (Rand()-0.5f)*1.0f; - speed.z = (Rand()-0.5f)*1.0f; - speed.y = -7.0f; - dim.x = Rand()*0.5f+0.5f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ, 1.0f, 0.0f, 0.0f); - } - } - else - { - m_phase = AENP_WAIT; // still waiting ... - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - if ( m_phase == AENP_CREATE ) - { - if ( m_progress < 1.0f ) - { - fret = SearchMetal(); - if ( fret != 0 ) - { - if ( fret->RetType() == OBJECT_METAL ) - { - big -= event.rTime/ENERGY_DELAY*ENERGY_POWER; - } - else - { - big += event.rTime/ENERGY_DELAY*0.25f; - } - fret->SetZoom(0, 1.0f-m_progress); - } - - fret = SearchPower(); - if ( fret != 0 ) - { - fret->SetZoom(0, m_progress); - } - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_object->RetPosition(0); - c.x = pos.x; - c.y = pos.z; - p.x = c.x; - p.y = c.y+2.0f; - p = RotatePoint(c, Rand()*PI*2.0f, p); - pos.x = p.x; - pos.z = p.y; - pos.y += 2.5f+Rand()*3.0f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = Rand()*2.0f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 1.0f, 0.0f, 0.0f); - - pos = m_object->RetPosition(0); - pos.y += 3.0f; - speed.x = (Rand()-0.5f)*30.0f; - speed.z = (Rand()-0.5f)*30.0f; - speed.y = Rand()*20.0f+10.0f; - dim.x = Rand()*0.4f+0.4f; - dim.y = dim.x; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK2, 2.0f, 50.0f, 1.2f, 1.2f); - - pos = m_object->RetPosition(0); - pos.y += 10.0f; - speed.x = (Rand()-0.5f)*1.5f; - speed.z = (Rand()-0.5f)*1.5f; - speed.y = -6.0f; - dim.x = Rand()*1.0f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ, 1.0f, 0.0f, 0.0f); - - m_sound->Play(SOUND_ENERGY, m_object->RetPosition(0), - 1.0f, 1.0f+Rand()*1.5f); - } - } - else - { - fret = SearchMetal(); - if ( fret != 0 ) - { - m_object->SetPower(0); - fret->DeleteObject(); // destroys the metal - delete fret; - } - - fret = SearchPower(); - if ( fret != 0 ) - { - fret->SetZoom(0, 1.0f); - fret->SetLock(FALSE); // usable battery - fret->SetTruck(m_object); - fret->SetPosition(0, D3DVECTOR(0.0f, 3.0f, 0.0f)); - m_object->SetPower(fret); - - m_displayText->DisplayError(INFO_ENERGY, m_object); - } - - SetBusy(FALSE); - CAuto::UpdateInterface(); - - m_phase = AENP_SMOKE; - m_progress = 0.0f; - m_speed = 1.0f/5.0f; - } - } - - if ( m_phase == AENP_SMOKE ) - { - if ( m_progress < 1.0f ) - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_object->RetPosition(0); - pos.y += 17.0f; - pos.x += (Rand()-0.5f)*3.0f; - pos.z += (Rand()-0.5f)*3.0f; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 6.0f+Rand()*6.0f; - dim.x = Rand()*1.5f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); - } - } - else - { - m_phase = AENP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - if ( big < 0.0f ) big = 0.0f; - if ( big > 1.0f ) big = 1.0f; - m_object->SetEnergy(big); // shift the big pile - - return TRUE; -} - - -// Seeking the metal object. - -CObject* CAutoEnergy::SearchMetal() -{ - CObject* pObj; - ObjectType type; - - pObj = m_object->RetPower(); - if ( pObj == 0 ) return 0; - - type = pObj->RetType(); - if ( type == OBJECT_METAL || - type == OBJECT_SCRAP1 || - type == OBJECT_SCRAP2 || - type == OBJECT_SCRAP3 ) return pObj; - - return 0; -} - -// Search if a vehicle is too close. - -BOOL CAutoEnergy::SearchVehicle() -{ - CObject* pObj; - D3DVECTOR cPos, oPos; - ObjectType type; - float oRadius, dist; - int i; - - cPos = m_object->RetPosition(0); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type != OBJECT_HUMAN && - type != OBJECT_MOBILEfa && - type != OBJECT_MOBILEta && - type != OBJECT_MOBILEwa && - type != OBJECT_MOBILEia && - type != OBJECT_MOBILEfc && - type != OBJECT_MOBILEtc && - type != OBJECT_MOBILEwc && - type != OBJECT_MOBILEic && - type != OBJECT_MOBILEfi && - type != OBJECT_MOBILEti && - type != OBJECT_MOBILEwi && - type != OBJECT_MOBILEii && - type != OBJECT_MOBILEfs && - type != OBJECT_MOBILEts && - type != OBJECT_MOBILEws && - type != OBJECT_MOBILEis && - type != OBJECT_MOBILErt && - type != OBJECT_MOBILErc && - type != OBJECT_MOBILErr && - type != OBJECT_MOBILErs && - type != OBJECT_MOBILEsa && - type != OBJECT_MOBILEtg && - type != OBJECT_MOBILEft && - type != OBJECT_MOBILEtt && - type != OBJECT_MOBILEwt && - type != OBJECT_MOBILEit && - type != OBJECT_MOBILEdr && - type != OBJECT_MOTHER && - type != OBJECT_ANT && - type != OBJECT_SPIDER && - type != OBJECT_BEE && - type != OBJECT_WORM ) continue; - - if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; - dist = Length(oPos, cPos)-oRadius; - - if ( dist < 10.0f ) return TRUE; - } - - return FALSE; -} - -// Create a cell. - -void CAutoEnergy::CreatePower() -{ - CObject* power; - D3DVECTOR pos; - float angle; - - pos = m_object->RetPosition(0); - angle = m_object->RetAngleY(0); - - power = new CObject(m_iMan); - if ( !power->CreateResource(pos, angle, OBJECT_POWER) ) - { - delete power; - m_displayText->DisplayError(ERR_TOOMANY, m_object); - return; - } - power->SetLock(TRUE); // battery not yet usable - - pos = power->RetPosition(0); - pos.y += 3.0f; - power->SetPosition(0, pos); -} - -// Seeking the battery during manufacture. - -CObject* CAutoEnergy::SearchPower() -{ - CObject* pObj; - D3DVECTOR cPos, oPos; - ObjectType type; - int i; - - cPos = m_object->RetPosition(0); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetLock() ) continue; - - type = pObj->RetType(); - if ( type != OBJECT_POWER ) continue; - - oPos = pObj->RetPosition(0); - if ( oPos.x == cPos.x && - oPos.z == cPos.z ) - { - return pObj; - } - } - - return 0; -} - - -// Returns an error due the state of the automation. - -Error CAutoEnergy::RetError() -{ - CObject* pObj; - ObjectType type; - TerrainRes res; - - if ( m_object->RetVirusMode() ) - { - return ERR_BAT_VIRUS; - } - - if ( m_phase != AENP_WAIT && - m_phase != AENP_BLITZ ) return ERR_OK; - - res = m_terrain->RetResource(m_object->RetPosition(0)); - if ( res != TR_POWER ) return ERR_ENERGY_NULL; - - if ( m_object->RetEnergy() < ENERGY_POWER ) return ERR_ENERGY_LOW; - - pObj = m_object->RetPower(); - if ( pObj == 0 ) return ERR_ENERGY_EMPTY; - type = pObj->RetType(); - if ( type == OBJECT_POWER ) return ERR_OK; - if ( type != OBJECT_METAL && - type != OBJECT_SCRAP1 && - type != OBJECT_SCRAP2 && - type != OBJECT_SCRAP3 ) return ERR_ENERGY_BAD; - - return ERR_OK; -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoEnergy::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*14.5f; - pos.y = oy+sy*0; - ddim.x = 14.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 108, EVENT_OBJECT_TYPE); - - return TRUE; -} - -// Updates the state of all buttons on the interface, -// following the time that elapses ... - -void CAutoEnergy::UpdateInterface(float rTime) -{ - CWindow* pw; - CGauge* pg; - - CAuto::UpdateInterface(rTime); - - if ( m_time < m_lastUpdateTime+0.1f ) return; - m_lastUpdateTime = m_time; - - if ( !m_object->RetSelect() ) return; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; - - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); - if ( pg != 0 ) - { - pg->SetLevel(m_object->RetEnergy()); - } -} - - -// Saves all parameters of the controller. - -BOOL CAutoEnergy::Write(char *line) -{ - char name[100]; - - if ( m_phase == AENP_STOP || - m_phase == AENP_WAIT ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller. - -BOOL CAutoEnergy::Read(char *line) -{ - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoEnergyPhase)OpInt(line, "aPhase", AENP_WAIT); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - - m_lastUpdateTime = 0.0f; - m_lastParticule = 0.0f; - - return TRUE; -} diff --git a/src/autoenergy.h b/src/autoenergy.h deleted file mode 100644 index dd920fb..0000000 --- a/src/autoenergy.h +++ /dev/null @@ -1,83 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autoenergy.h - -#ifndef _AUTOENERGY_H_ -#define _AUTOENERGY_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoEnergyPhase -{ - AENP_STOP = 1, - AENP_WAIT = 2, - AENP_BLITZ = 3, - AENP_CREATE = 4, - AENP_SMOKE = 5, -}; - - - -class CAutoEnergy : public CAuto -{ -public: - CAutoEnergy(CInstanceManager* iMan, CObject* object); - ~CAutoEnergy(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - - BOOL CreateInterface(BOOL bSelect); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - void UpdateInterface(float rTime); - - CObject* SearchMetal(); - BOOL SearchVehicle(); - void CreatePower(); - CObject* SearchPower(); - -protected: - AutoEnergyPhase m_phase; - float m_progress; - float m_speed; - float m_timeVirus; - float m_lastUpdateTime; - float m_lastParticule; - int m_partiSphere; -}; - - -#endif //_AUTOENERGY_H_ diff --git a/src/autofactory.cpp b/src/autofactory.cpp deleted file mode 100644 index 7fab2fb..0000000 --- a/src/autofactory.cpp +++ /dev/null @@ -1,961 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "restext.h" -#include "global.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "light.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "interface.h" -#include "button.h" -#include "window.h" -#include "displaytext.h" -#include "robotmain.h" -#include "sound.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autofactory.h" - - - - -// Object's constructor. - -CAutoFactory::CAutoFactory(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - Init(); - m_type = OBJECT_MOBILEws; - m_phase = AFP_WAIT; // paused until the first Init () - m_channelSound = -1; -} - -// Object's destructor. - -CAutoFactory::~CAutoFactory() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoFactory::DeleteObject(BOOL bAll) -{ - CObject* fret; - CObject* vehicle; - - if ( !bAll ) - { - fret = SearchFret(); // transform metal? - if ( fret != 0 ) - { - fret->DeleteObject(); // destroys the metal - delete fret; - } - - vehicle = SearchVehicle(); - if ( vehicle != 0 ) - { - vehicle->DeleteObject(); // destroys the vehicle - delete vehicle; - } - } - - if ( m_channelSound != -1 ) - { - m_sound->FlushEnvelope(m_channelSound); - m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_channelSound = -1; - } - - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoFactory::Init() -{ - m_phase = AFP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - - m_time = 0.0f; - m_lastParticule = 0.0f; - - m_fretPos = m_object->RetPosition(0); - - CAuto::Init(); -} - - -// Management of an event. - -BOOL CAutoFactory::EventProcess(const Event &event) -{ - CObject* fret; - CObject* vehicle; - D3DMATRIX* mat; - CPhysics* physics; - D3DVECTOR pos, speed; - FPOINT dim; - ObjectType type; - float zoom, angle, prog; - int i; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - - if ( m_object->RetSelect() ) // factory selected? - { - if ( event.event == EVENT_UPDINTERFACE ) - { - CreateInterface(TRUE); - } - - type = OBJECT_NULL; - if ( event.event == EVENT_OBJECT_FACTORYwa ) type = OBJECT_MOBILEwa; - if ( event.event == EVENT_OBJECT_FACTORYta ) type = OBJECT_MOBILEta; - if ( event.event == EVENT_OBJECT_FACTORYfa ) type = OBJECT_MOBILEfa; - if ( event.event == EVENT_OBJECT_FACTORYia ) type = OBJECT_MOBILEia; - if ( event.event == EVENT_OBJECT_FACTORYws ) type = OBJECT_MOBILEws; - if ( event.event == EVENT_OBJECT_FACTORYts ) type = OBJECT_MOBILEts; - if ( event.event == EVENT_OBJECT_FACTORYfs ) type = OBJECT_MOBILEfs; - if ( event.event == EVENT_OBJECT_FACTORYis ) type = OBJECT_MOBILEis; - if ( event.event == EVENT_OBJECT_FACTORYwc ) type = OBJECT_MOBILEwc; - if ( event.event == EVENT_OBJECT_FACTORYtc ) type = OBJECT_MOBILEtc; - if ( event.event == EVENT_OBJECT_FACTORYfc ) type = OBJECT_MOBILEfc; - if ( event.event == EVENT_OBJECT_FACTORYic ) type = OBJECT_MOBILEic; - if ( event.event == EVENT_OBJECT_FACTORYwi ) type = OBJECT_MOBILEwi; - if ( event.event == EVENT_OBJECT_FACTORYti ) type = OBJECT_MOBILEti; - if ( event.event == EVENT_OBJECT_FACTORYfi ) type = OBJECT_MOBILEfi; - if ( event.event == EVENT_OBJECT_FACTORYii ) type = OBJECT_MOBILEii; - if ( event.event == EVENT_OBJECT_FACTORYrt ) type = OBJECT_MOBILErt; - if ( event.event == EVENT_OBJECT_FACTORYrc ) type = OBJECT_MOBILErc; - if ( event.event == EVENT_OBJECT_FACTORYrr ) type = OBJECT_MOBILErr; - if ( event.event == EVENT_OBJECT_FACTORYrs ) type = OBJECT_MOBILErs; - if ( event.event == EVENT_OBJECT_FACTORYsa ) type = OBJECT_MOBILEsa; - - if ( type != OBJECT_NULL ) - { - m_type = type; - - if ( m_phase != AFP_WAIT ) - { - return FALSE; - } - - fret = SearchFret(); // transform metal? - if ( fret == 0 ) - { - m_displayText->DisplayError(ERR_FACTORY_NULL, m_object); - return FALSE; - } - if ( NearestVehicle() ) - { - m_displayText->DisplayError(ERR_FACTORY_NEAR, m_object); - return FALSE; - } - - SetBusy(TRUE); - InitProgressTotal(3.0f+2.0f+15.0f+2.0f+3.0f); - UpdateInterface(); - - fret->SetLock(TRUE); // usable metal - SoundManip(3.0f, 1.0f, 0.5f); - - m_phase = AFP_CLOSE_S; - m_progress = 0.0f; - m_speed = 1.0f/3.0f; - return TRUE; - } - } - - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_speed; - EventProgress(event.rTime); - - if ( m_phase == AFP_WAIT ) - { - if ( m_progress >= 1.0f ) - { - m_phase = AFP_WAIT; // still waiting ... - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - if ( m_phase == AFP_CLOSE_S ) - { - if ( m_progress < 1.0f ) - { - for ( i=0 ; i<9 ; i++ ) - { - zoom = 0.30f+(m_progress-0.5f+i/16.0f)*2.0f*0.70f; - if ( zoom < 0.30f ) zoom = 0.30f; - if ( zoom > 1.00f ) zoom = 1.00f; - m_object->SetZoomZ( 1+i, zoom); - m_object->SetZoomZ(10+i, zoom); - } - } - else - { - for ( i=0 ; i<9 ; i++ ) - { - m_object->SetZoomZ( 1+i, 1.0f); - m_object->SetZoomZ(10+i, 1.0f); - } - - SoundManip(2.0f, 1.0f, 1.2f); - - m_phase = AFP_CLOSE_T; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - if ( m_phase == AFP_CLOSE_T ) - { - if ( m_progress < 1.0f ) - { - for ( i=0 ; i<9 ; i++ ) - { - angle = -m_progress*(PI/2.0f)+PI/2.0f; - m_object->SetAngleZ( 1+i, angle); - m_object->SetAngleZ(10+i, -angle); - } - } - else - { - for ( i=0 ; i<9 ; i++ ) - { - m_object->SetAngleZ( 1+i, 0.0f); - m_object->SetAngleZ(10+i, 0.0f); - } - - m_channelSound = m_sound->Play(SOUND_FACTORY, m_object->RetPosition(0), 0.0f, 1.0f, TRUE); - m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 2.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 11.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 2.0f, SOPER_STOP); - - m_phase = AFP_BUILD; - m_progress = 0.0f; - m_speed = 1.0f/15.0f; - } - } - - if ( m_phase == AFP_BUILD ) - { - if ( m_progress == 0.0f ) - { - if ( !CreateVehicle() ) - { - fret = SearchFret(); // transform metal? - if ( fret != 0 ) - { - fret->SetLock(FALSE); // metal usable again - } - - if ( m_channelSound != -1 ) - { - m_sound->FlushEnvelope(m_channelSound); - m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_channelSound = -1; - } - - m_phase = AFP_OPEN_T; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - return TRUE; - } - } - - if ( m_progress < 1.0f ) - { - if ( m_type == OBJECT_MOBILErt || - m_type == OBJECT_MOBILErc || - m_type == OBJECT_MOBILErr || - m_type == OBJECT_MOBILErs ) - { - prog = 1.0f-m_progress*1.5f; - if ( prog < 0.0f ) prog = 0.0f; - } - else - { - prog = 1.0f-m_progress; - } - angle = powf(prog*10.0f, 2.0f)+m_object->RetAngleY(0); - - vehicle = SearchVehicle(); - if ( vehicle != 0 ) - { - vehicle->SetAngleY(0, angle+PI); - vehicle->SetZoom(0, m_progress); - } - - fret = SearchFret(); // transform metal? - if ( fret != 0 ) - { - fret->SetZoom(0, 1.0f-m_progress); - } - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - -#if 0 - pos = m_fretPos; - pos.x += (Rand()-0.5f)*20.0f; - pos.z += (Rand()-0.5f)*20.0f; - pos.y += 1.0f; - speed.x = (Rand()-0.5f)*12.0f; - speed.z = (Rand()-0.5f)*12.0f; - speed.y = Rand()*12.0f; - dim.x = Rand()*12.0f+10.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); -#else - mat = m_object->RetWorldMatrix(0); - pos = D3DVECTOR(-12.0f, 20.0f, -4.0f); // position of chimney - pos = Transform(*mat, pos); - pos.y += 2.0f; - pos.x += (Rand()-0.5f)*2.0f; - pos.z += (Rand()-0.5f)*2.0f; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 6.0f+Rand()*6.0f; - dim.x = Rand()*1.5f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); -#endif - } - } - else - { - m_displayText->DisplayError(INFO_FACTORY, m_object); - SoundManip(2.0f, 1.0f, 1.2f); - - fret = SearchFret(); // transform metal? - if ( fret != 0 ) - { - fret->DeleteObject(); // removes the metal - delete fret; - } - - vehicle = SearchVehicle(); - if ( vehicle != 0 ) - { - physics = vehicle->RetPhysics(); - if ( physics != 0 ) - { - physics->SetFreeze(FALSE); // can move - } - - vehicle->SetLock(FALSE); // vehicle useable -//? vehicle->RetPhysics()->RetBrain()->StartTaskAdvance(16.0f); - vehicle->SetAngleY(0, m_object->RetAngleY(0)+PI); - vehicle->SetZoom(0, 1.0f); - } - - m_main->CreateShortcuts(); - - m_phase = AFP_OPEN_T; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - if ( m_phase == AFP_OPEN_T ) - { - if ( m_progress < 1.0f ) - { - for ( i=0 ; i<9 ; i++ ) - { - angle = -(1.0f-m_progress)*(PI/2.0f)+PI/2.0f; - m_object->SetAngleZ( 1+i, angle); - m_object->SetAngleZ(10+i, -angle); - } - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_fretPos; - pos.x += (Rand()-0.5f)*10.0f; - pos.z += (Rand()-0.5f)*10.0f; - pos.y += Rand()*10.0f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f); - } - } - else - { - for ( i=0 ; i<9 ; i++ ) - { - m_object->SetAngleZ( 1+i, PI/2.0f); - m_object->SetAngleZ(10+i, -PI/2.0f); - } - - SoundManip(3.0f, 1.0f, 0.5f); - - m_phase = AFP_OPEN_S; - m_progress = 0.0f; - m_speed = 1.0f/3.0f; - } - } - - if ( m_phase == AFP_OPEN_S ) - { - if ( m_progress < 1.0f ) - { - for ( i=0 ; i<9 ; i++ ) - { - zoom = 0.30f+((1.0f-m_progress)-0.5f+i/16.0f)*2.0f*0.70f; - if ( zoom < 0.30f ) zoom = 0.30f; - if ( zoom > 1.00f ) zoom = 1.00f; - m_object->SetZoomZ( 1+i, zoom); - m_object->SetZoomZ(10+i, zoom); - } - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_fretPos; - pos.x += (Rand()-0.5f)*10.0f; - pos.z += (Rand()-0.5f)*10.0f; - pos.y += Rand()*10.0f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f); - } - } - else - { - for ( i=0 ; i<9 ; i++ ) - { - m_object->SetZoomZ( 1+i, 0.30f); - m_object->SetZoomZ(10+i, 0.30f); - } - - SetBusy(FALSE); - UpdateInterface(); - - m_phase = AFP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - return TRUE; -} - - -// Saves all parameters of the controller. - -BOOL CAutoFactory::Write(char *line) -{ - char name[100]; - - if ( m_phase == AFP_WAIT ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller - -BOOL CAutoFactory::Read(char *line) -{ - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoFactoryPhase)OpInt(line, "aPhase", AFP_WAIT); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - - m_lastParticule = 0.0f; - m_fretPos = m_object->RetPosition(0); - - return TRUE; -} - - -//Seeks the cargo. - -CObject* CAutoFactory::SearchFret() -{ - CObject* pObj; - D3DVECTOR oPos; - ObjectType type; - float dist; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type != OBJECT_METAL ) continue; - if ( pObj->RetTruck() != 0 ) continue; - - oPos = pObj->RetPosition(0); - dist = Length(oPos, m_fretPos); - - if ( dist < 8.0f ) return pObj; - } - - return 0; -} - -// Search if a vehicle is too close. - -BOOL CAutoFactory::NearestVehicle() -{ - CObject* pObj; - D3DVECTOR cPos, oPos; - ObjectType type; - float oRadius, dist; - int i; - - cPos = m_object->RetPosition(0); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type != OBJECT_HUMAN && - type != OBJECT_MOBILEfa && - type != OBJECT_MOBILEta && - type != OBJECT_MOBILEwa && - type != OBJECT_MOBILEia && - type != OBJECT_MOBILEfc && - type != OBJECT_MOBILEtc && - type != OBJECT_MOBILEwc && - type != OBJECT_MOBILEic && - type != OBJECT_MOBILEfi && - type != OBJECT_MOBILEti && - type != OBJECT_MOBILEwi && - type != OBJECT_MOBILEii && - type != OBJECT_MOBILEfs && - type != OBJECT_MOBILEts && - type != OBJECT_MOBILEws && - type != OBJECT_MOBILEis && - type != OBJECT_MOBILErt && - type != OBJECT_MOBILErc && - type != OBJECT_MOBILErr && - type != OBJECT_MOBILErs && - type != OBJECT_MOBILEsa && - type != OBJECT_MOBILEtg && - type != OBJECT_MOBILEft && - type != OBJECT_MOBILEtt && - type != OBJECT_MOBILEwt && - type != OBJECT_MOBILEit && - type != OBJECT_MOBILEdr && - type != OBJECT_MOTHER && - type != OBJECT_ANT && - type != OBJECT_SPIDER && - type != OBJECT_BEE && - type != OBJECT_WORM ) continue; - - if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; - dist = Length(oPos, cPos)-oRadius; - - if ( dist < 10.0f ) return TRUE; - } - - return FALSE; -} - - -// Creates a vehicle. - -BOOL CAutoFactory::CreateVehicle() -{ - CObject* vehicle; - D3DMATRIX* mat; - CPhysics* physics; - D3DVECTOR pos; - float angle; - char* name; - int i; - - angle = m_object->RetAngleY(0); - - mat = m_object->RetWorldMatrix(0); - if ( m_type == OBJECT_MOBILErt || - m_type == OBJECT_MOBILErc || - m_type == OBJECT_MOBILErr || - m_type == OBJECT_MOBILErs ) - { - pos = D3DVECTOR(2.0f, 0.0f, 0.0f); - } - else - { - pos = D3DVECTOR(4.0f, 0.0f, 0.0f); - } - pos = Transform(*mat, pos); - - vehicle = new CObject(m_iMan); - if ( !vehicle->CreateVehicle(pos, angle, m_type, -1.0f, FALSE, FALSE) ) - { - delete vehicle; - m_displayText->DisplayError(ERR_TOOMANY, m_object); - return FALSE; - } - vehicle->UpdateMapping(); - vehicle->SetLock(TRUE); // not usable - vehicle->SetRange(30.0f); - - physics = vehicle->RetPhysics(); - if ( physics != 0 ) - { - physics->SetFreeze(TRUE); // it doesn't move - } - - for ( i=0 ; i<10 ; i++ ) - { - name = m_main->RetNewScriptName(m_type, i); - if ( name == 0 ) break; - vehicle->ReadProgram(i, name); - } - - return TRUE; -} - -// Seeking the vehicle during manufacture. - -CObject* CAutoFactory::SearchVehicle() -{ - CObject* pObj; - D3DVECTOR oPos; - ObjectType type; - float dist; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetLock() ) continue; - - type = pObj->RetType(); - if ( type != m_type ) continue; - if ( pObj->RetTruck() != 0 ) continue; - - oPos = pObj->RetPosition(0); - dist = Length(oPos, m_fretPos); - - if ( dist < 8.0f ) return pObj; - } - - return 0; -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoFactory::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, dim, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - dim.x = 33.0f/640.0f; - dim.y = 33.0f/480.0f; - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = 0.0f; - pos.y = oy+sy*2.6f; - ddim.x = 138.0f/640.0f; - ddim.y = 222.0f/480.0f; - pw->CreateGroup(pos, ddim, 6, EVENT_WINDOW3); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*8.2f; - pw->CreateButton(pos, dim, 128+9, EVENT_OBJECT_FACTORYwa); - pos.x += dim.x; - pw->CreateButton(pos, dim, 128+10, EVENT_OBJECT_FACTORYta); - pos.x += dim.x; - pw->CreateButton(pos, dim, 128+11, EVENT_OBJECT_FACTORYfa); - pos.x += dim.x; - pw->CreateButton(pos, dim, 128+22, EVENT_OBJECT_FACTORYia); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*7.1f; - pw->CreateButton(pos, dim, 128+12, EVENT_OBJECT_FACTORYws); - pos.x += dim.x; - pw->CreateButton(pos, dim, 128+13, EVENT_OBJECT_FACTORYts); - pos.x += dim.x; - pw->CreateButton(pos, dim, 128+14, EVENT_OBJECT_FACTORYfs); - pos.x += dim.x; - pw->CreateButton(pos, dim, 128+24, EVENT_OBJECT_FACTORYis); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*6.0f; - pw->CreateButton(pos, dim, 128+15, EVENT_OBJECT_FACTORYwc); - pos.x += dim.x; - pw->CreateButton(pos, dim, 128+16, EVENT_OBJECT_FACTORYtc); - pos.x += dim.x; - pw->CreateButton(pos, dim, 128+17, EVENT_OBJECT_FACTORYfc); - pos.x += dim.x; - pw->CreateButton(pos, dim, 128+23, EVENT_OBJECT_FACTORYic); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*4.9f; - pw->CreateButton(pos, dim, 128+25, EVENT_OBJECT_FACTORYwi); - pos.x += dim.x; - pw->CreateButton(pos, dim, 128+26, EVENT_OBJECT_FACTORYti); - pos.x += dim.x; - pw->CreateButton(pos, dim, 128+27, EVENT_OBJECT_FACTORYfi); - pos.x += dim.x; - pw->CreateButton(pos, dim, 128+28, EVENT_OBJECT_FACTORYii); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*3.8f; - pw->CreateButton(pos, dim, 128+18, EVENT_OBJECT_FACTORYrt); - pos.x += dim.x; - pw->CreateButton(pos, dim, 128+19, EVENT_OBJECT_FACTORYrc); - pos.x += dim.x; - pw->CreateButton(pos, dim, 128+20, EVENT_OBJECT_FACTORYrr); - pos.x += dim.x; - pw->CreateButton(pos, dim, 128+29, EVENT_OBJECT_FACTORYrs); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*2.7f; - pw->CreateButton(pos, dim, 128+21, EVENT_OBJECT_FACTORYsa); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 101, EVENT_OBJECT_TYPE); - - UpdateInterface(); - return TRUE; -} - -// Updates the status of all interface buttons. - -void CAutoFactory::UpdateInterface() -{ - CWindow* pw; - - if ( !m_object->RetSelect() ) return; - - CAuto::UpdateInterface(); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - - UpdateButton(pw, EVENT_OBJECT_FACTORYwa, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYta, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYfa, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYia, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYws, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYts, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYfs, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYis, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYwc, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYtc, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYfc, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYic, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYwi, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYti, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYfi, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYii, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYrt, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYrc, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYrr, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYrs, m_bBusy); - UpdateButton(pw, EVENT_OBJECT_FACTORYsa, m_bBusy); -} - -// Updates the status of one interface button. - -void CAutoFactory::UpdateButton(CWindow *pw, EventMsg event, BOOL bBusy) -{ - BOOL bEnable = TRUE; - - EnableInterface(pw, event, !bBusy); - - if ( event == EVENT_OBJECT_FACTORYta ) - { - bEnable = g_researchDone&RESEARCH_TANK; - } - if ( event == EVENT_OBJECT_FACTORYfa ) - { - bEnable = g_researchDone&RESEARCH_FLY; - } - if ( event == EVENT_OBJECT_FACTORYia ) - { - bEnable = g_researchDone&RESEARCH_iPAW; - } - - if ( event == EVENT_OBJECT_FACTORYws ) - { - bEnable = g_researchDone&RESEARCH_SNIFFER; - } - if ( event == EVENT_OBJECT_FACTORYts ) - { - bEnable = ( (g_researchDone&RESEARCH_SNIFFER) && - (g_researchDone&RESEARCH_TANK) ); - } - if ( event == EVENT_OBJECT_FACTORYfs ) - { - bEnable = ( (g_researchDone&RESEARCH_SNIFFER) && - (g_researchDone&RESEARCH_FLY) ); - } - if ( event == EVENT_OBJECT_FACTORYis ) - { - bEnable = ( (g_researchDone&RESEARCH_SNIFFER) && - (g_researchDone&RESEARCH_iPAW) ); - } - - if ( event == EVENT_OBJECT_FACTORYwc ) - { - bEnable = g_researchDone&RESEARCH_CANON; - } - if ( event == EVENT_OBJECT_FACTORYtc ) - { - bEnable = ( (g_researchDone&RESEARCH_CANON) && - (g_researchDone&RESEARCH_TANK) ); - } - if ( event == EVENT_OBJECT_FACTORYfc ) - { - bEnable = ( (g_researchDone&RESEARCH_CANON) && - (g_researchDone&RESEARCH_FLY) ); - } - if ( event == EVENT_OBJECT_FACTORYic ) - { - bEnable = ( (g_researchDone&RESEARCH_CANON) && - (g_researchDone&RESEARCH_iPAW) ); - } - - if ( event == EVENT_OBJECT_FACTORYwi ) - { - bEnable = g_researchDone&RESEARCH_iGUN; - } - if ( event == EVENT_OBJECT_FACTORYti ) - { - bEnable = ( (g_researchDone&RESEARCH_iGUN) && - (g_researchDone&RESEARCH_TANK) ); - } - if ( event == EVENT_OBJECT_FACTORYfi ) - { - bEnable = ( (g_researchDone&RESEARCH_iGUN) && - (g_researchDone&RESEARCH_FLY) ); - } - if ( event == EVENT_OBJECT_FACTORYii ) - { - bEnable = ( (g_researchDone&RESEARCH_iGUN) && - (g_researchDone&RESEARCH_iPAW) ); - } - - if ( event == EVENT_OBJECT_FACTORYrt ) - { - bEnable = ( (g_researchDone&RESEARCH_THUMP) && - (g_researchDone&RESEARCH_TANK) ); - } - if ( event == EVENT_OBJECT_FACTORYrc ) - { - bEnable = ( (g_researchDone&RESEARCH_PHAZER) && - (g_researchDone&RESEARCH_TANK) ); - } - if ( event == EVENT_OBJECT_FACTORYrr ) - { - bEnable = ( (g_researchDone&RESEARCH_RECYCLER) && - (g_researchDone&RESEARCH_TANK) ); - } - if ( event == EVENT_OBJECT_FACTORYrs ) - { - bEnable = ( (g_researchDone&RESEARCH_SHIELD) && - (g_researchDone&RESEARCH_TANK) ); - } - - if ( event == EVENT_OBJECT_FACTORYsa ) - { - bEnable = g_researchDone&RESEARCH_SUBM; - } - - DeadInterface(pw, event, bEnable); -} - -// Plays the sound of the manipulator arm. - -void CAutoFactory::SoundManip(float time, float amplitude, float frequency) -{ - int i; - - i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f*frequency, TRUE); - m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, 0.1f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP); -} - diff --git a/src/autofactory.h b/src/autofactory.h deleted file mode 100644 index bcfc43e..0000000 --- a/src/autofactory.h +++ /dev/null @@ -1,85 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autofactory.h - -#ifndef _AUTOFACTORY_H_ -#define _AUTOFACTORY_H_ - - -#include "auto.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoFactoryPhase -{ - AFP_WAIT = 1, // expected metal - AFP_CLOSE_S = 2, // closes doors (shift) - AFP_CLOSE_T = 3, // closes doors (turn) - AFP_BUILD = 4, // building the vehicle - AFP_OPEN_T = 5, // opens the doors (turn) - AFP_OPEN_S = 6, // opens the doors (shift) - AFP_ADVANCE = 7, // advance at the door -}; - - - -class CAutoFactory : public CAuto -{ -public: - CAutoFactory(CInstanceManager* iMan, CObject* object); - ~CAutoFactory(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - - BOOL CreateInterface(BOOL bSelect); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - void UpdateInterface(); - void UpdateButton(CWindow *pw, EventMsg event, BOOL bBusy); - - CObject* SearchFret(); - BOOL NearestVehicle(); - BOOL CreateVehicle(); - CObject* SearchVehicle(); - - void SoundManip(float time, float amplitude, float frequency); - -protected: - AutoFactoryPhase m_phase; - float m_progress; - float m_speed; - float m_lastParticule; - D3DVECTOR m_fretPos; - int m_channelSound; -}; - - -#endif //_AUTOFACTORY_H_ diff --git a/src/autoflag.cpp b/src/autoflag.cpp deleted file mode 100644 index 5cd4bf2..0000000 --- a/src/autoflag.cpp +++ /dev/null @@ -1,178 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "auto.h" -#include "autoflag.h" - - - -#define ADJUST_ANGLE FALSE // TRUE -> adjusts the angles of the members - - -#if ADJUST_ANGLE -static float g_flag1 = 6.00f; -static float g_flag2 = 0.10f; -static float g_flag3 = 2.00f; -#endif - - -// Object's constructor. - -CAutoFlag::CAutoFlag(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - Init(); -} - -// Object's destructor. - -CAutoFlag::~CAutoFlag() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoFlag::DeleteObject(BOOL bAll) -{ - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoFlag::Init() -{ - D3DVECTOR wind; - float angle; - - m_time = 0.0f; - m_param = 0; - m_progress = 0.0f; - - wind = m_terrain->RetWind(); - angle = RotateAngle(wind.x, -wind.z); - m_object->SetAngleY(0, angle); // directs the flag in the wind - - m_strong = Length(wind); -} - - -// Beginning of an action (1 = shakes). - -void CAutoFlag::Start(int param) -{ - if ( m_param == 0 ) - { - m_param = param; - m_progress = 0.0f; - } -} - - -// Management of an event. - -BOOL CAutoFlag::EventProcess(const Event &event) -{ - float angle; - int i; - - CAuto::EventProcess(event); - -#if ADJUST_ANGLE - if ( event.event == EVENT_KEYDOWN ) - { - if ( event.param == 'E' ) g_flag1 += 0.1f; - if ( event.param == 'D' ) g_flag1 -= 0.1f; - if ( event.param == 'R' ) g_flag2 += 0.1f; - if ( event.param == 'F' ) g_flag2 -= 0.1f; - if ( event.param == 'T' ) g_flag3 += 0.1f; - if ( event.param == 'G' ) g_flag3 -= 0.1f; - } -#endif - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - if ( m_param == 1 ) // shakes? - { - m_progress += event.rTime*(1.0f/2.0f); - if ( m_progress < 1.0f ) - { - angle = sinf(m_progress*PI*8.0f)*0.3f*(1.0f-m_progress); - m_object->SetAngleX(0, angle); - angle = sinf(m_progress*PI*4.0f)*0.3f*(1.0f-m_progress); - m_object->SetAngleZ(0, angle); - } - else - { - m_object->SetAngleX(0, 0.0f); - m_object->SetAngleZ(0, 0.0f); - m_param = 0; - m_progress = 0.0f; - } - } - - if ( m_strong == 0.0f ) return TRUE; // no wind? - - for ( i=0 ; i<4 ; i++ ) - { -#if ADJUST_ANGLE - angle = sinf(m_time*g_flag1+i*2.0f)*((i+g_flag3)*g_flag2); -#else - angle = sinf(m_time*6.0f+i*2.0f)*((i+2.0f)*0.1f); -#endif - m_object->SetAngleY(1+i, angle); - } - -#if ADJUST_ANGLE - char s[100]; - sprintf(s, "a=%.2f b=%.2f c=%.2f", g_flag1, g_flag2, g_flag3); - m_engine->SetInfoText(4, s); -#endif - return TRUE; -} - - -// Returns an error due the state of the automation - -Error CAutoFlag::RetError() -{ - return ERR_OK; -} - - diff --git a/src/autoflag.h b/src/autoflag.h deleted file mode 100644 index 4ef0fe4..0000000 --- a/src/autoflag.h +++ /dev/null @@ -1,58 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autoflag.h - -#ifndef _AUTOFLAG_H_ -#define _AUTOFLAG_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -class CAutoFlag : public CAuto -{ -public: - CAutoFlag(CInstanceManager* iMan, CObject* object); - ~CAutoFlag(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - void Start(int param); - BOOL EventProcess(const Event &event); - Error RetError(); - -protected: - -protected: - float m_strong; - int m_param; - float m_progress; -}; - - -#endif //_AUTOFLAG_H_ diff --git a/src/autohuston.cpp b/src/autohuston.cpp deleted file mode 100644 index ad66702..0000000 --- a/src/autohuston.cpp +++ /dev/null @@ -1,315 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "interface.h" -#include "button.h" -#include "window.h" -#include "auto.h" -#include "autohuston.h" - - - - -// Object's constructor. - -CAutoHuston::CAutoHuston(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - D3DVECTOR pos; - int i; - - CAuto::CAuto(iMan, object); - - for ( i=0 ; iRetPosition(0); - m_lens[0].type = PARTISELR; - m_lens[1].type = PARTISELR; - m_lens[2].type = PARTISELR; - m_lens[3].type = PARTISELR; - m_lens[0].pos = pos+D3DVECTOR(0.0f+13.0f, 34.0f, 30.0f ); - m_lens[1].pos = pos+D3DVECTOR(0.0f-13.0f, 34.0f, 30.0f ); - m_lens[2].pos = pos+D3DVECTOR(0.0f , 34.0f, 30.0f+13.0f); - m_lens[3].pos = pos+D3DVECTOR(0.0f , 34.0f, 30.0f-13.0f); - m_lens[0].dim = 4.0f; - m_lens[1].dim = 4.0f; - m_lens[2].dim = 4.0f; - m_lens[3].dim = 4.0f; - m_lens[0].total = 1.0f; - m_lens[1].total = 1.0f; - m_lens[2].total = 1.0f; - m_lens[3].total = 1.0f; - m_lens[0].off = 0.4f; - m_lens[1].off = 0.4f; - m_lens[2].off = 0.4f; - m_lens[3].off = 0.4f; - - // Part under the radar. - i = 4; - m_lens[i].type = PARTISELR; - m_lens[i].pos = pos+D3DVECTOR(-7.0f, 9.9f, 40.1f); - m_lens[i].dim = 1.8f; - m_lens[i].total = 0.4f; - m_lens[i].off = 0.2f; - i ++; - - m_lens[i].type = PARTISELY; - m_lens[i].pos = pos+D3DVECTOR(-7.0f, 7.2f, 34.8f); - m_lens[i].dim = 0.4f; - m_lens[i].total = 0.7f; - m_lens[i].off = 0.3f; - i ++; - m_lens[i].type = PARTISELY; - m_lens[i].pos = pos+D3DVECTOR(-7.0f, 6.5f, 34.3f); - m_lens[i].dim = 0.4f; - m_lens[i].total = 0.7f; - m_lens[i].off = 0.3f; - i ++; - m_lens[i].type = PARTISELR; - m_lens[i].pos = pos+D3DVECTOR(-7.0f, 6.5f, 33.4f); - m_lens[i].dim = 0.4f; - m_lens[i].total = 0.0f; - m_lens[i].off = 0.0f; - i ++; - m_lens[i].type = PARTISELR; - m_lens[i].pos = pos+D3DVECTOR(-7.0f, 6.5f, 33.0f); - m_lens[i].dim = 0.4f; - m_lens[i].total = 1.0f; - m_lens[i].off = 0.5f; - i ++; - - m_lens[i].type = PARTISELY; - m_lens[i].pos = pos+D3DVECTOR(-7.0f, 8.5f, 14.0f); - m_lens[i].dim = 1.2f; - m_lens[i].total = 0.8f; - m_lens[i].off = 0.2f; - i ++; - - m_lens[i].type = PARTISELR; - m_lens[i].pos = pos+D3DVECTOR(4.0f, 6.0f, 8.6f); - m_lens[i].dim = 1.0f; - m_lens[i].total = 0.9f; - m_lens[i].off = 0.7f; - i ++; - - // Part with three windows. - m_lens[i].type = PARTISELR; - m_lens[i].pos = pos+D3DVECTOR(-7.0f, 9.9f, -19.9f); - m_lens[i].dim = 1.0f; - m_lens[i].total = 0.6f; - m_lens[i].off = 0.3f; - i ++; - - m_lens[i].type = PARTISELY; - m_lens[i].pos = pos+D3DVECTOR(-7.0f, 7.2f, 34.8f-60.0f); - m_lens[i].dim = 0.4f; - m_lens[i].total = 0.7f; - m_lens[i].off = 0.3f; - i ++; - m_lens[i].type = PARTISELY; - m_lens[i].pos = pos+D3DVECTOR(-7.0f, 6.5f, 34.3f-60.0f); - m_lens[i].dim = 0.4f; - m_lens[i].total = 0.0f; - m_lens[i].off = 0.0f; - i ++; - m_lens[i].type = PARTISELR; - m_lens[i].pos = pos+D3DVECTOR(-7.0f, 6.5f, 33.4f-60.0f); - m_lens[i].dim = 0.4f; - m_lens[i].total = 0.6f; - m_lens[i].off = 0.4f; - i ++; - m_lens[i].type = PARTISELR; - m_lens[i].pos = pos+D3DVECTOR(-7.0f, 6.5f, 33.0f-60.0f); - m_lens[i].dim = 0.4f; - m_lens[i].total = 0.8f; - m_lens[i].off = 0.2f; - i ++; - - m_lens[i].type = PARTISELY; - m_lens[i].pos = pos+D3DVECTOR(-6.5f, 13.5f, -37.0f); - m_lens[i].dim = 1.0f; - m_lens[i].total = 0.0f; - m_lens[i].off = 0.0f; - i ++; - - m_lens[i].type = PARTISELY; - m_lens[i].pos = pos+D3DVECTOR(-7.0f, 12.2f, -39.8f); - m_lens[i].dim = 1.8f; - m_lens[i].total = 1.5f; - m_lens[i].off = 0.5f; - i ++; - - m_lens[i].type = PARTISELY; - m_lens[i].pos = pos+D3DVECTOR(-7.0f, 8.5f, -47.0f); - m_lens[i].dim = 0.6f; - m_lens[i].total = 0.7f; - m_lens[i].off = 0.5f; - i ++; - - m_lensTotal = i; - - Init(); -} - -// Object's destructor. - -CAutoHuston::~CAutoHuston() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoHuston::DeleteObject(BOOL bAll) -{ - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoHuston::Init() -{ - m_time = 0.0f; - - m_progress = 0.0f; - m_speed = 1.0f/2.0f; -} - - -// Start the object. - -void CAutoHuston::Start(int param) -{ -} - - -// Management of an event. - -BOOL CAutoHuston::EventProcess(const Event &event) -{ - D3DVECTOR speed; - FPOINT dim; - float angle; - int i; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - - angle = -m_time*1.0f; - m_object->SetAngleY(1, angle); // rotates the radar - angle = sinf(m_time*4.0f)*0.3f; - m_object->SetAngleX(2, angle); - - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_speed; - - // Flashes the keys. - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - for ( i=0 ; iDeleteParticule(m_lens[i].parti); - m_lens[i].parti = -1; - } - } - else - { - if ( m_lens[i].parti == -1 ) - { - dim.x = m_lens[i].dim; - dim.y = dim.x; - m_lens[i].parti = m_particule->CreateParticule(m_lens[i].pos, speed, dim, m_lens[i].type, 1.0f, 0.0f, 0.0f); - } - } - } - - return TRUE; -} - -// Stops the controller. - -BOOL CAutoHuston::Abort() -{ - return TRUE; -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoHuston::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 115, EVENT_OBJECT_TYPE); - - return TRUE; -} - - -// Returns an error due to state of the automation. - -Error CAutoHuston::RetError() -{ - return ERR_OK; -} - diff --git a/src/autohuston.h b/src/autohuston.h deleted file mode 100644 index 0611eb2..0000000 --- a/src/autohuston.h +++ /dev/null @@ -1,77 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autohuston.h - -#ifndef _AUTOHUSTON_H_ -#define _AUTOHUSTON_H_ - - -#include "auto.h" -#include "particule.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -typedef struct -{ - int parti; - ParticuleType type; - D3DVECTOR pos; - float dim; - float total; - float off; -} -HustonLens; - - -#define HUSTONMAXLENS 20 - - -class CAutoHuston : public CAuto -{ -public: - CAutoHuston(CInstanceManager* iMan, CObject* object); - ~CAutoHuston(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - void Start(int param); - BOOL EventProcess(const Event &event); - BOOL Abort(); - Error RetError(); - - BOOL CreateInterface(BOOL bSelect); - -protected: - -protected: - float m_progress; - float m_speed; - HustonLens m_lens[HUSTONMAXLENS]; - int m_lensTotal; -}; - - -#endif //_AUTOHUSTON_H_ diff --git a/src/autoinfo.cpp b/src/autoinfo.cpp deleted file mode 100644 index e9708e0..0000000 --- a/src/autoinfo.cpp +++ /dev/null @@ -1,537 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "light.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "interface.h" -#include "button.h" -#include "list.h" -#include "window.h" -#include "sound.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autoinfo.h" - - - - -// Object's constructor. - -CAutoInfo::CAutoInfo(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - Init(); -} - -// Object's destructor. - -CAutoInfo::~CAutoInfo() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoInfo::DeleteObject(BOOL bAll) -{ - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoInfo::Init() -{ - m_phase = AIP_WAIT; - m_time = 0.0f; - m_timeVirus = 0.0f; - m_bLastVirus = FALSE; - - CAuto::Init(); -} - - -// Start a emission. - -void CAutoInfo::Start(int param) -{ - D3DVECTOR pos, speed; - FPOINT dim; - - if ( param == 0 ) // instruction "receive" ? - { - m_phase = AIP_EMETTE; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - else if ( param == 2 ) // instruction "send" ? - { - m_phase = AIP_RECEIVE; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - else - { - m_phase = AIP_ERROR; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - - m_lastParticule = 0; - m_goal = m_object->RetPosition(0); - - if ( m_phase == AIP_EMETTE ) - { - pos = m_goal; - pos.y += 9.5f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 30.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISPHERE4, 1.5f, 0.0f, 0.0f); - - m_sound->Play(SOUND_LABO, pos, 1.0f, 2.0f); - } - if ( m_phase == AIP_RECEIVE ) - { - pos = m_goal; - pos.y += 9.5f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 50.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISPHERE6, 1.5f, 0.0f, 0.0f); - - m_sound->Play(SOUND_LABO, pos, 1.0f, 2.0f); - } - if ( m_phase == AIP_ERROR ) - { - m_sound->Play(SOUND_GGG, pos, 1.0f, 0.5f); - } -} - - -// Management of an event. - -BOOL CAutoInfo::EventProcess(const Event &event) -{ - D3DVECTOR pos, speed; - FPOINT dim; - float duration, angle, rTime; - int i; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_timeVirus -= event.rTime; - - if ( m_object->RetVirusMode() ) // contaminated by a virus? - { - if ( m_timeVirus <= 0.0f ) - { - m_timeVirus = 0.1f+Rand()*0.3f; - - angle = m_object->RetAngleY(1); - angle += Rand()*0.3f; - m_object->SetAngleY(1, angle); - - m_object->SetAngleX(2, (Rand()-0.5f)*0.3f); - m_object->SetAngleX(4, (Rand()-0.5f)*0.3f); - m_object->SetAngleX(6, (Rand()-0.5f)*0.3f); - - m_object->SetAngleZ(2, (Rand()-0.5f)*0.3f); - m_object->SetAngleZ(4, (Rand()-0.5f)*0.3f); - m_object->SetAngleZ(6, (Rand()-0.5f)*0.3f); - - UpdateListVirus(); - } - m_bLastVirus = TRUE; - return TRUE; - } - else - { - if ( m_bLastVirus ) - { - m_bLastVirus = FALSE; - UpdateList(); // normally returns the list - } - else - { - if ( m_object->RetInfoUpdate() ) - { - UpdateList(); // updates the list - } - } - } - - UpdateInterface(event.rTime); - - rTime = event.rTime; - - if ( m_phase == AIP_EMETTE ) // instruction "receive" ? - { - if ( m_progress < 0.5f && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - for ( i=0 ; i<4 ; i++ ) - { - pos = m_goal; - pos.y += 9.5f; - speed.x = (Rand()-0.5f)*50.0f; - speed.z = (Rand()-0.5f)*50.0f; - speed.y = (Rand()-0.5f)*50.0f; - speed *= 0.5f+m_progress*0.5f; - dim.x = 0.6f; - dim.y = dim.x; - duration = Rand()*0.5f+0.5f; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK6, - duration, 0.0f, - duration*0.9f, 0.7f); - } - } - - if ( m_progress < 1.0f ) - { - m_progress += rTime*m_speed; - - m_object->SetAngleZ(2, m_progress*2.0f*PI); - m_object->SetAngleZ(4, m_progress*2.0f*PI); - m_object->SetAngleZ(6, m_progress*2.0f*PI); - } - else - { - m_phase = AIP_WAIT; - - m_object->SetAngleX(2, 0.0f); - m_object->SetAngleX(4, 0.0f); - m_object->SetAngleX(6, 0.0f); - - m_object->SetAngleZ(2, 0.0f); - m_object->SetAngleZ(4, 0.0f); - m_object->SetAngleZ(6, 0.0f); - } - } - - if ( m_phase == AIP_RECEIVE ) // instruction "send" ? - { - if ( m_progress < 0.5f && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - for ( i=0 ; i<4 ; i++ ) - { - pos = m_goal; - pos.y += 9.5f; - speed = pos; - pos.x += (Rand()-0.5f)*40.0f; - pos.y += (Rand()-0.5f)*40.0f; - pos.z += (Rand()-0.5f)*40.0f; - speed = (speed-pos)*1.0f; -//? speed *= 0.5f+m_progress*0.5f; - dim.x = 0.6f; - dim.y = dim.x; - duration = Rand()*0.5f+0.5f; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK6, - duration, 0.0f, - duration*0.9f, 0.7f); - } - } - - if ( m_progress < 1.0f ) - { - m_progress += rTime*m_speed; - - m_object->SetAngleZ(2, m_progress*2.0f*PI); - m_object->SetAngleZ(4, m_progress*2.0f*PI); - m_object->SetAngleZ(6, m_progress*2.0f*PI); - } - else - { - m_phase = AIP_WAIT; - - m_object->SetAngleX(2, 0.0f); - m_object->SetAngleX(4, 0.0f); - m_object->SetAngleX(6, 0.0f); - - m_object->SetAngleZ(2, 0.0f); - m_object->SetAngleZ(4, 0.0f); - m_object->SetAngleZ(6, 0.0f); - } - } - - if ( m_phase == AIP_ERROR ) - { - if ( m_progress < 0.5f && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_goal; - speed.x = (Rand()-0.5f)*5.0f; - speed.z = (Rand()-0.5f)*5.0f; - speed.y = 5.0f+Rand()*5.0f; - dim.x = 5.0f+Rand()*5.0f; - dim.y = dim.x; - duration = Rand()*0.5f+0.5f; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 4.0f); - } - - if ( m_progress < 1.0f ) - { - m_progress += rTime*m_speed; - rTime = 0.0f; // stops the rotation - - if ( m_progress < 0.5f ) - { - angle = m_progress/0.5f; - } - else - { - angle = 1.0f-(m_progress-0.5f)/0.5f; - } - m_object->SetAngleX(2, angle*0.5f); - m_object->SetAngleX(4, angle*0.5f); - m_object->SetAngleX(6, angle*0.5f); - - m_object->SetAngleZ(2, (Rand()-0.5f)*0.2f); - m_object->SetAngleZ(4, (Rand()-0.5f)*0.2f); - m_object->SetAngleZ(6, (Rand()-0.5f)*0.2f); - } - else - { - m_phase = AIP_WAIT; - - m_object->SetAngleX(2, 0.0f); - m_object->SetAngleX(4, 0.0f); - m_object->SetAngleX(6, 0.0f); - - m_object->SetAngleZ(2, 0.0f); - m_object->SetAngleZ(4, 0.0f); - m_object->SetAngleZ(6, 0.0f); - } - } - - angle = m_object->RetAngleY(1); - angle += rTime*0.5f; - m_object->SetAngleY(1, angle); - - m_object->SetAngleX(3, sinf(m_time*6.0f+PI*0.0f/3.0f)*0.3f); - m_object->SetAngleX(5, sinf(m_time*6.0f+PI*2.0f/3.0f)*0.3f); - m_object->SetAngleX(7, sinf(m_time*6.0f+PI*4.0f/3.0f)*0.3f); - - return TRUE; -} - - -// Returns an error due the state of the automation. - -Error CAutoInfo::RetError() -{ - if ( m_object->RetVirusMode() ) - { - return ERR_BAT_VIRUS; - } - - return ERR_OK; -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoInfo::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - CList* pl; - FPOINT pos, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*7.0f; - pos.y = oy+sy*0.0f; - ddim.x = 160.0f/640.0f; - ddim.y = 66.0f/480.0f; - pl = pw->CreateList(pos, ddim, 1, EVENT_OBJECT_GINFO, 1.10f); - pl->SetSelectCap(FALSE); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 112, EVENT_OBJECT_TYPE); - - UpdateList(); - return TRUE; -} - -// Updates the state of all buttons on the interface, -// following the time that elapses ... - -void CAutoInfo::UpdateInterface(float rTime) -{ - CAuto::UpdateInterface(rTime); -} - - -// Updates the contents of the list. - -void CAutoInfo::UpdateList() -{ - CWindow* pw; - CList* pl; - Info info; - int total, i; - char text[100]; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; - - pl = (CList*)pw->SearchControl(EVENT_OBJECT_GINFO); - if ( pl == 0 ) return; - - pl->Flush(); - total = m_object->RetInfoTotal(); - if ( total == 0 ) - { - pl->ClearState(STATE_ENABLE); - } - else - { - pl->SetState(STATE_ENABLE); - - for ( i=0 ; iRetInfo(i); - sprintf(text, "%s = %.2f", info.name, info.value); - pl->SetName(i, text); - } - } - - m_object->SetInfoUpdate(FALSE); -} - -// Updates the content of contaminating the list. - -void CAutoInfo::UpdateListVirus() -{ - CWindow* pw; - CList* pl; - int i, j, max; - char text[100]; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; - - pl = (CList*)pw->SearchControl(EVENT_OBJECT_GINFO); - if ( pl == 0 ) return; - - pl->SetState(STATE_ENABLE); - - pl->Flush(); - for ( i=0 ; i<4 ; i++ ) - { - max = (int)(2.0f+Rand()*10.0f); - for ( j=0 ; jSetName(i, text); - } -} - - -// Saves all parameters of the controller. - -BOOL CAutoInfo::Write(char *line) -{ - char name[100]; - - if ( m_phase == AIP_WAIT ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller. - -BOOL CAutoInfo::Read(char *line) -{ - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoInfoPhase)OpInt(line, "aPhase", AIP_WAIT); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - - m_lastParticule = 0.0f; - - return TRUE; -} - - diff --git a/src/autoinfo.h b/src/autoinfo.h deleted file mode 100644 index 28fc9ab..0000000 --- a/src/autoinfo.h +++ /dev/null @@ -1,80 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autoinfo.h - -#ifndef _AUTOINFO_H_ -#define _AUTOINFO_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoInfoPhase -{ - AIP_WAIT = 1, - AIP_EMETTE = 2, - AIP_RECEIVE = 3, - AIP_ERROR = 4, -}; - - - -class CAutoInfo : public CAuto -{ -public: - CAutoInfo(CInstanceManager* iMan, CObject* object); - ~CAutoInfo(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - void Start(int param); - BOOL EventProcess(const Event &event); - Error RetError(); - - BOOL CreateInterface(BOOL bSelect); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - void UpdateInterface(float rTime); - void UpdateList(); - void UpdateListVirus(); - -protected: - AutoInfoPhase m_phase; - float m_progress; - float m_speed; - float m_timeVirus; - float m_lastParticule; - D3DVECTOR m_goal; - BOOL m_bLastVirus; -}; - - -#endif //_AUTOINFO_H_ diff --git a/src/autojostle.cpp b/src/autojostle.cpp deleted file mode 100644 index 1bcd11e..0000000 --- a/src/autojostle.cpp +++ /dev/null @@ -1,167 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "light.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "interface.h" -#include "button.h" -#include "list.h" -#include "window.h" -#include "sound.h" -#include "auto.h" -#include "autojostle.h" - - - - -// Object's constructor. - -CAutoJostle::CAutoJostle(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - Init(); -} - -// Object's destructor. - -CAutoJostle::~CAutoJostle() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoJostle::DeleteObject(BOOL bAll) -{ - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoJostle::Init() -{ - m_time = 0.0f; - m_error = ERR_CONTINUE; - - CAuto::Init(); -} - - -// Start an emission. - -void CAutoJostle::Start(int param, float force) -{ - ObjectType type; - - if ( force < 0.0f ) force = 0.0f; - if ( force > 1.0f ) force = 1.0f; - - m_force = force; - m_progress = 0.0f; - m_speed = 1.0f/(0.5f+force*1.0f); // 0.5 .. 1.5 - m_time = 0.0f; - m_error = ERR_CONTINUE; - - type = m_object->RetType(); - if ( type >= OBJECT_PLANT5 && - type <= OBJECT_PLANT7 ) // clover? - { - m_force *= 3.0f; - } -} - - -// Management of an event. - -BOOL CAutoJostle::EventProcess(const Event &event) -{ - D3DVECTOR dir; - float factor, angle, zoom; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - if ( m_progress < 1.0f ) - { - m_progress += event.rTime*m_speed; - - if ( m_progress < 0.5f ) - { - factor = m_progress/0.5f; - } - else - { - factor = 2.0f-m_progress/0.5f; - } - factor *= m_force; - - dir.x = sinf(m_progress*PI*4.0f); - dir.z = cosf(m_progress*PI*4.0f); - - angle = sinf(m_time*10.0f)*factor*0.04f; - m_object->SetAngleX(0, angle*dir.z); - m_object->SetAngleZ(0, angle*dir.x); - - zoom = 1.0f+sinf(m_time*8.0f)*factor*0.06f; - m_object->SetZoomX(0, zoom); - zoom = 1.0f+sinf(m_time*5.0f)*factor*0.06f; - m_object->SetZoomY(0, zoom); - zoom = 1.0f+sinf(m_time*7.0f)*factor*0.06f; - m_object->SetZoomZ(0, zoom); - } - else - { - m_object->SetAngleX(0, 0.0f); - m_object->SetAngleZ(0, 0.0f); - m_object->SetZoom(0, D3DVECTOR(1.0f, 1.0f, 1.0f)); - m_error = ERR_STOP; - } - - return TRUE; -} - - -// Indicates whether the controller has completed its activity. - -Error CAutoJostle::IsEnded() -{ - return m_error; -} - - diff --git a/src/autojostle.h b/src/autojostle.h deleted file mode 100644 index 18027a0..0000000 --- a/src/autojostle.h +++ /dev/null @@ -1,60 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autojostle.h - -#ifndef _AUTOJOSTLE_H_ -#define _AUTOJOSTLE_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -class CAutoJostle : public CAuto -{ -public: - CAutoJostle(CInstanceManager* iMan, CObject* object); - ~CAutoJostle(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - void Start(int param, float force); - BOOL EventProcess(const Event &event); - Error IsEnded(); - -protected: - -protected: - float m_force; - float m_progress; - float m_speed; - float m_lastParticule; - Error m_error; -}; - - -#endif //_AUTOJOSTLE_H_ diff --git a/src/autokid.cpp b/src/autokid.cpp deleted file mode 100644 index 98c0f45..0000000 --- a/src/autokid.cpp +++ /dev/null @@ -1,222 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "terrain.h" -#include "water.h" -#include "camera.h" -#include "object.h" -#include "sound.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autokid.h" - - - - -// Object's constructor. - -CAutoKid::CAutoKid(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - m_soundChannel = -1; - Init(); -} - -// Object's constructor. - -CAutoKid::~CAutoKid() -{ - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } - - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoKid::DeleteObject(BOOL bAll) -{ - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoKid::Init() -{ - D3DVECTOR pos; - - m_speed = 1.0f/1.0f; - m_progress = 0.0f; - m_lastParticule = 0.0f; - - if ( m_type == OBJECT_TEEN36 ) // trunk ? - { - pos = m_object->RetPosition(0); - m_speed = 1.0f/(1.0f+(Mod(pos.x/10.0f-0.5f, 1.0f)*0.2f)); - m_progress = Mod(pos.x/10.0f, 1.0f); - } - - if ( m_type == OBJECT_TEEN37 ) // boat? - { - pos = m_object->RetPosition(0); - m_speed = 1.0f/(1.0f+(Mod(pos.x/10.0f-0.5f, 1.0f)*0.2f))*2.5f; - m_progress = Mod(pos.x/10.0f, 1.0f); - } - - if ( m_type == OBJECT_TEEN38 ) // fan? - { - if ( m_soundChannel == -1 ) - { -//? m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 1.0f, 0.5f, TRUE); - m_bSilent = FALSE; - } - } -} - - -// Management of an event. - -BOOL CAutoKid::EventProcess(const Event &event) -{ - D3DVECTOR vib, pos, speed; - FPOINT dim; - - CAuto::EventProcess(event); - - if ( m_soundChannel != -1 ) - { - if ( m_engine->RetPause() ) - { - if ( !m_bSilent ) - { - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.1f, SOPER_CONTINUE); - m_bSilent = TRUE; - } - } - else - { - if ( m_bSilent ) - { - m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 0.1f, SOPER_CONTINUE); - m_bSilent = FALSE; - } - } - } - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_speed; - - if ( m_type == OBJECT_TEEN36 ) // trunk? - { - vib.x = 0.0f; - vib.y = sinf(m_progress)*1.0f; - vib.z = 0.0f; - m_object->SetLinVibration(vib); - - vib.x = 0.0f; - vib.y = 0.0f; - vib.z = sinf(m_progress*0.5f)*0.05f; - m_object->SetCirVibration(vib); - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.15f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_object->RetPosition(0); - pos.y = m_water->RetLevel()+1.0f; - pos.x += (Rand()-0.5f)*50.0f; - pos.z += (Rand()-0.5f)*50.0f; - speed.y = 0.0f; - speed.x = 0.0f; - speed.z = 0.0f; - dim.x = 50.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFLIC, 3.0f, 0.0f, 0.0f); - } - } - - if ( m_type == OBJECT_TEEN37 ) // boat? - { - vib.x = 0.0f; - vib.y = sinf(m_progress)*1.0f; - vib.z = 0.0f; - m_object->SetLinVibration(vib); - - vib.x = 0.0f; - vib.y = 0.0f; - vib.z = sinf(m_progress*0.5f)*0.15f; - m_object->SetCirVibration(vib); - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.15f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_object->RetPosition(0); - pos.y = m_water->RetLevel()+1.0f; - pos.x += (Rand()-0.5f)*20.0f; - pos.z += (Rand()-0.5f)*20.0f; - speed.y = 0.0f; - speed.x = 0.0f; - speed.z = 0.0f; - dim.x = 20.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFLIC, 3.0f, 0.0f, 0.0f); - } - } - - if ( m_type == OBJECT_TEEN38 ) // fan? - { - m_object->SetAngleY(1, sinf(m_progress*0.6f)*0.4f); - m_object->SetAngleX(2, m_progress*5.0f); - } - - return TRUE; -} - - -// Returns an error due the state of the automation. - -Error CAutoKid::RetError() -{ - return ERR_OK; -} - - diff --git a/src/autokid.h b/src/autokid.h deleted file mode 100644 index dc5305b..0000000 --- a/src/autokid.h +++ /dev/null @@ -1,59 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autokid.h - -#ifndef _AUTOKID_H_ -#define _AUTOKID_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -class CAutoKid : public CAuto -{ -public: - CAutoKid(CInstanceManager* iMan, CObject* object); - ~CAutoKid(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - -protected: - -protected: - float m_speed; - float m_progress; - float m_lastParticule; - int m_soundChannel; - BOOL m_bSilent; -}; - - -#endif //_AUTOKID_H_ diff --git a/src/autolabo.cpp b/src/autolabo.cpp deleted file mode 100644 index ce6214c..0000000 --- a/src/autolabo.cpp +++ /dev/null @@ -1,629 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "global.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "light.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "interface.h" -#include "button.h" -#include "window.h" -#include "displaytext.h" -#include "sound.h" -#include "robotmain.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autolabo.h" - - - -#define LABO_DELAY 20.0f // duration of the analysis - - - - -// Object's constructor. - -CAutoLabo::CAutoLabo(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - int i; - - CAuto::CAuto(iMan, object); - - for ( i=0 ; i<3 ; i++ ) - { - m_partiRank[i] = -1; - } - m_partiSphere = -1; - - m_soundChannel = -1; - Init(); -} - -// Object's destructor. - -CAutoLabo::~CAutoLabo() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoLabo::DeleteObject(BOOL bAll) -{ - int i; - - for ( i=0 ; i<3 ; i++ ) - { - if ( m_partiRank[i] != -1 ) - { - m_particule->DeleteParticule(m_partiRank[i]); - m_partiRank[i] = -1; - } - } - - if ( m_partiSphere != -1 ) - { - m_particule->DeleteParticule(m_partiSphere); - m_partiSphere = -1; - } - - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } - - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoLabo::Init() -{ - m_time = 0.0f; - m_timeVirus = 0.0f; - m_lastParticule = 0.0f; - - m_phase = ALAP_WAIT; // waiting ... - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - - CAuto::Init(); -} - - -// Management of an event. - -BOOL CAutoLabo::EventProcess(const Event &event) -{ - CObject* power; - D3DVECTOR pos, goal, speed; - FPOINT dim, rot; - float angle; - int i; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - - if ( event.event == EVENT_UPDINTERFACE ) - { - if ( m_object->RetSelect() ) CreateInterface(TRUE); - } - - if ( m_object->RetSelect() && // center selected? - (event.event == EVENT_OBJECT_RiPAW || - event.event == EVENT_OBJECT_RiGUN) ) - { - if ( m_phase != ALAP_WAIT ) - { - return FALSE; - } - - m_research = event.event; - - if ( TestResearch(m_research) ) - { - m_displayText->DisplayError(ERR_LABO_ALREADY, m_object); - return FALSE; - } - - power = m_object->RetPower(); - if ( power == 0 ) - { - m_displayText->DisplayError(ERR_LABO_NULL, m_object); - return FALSE; - } - if ( power->RetType() != OBJECT_BULLET ) - { - m_displayText->DisplayError(ERR_LABO_BAD, m_object); - return FALSE; - } - - SetBusy(TRUE); - InitProgressTotal(1.0f+1.5f+1.5f+LABO_DELAY+1.5f+1.5f+1.0f); - UpdateInterface(); - - power->SetLock(TRUE); // ball longer usable - - SoundManip(1.0f, 1.0f, 1.0f); - m_phase = ALAP_OPEN1; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - return TRUE; - } - - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_speed; - m_timeVirus -= event.rTime; - - if ( m_object->RetVirusMode() ) // contaminated by a virus? - { - if ( m_timeVirus <= 0.0f ) - { - m_timeVirus = 0.1f+Rand()*0.3f; - } - return TRUE; - } - - EventProgress(event.rTime); - - if ( m_phase == ALAP_WAIT ) - { - if ( m_progress >= 1.0f ) - { - m_phase = ALAP_WAIT; // still waiting ... - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - if ( m_phase == ALAP_OPEN1 ) - { - if ( m_progress < 1.0f ) - { - angle = 80.0f-(35.0f*m_progress); - m_object->SetAngleZ(3, angle*PI/180.0f); - m_object->SetAngleZ(4, angle*PI/180.0f); - m_object->SetAngleZ(5, angle*PI/180.0f); - } - else - { - m_object->SetAngleZ(3, 45.0f*PI/180.0f); - m_object->SetAngleZ(4, 45.0f*PI/180.0f); - m_object->SetAngleZ(5, 45.0f*PI/180.0f); - - SoundManip(1.5f, 1.0f, 0.7f); - m_phase = ALAP_OPEN2; - m_progress = 0.0f; - m_speed = 1.0f/1.5f; - } - } - - if ( m_phase == ALAP_OPEN2 ) - { - if ( m_progress < 1.0f ) - { - pos.x = -9.0f; - pos.y = 3.0f+m_progress*10.0f; - pos.z = 0.0f; - m_object->SetPosition(1, pos); - } - else - { - m_object->SetPosition(1, D3DVECTOR(-9.0f, 13.0f, 0.0f)); - - SoundManip(1.5f, 1.0f, 0.5f); - m_phase = ALAP_OPEN3; - m_progress = 0.0f; - m_speed = 1.0f/1.5f; - } - } - - if ( m_phase == ALAP_OPEN3 ) - { - if ( m_progress < 1.0f ) - { - angle = (1.0f-m_progress)*PI/2.0f; - m_object->SetAngleZ(1, angle); - } - else - { - m_object->SetAngleZ(1, 0.0f); - - goal = m_object->RetPosition(0); - goal.y += 3.0f; - pos = goal; - pos.x -= 4.0f; - pos.y += 4.0f; - for ( i=0 ; i<3 ; i++ ) - { - m_partiRank[i] = m_particule->CreateRay(pos, goal, - PARTIRAY2, - FPOINT(2.9f, 2.9f), - LABO_DELAY); - } - - m_soundChannel = m_sound->Play(SOUND_LABO, m_object->RetPosition(0), 0.0f, 0.25f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.60f, 2.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 2.00f, 8.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.60f, 8.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.25f, 2.0f, SOPER_STOP); - - pos = m_object->RetPosition(0); - pos.y += 4.0f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 4.0f; - dim.y = dim.x; - m_partiSphere = m_particule->CreateParticule(pos, speed, dim, PARTISPHERE2, LABO_DELAY, 0.0f, 0.0f); - - m_phase = ALAP_ANALYSE; - m_progress = 0.0f; - m_speed = 1.0f/LABO_DELAY; - } - } - - if ( m_phase == ALAP_ANALYSE ) - { - if ( m_progress < 1.0f ) - { - power = m_object->RetPower(); - if ( power != 0 ) - { - power->SetZoom(0, 1.0f-m_progress); - } - - angle = m_object->RetAngleY(2); - if ( m_progress < 0.5f ) - { - angle -= event.rTime*m_progress*20.0f; - } - else - { - angle -= event.rTime*(20.0f-m_progress*20.0f); - } - m_object->SetAngleY(2, angle); // rotates the analyzer - - angle += m_object->RetAngleY(0); - for ( i=0 ; i<3 ; i++ ) - { - rot = RotatePoint(-angle, -4.0f); - pos = m_object->RetPosition(0); - pos.x += rot.x; - pos.z += rot.y; - pos.y += 3.0f+4.0f;; - m_particule->SetPosition(m_partiRank[i], pos); // adjusts ray - - angle += PI*2.0f/3.0f; - } - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - if ( m_progress > 0.25f && - m_progress < 0.80f ) - { - pos = m_object->RetPosition(0); - pos.y += 3.0f; - pos.x += (Rand()-0.5f)*2.0f; - pos.z += (Rand()-0.5f)*2.0f; - speed.y = Rand()*5.0f+5.0f; - speed.x = (Rand()-0.5f)*10.0f; - speed.z = (Rand()-0.5f)*10.0f; - dim.x = Rand()*0.4f*m_progress+1.0f; - dim.y = dim.x; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK2, - 2.0f+2.0f*m_progress, 10.0f, 1.5f, 1.4f); - } - } - } - else - { - SetResearch(m_research); // research done - - power = m_object->RetPower(); - if ( power != 0 ) - { - m_object->SetPower(0); - power->DeleteObject(); // destroys the ball - delete power; - } - - m_displayText->DisplayError(INFO_LABO, m_object); - - SoundManip(1.5f, 1.0f, 0.5f); - m_phase = ALAP_CLOSE1; - m_progress = 0.0f; - m_speed = 1.0f/1.5f; - } - } - - if ( m_phase == ALAP_CLOSE1 ) - { - if ( m_progress < 1.0f ) - { - angle = m_progress*PI/2.0f; - m_object->SetAngleZ(1, angle); - } - else - { - m_object->SetAngleZ(1, PI/2.0f); - - SoundManip(1.5f, 1.0f, 0.7f); - m_phase = ALAP_CLOSE2; - m_progress = 0.0f; - m_speed = 1.0f/1.5f; - } - } - - if ( m_phase == ALAP_CLOSE2 ) - { - if ( m_progress < 1.0f ) - { - pos.x = -9.0f; - pos.y = 3.0f+(1.0f-m_progress)*10.0f;; - pos.z = 0.0f; - m_object->SetPosition(1, pos); - } - else - { - m_object->SetPosition(1, D3DVECTOR(-9.0f, 3.0f, 0.0f)); - - SoundManip(1.0f, 1.0f, 1.0f); - m_phase = ALAP_CLOSE3; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - if ( m_phase == ALAP_CLOSE3 ) - { - if ( m_progress < 1.0f ) - { - angle = 45.0f+(35.0f*m_progress); - m_object->SetAngleZ(3, angle*PI/180.0f); - m_object->SetAngleZ(4, angle*PI/180.0f); - m_object->SetAngleZ(5, angle*PI/180.0f); - } - else - { - m_object->SetAngleZ(3, 80.0f*PI/180.0f); - m_object->SetAngleZ(4, 80.0f*PI/180.0f); - m_object->SetAngleZ(5, 80.0f*PI/180.0f); - - SetBusy(FALSE); - UpdateInterface(); - - m_phase = ALAP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - return TRUE; -} - - -// Returns an error due the state of the automation. - -Error CAutoLabo::RetError() -{ - CObject* pObj; - ObjectType type; - - if ( m_object->RetVirusMode() ) - { - return ERR_BAT_VIRUS; - } - - pObj = m_object->RetPower(); - if ( pObj == 0 ) return ERR_LABO_NULL; - type = pObj->RetType(); - if ( type != OBJECT_BULLET ) return ERR_LABO_BAD; - - return ERR_OK; -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoLabo::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, dim, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - dim.x = 33.0f/640.0f; - dim.y = 33.0f/480.0f; - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*7.0f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 64+45, EVENT_OBJECT_RiPAW); - - pos.x = ox+sx*8.0f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 64+46, EVENT_OBJECT_RiGUN); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 111, EVENT_OBJECT_TYPE); - - UpdateInterface(); - - return TRUE; -} - -// Updates the status of all interface buttons. - -void CAutoLabo::UpdateInterface() -{ - CWindow* pw; - - if ( !m_object->RetSelect() ) return; - - CAuto::UpdateInterface(); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; - - DeadInterface(pw, EVENT_OBJECT_RiPAW, g_researchEnable&RESEARCH_iPAW); - DeadInterface(pw, EVENT_OBJECT_RiGUN, g_researchEnable&RESEARCH_iGUN); - - OkayButton(pw, EVENT_OBJECT_RiPAW); - OkayButton(pw, EVENT_OBJECT_RiGUN); - - VisibleInterface(pw, EVENT_OBJECT_RiPAW, !m_bBusy); - VisibleInterface(pw, EVENT_OBJECT_RiGUN, !m_bBusy); -} - -// Indicates the research conducted for a button. - -void CAutoLabo::OkayButton(CWindow *pw, EventMsg event) -{ - CControl* control; - - control = pw->SearchControl(event); - if ( control == 0 ) return; - - control->SetState(STATE_OKAY, TestResearch(event)); -} - - -// Test whether a search has already been done. - -BOOL CAutoLabo::TestResearch(EventMsg event) -{ - if ( event == EVENT_OBJECT_RiPAW ) return (g_researchDone & RESEARCH_iPAW); - if ( event == EVENT_OBJECT_RiGUN ) return (g_researchDone & RESEARCH_iGUN); - - return FALSE; -} - -// Indicates a search as made. - -void CAutoLabo::SetResearch(EventMsg event) -{ - Event newEvent; - - if ( event == EVENT_OBJECT_RiPAW ) g_researchDone |= RESEARCH_iPAW; - if ( event == EVENT_OBJECT_RiGUN ) g_researchDone |= RESEARCH_iGUN; - - m_main->WriteFreeParam(); - - m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); - m_event->AddEvent(newEvent); - UpdateInterface(); -} - -// Plays the sound of the manipulator arm. - -void CAutoLabo::SoundManip(float time, float amplitude, float frequency) -{ - int i; - - i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f*frequency, TRUE); - m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, 0.1f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP); -} - - -// Saves all parameters of the controller. - -BOOL CAutoLabo::Write(char *line) -{ - D3DVECTOR pos; - char name[100]; - - if ( m_phase == ALAP_WAIT ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - sprintf(name, " aResearch=%d", m_research); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller. - -BOOL CAutoLabo::Read(char *line) -{ - D3DVECTOR pos; - - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoLaboPhase)OpInt(line, "aPhase", ALAP_WAIT); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - m_research = (EventMsg)OpInt(line, "aResearch", 0); - - m_lastParticule = 0.0f; - - return TRUE; -} - - diff --git a/src/autolabo.h b/src/autolabo.h deleted file mode 100644 index 997bc55..0000000 --- a/src/autolabo.h +++ /dev/null @@ -1,87 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autolabo.h - -#ifndef _AUTOLABO_H_ -#define _AUTOLABO_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoLaboPhase -{ - ALAP_WAIT = 1, - ALAP_OPEN1 = 2, - ALAP_OPEN2 = 3, - ALAP_OPEN3 = 4, - ALAP_ANALYSE = 5, - ALAP_CLOSE1 = 6, - ALAP_CLOSE2 = 7, - ALAP_CLOSE3 = 8, -}; - - - -class CAutoLabo : public CAuto -{ -public: - CAutoLabo(CInstanceManager* iMan, CObject* object); - ~CAutoLabo(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - - BOOL CreateInterface(BOOL bSelect); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - void UpdateInterface(); - void OkayButton(CWindow *pw, EventMsg event); - BOOL TestResearch(EventMsg event); - void SetResearch(EventMsg event); - void SoundManip(float time, float amplitude, float frequency); - -protected: - AutoLaboPhase m_phase; - float m_progress; - float m_speed; - float m_timeVirus; - float m_lastParticule; - EventMsg m_research; - int m_partiRank[3]; - int m_partiSphere; - int m_soundChannel; -}; - - -#endif //_AUTOLABO_H_ diff --git a/src/automush.cpp b/src/automush.cpp deleted file mode 100644 index d1107ed..0000000 --- a/src/automush.cpp +++ /dev/null @@ -1,362 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "cmdtoken.h" -#include "sound.h" -#include "auto.h" -#include "automush.h" - - - - -// Object's constructor. - -CAutoMush::CAutoMush(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - Init(); -} - -// Object's destructor. - -CAutoMush::~CAutoMush() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoMush::DeleteObject(BOOL bAll) -{ - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoMush::Init() -{ - m_phase = AMP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/4.0f; - - m_time = 0.0f; - m_lastParticule = 0.0f; -} - - -// Management of an event. - -BOOL CAutoMush::EventProcess(const Event &event) -{ - D3DVECTOR pos, speed, dir; - FPOINT dim; - float factor, zoom, size, angle; - int i, channel; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_speed; - - factor = 0.0f; - size = 1.0f; - - if ( m_phase == AMP_WAIT ) - { - if ( m_progress >= 1.0f ) - { - if ( !SearchTarget() ) - { - m_phase = AMP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/(2.0f+Rand()*2.0f); - } - else - { - m_phase = AMP_SNIF; - m_progress = 0.0f; - m_speed = 1.0f/1.5f; - } - } - } - - if ( m_phase == AMP_SNIF ) - { - if ( m_progress < 1.0f ) - { - factor = m_progress; - } - else - { - m_phase = AMP_ZOOM; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - if ( m_phase == AMP_ZOOM ) - { - if ( m_progress < 1.0f ) - { - factor = 1.0f; - size = 1.0f+m_progress*0.3f; - } - else - { - m_sound->Play(SOUND_MUSHROOM, m_object->RetPosition(0)); - - m_phase = AMP_FIRE; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - if ( m_phase == AMP_FIRE ) - { - if ( m_progress < 1.0f ) - { - factor = 1.0f-m_progress; - size = 1.0f+(1.0f-m_progress)*0.3f; - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - for ( i=0 ; i<10 ; i++ ) - { - pos = m_object->RetPosition(0); - pos.y += 5.0f; - speed.x = (Rand()-0.5f)*200.0f; - speed.z = (Rand()-0.5f)*200.0f; - speed.y = -(20.0f+Rand()*20.0f); - dim.x = 1.0f; - dim.y = dim.x; - channel = m_particule->CreateParticule(pos, speed, dim, PARTIGUN2, 2.0f, 100.0f, 0.0f); - m_particule->SetObjectFather(channel, m_object); - } - } - } - else - { - m_phase = AMP_SMOKE; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - if ( m_phase == AMP_SMOKE ) - { - if ( m_progress < 1.0f ) - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_object->RetPosition(0); - pos.y += 5.0f; - speed.x = (Rand()-0.5f)*4.0f; - speed.z = (Rand()-0.5f)*4.0f; - speed.y = -(0.5f+Rand()*0.5f); - dim.x = Rand()*2.5f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 0.0f); - } - } - else - { - m_phase = AMP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/(2.0f+Rand()*2.0f); - } - } - - if ( factor != 0.0f || size != 1.0f ) - { - dir.x = sinf(m_time*PI*4.0f); - dir.z = cosf(m_time*PI*4.0f); - - angle = sinf(m_time*10.0f)*factor*0.04f; - m_object->SetAngleX(0, angle*dir.z); - m_object->SetAngleZ(0, angle*dir.x); - - zoom = 1.0f+sinf(m_time*8.0f)*factor*0.06f; - m_object->SetZoomX(0, zoom*size); - zoom = 1.0f+sinf(m_time*5.0f)*factor*0.06f; - m_object->SetZoomY(0, zoom*size); - zoom = 1.0f+sinf(m_time*7.0f)*factor*0.06f; - m_object->SetZoomZ(0, zoom*size); - } - else - { - m_object->SetAngleX(0, 0.0f); - m_object->SetAngleZ(0, 0.0f); - m_object->SetZoom(0, D3DVECTOR(1.0f, 1.0f, 1.0f)); - } - - return TRUE; -} - - -// Seeking a nearby target. - -BOOL CAutoMush::SearchTarget() -{ - CObject* pObj; - D3DVECTOR iPos, oPos; - ObjectType type; - float dist; - int i; - - iPos = m_object->RetPosition(0); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj->RetLock() ) continue; - - type = pObj->RetType(); - if ( type != OBJECT_MOBILEfa && - type != OBJECT_MOBILEta && - type != OBJECT_MOBILEwa && - type != OBJECT_MOBILEia && - type != OBJECT_MOBILEfc && - type != OBJECT_MOBILEtc && - type != OBJECT_MOBILEwc && - type != OBJECT_MOBILEic && - type != OBJECT_MOBILEfi && - type != OBJECT_MOBILEti && - type != OBJECT_MOBILEwi && - type != OBJECT_MOBILEii && - type != OBJECT_MOBILEfs && - type != OBJECT_MOBILEts && - type != OBJECT_MOBILEws && - type != OBJECT_MOBILEis && - type != OBJECT_MOBILErt && - type != OBJECT_MOBILErc && - type != OBJECT_MOBILErr && - type != OBJECT_MOBILErs && - type != OBJECT_MOBILEsa && - type != OBJECT_MOBILEtg && - type != OBJECT_MOBILEft && - type != OBJECT_MOBILEtt && - type != OBJECT_MOBILEwt && - type != OBJECT_MOBILEit && - type != OBJECT_MOBILEdr && - type != OBJECT_DERRICK && - type != OBJECT_STATION && - type != OBJECT_FACTORY && - type != OBJECT_REPAIR && - type != OBJECT_DESTROYER&& - type != OBJECT_CONVERT && - type != OBJECT_TOWER && - type != OBJECT_RESEARCH && - type != OBJECT_RADAR && - type != OBJECT_INFO && - type != OBJECT_ENERGY && - type != OBJECT_LABO && - type != OBJECT_NUCLEAR && - type != OBJECT_PARA && - type != OBJECT_HUMAN ) continue; - - oPos = pObj->RetPosition(0); - dist = Length(oPos, iPos); - if ( dist < 50.0f ) return TRUE; - } - - return FALSE; -} - - -// Returns an error due the state of the automation. - -Error CAutoMush::RetError() -{ - return ERR_OK; -} - - -// Saves all parameters of the controller. - -BOOL CAutoMush::Write(char *line) -{ - D3DVECTOR pos; - char name[100]; - - if ( m_phase == AMP_WAIT ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller. - -BOOL CAutoMush::Read(char *line) -{ - D3DVECTOR pos; - - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoMushPhase)OpInt(line, "aPhase", AMP_WAIT); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - - m_lastParticule = 0.0f; - - return TRUE; -} - - diff --git a/src/automush.h b/src/automush.h deleted file mode 100644 index 81314ee..0000000 --- a/src/automush.h +++ /dev/null @@ -1,73 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// automush.h - -#ifndef _AUTOMUSH_H_ -#define _AUTOMUSH_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoMushPhase -{ - AMP_WAIT = 1, - AMP_SNIF = 2, - AMP_ZOOM = 3, - AMP_FIRE = 4, - AMP_SMOKE = 5, -}; - - - -class CAutoMush : public CAuto -{ -public: - CAutoMush(CInstanceManager* iMan, CObject* object); - ~CAutoMush(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - BOOL SearchTarget(); - -protected: - AutoMushPhase m_phase; - float m_progress; - float m_speed; - float m_lastParticule; -}; - - -#endif //_AUTOMUSH_H_ diff --git a/src/autonest.cpp b/src/autonest.cpp deleted file mode 100644 index a86e7b8..0000000 --- a/src/autonest.cpp +++ /dev/null @@ -1,291 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autonest.h" - - - - -// Object's constructor. - -CAutoNest::CAutoNest(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - Init(); -} - -// Object's destructor. - -CAutoNest::~CAutoNest() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoNest::DeleteObject(BOOL bAll) -{ - CObject* fret; - - if ( !bAll ) - { - fret = SearchFret(); - if ( fret != 0 ) - { - fret->DeleteObject(); - delete fret; - } - } - - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoNest::Init() -{ - D3DVECTOR pos; - - m_phase = ANP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/4.0f; - - m_time = 0.0f; - m_lastParticule = 0.0f; - - pos = m_object->RetPosition(0); - m_terrain->MoveOnFloor(pos); - m_fretPos = pos; -} - - -// Management of an event. - -BOOL CAutoNest::EventProcess(const Event &event) -{ - CObject* fret; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_speed; - - if ( m_phase == ANP_WAIT ) - { - if ( m_progress >= 1.0f ) - { - if ( !SearchFree(m_fretPos) ) - { - m_phase = ANP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/4.0f; - } - else - { - CreateFret(m_fretPos, 0.0f, OBJECT_BULLET); - m_phase = ANP_BIRTH; - m_progress = 0.0f; - m_speed = 1.0f/5.0f; - } - } - } - - if ( m_phase == ANP_BIRTH ) - { - fret = SearchFret(); - - if ( m_progress < 1.0f ) - { - if ( fret != 0 ) - { - fret->SetZoom(0, m_progress); - } - } - else - { - if ( fret != 0 ) - { - fret->SetZoom(0, 1.0f); - fret->SetLock(FALSE); - } - - m_phase = ANP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/5.0f; - } - } - - return TRUE; -} - - -// Seeks if a site is free. - -BOOL CAutoNest::SearchFree(D3DVECTOR pos) -{ - CObject* pObj; - D3DVECTOR sPos; - ObjectType type; - float sRadius, distance; - int i, j; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type == OBJECT_NEST ) continue; - - j = 0; - while ( pObj->GetCrashSphere(j++, sPos, sRadius) ) - { - distance = Length(sPos, pos); - distance -= sRadius; - if ( distance < 2.0f ) return FALSE; // location occupied - } - } - - return TRUE; // free location -} - -// Create a transportable object. - -void CAutoNest::CreateFret(D3DVECTOR pos, float angle, ObjectType type) -{ - CObject* fret; - - fret = new CObject(m_iMan); - if ( !fret->CreateResource(pos, angle, type) ) - { - delete fret; - return; - } - fret->SetLock(TRUE); // not usable - fret->SetZoom(0, 0.0f); -} - -// Looking for the ball during manufacture. - -CObject* CAutoNest::SearchFret() -{ - CObject* pObj; - D3DVECTOR oPos; - ObjectType type; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetLock() ) continue; - - type = pObj->RetType(); - if ( type != OBJECT_BULLET ) continue; - - oPos = pObj->RetPosition(0); - if ( oPos.x == m_fretPos.x && - oPos.z == m_fretPos.z ) - { - return pObj; - } - } - - return 0; -} - - -// Returns an error due the state of the automation. - -Error CAutoNest::RetError() -{ - return ERR_OK; -} - - -// Saves all parameters of the controller. - -BOOL CAutoNest::Write(char *line) -{ - D3DVECTOR pos; - char name[100]; - - if ( m_phase == ANP_WAIT ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller. - -BOOL CAutoNest::Read(char *line) -{ - D3DVECTOR pos; - - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoNestPhase)OpInt(line, "aPhase", ANP_WAIT); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - - m_lastParticule = 0.0f; - - return TRUE; -} - - diff --git a/src/autonest.h b/src/autonest.h deleted file mode 100644 index 0c6febc..0000000 --- a/src/autonest.h +++ /dev/null @@ -1,73 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autonest.h - -#ifndef _AUTONEST_H_ -#define _AUTONEST_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoNestPhase -{ - ANP_WAIT = 1, - ANP_BIRTH = 2, // appearance of a ball -}; - - - -class CAutoNest : public CAuto -{ -public: - CAutoNest(CInstanceManager* iMan, CObject* object); - ~CAutoNest(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - BOOL SearchFree(D3DVECTOR pos); - void CreateFret(D3DVECTOR pos, float angle, ObjectType type); - CObject* SearchFret(); - -protected: - AutoNestPhase m_phase; - float m_progress; - float m_speed; - float m_lastParticule; - D3DVECTOR m_fretPos; -}; - - -#endif //_AUTONEST_H_ diff --git a/src/autonuclear.cpp b/src/autonuclear.cpp deleted file mode 100644 index 824bfca..0000000 --- a/src/autonuclear.cpp +++ /dev/null @@ -1,504 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "global.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "light.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "interface.h" -#include "button.h" -#include "window.h" -#include "sound.h" -#include "displaytext.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autonuclear.h" - - - -#define NUCLEAR_DELAY 30.0f // duration of the generation - - - - -// Object's constructor. - -CAutoNuclear::CAutoNuclear(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - m_channelSound = -1; - Init(); -} - -// Object's destructor. - -CAutoNuclear::~CAutoNuclear() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoNuclear::DeleteObject(BOOL bAll) -{ - CObject* fret; - - if ( !bAll ) - { - fret = SearchUranium(); - if ( fret != 0 ) - { - fret->DeleteObject(); // destroys the metal - delete fret; - } - } - - if ( m_channelSound != -1 ) - { - m_sound->FlushEnvelope(m_channelSound); - m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_channelSound = -1; - } - - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoNuclear::Init() -{ - D3DMATRIX* mat; - - m_time = 0.0f; - m_timeVirus = 0.0f; - m_lastParticule = 0.0f; - - mat = m_object->RetWorldMatrix(0); - m_pos = Transform(*mat, D3DVECTOR(22.0f, 4.0f, 0.0f)); - - m_phase = ANUP_WAIT; // waiting ... - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - - CAuto::Init(); -} - - -// Management of an event. - -BOOL CAutoNuclear::EventProcess(const Event &event) -{ - CObject* fret; - D3DMATRIX* mat; - D3DVECTOR pos, goal, speed; - FPOINT dim, rot; - float angle; - int i, max; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_speed; - m_timeVirus -= event.rTime; - - if ( m_object->RetVirusMode() ) // contaminated by a virus? - { - if ( m_timeVirus <= 0.0f ) - { - m_timeVirus = 0.1f+Rand()*0.3f; - } - return TRUE; - } - - EventProgress(event.rTime); - - if ( m_phase == ANUP_WAIT ) - { - if ( m_progress >= 1.0f ) - { - fret = SearchUranium(); // transform uranium? - if ( fret == 0 || SearchVehicle() ) - { - m_phase = ANUP_WAIT; // still waiting ... - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - else - { - fret->SetLock(TRUE); // usable uranium - - SetBusy(TRUE); - InitProgressTotal(1.5f+NUCLEAR_DELAY+1.5f); - UpdateInterface(); - - m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.4f); - - m_phase = ANUP_CLOSE; - m_progress = 0.0f; - m_speed = 1.0f/1.5f; - } - } - } - - if ( m_phase == ANUP_CLOSE ) - { - if ( m_progress < 1.0f ) - { - angle = (1.0f-m_progress)*(135.0f*PI/180.0f); - m_object->SetAngleZ(1, angle); - } - else - { - m_object->SetAngleZ(1, 0.0f); - - mat = m_object->RetWorldMatrix(0); - max = (int)(10.0f*m_engine->RetParticuleDensity()); - for ( i=0 ; iCreateParticule(pos, speed, dim, PARTICRASH); - } - - m_sound->Play(SOUND_CLOSE, m_object->RetPosition(0), 1.0f, 1.0f); - - m_channelSound = m_sound->Play(SOUND_NUCLEAR, m_object->RetPosition(0), 1.0f, 0.1f, TRUE); - m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, NUCLEAR_DELAY-1.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 2.0f, SOPER_STOP); - - m_phase = ANUP_GENERATE; - m_progress = 0.0f; - m_speed = 1.0f/NUCLEAR_DELAY; - } - } - - if ( m_phase == ANUP_GENERATE ) - { - if ( m_progress < 1.0f ) - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_object->RetPosition(0); - pos.y += 30.0f; - pos.x += (Rand()-0.5f)*6.0f; - pos.z += (Rand()-0.5f)*6.0f; - speed.y = Rand()*15.0f+15.0f; - speed.x = 0.0f; - speed.z = 0.0f; - dim.x = Rand()*8.0f+8.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH); - - pos = m_pos; - speed.x = (Rand()-0.5f)*20.0f; - speed.y = (Rand()-0.5f)*20.0f; - speed.z = (Rand()-0.5f)*20.0f; - dim.x = 2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 1.0f, 0.0f, 0.0f); - } - } - else - { - fret = SearchUranium(); - if ( fret != 0 ) - { - fret->DeleteObject(); // destroyed uranium - delete fret; - m_object->SetPower(0); - } - - CreatePower(); // creates the atomic cell - - max = (int)(20.0f*m_engine->RetParticuleDensity()); - for ( i=0 ; iCreateParticule(pos, speed, dim, PARTIBLUE, Rand()*5.0f+5.0f, 0.0f, 0.0f); - } - - m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.4f); - - m_phase = ANUP_OPEN; - m_progress = 0.0f; - m_speed = 1.0f/1.5f; - } - } - - if ( m_phase == ANUP_OPEN ) - { - if ( m_progress < 1.0f ) - { - angle = m_progress*(135.0f*PI/180.0f); - m_object->SetAngleZ(1, angle); - } - else - { - m_object->SetAngleZ(1, 135.0f*PI/180.0f); - - SetBusy(FALSE); - UpdateInterface(); - - m_displayText->DisplayError(INFO_NUCLEAR, m_object); - - m_phase = ANUP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - return TRUE; -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoNuclear::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 110, EVENT_OBJECT_TYPE); - - return TRUE; -} - - -// Seeking the uranium. - -CObject* CAutoNuclear::SearchUranium() -{ - CObject* pObj; - - pObj = m_object->RetPower(); - if ( pObj == 0 ) return 0; - if ( pObj->RetType() == OBJECT_URANIUM ) return pObj; - return 0; -} - -// Seeks if a vehicle is too close. - -BOOL CAutoNuclear::SearchVehicle() -{ - CObject* pObj; - D3DVECTOR oPos; - ObjectType type; - float oRadius, dist; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type != OBJECT_HUMAN && - type != OBJECT_MOBILEfa && - type != OBJECT_MOBILEta && - type != OBJECT_MOBILEwa && - type != OBJECT_MOBILEia && - type != OBJECT_MOBILEfc && - type != OBJECT_MOBILEtc && - type != OBJECT_MOBILEwc && - type != OBJECT_MOBILEic && - type != OBJECT_MOBILEfi && - type != OBJECT_MOBILEti && - type != OBJECT_MOBILEwi && - type != OBJECT_MOBILEii && - type != OBJECT_MOBILEfs && - type != OBJECT_MOBILEts && - type != OBJECT_MOBILEws && - type != OBJECT_MOBILEis && - type != OBJECT_MOBILErt && - type != OBJECT_MOBILErc && - type != OBJECT_MOBILErr && - type != OBJECT_MOBILErs && - type != OBJECT_MOBILEsa && - type != OBJECT_MOBILEtg && - type != OBJECT_MOBILEft && - type != OBJECT_MOBILEtt && - type != OBJECT_MOBILEwt && - type != OBJECT_MOBILEit && - type != OBJECT_MOBILEdr && - type != OBJECT_MOTHER && - type != OBJECT_ANT && - type != OBJECT_SPIDER && - type != OBJECT_BEE && - type != OBJECT_WORM ) continue; - - if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; - dist = Length(oPos, m_pos)-oRadius; - - if ( dist < 10.0f ) return TRUE; - } - - return FALSE; -} - -// Creates an object stack. - -void CAutoNuclear::CreatePower() -{ - CObject* power; - D3DVECTOR pos; - float angle; - - pos = m_object->RetPosition(0); - angle = m_object->RetAngleY(0); - - power = new CObject(m_iMan); - if ( !power->CreateResource(pos, angle, OBJECT_ATOMIC) ) - { - delete power; - m_displayText->DisplayError(ERR_TOOMANY, m_object); - return; - } - - power->SetTruck(m_object); - power->SetPosition(0, D3DVECTOR(22.0f, 3.0f, 0.0f)); - m_object->SetPower(power); -} - - -// Returns an error due the state of the automation. - -Error CAutoNuclear::RetError() -{ - CObject* pObj; - ObjectType type; -//? TerrainRes res; - - if ( m_object->RetVirusMode() ) - { - return ERR_BAT_VIRUS; - } - -//? res = m_terrain->RetResource(m_object->RetPosition(0)); -//? if ( res != TR_POWER ) return ERR_NUCLEAR_NULL; - -//? if ( m_object->RetEnergy() < ENERGY_POWER ) return ERR_NUCLEAR_LOW; - - pObj = m_object->RetPower(); - if ( pObj == 0 ) return ERR_NUCLEAR_EMPTY; - if ( pObj->RetLock() ) return ERR_OK; - type = pObj->RetType(); - if ( type == OBJECT_ATOMIC ) return ERR_OK; - if ( type != OBJECT_URANIUM ) return ERR_NUCLEAR_BAD; - - return ERR_OK; -} - - -// Saves all parameters of the controller. - -BOOL CAutoNuclear::Write(char *line) -{ - char name[100]; - - if ( m_phase == ANUP_STOP || - m_phase == ANUP_WAIT ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller. - -BOOL CAutoNuclear::Read(char *line) -{ - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoNuclearPhase)OpInt(line, "aPhase", ANUP_WAIT); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - - m_lastParticule = 0.0f; - - return TRUE; -} - - diff --git a/src/autonuclear.h b/src/autonuclear.h deleted file mode 100644 index e62282a..0000000 --- a/src/autonuclear.h +++ /dev/null @@ -1,80 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autonuclear.h - -#ifndef _AUTONUCLEAR_H_ -#define _AUTONUCLEAR_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoNuclearPhase -{ - ANUP_STOP = 1, - ANUP_WAIT = 2, - ANUP_CLOSE = 3, - ANUP_GENERATE = 4, - ANUP_OPEN = 5, -}; - - - -class CAutoNuclear : public CAuto -{ -public: - CAutoNuclear(CInstanceManager* iMan, CObject* object); - ~CAutoNuclear(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - - BOOL CreateInterface(BOOL bSelect); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - CObject* SearchUranium(); - BOOL SearchVehicle(); - void CreatePower(); - -protected: - AutoNuclearPhase m_phase; - float m_progress; - float m_speed; - float m_timeVirus; - float m_lastParticule; - D3DVECTOR m_pos; - int m_channelSound; -}; - - -#endif //_AUTONUCLEAR_H_ diff --git a/src/autopara.cpp b/src/autopara.cpp deleted file mode 100644 index cb42e6d..0000000 --- a/src/autopara.cpp +++ /dev/null @@ -1,347 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "global.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "light.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "interface.h" -#include "button.h" -#include "window.h" -#include "sound.h" -#include "displaytext.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autopara.h" - - - - -// Object's constructor. - -CAutoPara::CAutoPara(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - m_channelSound = -1; - Init(); -} - -// Object's destructor. - -CAutoPara::~CAutoPara() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoPara::DeleteObject(BOOL bAll) -{ - if ( m_channelSound != -1 ) - { - m_sound->FlushEnvelope(m_channelSound); - m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_channelSound = -1; - } - - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoPara::Init() -{ - D3DMATRIX* mat; - - m_time = 0.0f; - m_timeVirus = 0.0f; - m_lastParticule = 0.0f; - - mat = m_object->RetWorldMatrix(0); - m_pos = Transform(*mat, D3DVECTOR(22.0f, 4.0f, 0.0f)); - - m_phase = APAP_WAIT; // waiting ... - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - - CAuto::Init(); -} - - -// Reception of lightning. - -void CAutoPara::StartBlitz() -{ - m_phase = APAP_BLITZ; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; -} - - -// Management of an event. - -BOOL CAutoPara::EventProcess(const Event &event) -{ - D3DVECTOR pos, speed; - FPOINT dim; - int i; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_speed; - m_timeVirus -= event.rTime; - - if ( m_object->RetVirusMode() ) // contaminated by a virus? - { - if ( m_timeVirus <= 0.0f ) - { - m_timeVirus = 0.1f+Rand()*0.3f; - } - return TRUE; - } - - EventProgress(event.rTime); - - if ( m_phase == APAP_BLITZ ) - { - if ( m_progress < 1.0f ) - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - for ( i=0 ; i<10 ; i++ ) - { - pos = m_object->RetPosition(0); - pos.x += (Rand()-0.5f)*m_progress*40.0f; - pos.z += (Rand()-0.5f)*m_progress*40.0f; - pos.y += 50.0f-m_progress*50.0f; - speed.x = (Rand()-0.5f)*20.0f; - speed.z = (Rand()-0.5f)*20.0f; - speed.y = 5.0f+Rand()*5.0f; - dim.x = 2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 1.0f, 20.0f, 0.5f); - } - } - } - else - { - m_phase = APAP_CHARGE; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - if ( m_phase == APAP_CHARGE ) - { - if ( m_progress < 1.0f ) - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - for ( i=0 ; i<2 ; i++ ) - { - pos = m_object->RetPosition(0); - pos.y += 16.0f; - speed.x = (Rand()-0.5f)*10.0f; - speed.z = (Rand()-0.5f)*10.0f; - speed.y = -Rand()*30.0f; - dim.x = 1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 1.0f, 0.0f, 0.0f); - } - } - - ChargeObject(event.rTime); - } - else - { - m_phase = APAP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - return TRUE; -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoPara::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 113, EVENT_OBJECT_TYPE); - - pos.x = ox+sx*10.2f; - pos.y = oy+sy*0.5f; - ddim.x = 33.0f/640.0f; - ddim.y = 33.0f/480.0f; - pw->CreateButton(pos, ddim, 41, EVENT_OBJECT_LIMIT); - - return TRUE; -} - - -// Returns an error due the state of the automation. - -Error CAutoPara::RetError() -{ - if ( m_object->RetVirusMode() ) - { - return ERR_BAT_VIRUS; - } - return ERR_OK; -} - - -// Load all objects under the lightning rod. - -void CAutoPara::ChargeObject(float rTime) -{ - CObject* pObj; - CObject* power; - D3DVECTOR sPos, oPos; - float dist, energy; - int i; - - sPos = m_object->RetPosition(0); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - oPos = pObj->RetPosition(0); - dist = Length(oPos, sPos); - if ( dist > 20.0f ) continue; - - if ( pObj->RetTruck() == 0 && pObj->RetType() == OBJECT_POWER ) - { - energy = pObj->RetEnergy(); - energy += rTime/2.0f; - if ( energy > 1.0f ) energy = 1.0f; - pObj->SetEnergy(energy); - } - - power = pObj->RetPower(); - if ( power != 0 && power->RetType() == OBJECT_POWER ) - { - energy = power->RetEnergy(); - energy += rTime/2.0f; - if ( energy > 1.0f ) energy = 1.0f; - power->SetEnergy(energy); - } - - power = pObj->RetFret(); - if ( power != 0 && power->RetType() == OBJECT_POWER ) - { - energy = power->RetEnergy(); - energy += rTime/2.0f; - if ( energy > 1.0f ) energy = 1.0f; - power->SetEnergy(energy); - } - } -} - - -// Saves all parameters of the controller. - -BOOL CAutoPara::Write(char *line) -{ - char name[100]; - - if ( m_phase == APAP_WAIT ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller. - -BOOL CAutoPara::Read(char *line) -{ - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoParaPhase)OpInt(line, "aPhase", APAP_WAIT); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - - m_lastParticule = 0.0f; - - return TRUE; -} - - diff --git a/src/autopara.h b/src/autopara.h deleted file mode 100644 index 9a7c0c4..0000000 --- a/src/autopara.h +++ /dev/null @@ -1,77 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autopara.h - -#ifndef _AUTOPARA_H_ -#define _AUTOPARA_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoParaPhase -{ - APAP_WAIT = 1, - APAP_BLITZ = 2, - APAP_CHARGE = 3, -}; - - - -class CAutoPara : public CAuto -{ -public: - CAutoPara(CInstanceManager* iMan, CObject* object); - ~CAutoPara(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - void StartBlitz(); - - BOOL CreateInterface(BOOL bSelect); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - void ChargeObject(float rTime); - -protected: - AutoParaPhase m_phase; - float m_progress; - float m_speed; - float m_timeVirus; - float m_lastParticule; - D3DVECTOR m_pos; - int m_channelSound; -}; - - -#endif //_AUTOPARA_H_ diff --git a/src/autoportico.cpp b/src/autoportico.cpp deleted file mode 100644 index c02348d..0000000 --- a/src/autoportico.cpp +++ /dev/null @@ -1,446 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "interface.h" -#include "button.h" -#include "window.h" -#include "displaytext.h" -#include "robotmain.h" -#include "sound.h" -#include "auto.h" -#include "autoportico.h" - - - -#define PARAM_DEPOSE 2 // run=2 -> deposits the spaceship - -#define PORTICO_POSa 75.0f -#define PORTICO_POSb 65.0f -#define PORTICO_ANGLE1a ( 25.0f*PI/180.0f) -#define PORTICO_ANGLE1b ( 70.0f*PI/180.0f) -#define PORTICO_ANGLE2a (-37.5f*PI/180.0f) -#define PORTICO_ANGLE2b (-62.5f*PI/180.0f) -#define PORTICO_ANGLE3a (-77.5f*PI/180.0f) -#define PORTICO_ANGLE3b (-30.0f*PI/180.0f) - -#define PORTICO_TIME_MOVE 16.0f -#define PORTICO_TIME_DOWN 4.0f -#define PORTICO_TIME_OPEN 12.0f - - - - -// Si progress=0, return a. -// Si progress=1, return b. - -float Progress(float a, float b, float progress) -{ - return a+(b-a)*progress; -} - - - -// Object's constructor. - -CAutoPortico::CAutoPortico(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - Init(); - m_phase = APOP_WAIT; - m_soundChannel = -1; -} - -// Object's destructor. - -CAutoPortico::~CAutoPortico() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoPortico::DeleteObject(BOOL bAll) -{ - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } - - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoPortico::Init() -{ - m_time = 0.0f; - m_lastParticule = 0.0f; - m_posTrack = 0.0f; - - m_phase = APOP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - - m_cameraProgress = 0.0f; - m_cameraSpeed = 1.0f/(PORTICO_TIME_MOVE-2.0f); -} - - -// Starts the object. - -void CAutoPortico::Start(int param) -{ - D3DVECTOR pos; - - pos = m_object->RetPosition(0); - m_finalPos = pos; - pos.z += PORTICO_TIME_MOVE*5.0f; // back to start - m_object->SetPosition(0, pos); - m_finalPos.z += PORTICO_TIME_OPEN*5.3f; - - m_object->SetPosition(1, D3DVECTOR(0.0f, PORTICO_POSa, 0.0f)); - m_object->SetAngleY(2, PORTICO_ANGLE1a); - m_object->SetAngleY(3, PORTICO_ANGLE2a); - m_object->SetAngleY(4, PORTICO_ANGLE3a); - m_object->SetAngleY(5, -PORTICO_ANGLE1a); - m_object->SetAngleY(6, -PORTICO_ANGLE2a); - m_object->SetAngleY(7, -PORTICO_ANGLE3a); - - m_phase = APOP_START; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - - m_param = param; -} - - -// Management of an event. - -BOOL CAutoPortico::EventProcess(const Event &event) -{ - CObject* pObj; - D3DVECTOR pos; - float angle; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - - if ( m_phase == APOP_START ) - { - if ( m_param == PARAM_DEPOSE ) // deposits the ship? - { - m_startPos = m_object->RetPosition(0); - - m_soundChannel = m_sound->Play(SOUND_MOTORr, m_object->RetPosition(0), 0.0f, 0.3f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, 0.5f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, PORTICO_TIME_MOVE-0.5f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 0.5f, SOPER_STOP); - - m_phase = APOP_MOVE; - m_progress = 0.0f; - m_speed = 1.0f/PORTICO_TIME_MOVE; - - m_main->SetMovieLock(TRUE); // blocks everything until the end of the landing - - m_camera->SetType(CAMERA_SCRIPT); - - pos = m_startPos; - pos.x += -100.0f; - pos.y += 9.0f; - pos.z += -200.0f; - m_camera->SetScriptEye(pos); - - pos = m_object->RetPosition(0); - pos.x += 0.0f; - pos.y += 10.0f; - pos.z += -40.0f; - m_camera->SetScriptLookat(pos); - - m_camera->FixCamera(); - } - } - - angle = -m_time*1.0f; - m_object->SetAngleY(8, angle); // rotates the radar right - angle = sinf(m_time*4.0f)*0.3f; - m_object->SetAngleX(9, angle); - - angle = -m_time*1.0f+PI/2.3f; - m_object->SetAngleY(10, angle); // turns the left side radar - angle = sinf(m_time*4.0f)*0.3f; - m_object->SetAngleX(11, angle); - - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_phase == APOP_WAIT ) return TRUE; - - m_progress += event.rTime*m_speed; - m_cameraProgress += event.rTime*m_cameraSpeed; - - if ( m_phase == APOP_MOVE ) - { - if ( m_progress < 1.0f ) - { - pos = m_object->RetPosition(0); - pos.z -= event.rTime*5.0f; // advance - m_object->SetPosition(0, pos); - - m_posTrack += event.rTime*0.5f; - UpdateTrackMapping(m_posTrack, m_posTrack); - } - else - { - m_phase = APOP_WAIT1; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - if ( m_phase == APOP_WAIT1 ) - { - if ( m_progress >= 1.0f ) - { - m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.5f, 1.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.6f, PORTICO_TIME_DOWN-1.5f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 1.0f, SOPER_STOP); - - m_phase = APOP_DOWN; - m_progress = 0.0f; - m_speed = 1.0f/PORTICO_TIME_DOWN; - } - } - - if ( m_phase == APOP_DOWN ) - { - if ( m_progress < 1.0f ) - { - pos.x = 0.0f; - pos.y = Progress(PORTICO_POSa, PORTICO_POSb, m_progress); - pos.z = 0.0f; - m_object->SetPosition(1, pos); - } - else - { - pos.x = 0.0f; - pos.y = PORTICO_POSb; - pos.z = 0.0f; - m_object->SetPosition(1, pos); - - m_phase = APOP_WAIT2; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - if ( m_phase == APOP_WAIT2 ) - { - if ( m_progress >= 1.0f ) - { - m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.5f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 0.5f, 1.0f, 0.5f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.5f, 1.0f, PORTICO_TIME_OPEN/2.0f-0.5f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.5f, SOPER_STOP); - - m_soundChannel = m_sound->Play(SOUND_MOTORr, m_object->RetPosition(0), 0.0f, 0.3f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, 0.5f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, PORTICO_TIME_OPEN-0.5f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 0.5f, SOPER_STOP); - - m_phase = APOP_OPEN; - m_progress = 0.0f; - m_speed = 1.0f/PORTICO_TIME_OPEN; - } - } - - if ( m_phase == APOP_OPEN ) - { - if ( m_progress < 1.0f ) - { - pos = m_object->RetPosition(0); - pos.z += event.rTime*5.3f; // back - m_object->SetPosition(0, pos); - - m_posTrack -= event.rTime*1.0f; - UpdateTrackMapping(m_posTrack, m_posTrack); - - if ( m_progress < 0.5f ) - { - angle = Progress(PORTICO_ANGLE1a, PORTICO_ANGLE1b, m_progress/0.5f); - m_object->SetAngleY(2, angle); - m_object->SetAngleY(5, -angle); - angle = Progress(PORTICO_ANGLE2a, PORTICO_ANGLE2b, m_progress/0.5f); - m_object->SetAngleY(3, angle); - m_object->SetAngleY(6, -angle); - angle = Progress(PORTICO_ANGLE3a, PORTICO_ANGLE3b, m_progress/0.5f); - m_object->SetAngleY(4, angle); - m_object->SetAngleY(7, -angle); - } - else - { - m_object->SetAngleY(2, PORTICO_ANGLE1b); - m_object->SetAngleY(3, PORTICO_ANGLE2b); - m_object->SetAngleY(4, PORTICO_ANGLE3b); - m_object->SetAngleY(5, -PORTICO_ANGLE1b); - m_object->SetAngleY(6, -PORTICO_ANGLE2b); - m_object->SetAngleY(7, -PORTICO_ANGLE3b); - } - } - else - { - m_main->SetMovieLock(FALSE); // you can play! - - pObj = m_main->SearchHuman(); - m_main->SelectObject(pObj); - m_camera->SetObject(pObj); - m_camera->SetType(CAMERA_BACK); - - m_phase = APOP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - } - - if ( m_soundChannel != -1 ) - { -//? m_sound->Position(m_soundChannel, m_object->RetPosition(0)); - pos = m_engine->RetEyePt(); - m_sound->Position(m_soundChannel, pos); - } - - if ( m_cameraProgress < 1.0f ) - { - if ( m_cameraProgress < 0.5f ) - { - } - else - { - pos = m_startPos; - pos.x += -100.0f-(m_cameraProgress-0.5f)*1.0f*120.0f; - pos.y += 9.0f; - pos.z += -200.0f+(m_cameraProgress-0.5f)*1.0f*210.0f; - m_camera->SetScriptEye(pos); - } - - pos = m_object->RetPosition(0); - pos.x += 0.0f; - pos.y += 10.0f; - pos.z += -40.0f; - m_camera->SetScriptLookat(pos); - } - - return TRUE; -} - -// Stops the controller. - -BOOL CAutoPortico::Abort() -{ - CObject* pObj; - - m_object->SetPosition(0, m_finalPos); - m_object->SetPosition(1, D3DVECTOR(0.0f, PORTICO_POSb, 0.0f)); - m_object->SetAngleY(2, PORTICO_ANGLE1b); - m_object->SetAngleY(3, PORTICO_ANGLE2b); - m_object->SetAngleY(4, PORTICO_ANGLE3b); - m_object->SetAngleY(5, -PORTICO_ANGLE1b); - m_object->SetAngleY(6, -PORTICO_ANGLE2b); - m_object->SetAngleY(7, -PORTICO_ANGLE3b); - - m_main->SetMovieLock(FALSE); // you can play! - - pObj = m_main->SearchHuman(); - m_main->SelectObject(pObj); - m_camera->SetObject(pObj); - m_camera->SetType(CAMERA_BACK); - - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } - - m_phase = APOP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - - return TRUE; -} - - -// Returns an error due the state of the automation. - -Error CAutoPortico::RetError() -{ - return ERR_OK; -} - - -// Updates the mapping of the texture of the caterpillars. - -void CAutoPortico::UpdateTrackMapping(float left, float right) -{ - D3DMATERIAL7 mat; - float limit[2]; - int rank; - - ZeroMemory( &mat, sizeof(D3DMATERIAL7) ); - mat.diffuse.r = 1.0f; - mat.diffuse.g = 1.0f; - mat.diffuse.b = 1.0f; // blank - mat.ambient.r = 0.5f; - mat.ambient.g = 0.5f; - mat.ambient.b = 0.5f; - - rank = m_object->RetObjectRank(0); - - limit[0] = 0.0f; - limit[1] = 1000000.0f; - - m_engine->TrackTextureMapping(rank, mat, D3DSTATEPART1, "lemt.tga", "", - limit[0], limit[1], D3DMAPPINGX, - right, 8.0f, 8.0f, 192.0f, 256.0f); - - m_engine->TrackTextureMapping(rank, mat, D3DSTATEPART2, "lemt.tga", "", - limit[0], limit[1], D3DMAPPINGX, - left, 8.0f, 8.0f, 192.0f, 256.0f); -} - diff --git a/src/autoportico.h b/src/autoportico.h deleted file mode 100644 index 7ed2e70..0000000 --- a/src/autoportico.h +++ /dev/null @@ -1,81 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autoportico.h - -#ifndef _AUTOPORTICO_H_ -#define _AUTOPORTICO_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoPorticoPhase -{ - APOP_WAIT = 1, // waits - APOP_START = 2, // start of the action - APOP_MOVE = 3, // advance - APOP_WAIT1 = 4, // waits - APOP_DOWN = 5, // down - APOP_WAIT2 = 6, // waits - APOP_OPEN = 7, // opens -}; - - - -class CAutoPortico : public CAuto -{ -public: - CAutoPortico(CInstanceManager* iMan, CObject* object); - ~CAutoPortico(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - void Start(int param); - BOOL EventProcess(const Event &event); - BOOL Abort(); - Error RetError(); - -protected: - void UpdateTrackMapping(float left, float right); - -protected: - AutoPorticoPhase m_phase; - float m_progress; - float m_speed; - float m_cameraProgress; - float m_cameraSpeed; - float m_lastParticule; - D3DVECTOR m_finalPos; - D3DVECTOR m_startPos; - float m_posTrack; - int m_param; - int m_soundChannel; -}; - - -#endif //_AUTOPORTICO_H_ diff --git a/src/autoradar.cpp b/src/autoradar.cpp deleted file mode 100644 index 2353149..0000000 --- a/src/autoradar.cpp +++ /dev/null @@ -1,326 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "interface.h" -#include "button.h" -#include "window.h" -#include "gauge.h" -#include "sound.h" -#include "auto.h" -#include "autoradar.h" - - - - -// Object's constructor. - -CAutoRadar::CAutoRadar(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - Init(); - m_phase = ARAP_WAIT; - m_totalDetect = 0; -} - -// Object's destructor. - -CAutoRadar::~CAutoRadar() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoRadar::DeleteObject(BOOL bAll) -{ - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoRadar::Init() -{ - m_phase = ARAP_SEARCH; - m_progress = 0.0f; - m_speed = 1.0f/3.0f; - - m_aTime = 0.0f; - m_time = 0.0f; - m_timeVirus = 0.0f; -} - - -// Management of an event. - -BOOL CAutoRadar::EventProcess(const Event &event) -{ - D3DVECTOR pos, ePos; - float speed, angle, prog, freq, ampl; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_phase == ARAP_WAIT ) return TRUE; - - m_progress += event.rTime*m_speed; - m_aTime += event.rTime; - m_timeVirus -= event.rTime; - - if ( m_object->RetVirusMode() ) // contaminated by a virus? - { - if ( m_timeVirus <= 0.0f ) - { - m_timeVirus = 0.1f+Rand()*0.3f; - - angle = m_object->RetAngleY(1); - angle += (Rand()-0.2f)*0.5f; - m_object->SetAngleY(1, angle); - - angle = m_object->RetAngleY(2); - angle += (Rand()-0.8f)*1.0f; - m_object->SetAngleY(2, angle); - - m_object->SetAngleX(3, (Rand()-0.5f)*0.3f); - - m_totalDetect = (int)(Rand()*10.0f); - UpdateInterface(); - } - return TRUE; - } - - if ( m_phase == ARAP_SEARCH ) - { - if ( m_progress < 1.0f ) - { - speed = Min(10.0f, m_progress*50.0f); - angle = m_object->RetAngleY(1); - angle += event.rTime*speed; - m_object->SetAngleY(1, angle); - } - else - { - if ( !SearchEnemy(ePos) ) - { - m_phase = ARAP_SEARCH; - m_progress = 10.0f/50.0f; // full speed immediately - m_speed = 1.0f/3.0f; - } - else - { - pos = m_object->RetPosition(0); - m_start = m_object->RetAngleY(1); - m_angle = m_start-NormAngle(m_start)+PI*2.0f; - m_angle += RotateAngle(pos.x-ePos.x, ePos.z-pos.z); - m_angle += PI-m_object->RetAngleY(0); - - m_phase = ARAP_SHOW; - m_progress = 0.0f; - m_speed = 1.0f/(Abs(m_angle-m_start)/10.0f); - } - } - } - - if ( m_phase == ARAP_SHOW ) - { - if ( m_progress < 1.0f ) - { - angle = m_start + (m_angle-m_start)*m_progress; - m_object->SetAngleY(1, angle); - } - else - { - m_sound->Play(SOUND_RADAR, m_object->RetPosition(0)); - - m_phase = ARAP_SINUS; - m_progress = 0.0f; - m_speed = 1.0f/4.0f; - m_time = 0.0f; - } - } - - if ( m_phase == ARAP_SINUS ) - { - if ( m_progress < 1.0f ) - { - prog = Min(1.0f, m_progress*2.0f); - freq = 16.0f*(prog+1.0f); - ampl = 0.2f-prog*0.2f; - angle = m_angle + sinf(m_time*freq)*ampl; - m_object->SetAngleY(1, angle); - } - else - { - m_phase = ARAP_SEARCH; - m_progress = 0.0f; - m_speed = 1.0f/3.0f; - } - } - - angle = -m_aTime*2.0f; - m_object->SetAngleY(2, angle); - - angle = sinf(m_aTime*4.0f)*0.3f; - m_object->SetAngleX(3, angle); - - return TRUE; -} - - -// Returns an error due the state of the automation. - -Error CAutoRadar::RetError() -{ - if ( m_object->RetVirusMode() ) - { - return ERR_BAT_VIRUS; - } - - return ERR_OK; -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoRadar::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, dim, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*7.0f; - pos.y = oy+sy*0.6f; - dim.x = 160.0f/640.0f; - dim.y = 26.0f/480.0f; - pw->CreateGauge(pos, dim, 1, EVENT_OBJECT_GRADAR); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 105, EVENT_OBJECT_TYPE); - - UpdateInterface(); - return TRUE; -} - -// Updates the status of all interface buttons. - -void CAutoRadar::UpdateInterface() -{ - CWindow* pw; - CGauge* pg; - float level; - - if ( !m_object->RetSelect() ) return; - - CAuto::UpdateInterface(); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; - - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GRADAR); - if ( pg != 0 ) - { - level = (float)m_totalDetect*(1.0f/8.0f); - if ( level > 1.0f ) level = 1.0f; - pg->SetLevel(level); - } -} - - -// Seeking the position of an enemy. - -BOOL CAutoRadar::SearchEnemy(D3DVECTOR &pos) -{ - CObject* pObj; - CObject* pBest = 0; - D3DVECTOR iPos, oPos; - ObjectType oType; - float distance, min; - int i; - - iPos = m_object->RetPosition(0); - min = 1000000.0f; - m_totalDetect = 0; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetActif() ) continue; - - oType = pObj->RetType(); - if ( oType != OBJECT_ANT && - oType != OBJECT_SPIDER && - oType != OBJECT_BEE && - oType != OBJECT_WORM && - oType != OBJECT_MOTHER ) continue; - - m_totalDetect ++; - - oPos = pObj->RetPosition(0); - distance = Length(oPos, iPos); - if ( distance < min ) - { - min = distance; - pBest = pObj; - } - } - - UpdateInterface(); - - if ( pBest == 0 ) return FALSE; - pos = pBest->RetPosition(0); - return TRUE; -} - - diff --git a/src/autoradar.h b/src/autoradar.h deleted file mode 100644 index 298d011..0000000 --- a/src/autoradar.h +++ /dev/null @@ -1,76 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autoradar.h - -#ifndef _AUTORADAR_H_ -#define _AUTORADAR_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoRadarPhase -{ - ARAP_WAIT = 1, // waiting - ARAP_SEARCH = 2, // seeking - ARAP_SHOW = 3, // watching - ARAP_SINUS = 4, // oscillates -}; - - - -class CAutoRadar : public CAuto -{ -public: - CAutoRadar(CInstanceManager* iMan, CObject* object); - ~CAutoRadar(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - BOOL CreateInterface(BOOL bSelect); - Error RetError(); - -protected: - void UpdateInterface(); - BOOL SearchEnemy(D3DVECTOR &pos); - -protected: - AutoRadarPhase m_phase; - float m_progress; - float m_speed; - float m_aTime; - float m_timeVirus; - float m_lastParticule; - float m_angle; - float m_start; - int m_totalDetect; -}; - - -#endif //_AUTORADAR_H_ diff --git a/src/autorepair.cpp b/src/autorepair.cpp deleted file mode 100644 index 6994842..0000000 --- a/src/autorepair.cpp +++ /dev/null @@ -1,362 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "light.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "physics.h" -#include "sound.h" -#include "interface.h" -#include "button.h" -#include "window.h" -#include "robotmain.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autorepair.h" - - - - -// Object's constructor. - -CAutoRepair::CAutoRepair(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - Init(); - m_phase = ARP_WAIT; // paused until the first Init () -} - -// Object's destructor. - -CAutoRepair::~CAutoRepair() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoRepair::DeleteObject(BOOL bAll) -{ - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoRepair::Init() -{ - m_phase = ARP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - - m_time = 0.0f; - m_timeVirus = 0.0f; - m_lastParticule = 0.0f; - - CAuto::Init(); -} - - -// Management of an event. - -BOOL CAutoRepair::EventProcess(const Event &event) -{ - CObject* vehicule; - D3DVECTOR pos, speed; - FPOINT dim; - float angle, shield; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_speed; - m_timeVirus -= event.rTime; - - if ( m_object->RetVirusMode() ) // contaminated by a virus? - { - if ( m_timeVirus <= 0.0f ) - { - m_timeVirus = 0.1f+Rand()*0.3f; - } - return TRUE; - } - - if ( m_phase == ARP_WAIT ) - { - if ( m_progress >= 1.0f ) - { - if ( SearchVehicle() == 0 ) - { - m_phase = ARP_WAIT; // still waiting ... - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - else - { - m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 0.8f); - - m_phase = ARP_DOWN; - m_progress = 0.0f; - m_speed = 1.0f/3.0f; - } - } - } - - if ( m_phase == ARP_DOWN ) - { - if ( m_progress < 1.0f ) - { - angle = -m_progress*(PI/2.0f)+PI/2.0f; - m_object->SetAngleZ(1, angle); - } - else - { - m_object->SetAngleZ(1, 0.0f); - m_sound->Play(SOUND_REPAIR, m_object->RetPosition(0)); - - m_phase = ARP_REPAIR; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - if ( m_phase == ARP_REPAIR ) - { - vehicule = SearchVehicle(); - if ( m_progress < 1.0f || - (vehicule != 0 && vehicule->RetShield() < 1.0f) ) - { - if ( vehicule != 0 ) - { - shield = vehicule->RetShield(); - shield += event.rTime*0.2f; - if ( shield > 1.0f ) shield = 1.0f; - vehicule->SetShield(shield); - } - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_object->RetPosition(0); - pos.x += (Rand()-0.5f)*5.0f; - pos.z += (Rand()-0.5f)*5.0f; - pos.y += 1.0f; - speed.x = (Rand()-0.5f)*12.0f; - speed.z = (Rand()-0.5f)*12.0f; - speed.y = Rand()*15.0f; - dim.x = Rand()*6.0f+4.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); - } - } - else - { - m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 0.8f); - - m_phase = ARP_UP; - m_progress = 0.0f; - m_speed = 1.0f/3.0f; - } - } - - if ( m_phase == ARP_UP ) - { - if ( m_progress < 1.0f ) - { - angle = -(1.0f-m_progress)*(PI/2.0f)+PI/2.0f; - m_object->SetAngleZ(1, angle); - } - else - { - m_object->SetAngleZ(1, PI/2.0f); - - m_phase = ARP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - return TRUE; -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoRepair::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 106, EVENT_OBJECT_TYPE); - - return TRUE; -} - - -// Seeking the vehicle on the station. - -CObject* CAutoRepair::SearchVehicle() -{ - CObject* pObj; - CPhysics* physics; - D3DVECTOR sPos, oPos; - ObjectType type; - float dist; - int i; - - sPos = m_object->RetPosition(0); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type != OBJECT_MOBILEfa && - type != OBJECT_MOBILEta && - type != OBJECT_MOBILEwa && - type != OBJECT_MOBILEia && - type != OBJECT_MOBILEfc && - type != OBJECT_MOBILEtc && - type != OBJECT_MOBILEwc && - type != OBJECT_MOBILEic && - type != OBJECT_MOBILEfi && - type != OBJECT_MOBILEti && - type != OBJECT_MOBILEwi && - type != OBJECT_MOBILEii && - type != OBJECT_MOBILEfs && - type != OBJECT_MOBILEts && - type != OBJECT_MOBILEws && - type != OBJECT_MOBILEis && - type != OBJECT_MOBILErt && - type != OBJECT_MOBILErc && - type != OBJECT_MOBILErr && - type != OBJECT_MOBILErs && - type != OBJECT_MOBILEsa && - type != OBJECT_MOBILEtg && - type != OBJECT_MOBILEft && - type != OBJECT_MOBILEtt && - type != OBJECT_MOBILEwt && - type != OBJECT_MOBILEit && - type != OBJECT_MOBILEdr ) continue; - - physics = pObj->RetPhysics(); - if ( physics != 0 && !physics->RetLand() ) continue; // in flight? - - oPos = pObj->RetPosition(0); - dist = Length(oPos, sPos); - if ( dist <= 5.0f ) return pObj; - } - - return 0; -} - - -// Returns an error due the state of the automation. - -Error CAutoRepair::RetError() -{ - if ( m_object->RetVirusMode() ) - { - return ERR_BAT_VIRUS; - } - - return ERR_OK; -} - - -// Saves all parameters of the controller. - -BOOL CAutoRepair::Write(char *line) -{ - char name[100]; - - if ( m_phase == ARP_WAIT ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller. - -BOOL CAutoRepair::Read(char *line) -{ - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoRepairPhase)OpInt(line, "aPhase", ARP_WAIT); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - - m_lastParticule = 0.0f; - - return TRUE; -} - - diff --git a/src/autorepair.h b/src/autorepair.h deleted file mode 100644 index 1383fc7..0000000 --- a/src/autorepair.h +++ /dev/null @@ -1,76 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autorepair.h - -#ifndef _AUTOREPAIR_H_ -#define _AUTOREPAIR_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoRepairPhase -{ - ARP_WAIT = 1, // expected metal - ARP_DOWN = 2, // down the cover - ARP_REPAIR = 3, // repair the vehicle - ARP_UP = 4, // back cover - -}; - - - -class CAutoRepair : public CAuto -{ -public: - CAutoRepair(CInstanceManager* iMan, CObject* object); - ~CAutoRepair(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - - BOOL CreateInterface(BOOL bSelect); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - CObject* SearchVehicle(); - -protected: - AutoRepairPhase m_phase; - float m_progress; - float m_speed; - float m_timeVirus; - float m_lastParticule; -}; - - -#endif //_AUTOREPAIR_H_ diff --git a/src/autoresearch.cpp b/src/autoresearch.cpp deleted file mode 100644 index b15a9b8..0000000 --- a/src/autoresearch.cpp +++ /dev/null @@ -1,627 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "global.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "interface.h" -#include "button.h" -#include "gauge.h" -#include "window.h" -#include "displaytext.h" -#include "sound.h" -#include "robotmain.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autoresearch.h" - - - -#define SEARCH_TIME 30.0f // duration of a research - - - -// Object's constructor. - -CAutoResearch::CAutoResearch(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - int i; - - CAuto::CAuto(iMan, object); - - for ( i=0 ; i<6 ; i++ ) - { - m_partiStop[i] = -1; - } - m_channelSound = -1; - - Init(); -} - -// Object's destructor. - -CAutoResearch::~CAutoResearch() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoResearch::DeleteObject(BOOL bAll) -{ - if ( m_channelSound != -1 ) - { - m_sound->FlushEnvelope(m_channelSound); - m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_channelSound = -1; - } - - FireStopUpdate(0.0f, FALSE); - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoResearch::Init() -{ - m_phase = ALP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - - m_time = 0.0f; - m_timeVirus = 0.0f; - m_lastUpdateTime = 0.0f; - m_lastParticule = 0.0f; -} - - -// Management of an event. - -BOOL CAutoResearch::EventProcess(const Event &event) -{ - CObject* power; - D3DVECTOR pos, speed; - Error message; - FPOINT dim; - float angle, time; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - - if ( event.event == EVENT_UPDINTERFACE ) - { - if ( m_object->RetSelect() ) CreateInterface(TRUE); - } - - if ( m_object->RetSelect() && // center selected? - (event.event == EVENT_OBJECT_RTANK || - event.event == EVENT_OBJECT_RFLY || - event.event == EVENT_OBJECT_RTHUMP || - event.event == EVENT_OBJECT_RCANON || - event.event == EVENT_OBJECT_RTOWER || - event.event == EVENT_OBJECT_RPHAZER || - event.event == EVENT_OBJECT_RSHIELD || - event.event == EVENT_OBJECT_RATOMIC ) ) - { - if ( m_phase != ALP_WAIT ) - { - return FALSE; - } - - m_research = event.event; - - if ( TestResearch(m_research) ) - { - m_displayText->DisplayError(ERR_RESEARCH_ALREADY, m_object); - return FALSE; - } - - power = m_object->RetPower(); - if ( power == 0 ) - { - m_displayText->DisplayError(ERR_RESEARCH_POWER, m_object); - return FALSE; - } - if ( power->RetCapacity() > 1.0f ) - { - m_displayText->DisplayError(ERR_RESEARCH_TYPE, m_object); - return FALSE; - } - if ( power->RetEnergy() < 1.0f ) - { - m_displayText->DisplayError(ERR_RESEARCH_ENERGY, m_object); - return FALSE; - } - - time = SEARCH_TIME; - if ( event.event == EVENT_OBJECT_RTANK ) time *= 0.3f; - if ( event.event == EVENT_OBJECT_RFLY ) time *= 0.3f; - if ( event.event == EVENT_OBJECT_RATOMIC ) time *= 2.0f; - - SetBusy(TRUE); - InitProgressTotal(time); - UpdateInterface(); - - m_channelSound = m_sound->Play(SOUND_RESEARCH, m_object->RetPosition(0), 0.0f, 1.0f, TRUE); - m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 2.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, time-4.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 2.0f, SOPER_STOP); - - m_phase = ALP_SEARCH; - m_progress = 0.0f; - m_speed = 1.0f/time; - return TRUE; - } - - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_speed; - m_timeVirus -= event.rTime; - - if ( m_object->RetVirusMode() ) // contaminated by a virus? - { - if ( m_timeVirus <= 0.0f ) - { - m_timeVirus = 0.1f+Rand()*0.3f; - } - return TRUE; - } - - UpdateInterface(event.rTime); - EventProgress(event.rTime); - - angle = m_time*0.1f; - m_object->SetAngleY(1, angle); // rotates the antenna - - angle = (30.0f+sinf(m_time*0.3f)*20.0f)*PI/180.0f; - m_object->SetAngleZ(2, angle); // directs the antenna - - if ( m_phase == ALP_WAIT ) - { - FireStopUpdate(m_progress, FALSE); // extinguished - return TRUE; - } - - if ( m_phase == ALP_SEARCH ) - { - FireStopUpdate(m_progress, TRUE); // flashes - if ( m_progress < 1.0f ) - { - power = m_object->RetPower(); - if ( power == 0 ) // more battery? - { - SetBusy(FALSE); - UpdateInterface(); - - m_phase = ALP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - return TRUE; - } - power->SetEnergy(1.0f-m_progress); - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_object->RetPosition(0); - pos.x += (Rand()-0.5f)*6.0f; - pos.z += (Rand()-0.5f)*6.0f; - pos.y += 11.0f; - speed.x = (Rand()-0.5f)*2.0f; - speed.z = (Rand()-0.5f)*2.0f; - speed.y = Rand()*20.0f; - dim.x = Rand()*1.0f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIVAPOR); - } - } - else - { - SetResearch(m_research); // research done - m_displayText->DisplayError(INFO_RESEARCH, m_object); - - message = ERR_OK; - if ( m_research == EVENT_OBJECT_RTANK ) message = INFO_RESEARCHTANK; - if ( m_research == EVENT_OBJECT_RFLY ) message = INFO_RESEARCHFLY; - if ( m_research == EVENT_OBJECT_RTHUMP ) message = INFO_RESEARCHTHUMP; - if ( m_research == EVENT_OBJECT_RCANON ) message = INFO_RESEARCHCANON; - if ( m_research == EVENT_OBJECT_RTOWER ) message = INFO_RESEARCHTOWER; - if ( m_research == EVENT_OBJECT_RPHAZER ) message = INFO_RESEARCHPHAZER; - if ( m_research == EVENT_OBJECT_RSHIELD ) message = INFO_RESEARCHSHIELD; - if ( m_research == EVENT_OBJECT_RATOMIC ) message = INFO_RESEARCHATOMIC; - if ( message != ERR_OK ) - { - m_displayText->DisplayError(message, m_object); - } - - SetBusy(FALSE); - UpdateInterface(); - - m_phase = ALP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - return TRUE; -} - - -// Returns an error due the state of the automation. - -Error CAutoResearch::RetError() -{ - CObject* power; - - if ( m_phase == ALP_SEARCH ) - { - return ERR_OK; - } - - if ( m_object->RetVirusMode() ) - { - return ERR_BAT_VIRUS; - } - - power = m_object->RetPower(); - if ( power == 0 ) - { - return ERR_RESEARCH_POWER; - } - if ( power != 0 && power->RetCapacity() > 1.0f ) - { - return ERR_RESEARCH_TYPE; - } - if ( power != 0 && power->RetEnergy() < 1.0f ) - { - return ERR_RESEARCH_ENERGY; - } - - return ERR_OK; -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoResearch::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, dim, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - dim.x = 33.0f/640.0f; - dim.y = 33.0f/480.0f; - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*7.0f; - pos.y = oy+sy*1.0f; - pw->CreateButton(pos, dim, 64+0, EVENT_OBJECT_RTANK); - - pos.x = ox+sx*8.0f; - pos.y = oy+sy*1.0f; - pw->CreateButton(pos, dim, 64+1, EVENT_OBJECT_RFLY); - - pos.x = ox+sx*9.0f; - pos.y = oy+sy*1.0f; - pw->CreateButton(pos, dim, 64+3, EVENT_OBJECT_RCANON); - - pos.x = ox+sx*10.0f; - pos.y = oy+sy*1.0f; - pw->CreateButton(pos, dim, 64+4, EVENT_OBJECT_RTOWER); - - pos.x = ox+sx*7.0f; - pos.y = oy+sy*0.0f; - pw->CreateButton(pos, dim, 64+7, EVENT_OBJECT_RATOMIC); - - pos.x = ox+sx*8.0f; - pos.y = oy+sy*0.0f; - pw->CreateButton(pos, dim, 64+2, EVENT_OBJECT_RTHUMP); - - pos.x = ox+sx*9.0f; - pos.y = oy+sy*0.0f; - pw->CreateButton(pos, dim, 64+6, EVENT_OBJECT_RSHIELD); - - pos.x = ox+sx*10.0f; - pos.y = oy+sy*0.0f; - pw->CreateButton(pos, dim, 64+5, EVENT_OBJECT_RPHAZER); - - pos.x = ox+sx*14.5f; - pos.y = oy+sy*0; - ddim.x = 14.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 102, EVENT_OBJECT_TYPE); - - UpdateInterface(); - - return TRUE; -} - -// Updates the status of all interface buttons. - -void CAutoResearch::UpdateInterface() -{ - CWindow* pw; - - if ( !m_object->RetSelect() ) return; - - CAuto::UpdateInterface(); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; - - DeadInterface(pw, EVENT_OBJECT_RTANK, g_researchEnable&RESEARCH_TANK); - DeadInterface(pw, EVENT_OBJECT_RFLY, g_researchEnable&RESEARCH_FLY); - DeadInterface(pw, EVENT_OBJECT_RTHUMP, g_researchEnable&RESEARCH_THUMP); - DeadInterface(pw, EVENT_OBJECT_RCANON, g_researchEnable&RESEARCH_CANON); - DeadInterface(pw, EVENT_OBJECT_RTOWER, g_researchEnable&RESEARCH_TOWER); - DeadInterface(pw, EVENT_OBJECT_RPHAZER, g_researchEnable&RESEARCH_PHAZER); - DeadInterface(pw, EVENT_OBJECT_RSHIELD, g_researchEnable&RESEARCH_SHIELD); - DeadInterface(pw, EVENT_OBJECT_RATOMIC, g_researchEnable&RESEARCH_ATOMIC); - - OkayButton(pw, EVENT_OBJECT_RTANK); - OkayButton(pw, EVENT_OBJECT_RFLY); - OkayButton(pw, EVENT_OBJECT_RTHUMP); - OkayButton(pw, EVENT_OBJECT_RCANON); - OkayButton(pw, EVENT_OBJECT_RTOWER); - OkayButton(pw, EVENT_OBJECT_RPHAZER); - OkayButton(pw, EVENT_OBJECT_RSHIELD); - OkayButton(pw, EVENT_OBJECT_RATOMIC); - - VisibleInterface(pw, EVENT_OBJECT_RTANK, !m_bBusy); - VisibleInterface(pw, EVENT_OBJECT_RFLY, !m_bBusy); - VisibleInterface(pw, EVENT_OBJECT_RTHUMP, !m_bBusy); - VisibleInterface(pw, EVENT_OBJECT_RCANON, !m_bBusy); - VisibleInterface(pw, EVENT_OBJECT_RTOWER, !m_bBusy); - VisibleInterface(pw, EVENT_OBJECT_RPHAZER, !m_bBusy); - VisibleInterface(pw, EVENT_OBJECT_RSHIELD, !m_bBusy); - VisibleInterface(pw, EVENT_OBJECT_RATOMIC, !m_bBusy); -} - -// Updates the state of all buttons on the interface, -// following the time that elapses ... - -void CAutoResearch::UpdateInterface(float rTime) -{ - CWindow* pw; - CGauge* pg; - CObject* power; - float energy; - - CAuto::UpdateInterface(rTime); - - if ( m_time < m_lastUpdateTime+0.1f ) return; - m_lastUpdateTime = m_time; - - if ( !m_object->RetSelect() ) return; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; - - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); - if ( pg != 0 ) - { - energy = 0.0f; - power = m_object->RetPower(); - if ( power != 0 ) - { - energy = power->RetEnergy(); - } - pg->SetLevel(energy); - } -} - -// Research shows already performed button. - -void CAutoResearch::OkayButton(CWindow *pw, EventMsg event) -{ - CControl* control; - - control = pw->SearchControl(event); - if ( control == 0 ) return; - - control->SetState(STATE_OKAY, TestResearch(event)); -} - - -// Test whether a search has already been done. - -BOOL CAutoResearch::TestResearch(EventMsg event) -{ - if ( event == EVENT_OBJECT_RTANK ) return (g_researchDone & RESEARCH_TANK ); - if ( event == EVENT_OBJECT_RFLY ) return (g_researchDone & RESEARCH_FLY ); - if ( event == EVENT_OBJECT_RTHUMP ) return (g_researchDone & RESEARCH_THUMP ); - if ( event == EVENT_OBJECT_RCANON ) return (g_researchDone & RESEARCH_CANON ); - if ( event == EVENT_OBJECT_RTOWER ) return (g_researchDone & RESEARCH_TOWER ); - if ( event == EVENT_OBJECT_RPHAZER ) return (g_researchDone & RESEARCH_PHAZER ); - if ( event == EVENT_OBJECT_RSHIELD ) return (g_researchDone & RESEARCH_SHIELD); - if ( event == EVENT_OBJECT_RATOMIC ) return (g_researchDone & RESEARCH_ATOMIC); - - return FALSE; -} - -// Indicates a search as made. - -void CAutoResearch::SetResearch(EventMsg event) -{ - Event newEvent; - - if ( event == EVENT_OBJECT_RTANK ) g_researchDone |= RESEARCH_TANK; - if ( event == EVENT_OBJECT_RFLY ) g_researchDone |= RESEARCH_FLY; - if ( event == EVENT_OBJECT_RTHUMP ) g_researchDone |= RESEARCH_THUMP; - if ( event == EVENT_OBJECT_RCANON ) g_researchDone |= RESEARCH_CANON; - if ( event == EVENT_OBJECT_RTOWER ) g_researchDone |= RESEARCH_TOWER; - if ( event == EVENT_OBJECT_RPHAZER ) g_researchDone |= RESEARCH_PHAZER; - if ( event == EVENT_OBJECT_RSHIELD ) g_researchDone |= RESEARCH_SHIELD; - if ( event == EVENT_OBJECT_RATOMIC ) g_researchDone |= RESEARCH_ATOMIC; - - m_main->WriteFreeParam(); - - m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); - m_event->AddEvent(newEvent); - UpdateInterface(); -} - - -// Updates the stop lights. - -void CAutoResearch::FireStopUpdate(float progress, BOOL bLightOn) -{ - D3DMATRIX* mat; - D3DVECTOR pos, speed; - FPOINT dim; - int i; - - static float listpos[12] = - { - 9.5f, 0.0f, - 4.7f, 8.2f, - -4.7f, 8.2f, - -9.5f, 0.0f, - -4.7f, -8.2f, - 4.7f, -8.2f, - }; - - if ( !bLightOn ) // �teint ? - { - for ( i=0 ; i<6 ; i++ ) - { - if ( m_partiStop[i] != -1 ) - { - m_particule->DeleteParticule(m_partiStop[i]); - m_partiStop[i] = -1; - } - } - return; - } - - mat = m_object->RetWorldMatrix(0); - - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 2.0f; - dim.y = dim.x; - - for ( i=0 ; i<6 ; i++ ) - { - if ( Mod(progress, 0.025f) < 0.005f ) - { - if ( m_partiStop[i] != -1 ) - { - m_particule->DeleteParticule(m_partiStop[i]); - m_partiStop[i] = -1; - } - } - else - { - if ( m_partiStop[i] == -1 ) - { - pos.x = listpos[i*2+0]; - pos.y = 11.5f; - pos.z = listpos[i*2+1]; - pos = Transform(*mat, pos); - m_partiStop[i] = m_particule->CreateParticule(pos, speed, - dim, PARTISELY, - 1.0f, 0.0f, 0.0f); - } - } - } -} - - -// Saves all parameters of the controller. - -BOOL CAutoResearch::Write(char *line) -{ - char name[100]; - - if ( m_phase == ALP_WAIT ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - sprintf(name, " aResearch=%d", m_research); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller. - -BOOL CAutoResearch::Read(char *line) -{ - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoResearchPhase)OpInt(line, "aPhase", ALP_WAIT); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - m_research = (EventMsg)OpInt(line, "aResearch", 0); - - m_lastUpdateTime = 0.0f; - m_lastParticule = 0.0f; - - return TRUE; -} - - diff --git a/src/autoresearch.h b/src/autoresearch.h deleted file mode 100644 index f773084..0000000 --- a/src/autoresearch.h +++ /dev/null @@ -1,82 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autoresearch.h - -#ifndef _AUTORESEARCH_H_ -#define _AUTORESEARCH_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoResearchPhase -{ - ALP_WAIT = 1, - ALP_SEARCH = 2, // research in progress -}; - - - -class CAutoResearch : public CAuto -{ -public: - CAutoResearch(CInstanceManager* iMan, CObject* object); - ~CAutoResearch(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - - BOOL CreateInterface(BOOL bSelect); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - void UpdateInterface(); - void UpdateInterface(float rTime); - void OkayButton(CWindow *pw, EventMsg event); - BOOL TestResearch(EventMsg event); - void SetResearch(EventMsg event); - void FireStopUpdate(float progress, BOOL bLightOn); - -protected: - AutoResearchPhase m_phase; - float m_progress; - float m_speed; - float m_timeVirus; - float m_lastUpdateTime; - float m_lastParticule; - EventMsg m_research; - int m_partiStop[6]; - int m_channelSound; -}; - - -#endif //_AUTORESEARCH_H_ diff --git a/src/autoroot.cpp b/src/autoroot.cpp deleted file mode 100644 index 5f1afad..0000000 --- a/src/autoroot.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "auto.h" -#include "autoroot.h" - - - - -// Object's constructor. - -CAutoRoot::CAutoRoot(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - Init(); -} - -// Object's destructor. - -CAutoRoot::~CAutoRoot() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoRoot::DeleteObject(BOOL bAll) -{ - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoRoot::Init() -{ - D3DMATRIX* mat; - D3DVECTOR pos, speed; - FPOINT dim; - - m_time = 0.0f; - m_lastParticule = 0.0f; - - mat = m_object->RetWorldMatrix(0); - pos = D3DVECTOR(-5.0f, 28.0f, -4.0f); // peak position - pos = Transform(*mat, pos); - m_center = pos; - - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 100.0f; - dim.y = dim.x; - m_particule->CreateParticule(m_center, speed, dim, PARTISPHERE5, 0.5f, 0.0f, 0.0f); - - m_terrain->AddFlyingLimit(pos, 100.0f, 80.0f, pos.y-60.0f); -} - - -// Management of an event. - -BOOL CAutoRoot::EventProcess(const Event &event) -{ - D3DVECTOR pos, speed; - FPOINT dim; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_object->SetZoomX(1, 1.0f+sinf(m_time*2.0f)*0.2f); - m_object->SetZoomY(1, 1.0f+sinf(m_time*2.3f)*0.2f); - m_object->SetZoomZ(1, 1.0f+sinf(m_time*2.7f)*0.2f); - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_center; - pos.x += (Rand()-0.5f)*8.0f; - pos.z += (Rand()-0.5f)*8.0f; - pos.y += 0.0f; - speed.x = (Rand()-0.5f)*12.0f; - speed.z = (Rand()-0.5f)*12.0f; - speed.y = Rand()*12.0f; - dim.x = Rand()*6.0f+4.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIROOT, 1.0f, 0.0f, 0.0f); - } - - return TRUE; -} - - -// Returns an error due the state of the automation. - -Error CAutoRoot::RetError() -{ - return ERR_OK; -} - - diff --git a/src/autoroot.h b/src/autoroot.h deleted file mode 100644 index 85bdb69..0000000 --- a/src/autoroot.h +++ /dev/null @@ -1,56 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autoroot.h - -#ifndef _AUTOROOT_H_ -#define _AUTOROOT_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -class CAutoRoot : public CAuto -{ -public: - CAutoRoot(CInstanceManager* iMan, CObject* object); - ~CAutoRoot(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - -protected: - -protected: - float m_lastParticule; - D3DVECTOR m_center; -}; - - -#endif //_AUTOROOT_H_ diff --git a/src/autosafe.cpp b/src/autosafe.cpp deleted file mode 100644 index bdc6d32..0000000 --- a/src/autosafe.cpp +++ /dev/null @@ -1,636 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "global.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "light.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "interface.h" -#include "button.h" -#include "robotmain.h" -#include "window.h" -#include "sound.h" -#include "displaytext.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autosafe.h" - - - -#define OPEN_DELAY 8.0f // duration of opening - - - - -// Object's constructor. - -CAutoSafe::CAutoSafe(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - int i; - - CAuto::CAuto(iMan, object); - - for ( i=0 ; i<4 ; i++ ) - { - m_bKey[i] = FALSE; - m_keyParti[i] = -1; - } - - m_bLock = FALSE; - m_lastParticule = 0.0f; - m_channelSound = -1; - Init(); -} - -// Object's destructor. - -CAutoSafe::~CAutoSafe() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoSafe::DeleteObject(BOOL bAll) -{ - CObject* pObj; - - pObj = SearchVehicle(); - if ( pObj != 0 ) - { - pObj->DeleteObject(); - delete pObj; - } - - if ( m_channelSound != -1 ) - { - m_sound->FlushEnvelope(m_channelSound); - m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_channelSound = -1; - } - - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoSafe::Init() -{ - m_time = 0.0f; - m_timeVirus = 0.0f; - m_lastParticule = 0.0f; - - m_countKeys = 0; - m_actualAngle = 0.0f; - m_finalAngle = 0.0f; - - m_phase = ASAP_WAIT; // waiting ... - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - - CAuto::Init(); -} - - -// Management of an event. - -BOOL CAutoSafe::EventProcess(const Event &event) -{ - CObject* pObj; - D3DVECTOR pos, speed; - FPOINT dim; - int i, count; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_speed; - m_timeVirus -= event.rTime; - - if ( m_object->RetVirusMode() ) // contaminated by a virus? - { - if ( m_timeVirus <= 0.0f ) - { - m_timeVirus = 0.1f+Rand()*0.3f; - } - return TRUE; - } - - EventProgress(event.rTime); - - if ( !m_bLock ) - { - pObj = SearchVehicle(); - if ( pObj != 0 ) - { - pObj->SetLock(TRUE); // object not yet usable - m_main->CreateShortcuts(); - m_bLock = TRUE; - } - } - - if ( m_phase == ASAP_WAIT ) - { - if ( m_progress >= 1.0f ) - { - count = CountKeys(); // count these key - if ( count != m_countKeys ) - { - m_countKeys = count; - - if ( count == 0 ) m_finalAngle = 0.0f*PI/180.0f; - if ( count == 1 ) m_finalAngle = 5.0f*PI/180.0f; - if ( count == 2 ) m_finalAngle = 10.0f*PI/180.0f; - if ( count == 3 ) m_finalAngle = 15.0f*PI/180.0f; - if ( count == 4 ) m_finalAngle = 120.0f*PI/180.0f; - - if ( count == 4 ) // all the keys? - { - LockKeys(); - - m_channelSound = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 1.0f, 0.25f, TRUE); - m_sound->AddEnvelope(m_channelSound, 1.0f, 2.00f, OPEN_DELAY, SOPER_STOP); - - m_phase = ASAP_OPEN; - m_progress = 0.0f; - m_speed = 1.0f/OPEN_DELAY; - return TRUE; - } - else - { - m_channelSound = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 1.0f, 0.25f, TRUE); - m_sound->AddEnvelope(m_channelSound, 1.0f, 0.35f, 0.5f, SOPER_STOP); - } - } - - m_phase = ASAP_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - if ( m_phase == ASAP_OPEN ) - { - if ( m_progress < 1.0f ) - { - DownKeys(m_progress); - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - for ( i=0 ; i<10 ; i++ ) - { - pos = m_object->RetPosition(0); - pos.x += (Rand()-0.5f)*10.0f; - pos.z += (Rand()-0.5f)*10.0f; - speed.x = (Rand()-0.5f)*4.0f; - speed.z = (Rand()-0.5f)*4.0f; - speed.y = Rand()*15.0f; - dim.x = Rand()*6.0f+4.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); - } - - pos = m_object->RetPosition(0); - pos.x += (Rand()-0.5f)*10.0f; - pos.z += (Rand()-0.5f)*10.0f; - speed.x = (Rand()-0.5f)*4.0f; - speed.z = (Rand()-0.5f)*4.0f; - speed.y = Rand()*10.0f; - dim.x = Rand()*3.0f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 1.0f, 0.0f, 0.0f); - - for ( i=0 ; i<4 ; i++ ) - { - pos = m_keyPos[i]; - speed.x = (Rand()-0.5f)*2.0f; - speed.z = (Rand()-0.5f)*2.0f; - speed.y = 1.0f+Rand()*1.0f; - dim.x = Rand()*1.5f+1.5f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 0.0f); - } - } - } - else - { - DeleteKeys(); - - pObj = SearchVehicle(); - if ( pObj != 0 ) - { - pObj->SetLock(FALSE); // object usable - m_main->CreateShortcuts(); - } - - m_object->FlushCrashShere(); - m_object->SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 0.0f); - - m_sound->Play(SOUND_FINDING, m_object->RetPosition(0)); - - m_phase = ASAP_FINISH; - m_progress = 0.0f; - m_speed = 1.0f/100.0f; - } - } - - if ( m_phase == ASAP_FINISH ) - { - if ( m_progress >= 1.0f ) - { - m_phase = ASAP_FINISH; - m_progress = 0.0f; - m_speed = 1.0f/100.0f; - } - } - - // Opens or closes the doors. - if ( m_actualAngle != m_finalAngle ) - { - if ( m_actualAngle < m_finalAngle ) - { - m_actualAngle += (105.0f*PI/180.0f)*event.rTime/OPEN_DELAY; - if ( m_actualAngle > m_finalAngle ) m_actualAngle = m_finalAngle; - } - else - { - m_actualAngle -= (105.0f*PI/180.0f)*event.rTime/OPEN_DELAY; - if ( m_actualAngle < m_finalAngle ) m_actualAngle = m_finalAngle; - } - m_object->SetAngleZ(1, m_actualAngle); - m_object->SetAngleZ(2, -m_actualAngle); - } - - // Blinks the keys. - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 2.0f; - dim.y = dim.x; - for ( i=0 ; i<4 ; i++ ) - { - if ( m_phase != ASAP_WAIT || !m_bKey[i] || Mod(m_time, 1.0f) < 0.4f ) - { - if ( m_keyParti[i] != -1 ) - { - m_particule->DeleteParticule(m_keyParti[i]); - m_keyParti[i] = -1; - } - } - else - { - if ( m_keyParti[i] == -1 ) - { - pos = m_keyPos[i]; - pos.y += 2.2f; - m_keyParti[i] = m_particule->CreateParticule(pos, speed, dim, PARTISELY, 1.0f, 0.0f, 0.0f); - } - } - } - - return TRUE; -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoSafe::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 114, EVENT_OBJECT_TYPE); - - return TRUE; -} - - -// Returns an error due the state of the automation. - -Error CAutoSafe::RetError() -{ - if ( m_object->RetVirusMode() ) - { - return ERR_BAT_VIRUS; - } - return ERR_OK; -} - - -// Saves all parameters of the controller. - -BOOL CAutoSafe::Write(char *line) -{ - char name[100]; - - if ( m_phase == ASAP_WAIT ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller. - -BOOL CAutoSafe::Read(char *line) -{ - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoSafePhase)OpInt(line, "aPhase", ASAP_WAIT); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - - m_lastParticule = 0.0f; - - return TRUE; -} - - -// Counts the number of keys - -int CAutoSafe::CountKeys() -{ - CObject* pObj; - D3DVECTOR cPos, oPos; - FPOINT rot; - ObjectType oType; - float dist, angle, limit, cAngle, oAngle; - int i, index; - - cPos = m_object->RetPosition(0); - cAngle = m_object->RetAngleY(0); - - for ( index=0 ; index<4 ; index++ ) - { - m_bKey[index] = FALSE; - m_keyPos[index] = cPos; - } - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - oType = pObj->RetType(); - if ( pObj->RetTruck() != 0 ) continue; - - if ( oType != OBJECT_KEYa && - oType != OBJECT_KEYb && - oType != OBJECT_KEYc && - oType != OBJECT_KEYd ) continue; - - oPos = pObj->RetPosition(0); - dist = Length2d(oPos, cPos); - if ( dist > 20.0f ) continue; - - if ( oType == OBJECT_KEYa ) - { - limit = PI*1.0f; - oAngle = PI*0.0f; - index = 0; - } - if ( oType == OBJECT_KEYb ) - { - limit = PI*0.0f; - oAngle = PI*1.0f; - index = 1; - } - if ( oType == OBJECT_KEYc ) - { - limit = PI*1.5f; - oAngle = PI*0.5f; - index = 2; - } - if ( oType == OBJECT_KEYd ) - { - limit = PI*0.5f; - oAngle = PI*0.0f; - index = 3; - } - - angle = RotateAngle(oPos.x-cPos.x, oPos.z-cPos.z)+cAngle; - if ( !TestAngle(angle, limit-8.0f*PI/180.0f, limit+8.0f*PI/180.0f) ) continue; - - // Key changes the shape of the base. - rot = RotatePoint(FPOINT(cPos.x, cPos.z), limit-cAngle, FPOINT(cPos.x+16.0f, cPos.z)); - oPos.x = rot.x; - oPos.z = rot.y; - oPos.y = cPos.y+1.0f; - pObj->SetPosition(0, oPos); - pObj->SetAngleY(0, oAngle+cAngle); - m_keyPos[index] = oPos; - - m_bKey[index] = TRUE; - } - - i = 0; - for ( index=0 ; index<4 ; index++ ) - { - if ( m_bKey[index] ) i++; - } - return i; -} - -// Blocks all keys. - -void CAutoSafe::LockKeys() -{ - CObject* pObj; - D3DVECTOR cPos, oPos; - ObjectType oType; - float dist; - int i; - - cPos = m_object->RetPosition(0); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - oType = pObj->RetType(); - if ( pObj->RetTruck() != 0 ) continue; - - if ( oType != OBJECT_KEYa && - oType != OBJECT_KEYb && - oType != OBJECT_KEYc && - oType != OBJECT_KEYd ) continue; - - oPos = pObj->RetPosition(0); - dist = Length2d(oPos, cPos); - if ( dist > 20.0f ) continue; - - pObj->SetLock(TRUE); - } -} - -// Sent down all the keys. - -void CAutoSafe::DownKeys(float progress) -{ - CObject* pObj; - D3DVECTOR cPos, oPos; - ObjectType oType; - float dist; - int i; - - cPos = m_object->RetPosition(0); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - oType = pObj->RetType(); - if ( pObj->RetTruck() != 0 ) continue; - - if ( oType != OBJECT_KEYa && - oType != OBJECT_KEYb && - oType != OBJECT_KEYc && - oType != OBJECT_KEYd ) continue; - - oPos = pObj->RetPosition(0); - dist = Length2d(oPos, cPos); - if ( dist > 20.0f ) continue; - - oPos.y = cPos.y+1.0f-progress*2.2f; - pObj->SetPosition(0, oPos); - } -} - -// Delete all the keys. - -void CAutoSafe::DeleteKeys() -{ - CObject* pObj; - D3DVECTOR cPos, oPos; - ObjectType oType; - float dist; - int i; - BOOL bDelete; - - cPos = m_object->RetPosition(0); - - do - { - bDelete = FALSE; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - oType = pObj->RetType(); - if ( pObj->RetTruck() != 0 ) continue; - - if ( oType != OBJECT_KEYa && - oType != OBJECT_KEYb && - oType != OBJECT_KEYc && - oType != OBJECT_KEYd ) continue; - - oPos = pObj->RetPosition(0); - dist = Length2d(oPos, cPos); - if ( dist > 20.0f ) continue; - - pObj->DeleteObject(); - delete pObj; - bDelete = TRUE; - } - } - while ( bDelete ); -} - -// Seeking a vehicle in the safe. - -CObject* CAutoSafe::SearchVehicle() -{ - CObject* pObj; - D3DVECTOR cPos, oPos; - ObjectType oType; - float dist; - int i; - - cPos = m_object->RetPosition(0); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - oType = pObj->RetType(); - if ( pObj == m_object ) continue; - if ( pObj->RetTruck() != 0 ) continue; - - oPos = pObj->RetPosition(0); - dist = Length2d(oPos, cPos); - if ( dist <= 4.0f ) return pObj; - } - return 0; -} - - - diff --git a/src/autosafe.h b/src/autosafe.h deleted file mode 100644 index b60472d..0000000 --- a/src/autosafe.h +++ /dev/null @@ -1,86 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autosafe.h - -#ifndef _AUTOSAFE_H_ -#define _AUTOSAFE_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoSafePhase -{ - ASAP_WAIT = 1, - ASAP_OPEN = 2, - ASAP_FINISH = 3, -}; - - - -class CAutoSafe : public CAuto -{ -public: - CAutoSafe(CInstanceManager* iMan, CObject* object); - ~CAutoSafe(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - - BOOL CreateInterface(BOOL bSelect); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - int CountKeys(); - void LockKeys(); - void DownKeys(float progress); - void DeleteKeys(); - CObject* SearchVehicle(); - -protected: - AutoSafePhase m_phase; - float m_progress; - float m_speed; - float m_timeVirus; - float m_lastParticule; - int m_channelSound; - BOOL m_bLock; - int m_countKeys; - float m_actualAngle; - float m_finalAngle; - BOOL m_bKey[4]; - D3DVECTOR m_keyPos[4]; - int m_keyParti[4]; -}; - - -#endif //_AUTOSAFE_H_ diff --git a/src/autostation.cpp b/src/autostation.cpp deleted file mode 100644 index 1e23e1d..0000000 --- a/src/autostation.cpp +++ /dev/null @@ -1,387 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "light.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "interface.h" -#include "button.h" -#include "gauge.h" -#include "window.h" -#include "sound.h" -#include "auto.h" -#include "autostation.h" - - - - -// Object's constructor. - -CAutoStation::CAutoStation(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - CAuto::CAuto(iMan, object); - - Init(); -} - -// Object's destructor. - -CAutoStation::~CAutoStation() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoStation::DeleteObject(BOOL bAll) -{ - if ( m_soundChannel != -1 ) - { - m_sound->Stop(m_soundChannel); - m_soundChannel = -1; - } - - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoStation::Init() -{ - m_time = 0.0f; - m_timeVirus = 0.0f; - m_lastUpdateTime = 0.0f; - m_lastParticule = 0.0f; - m_soundChannel = -1; - m_bLastVirus = FALSE; - - CAuto::Init(); -} - - -// Management of an event. - -BOOL CAutoStation::EventProcess(const Event &event) -{ - D3DMATRIX* mat; - D3DVECTOR pos, ppos, speed; - FPOINT dim; - CObject* vehicule; - CObject* power; - TerrainRes res; - float big, energy, used, add, freq; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_timeVirus -= event.rTime; - - if ( m_object->RetVirusMode() ) // contaminated by a virus? - { - if ( !m_bLastVirus ) - { - m_bLastVirus = TRUE; - m_energyVirus = m_object->RetEnergy(); - } - - if ( m_timeVirus <= 0.0f ) - { - m_timeVirus = 0.1f+Rand()*0.3f; - - m_object->SetEnergy(Rand()); - } - return TRUE; - } - else - { - if ( m_bLastVirus ) - { - m_bLastVirus = FALSE; - m_object->SetEnergy(m_energyVirus); - } - } - - UpdateInterface(event.rTime); - - big = m_object->RetEnergy(); - - res = m_terrain->RetResource(m_object->RetPosition(0)); - if ( res == TR_POWER ) - { - big += event.rTime*0.01f; // recharges the large battery - } - - used = big; - freq = 1.0f; - if ( big > 0.0f ) - { - vehicule = SearchVehicle(); - if ( vehicule != 0 ) - { - power = vehicule->RetPower(); - if ( power != 0 && power->RetCapacity() == 1.0f ) - { - energy = power->RetEnergy(); - add = event.rTime*0.2f; - if ( add > big*4.0f ) add = big*4.0f; - if ( add > 1.0f-energy ) add = 1.0f-energy; - energy += add; // Charging the battery - power->SetEnergy(energy); - if ( energy < freq ) freq = energy; - big -= add/4.0f; // discharge the large battery - } - - power = vehicule->RetFret(); - if ( power != 0 && power->RetType() == OBJECT_POWER ) - { - energy = power->RetEnergy(); - add = event.rTime*0.2f; - if ( add > big*4.0f ) add = big*4.0f; - if ( add > 1.0f-energy ) add = 1.0f-energy; - energy += add; // Charging the battery - power->SetEnergy(energy); - if ( energy < freq ) freq = energy; - big -= add/4.0f; // discharge the large battery - } - } - } - used -= big; // energy used - - if ( freq < 1.0f ) // charging in progress? - { - freq = 1.0f+3.0f*freq; - if ( m_soundChannel == -1 ) - { - m_soundChannel = m_sound->Play(SOUND_STATION, m_object->RetPosition(0), - 0.3f, freq, TRUE); - } - m_sound->Frequency(m_soundChannel, freq); - } - else - { - if ( m_soundChannel != -1 ) - { - m_sound->Stop(m_soundChannel); - m_soundChannel = -1; - } - } - - if ( used != 0.0f && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - mat = m_object->RetWorldMatrix(0); - pos = D3DVECTOR(-15.0f, 7.0f, 0.0f); // battery position - pos = Transform(*mat, pos); - speed.x = (Rand()-0.5f)*20.0f; - speed.y = (Rand()-0.5f)*20.0f; - speed.z = (Rand()-0.5f)*20.0f; - ppos.x = pos.x; - ppos.y = pos.y+(Rand()-0.5f)*4.0f; - ppos.z = pos.z; - dim.x = 1.5f; - dim.y = 1.5f; - m_particule->CreateParticule(ppos, speed, dim, PARTIBLITZ, 1.0f, 0.0f, 0.0f); - -#if 0 - ppos = pos; - ppos.y += 1.0f; - ppos.x += (Rand()-0.5f)*3.0f; - ppos.z += (Rand()-0.5f)*3.0f; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 2.5f+Rand()*6.0f; - dim.x = Rand()*1.5f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(ppos, speed, dim, PARTISMOKE3, 4.0f); -#else - ppos = pos; - ppos.y += 1.0f; - ppos.x += (Rand()-0.5f)*3.0f; - ppos.z += (Rand()-0.5f)*3.0f; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 2.5f+Rand()*5.0f; - dim.x = Rand()*1.0f+0.6f; - dim.y = dim.x; - m_particule->CreateParticule(ppos, speed, dim, PARTIVAPOR, 3.0f); -#endif - } - - if ( big < 0.0f ) big = 0.0f; - if ( big > 1.0f ) big = 1.0f; - m_object->SetEnergy(big); // Shift the large battery - - return TRUE; -} - - -// Seeking the vehicle on the station. - -CObject* CAutoStation::SearchVehicle() -{ - CObject* pObj; - D3DVECTOR sPos, oPos; - ObjectType type; - float dist; - int i; - - sPos = m_object->RetPosition(0); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type != OBJECT_HUMAN && - type != OBJECT_MOBILEfa && - type != OBJECT_MOBILEta && - type != OBJECT_MOBILEwa && - type != OBJECT_MOBILEia && - type != OBJECT_MOBILEfc && - type != OBJECT_MOBILEtc && - type != OBJECT_MOBILEwc && - type != OBJECT_MOBILEic && - type != OBJECT_MOBILEfi && - type != OBJECT_MOBILEti && - type != OBJECT_MOBILEwi && - type != OBJECT_MOBILEii && - type != OBJECT_MOBILEfs && - type != OBJECT_MOBILEts && - type != OBJECT_MOBILEws && - type != OBJECT_MOBILEis && - type != OBJECT_MOBILErt && - type != OBJECT_MOBILErc && - type != OBJECT_MOBILErr && - type != OBJECT_MOBILErs && - type != OBJECT_MOBILEsa && - type != OBJECT_MOBILEft && - type != OBJECT_MOBILEtt && - type != OBJECT_MOBILEwt && - type != OBJECT_MOBILEit && - type != OBJECT_MOBILEdr ) continue; - - oPos = pObj->RetPosition(0); - dist = Length(oPos, sPos); - if ( dist <= 5.0f ) return pObj; - } - - return 0; -} - - -// Returns an error due the state of the automation. - -Error CAutoStation::RetError() -{ - TerrainRes res; - - if ( m_object->RetVirusMode() ) - { - return ERR_BAT_VIRUS; - } - - res = m_terrain->RetResource(m_object->RetPosition(0)); - if ( res != TR_POWER ) return ERR_STATION_NULL; - - return ERR_OK; -} - - -// Crée toute l'interface lorsque l'objet est sélectionné . - -BOOL CAutoStation::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*14.5f; - pos.y = oy+sy*0; - ddim.x = 14.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 104, EVENT_OBJECT_TYPE); - - return TRUE; -} - -// Updates the state of all buttons on the interface, -// following the time that elapses ... - -void CAutoStation::UpdateInterface(float rTime) -{ - CWindow* pw; - CGauge* pg; - - CAuto::UpdateInterface(rTime); - - if ( m_time < m_lastUpdateTime+0.1f ) return; - m_lastUpdateTime = m_time; - - if ( !m_object->RetSelect() ) return; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; - - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); - if ( pg != 0 ) - { - pg->SetLevel(m_object->RetEnergy()); - } -} - - diff --git a/src/autostation.h b/src/autostation.h deleted file mode 100644 index d783cc9..0000000 --- a/src/autostation.h +++ /dev/null @@ -1,68 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autostation.h - -#ifndef _AUTOSTATION_H_ -#define _AUTOSTATION_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -class CAutoStation : public CAuto -{ -public: - CAutoStation(CInstanceManager* iMan, CObject* object); - ~CAutoStation(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - - BOOL CreateInterface(BOOL bSelect); - -protected: - void UpdateInterface(float rTime); - - CObject* SearchVehicle(); - -protected: - float m_progress; - float m_speed; - float m_timeVirus; - float m_lastUpdateTime; - float m_lastParticule; - int m_soundChannel; - D3DVECTOR m_fretPos; - BOOL m_bLastVirus; - float m_energyVirus; -}; - - -#endif //_AUTOSTATION_H_ diff --git a/src/autotower.cpp b/src/autotower.cpp deleted file mode 100644 index 7dcdb05..0000000 --- a/src/autotower.cpp +++ /dev/null @@ -1,561 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "global.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "terrain.h" -#include "camera.h" -#include "object.h" -#include "physics.h" -#include "interface.h" -#include "button.h" -#include "gauge.h" -#include "window.h" -#include "sound.h" -#include "displaytext.h" -#include "cmdtoken.h" -#include "auto.h" -#include "autotower.h" - - - -#define TOWER_SCOPE 200.0f // range of beam -#define ENERGY_FIRE 0.125f // energy consumed by fire - - -// Object's constructor. - -CAutoTower::CAutoTower(CInstanceManager* iMan, CObject* object) - : CAuto(iMan, object) -{ - int i; - - CAuto::CAuto(iMan, object); - - for ( i=0 ; i<4 ; i++ ) - { - m_partiStop[i] = -1; - } - - Init(); - m_phase = ATP_WAIT; // paused until the first Init () - m_time = 0.0f; - m_lastUpdateTime = 0.0f; -} - -// Object's destructor. - -CAutoTower::~CAutoTower() -{ - this->CAuto::~CAuto(); -} - - -// Destroys the object. - -void CAutoTower::DeleteObject(BOOL bAll) -{ - FireStopUpdate(0.0f, FALSE); - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoTower::Init() -{ - m_phase = ATP_ZERO; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - - m_time = 0.0f; - m_timeVirus = 0.0f; - m_lastUpdateTime = 0.0f; - m_lastParticule = 0.0f; -} - - -// Management of an event. - -BOOL CAutoTower::EventProcess(const Event &event) -{ - CObject* power; - CObject* target; - D3DVECTOR pos; - float angle, energy, quick; - - CAuto::EventProcess(event); - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_timeVirus -= event.rTime; - - if ( m_object->RetVirusMode() ) // contaminated by a virus? - { - if ( m_timeVirus <= 0.0f ) - { - m_timeVirus = 0.1f+Rand()*0.3f; - - angle = m_object->RetAngleY(1); - angle += Rand()*0.5f; - m_object->SetAngleY(1, angle); - - m_object->SetAngleZ(2, Rand()*0.5f); - } - return TRUE; - } - - UpdateInterface(event.rTime); - - if ( m_phase == ATP_WAIT ) return TRUE; - - m_progress += event.rTime*m_speed; - - if ( m_phase == ATP_ZERO ) - { - FireStopUpdate(m_progress, TRUE); // blinks - if ( m_progress < 1.0f ) - { - energy = 0.0f; - power = m_object->RetPower(); - if ( power != 0 ) - { - energy = power->RetEnergy(); - } - if ( energy >= ENERGY_FIRE ) - { - m_phase = ATP_SEARCH; - m_progress = 0.0f; - m_speed = 1.0f/3.0f; - } - } - else - { - m_phase = ATP_ZERO; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - if ( m_phase == ATP_SEARCH ) - { - FireStopUpdate(m_progress, FALSE); // extinguished - if ( m_progress < 1.0f ) - { - quick = 1.0f; -//? if ( g_researchDone & RESEARCH_QUICK ) quick = 3.0f; - - angle = m_object->RetAngleY(1); - angle -= event.rTime*quick*2.0f; - m_object->SetAngleY(1, angle); - - angle = m_object->RetAngleZ(2); - angle += event.rTime*quick*0.5f; - if ( angle > 0.0f ) angle = 0.0f; - m_object->SetAngleZ(2, angle); - } - else - { - energy = 0.0f; - power = m_object->RetPower(); - if ( power != 0 ) - { - energy = power->RetEnergy(); - } - - target = SearchTarget(m_targetPos); - if ( energy < ENERGY_FIRE ) - { - m_displayText->DisplayError(ERR_TOWER_ENERGY, m_object); - } - if ( target == 0 || energy < ENERGY_FIRE ) - { - m_phase = ATP_ZERO; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - else - { - pos = m_object->RetPosition(0); - pos.y += 24.5f; - m_angleYfinal = RotateAngle(m_targetPos.x-pos.x, pos.z-m_targetPos.z); // CW ! - m_angleYfinal += PI*2.0f; - m_angleYfinal -= m_object->RetAngleY(0); - m_angleYactual = NormAngle(m_object->RetAngleY(1)); - - m_angleZfinal = -PI/2.0f; - m_angleZfinal -= RotateAngle(Length2d(m_targetPos, pos), pos.y-m_targetPos.y); // CW ! - m_angleZactual = m_object->RetAngleZ(2); - - m_phase = ATP_TURN; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; -//? if ( g_researchDone & RESEARCH_QUICK ) m_speed = 1.0f/0.2f; - } - } - } - - if ( m_phase == ATP_TURN ) - { - if ( m_progress < 1.0f ) - { - angle = m_angleYactual+(m_angleYfinal-m_angleYactual)*m_progress; - m_object->SetAngleY(1, angle); - - angle = m_angleZactual+(m_angleZfinal-m_angleZactual)*m_progress; - m_object->SetAngleZ(2, angle); - } - else - { - m_object->SetAngleY(1, m_angleYfinal); - m_object->SetAngleZ(2, m_angleZfinal); - - power = m_object->RetPower(); - if ( power != 0 ) - { - energy = power->RetEnergy(); - energy -= ENERGY_FIRE/power->RetCapacity(); - power->SetEnergy(energy); - } - - m_sound->Play(SOUND_GGG, m_object->RetPosition(0)); - - m_phase = ATP_FIRE; - m_progress = 0.0f; - m_speed = 1.0f/1.5f; - } - } - - if ( m_phase == ATP_FIRE ) - { - if ( m_progress == 0.0f ) - { - pos = m_object->RetPosition(0); - pos.y += 24.5f; - m_particule->CreateRay(pos, m_targetPos, PARTIRAY1, - FPOINT(5.0f, 5.0f), 1.5f); - } - if ( m_progress >= 1.0f ) - { - m_phase = ATP_ZERO; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - - return TRUE; -} - - -// Seeks the nearest target object. - -CObject* CAutoTower::SearchTarget(D3DVECTOR &impact) -{ - CObject* pObj; - CObject* pBest = 0; - CPhysics* physics; - D3DVECTOR iPos, oPos; - ObjectType oType; - float distance, min, radius, speed; - int i; - - iPos = m_object->RetPosition(0); - min = 1000000.0f; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - oType = pObj->RetType(); - if ( oType != OBJECT_MOTHER && - oType != OBJECT_ANT && - oType != OBJECT_SPIDER && - oType != OBJECT_BEE && - oType != OBJECT_WORM ) continue; - - if ( !pObj->RetActif() ) continue; // inactive? - -//? if ( g_researchDone & RESEARCH_QUICK ) - if ( FALSE ) - { - physics = pObj->RetPhysics(); - if ( physics != 0 ) - { - speed = Abs(physics->RetLinMotionX(MO_REASPEED)); - if ( speed > 20.0f ) continue; // moving too fast? - } - } - - if ( !pObj->GetCrashSphere(0, oPos, radius) ) continue; - distance = Length(oPos, iPos); - if ( distance > TOWER_SCOPE ) continue; // too far - if ( distance < min ) - { - min = distance; - pBest = pObj; - } - } - if ( pBest == 0 ) return 0; - - impact = pBest->RetPosition(0); - return pBest; -} - - -// Returns an error due the state of the automation. - -Error CAutoTower::RetError() -{ - CObject* power; - - if ( m_object->RetVirusMode() ) - { - return ERR_BAT_VIRUS; - } - - power = m_object->RetPower(); - if ( power == 0 ) - { - return ERR_TOWER_POWER; // no battery - } - else - { - if ( power->RetEnergy() < ENERGY_FIRE ) - { - return ERR_TOWER_ENERGY; // not enough energy - } - } - return ERR_OK; -} - - -// Updates the stop lights. - -void CAutoTower::FireStopUpdate(float progress, BOOL bLightOn) -{ - D3DMATRIX* mat; - D3DVECTOR pos, speed; - FPOINT dim; - int i; - - static float listpos[8] = - { - 4.5f, 0.0f, - 0.0f, 4.5f, - -4.5f, 0.0f, - 0.0f, -4.5f, - }; - - if ( !bLightOn ) // extinguished? - { - for ( i=0 ; i<4 ; i++ ) - { - if ( m_partiStop[i] != -1 ) - { - m_particule->DeleteParticule(m_partiStop[i]); - m_partiStop[i] = -1; - } - } - return; - } - - mat = m_object->RetWorldMatrix(0); - - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 2.0f; - dim.y = dim.x; - - for ( i=0 ; i<4 ; i++ ) - { - if ( Mod(progress+i*0.125f, 0.5f) < 0.2f ) - { - if ( m_partiStop[i] != -1 ) - { - m_particule->DeleteParticule(m_partiStop[i]); - m_partiStop[i] = -1; - } - } - else - { - if ( m_partiStop[i] == -1 ) - { - pos.x = listpos[i*2+0]; - pos.y = 18.0f; - pos.z = listpos[i*2+1]; - pos = Transform(*mat, pos); - m_partiStop[i] = m_particule->CreateParticule(pos, speed, - dim, PARTISELR, - 1.0f, 0.0f, 0.0f); - } - } - } -} - - -// Creates all the interface when the object is selected. - -BOOL CAutoTower::CreateInterface(BOOL bSelect) -{ - CWindow* pw; - FPOINT pos, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*14.5f; - pos.y = oy+sy*0; - ddim.x = 14.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 107, EVENT_OBJECT_TYPE); - - pos.x = ox+sx*10.2f; - pos.y = oy+sy*0.5f; - ddim.x = 33.0f/640.0f; - ddim.y = 33.0f/480.0f; - pw->CreateButton(pos, ddim, 41, EVENT_OBJECT_LIMIT); - - return TRUE; -} - -// Updates the state of all buttons on the interface, -// following the time that elapses ... - -void CAutoTower::UpdateInterface(float rTime) -{ - CWindow* pw; - CGauge* pg; - CObject* power; - float energy; - - CAuto::UpdateInterface(rTime); - - if ( m_time < m_lastUpdateTime+0.1f ) return; - m_lastUpdateTime = m_time; - - if ( !m_object->RetSelect() ) return; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; - - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); - if ( pg != 0 ) - { - energy = 0.0f; - power = m_object->RetPower(); - if ( power != 0 ) - { - energy = power->RetEnergy(); - } - pg->SetLevel(energy); - } -} - - -// Saves all parameters of the controller. - -BOOL CAutoTower::Write(char *line) -{ - char name[100]; - - if ( m_phase == ATP_WAIT ) return FALSE; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - - CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - sprintf(name, " aTargetPos=%.2f;%.2f;%.2f", m_targetPos.x, m_targetPos.y, m_targetPos.z); - strcat(line, name); - - sprintf(name, " aAngleYactual=%.2f", m_angleYactual); - strcat(line, name); - - sprintf(name, " aAngleZactual=%.2f", m_angleZactual); - strcat(line, name); - - sprintf(name, " aAngleYfinal=%.2f", m_angleYfinal); - strcat(line, name); - - sprintf(name, " aAngleZfinal=%.2f", m_angleZfinal); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the controller. - -BOOL CAutoTower::Read(char *line) -{ - if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; - - CAuto::Read(line); - - m_phase = (AutoTowerPhase)OpInt(line, "aPhase", ATP_WAIT); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - m_targetPos = OpDir(line, "aTargetPos"); - m_angleYactual = OpFloat(line, "aAngleYactual", 0.0f); - m_angleZactual = OpFloat(line, "aAngleZactual", 0.0f); - m_angleYfinal = OpFloat(line, "aAngleYfinal", 0.0f); - m_angleZfinal = OpFloat(line, "aAngleZfinal", 0.0f); - - m_lastUpdateTime = 0.0f; - - return TRUE; -} - - diff --git a/src/autotower.h b/src/autotower.h deleted file mode 100644 index fa7e6cb..0000000 --- a/src/autotower.h +++ /dev/null @@ -1,86 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// autotower.h - -#ifndef _AUTOTOWER_H_ -#define _AUTOTOWER_H_ - - -#include "auto.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CParticule; -class CTerrain; -class CCamera; -class CObject; - - - -enum AutoTowerPhase -{ - ATP_WAIT = 1, - ATP_ZERO = 2, // more energy - ATP_SEARCH = 3, // search a target - ATP_TURN = 4, // turns to the target - ATP_FIRE = 5, // shoots on the target -}; - - - -class CAutoTower : public CAuto -{ -public: - CAutoTower(CInstanceManager* iMan, CObject* object); - ~CAutoTower(); - - void DeleteObject(BOOL bAll=FALSE); - - void Init(); - BOOL EventProcess(const Event &event); - Error RetError(); - - BOOL CreateInterface(BOOL bSelect); - - BOOL Write(char *line); - BOOL Read(char *line); - -protected: - void UpdateInterface(float rTime); - - CObject* SearchTarget(D3DVECTOR &impact); - void FireStopUpdate(float progress, BOOL bLightOn); - -protected: - AutoTowerPhase m_phase; - float m_progress; - float m_speed; - float m_timeVirus; - float m_lastUpdateTime; - float m_lastParticule; - D3DVECTOR m_targetPos; - float m_angleYactual; - float m_angleZactual; - float m_angleYfinal; - float m_angleZfinal; - int m_partiStop[4]; -}; - - -#endif //_AUTOTOWER_H_ diff --git a/src/blitz.cpp b/src/blitz.cpp deleted file mode 100644 index cf88fe3..0000000 --- a/src/blitz.cpp +++ /dev/null @@ -1,471 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "d3dutil.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "terrain.h" -#include "math3d.h" -#include "object.h" -#include "camera.h" -#include "auto.h" -#include "autopara.h" -#include "sound.h" -#include "blitz.h" - - - - -// Constructor of the terrain. - -CBlitz::CBlitz(CInstanceManager* iMan, CD3DEngine* engine) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_BLITZ, this); - - m_engine = engine; - m_terrain = 0; - m_camera = 0; - m_sound = 0; - Flush(); -} - -// Destructor of the terrain. - -CBlitz::~CBlitz() -{ -} - - -// Removes lightning. - -void CBlitz::Flush() -{ - int i; - - m_bBlitzExist = FALSE; - m_time = 0.0f; - m_phase = BPH_WAIT; - m_speed = 0.0f; - m_progress = 0.0f; - - for ( i=0 ; iRetPause() ) return TRUE; - if ( m_engine->RetMovieLock() ) return TRUE; - - m_time += event.rTime; - m_progress += event.rTime*m_speed; - - if ( m_phase == BPH_WAIT ) - { - if ( m_progress >= 1.0f ) - { -#if 1 - m_pos.x = (Rand()-0.5f)*(3200.0f-200.0f); - m_pos.z = (Rand()-0.5f)*(3200.0f-200.0f); -#else - m_pos.x = (Rand()-0.5f)*(3200.0f-2800.0f); - m_pos.z = (Rand()-0.5f)*(3200.0f-2800.0f); -#endif - m_pos.y = 0.0f; - - pObj = SearchObject(m_pos); - if ( pObj == 0 ) - { - m_terrain->MoveOnFloor(m_pos, TRUE); - } - else - { - m_pos = pObj->RetPosition(0); - m_terrain->MoveOnFloor(m_pos, TRUE); - - type = pObj->RetType(); - if ( type == OBJECT_BASE ) - { - m_pos.y += 120.0f; // top of the rocket - } - else if ( type == OBJECT_PARA ) - { - automat = (CAutoPara*)pObj->RetAuto(); - if ( automat != 0 ) - { - automat->StartBlitz(); - } - m_pos.y += 67.0f; // top of lightning rod - } - else - { - pObj->ExploObject(EXPLO_BOUM, 1.0f); - } - } - - eye = m_engine->RetEyePt(); - dist = Length(m_pos, eye); - deep = m_engine->RetDeepView(); - - if ( dist < deep ) - { - pos = eye+((m_pos-eye)*0.2f); // like so close! - m_sound->Play(SOUND_BLITZ, pos); - - m_camera->StartOver(OE_BLITZ, m_pos, 1.0f); - - m_phase = BPH_BLITZ; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - } - } - } - - if ( m_phase == BPH_BLITZ ) - { - if ( m_progress < 1.0f ) - { - max = 5.0f; - for ( i=0 ; i max ) m_shift[i].x = max; - - m_shift[i].y += (Rand()-0.5f)*max*2.0f; - if ( m_shift[i].y < -max ) m_shift[i].y = -max; - if ( m_shift[i].y > max ) m_shift[i].y = max; - - m_width[i] += (Rand()-0.5f)*2.0f; - if ( m_width[i] < 1.0f ) m_width[i] = 1.0f; - if ( m_width[i] > 6.0f ) m_width[i] = 6.0f; - } - m_shift[0].x = 0.0f; - m_shift[0].y = 0.0f; - m_width[0] = 0.0f; - } - else - { - m_phase = BPH_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/(1.0f+Rand()*m_delay); - } - } - - return TRUE; -} - - -// Draw lightning. - -void CBlitz::Draw() -{ - LPDIRECT3DDEVICE7 device; - D3DVERTEX2 vertex[4]; // 2 triangles - D3DVECTOR corner[4], eye, n, p, p1, p2; - D3DMATRIX matrix; - FPOINT texInf, texSup, rot; - float a; - int i; - - if ( !m_bBlitzExist ) return; - if ( m_phase != BPH_BLITZ ) return; - - device = m_engine->RetD3DDevice(); - device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - - D3DUtil_SetIdentityMatrix(matrix); - device->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); - - m_engine->SetTexture("effect00.tga"); - m_engine->SetState(D3DSTATETTb); - texInf.x = 64.5f/256.0f; - texInf.y = 33.0f/256.0f; - texSup.x = 95.5f/256.0f; - texSup.y = 34.0f/256.0f; // blank - - p1 = m_pos; - eye = m_engine->RetEyePt(); - a = RotateAngle(eye.x-p1.x, eye.z-p1.z); - n = Normalize(p1-eye); - - for ( i=0 ; iDrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); - - p1 = p2; - } - - device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE); -} - - -// Triggers lightning. - -BOOL CBlitz::Create(float sleep, float delay, float magnetic) -{ - m_bBlitzExist = TRUE; - if ( sleep < 1.0f ) sleep = 1.0f; - m_sleep = sleep; - m_delay = delay; - m_magnetic = magnetic; - - m_phase = BPH_WAIT; - m_progress = 0.0f; - m_speed = 1.0f/m_sleep; - - if ( m_terrain == 0 ) - { - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - } - - if ( m_camera == 0 ) - { - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - } - - if ( m_sound == 0 ) - { - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - } - - return FALSE; -} - - -// Gives the status of lightning. - -BOOL CBlitz::GetStatus(float &sleep, float &delay, float &magnetic, float &progress) -{ - if ( !m_bBlitzExist ) return FALSE; - - sleep = m_sleep; - delay = m_delay; - magnetic = m_magnetic; - progress = m_progress; - - return TRUE; -} - -// Specifies the status of lightning. - -BOOL CBlitz::SetStatus(float sleep, float delay, float magnetic, float progress) -{ - m_bBlitzExist = TRUE; - - m_sleep = sleep; - m_delay = delay; - m_magnetic = magnetic; - m_progress = progress; - m_phase = BPH_WAIT; - m_speed = 1.0f/m_sleep; - - return TRUE; -} - - -// Seeking the object closest to the lightning. - -CObject* CBlitz::SearchObject(D3DVECTOR pos) -{ - CObject *pObj, *pBest, *pObjPara[100]; - D3DVECTOR oPos, pPos[100]; - ObjectType type; - float min, dist, detect; - int i, nbPara; - - // Seeking the object closest to the point of impact of lightning. - pBest = 0; - min = 100000.0f; - nbPara = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetActif() ) continue; // inactive object? - if ( pObj->RetTruck() != 0 ) continue; // object transported? - - type = pObj->RetType(); - if ( type == OBJECT_BASE || - type == OBJECT_PARA ) // building a lightning effect? - { - pObjPara[nbPara] = pObj; - pPos[nbPara] = pObj->RetPosition(0); - nbPara ++; - } - - detect = 0.0f; - if ( type == OBJECT_BASE || - type == OBJECT_DERRICK || - type == OBJECT_FACTORY || - type == OBJECT_REPAIR || - type == OBJECT_DESTROYER|| - type == OBJECT_STATION || - type == OBJECT_CONVERT || - type == OBJECT_TOWER || - type == OBJECT_RESEARCH || - type == OBJECT_RADAR || - type == OBJECT_INFO || - type == OBJECT_ENERGY || - type == OBJECT_LABO || - type == OBJECT_NUCLEAR || - type == OBJECT_PARA || - type == OBJECT_SAFE || - type == OBJECT_HUSTON ) - { - detect = m_magnetic; - } - if ( type == OBJECT_METAL || - type == OBJECT_POWER || - type == OBJECT_ATOMIC ) - { - detect = m_magnetic*0.3f; - } - if ( type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs || - type == OBJECT_MOBILEsa || - type == OBJECT_MOBILEft || - type == OBJECT_MOBILEtt || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEit || - type == OBJECT_MOBILEdr ) - { - detect = m_magnetic*0.5f; - } - if ( detect == 0.0f ) continue; - - oPos = pObj->RetPosition(0); - dist = Length2d(oPos, pos); - if ( dist > detect ) continue; - if ( dist < min ) - { - min = dist; - pBest = pObj; - } - } - if ( pBest == 0 ) return 0; // nothing found - - // Under the protection of a lightning conductor? - oPos = pBest->RetPosition(0); - for ( i=nbPara-1 ; i>=0 ; i-- ) - { - dist = Length2d(oPos, pPos[i]); - if ( dist <= BLITZPARA ) - { - return pObjPara[i]; - } - } - return pBest; -} - diff --git a/src/blitz.h b/src/blitz.h deleted file mode 100644 index 30a34ed..0000000 --- a/src/blitz.h +++ /dev/null @@ -1,84 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// blitz.h - -#ifndef _BLITZ_H_ -#define _BLITZ_H_ - - -#include "misc.h" -#include "struct.h" - - -class CInstanceManager; -class CD3DEngine; -class CTerrain; -class CCamera; -class CSound; - - - -#define BLITZPARA 200.0f // radius of lightning protection -#define BLITZMAX 50 - -enum BlitzPhase -{ - BPH_WAIT, - BPH_BLITZ, -}; - - - -class CBlitz -{ -public: - CBlitz(CInstanceManager* iMan, CD3DEngine* engine); - ~CBlitz(); - - void Flush(); - BOOL EventProcess(const Event &event); - BOOL Create(float sleep, float delay, float magnetic); - BOOL GetStatus(float &sleep, float &delay, float &magnetic, float &progress); - BOOL SetStatus(float sleep, float delay, float magnetic, float progress); - void Draw(); - -protected: - BOOL EventFrame(const Event &event); - CObject* SearchObject(D3DVECTOR pos); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CTerrain* m_terrain; - CCamera* m_camera; - CSound* m_sound; - - BOOL m_bBlitzExist; - float m_sleep; - float m_delay; - float m_magnetic; - BlitzPhase m_phase; - float m_time; - float m_speed; - float m_progress; - D3DVECTOR m_pos; - FPOINT m_shift[BLITZMAX]; - float m_width[BLITZMAX]; -}; - - -#endif //_BLITZ_H_ diff --git a/src/brain.cpp b/src/brain.cpp deleted file mode 100644 index e942e5d..0000000 --- a/src/brain.cpp +++ /dev/null @@ -1,3000 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "CBot/CBotDll.h" -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "language.h" -#include "global.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "restext.h" -#include "math3d.h" -#include "robotmain.h" -#include "terrain.h" -#include "water.h" -#include "camera.h" -#include "object.h" -#include "physics.h" -#include "motion.h" -#include "motionspider.h" -#include "pyro.h" -#include "taskmanager.h" -#include "task.h" -#include "taskmanip.h" -#include "taskflag.h" -#include "taskshield.h" -#include "script.h" -#include "studio.h" -#include "interface.h" -#include "button.h" -#include "color.h" -#include "edit.h" -#include "list.h" -#include "label.h" -#include "group.h" -#include "gauge.h" -#include "slider.h" -#include "compass.h" -#include "target.h" -#include "window.h" -#include "displaytext.h" -#include "text.h" -#include "sound.h" -#include "particule.h" -#include "cmdtoken.h" -#include "brain.h" - - - -#define MAXTRACERECORD 1000 - - - -// Object's constructor. - -CBrain::CBrain(CInstanceManager* iMan, CObject* object) -{ - int i; - - m_iMan = iMan; - m_iMan->AddInstance(CLASS_BRAIN, this, 100); - - m_object = object; - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - m_physics = 0; - m_motion = 0; - m_primaryTask = 0; - m_secondaryTask = 0; - m_studio = 0; - - m_program = -1; - m_bActivity = TRUE; - m_bBurn = FALSE; - m_bActiveVirus = FALSE; - m_time = 0.0f; - m_burnTime = 0.0f; - m_lastUpdateTime = 0.0f; - m_lastHumanTime = 0.0f; - m_lastWormTime = 0.0f; - m_antTarget = 0; - m_beeBullet = 0; - m_lastAlarmTime = 0.0f; - m_soundChannelAlarm = -1; - m_flagColor = 0; - - m_buttonAxe = EVENT_NULL; - m_defaultEnter = EVENT_NULL; - m_manipStyle = EVENT_OBJECT_MFRONT; - - for ( i=0 ; iDeleteInstance(CLASS_BRAIN, this); -} - - -// Destroys the object. - -void CBrain::DeleteObject(BOOL bAll) -{ - if ( m_soundChannelAlarm != -1 ) - { - m_sound->FlushEnvelope(m_soundChannelAlarm); - m_sound->AddEnvelope(m_soundChannelAlarm, 0.0f, 0.5f, 0.5f, SOPER_STOP); - m_soundChannelAlarm = -1; - } - - if ( !bAll ) - { - if ( m_beeBullet != 0 ) - { - m_beeBullet->DeleteObject(); - delete m_beeBullet; - m_beeBullet = 0; - } - } - - if ( m_studio != 0 ) // current edition? - { - StopEditScript(TRUE); - } -} - - -void CBrain::SetPhysics(CPhysics* physics) -{ - m_physics = physics; -} - -void CBrain::SetMotion(CMotion* motion) -{ - m_motion = motion; -} - - -// Saves all parameters of the object. - -BOOL CBrain::Write(char *line) -{ - char name[100]; - - sprintf(name, " bVirusActive=%d", m_bActiveVirus); - strcat(line, name); - - return TRUE; -} - -// Restores all parameters of the object. - -BOOL CBrain::Read(char *line) -{ - m_bActiveVirus = OpInt(line, "bVirusActive", 0); - - return TRUE; -} - - -// Management of an event. - -BOOL CBrain::EventProcess(const Event &event) -{ - CWindow* pw; - CControl* pc; - CSlider* ps; - EventMsg action; - ObjectType type; - Error err; - float axeX, axeY, axeZ, factor; - - type = m_object->RetType(); - - if ( m_primaryTask != 0 ) // current task? - { - m_primaryTask->EventProcess(event); - } - - if ( m_secondaryTask != 0 ) // current task? - { - m_secondaryTask->EventProcess(event); - } - - action = EVENT_NULL; - - if ( event.event == EVENT_KEYDOWN && - (event.param == m_engine->RetKey(KEYRANK_ACTION, 0) || - event.param == m_engine->RetKey(KEYRANK_ACTION, 1) ) && - !m_main->RetEditLock() ) - { - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw != 0 ) - { - pc = pw->SearchControl(m_defaultEnter); - if ( pc != 0 ) - { - if ( pc->TestState(STATE_ENABLE) ) - { - action = m_defaultEnter; - } - } - } - } - else - { - action = event.event; - } - - if ( action == EVENT_NULL ) return TRUE; - - if ( action == EVENT_UPDINTERFACE ) - { - if ( m_object->RetSelect() ) CreateInterface(TRUE); - } - - if ( action == EVENT_FRAME ) - { - EventFrame(event); - } - - if ( m_object->RetSelect() && // robot selected? - m_studio != 0 ) // current issue? - { - m_studio->EventProcess(event); - - if ( action == EVENT_OBJECT_PROGRUN ) - { - if ( m_program == -1 ) - { - RunProgram(m_selScript); - } - else - { - StopProgram(); - } - } - if ( action == EVENT_OBJECT_PROGSTART ) - { - m_main->SaveOneScript(m_object); - RunProgram(m_selScript); - } - if ( action == EVENT_OBJECT_PROGSTOP ) - { - StopProgram(); - } - if ( action == EVENT_STUDIO_OK ) - { - StopEditScript(FALSE); - m_main->SaveOneScript(m_object); - } - if ( action == EVENT_STUDIO_CANCEL ) - { - StopEditScript(TRUE); - m_main->SaveOneScript(m_object); - } - return TRUE; - } - - if ( !m_object->RetSelect() && // robot pas sélectionné ? - m_program == -1 && - m_primaryTask == 0 ) - { - axeX = 0.0f; - axeY = 0.0f; - axeZ = 0.0f; - if ( m_object->RetBurn() ) // Gifted? - { - if ( !m_bBurn ) // beginning? - { - m_bBurn = TRUE; - m_burnTime = 0.0f; - } - - axeZ = -1.0f; // tomb - - if ( !m_object->RetFixed() && - (type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_WORM ) ) - { - axeY = 2.0f; // zigzag disorganized fast - if ( type == OBJECT_WORM ) axeY = 5.0f; - axeX = 0.5f+sinf(m_time* 1.0f)*0.5f+ - sinf(m_time* 6.0f)*2.0f+ - sinf(m_time*21.0f)*0.2f; - factor = 1.0f-m_burnTime/15.0f; // slow motion - if ( factor < 0.0f ) factor = 0.0f; - axeY *= factor; - axeX *= factor; - } - } - m_physics->SetMotorSpeedX(axeY); // move forward/move back - m_physics->SetMotorSpeedY(axeZ); // up / down - m_physics->SetMotorSpeedZ(axeX); // rotate - return TRUE; - } - - if ( m_program != -1 && - m_object->RetRuin() ) - { - StopProgram(); - return TRUE; - } - - if ( !m_object->RetSelect() ) // robot not selected? - { - return TRUE; - } - - if ( m_secondaryTask != 0 ) // current task? - { - if ( action == EVENT_OBJECT_ENDSHIELD ) - { - m_secondaryTask->StartTaskShield(TSM_DOWN, 0.0f); - } - } - if ( m_primaryTask != 0 || // current task? - m_program != -1 ) - { - if ( action == EVENT_OBJECT_PROGRUN ) - { - StopProgram(); - } - if ( action == EVENT_OBJECT_PROGEDIT ) - { - StartEditScript(m_selScript, m_main->RetScriptName()); - } - if ( m_primaryTask == 0 || !m_primaryTask->IsPilot() ) return TRUE; - } - - if ( action == EVENT_OBJECT_LEFT || - action == EVENT_OBJECT_RIGHT || - action == EVENT_OBJECT_UP || - action == EVENT_OBJECT_DOWN || - action == EVENT_OBJECT_GASUP || - action == EVENT_OBJECT_GASDOWN ) - { - m_buttonAxe = action; - } - if ( action == EVENT_LBUTTONUP || - action == EVENT_RBUTTONUP ) - { - m_buttonAxe = EVENT_NULL; - } - - axeX = event.axeX; - axeY = event.axeY; - axeZ = event.axeZ; - - if ( !m_main->RetTrainerPilot() && - m_object->RetTrainer() ) // drive vehicle? - { - axeX = 0.0f; - axeY = 0.0f; - axeZ = 0.0f; // Remote control impossible! - } - - if ( m_buttonAxe == EVENT_OBJECT_LEFT ) axeX = -1.0f; - if ( m_buttonAxe == EVENT_OBJECT_RIGHT ) axeX = 1.0f; - if ( m_buttonAxe == EVENT_OBJECT_UP ) axeY = 1.0f; - if ( m_buttonAxe == EVENT_OBJECT_DOWN ) axeY = -1.0f; - if ( m_buttonAxe == EVENT_OBJECT_GASUP ) axeZ = 1.0f; - if ( m_buttonAxe == EVENT_OBJECT_GASDOWN ) axeZ = -1.0f; - - if ( m_object->RetManual() ) // scribbler in manual mode? - { - if ( axeX != 0.0f ) axeY = 0.0f; // if running -> not moving! - axeX *= 0.5f; - axeY *= 0.5f; - } - - if ( (g_researchDone&RESEARCH_FLY) == 0 ) - { - axeZ = -1.0f; // tomb - } - - axeX += m_camera->RetMotorTurn(); // additional power according to camera - if ( axeX > 1.0f ) axeX = 1.0f; - if ( axeX < -1.0f ) axeX = -1.0f; - - m_physics->SetMotorSpeedX(axeY); // move forward/move back - m_physics->SetMotorSpeedY(axeZ); // up/down - m_physics->SetMotorSpeedZ(axeX); // rotate - - if ( action == EVENT_OBJECT_PROGLIST ) - { - m_selScript = RetSelScript(); - UpdateInterface(); - } - - if ( action == EVENT_OBJECT_PROGEDIT ) - { - StartEditScript(m_selScript, m_main->RetScriptName()); - } - - if ( action == EVENT_OBJECT_PROGRUN ) - { - StopProgram(); // stops the current program - RunProgram(m_selScript); - UpdateInterface(); - } - - err = ERR_OK; - - if ( m_program == -1 ) - { - if ( action == EVENT_OBJECT_HTAKE ) - { - err = StartTaskTake(); - } - - if ( action == EVENT_OBJECT_MFRONT || - action == EVENT_OBJECT_MBACK || - action == EVENT_OBJECT_MPOWER ) - { - m_manipStyle = action; - UpdateInterface(); - } - - if ( action == EVENT_OBJECT_MTAKE ) - { - if ( m_manipStyle == EVENT_OBJECT_MFRONT ) - { - err = StartTaskManip(TMO_AUTO, TMA_FFRONT); - } - if ( m_manipStyle == EVENT_OBJECT_MBACK ) - { - err = StartTaskManip(TMO_AUTO, TMA_FBACK); - if ( err == ERR_OK ) - { - m_manipStyle = EVENT_OBJECT_MFRONT; - UpdateInterface(); - } - } - if ( m_manipStyle == EVENT_OBJECT_MPOWER ) - { - err = StartTaskManip(TMO_AUTO, TMA_POWER); - if ( err == ERR_OK ) - { - m_manipStyle = EVENT_OBJECT_MFRONT; - UpdateInterface(); - } - } - } - - if ( action == EVENT_OBJECT_BDERRICK ) - { - err = StartTaskBuild(OBJECT_DERRICK); - } - if ( action == EVENT_OBJECT_BSTATION ) - { - err = StartTaskBuild(OBJECT_STATION); - } - if ( action == EVENT_OBJECT_BFACTORY ) - { - err = StartTaskBuild(OBJECT_FACTORY); - } - if ( action == EVENT_OBJECT_BREPAIR ) - { - err = StartTaskBuild(OBJECT_REPAIR); - } - if ( action == EVENT_OBJECT_BCONVERT ) - { - err = StartTaskBuild(OBJECT_CONVERT); - } - if ( action == EVENT_OBJECT_BTOWER ) - { - err = StartTaskBuild(OBJECT_TOWER); - } - if ( action == EVENT_OBJECT_BRESEARCH ) - { - err = StartTaskBuild(OBJECT_RESEARCH); - } - if ( action == EVENT_OBJECT_BRADAR ) - { - err = StartTaskBuild(OBJECT_RADAR); - } - if ( action == EVENT_OBJECT_BENERGY ) - { - err = StartTaskBuild(OBJECT_ENERGY); - } - if ( action == EVENT_OBJECT_BLABO ) - { - err = StartTaskBuild(OBJECT_LABO); - } - if ( action == EVENT_OBJECT_BNUCLEAR ) - { - err = StartTaskBuild(OBJECT_NUCLEAR); - } - if ( action == EVENT_OBJECT_BPARA ) - { - err = StartTaskBuild(OBJECT_PARA); - } - if ( action == EVENT_OBJECT_BINFO ) - { - err = StartTaskBuild(OBJECT_INFO); - } - - if ( action == EVENT_OBJECT_GFLAT ) - { - GroundFlat(); - } - if ( action == EVENT_OBJECT_FCREATE ) - { - err = StartTaskFlag(TFL_CREATE, m_flagColor); - } - if ( action == EVENT_OBJECT_FDELETE ) - { - err = StartTaskFlag(TFL_DELETE, m_flagColor); - } - if ( action == EVENT_OBJECT_FCOLORb || - action == EVENT_OBJECT_FCOLORr || - action == EVENT_OBJECT_FCOLORg || - action == EVENT_OBJECT_FCOLORy || - action == EVENT_OBJECT_FCOLORv ) - { - ColorFlag(action-EVENT_OBJECT_FCOLORb); - } - - if ( action == EVENT_OBJECT_SEARCH ) - { - err = StartTaskSearch(); - } - - if ( action == EVENT_OBJECT_TERRAFORM ) - { - err = StartTaskTerraform(); - } - - if ( action == EVENT_OBJECT_RECOVER ) - { - err = StartTaskRecover(); - } - - if ( action == EVENT_OBJECT_BEGSHIELD ) - { - err = StartTaskShield(TSM_UP); - } - - if ( action == EVENT_OBJECT_DIMSHIELD ) - { - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw != 0 ) - { - ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_DIMSHIELD); - if ( ps != 0 ) - { - m_object->SetParam((ps->RetVisibleValue()-(RADIUS_SHIELD_MIN/g_unit))/((RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)/g_unit)); - } - } - } - - if ( action == EVENT_OBJECT_FIRE && m_primaryTask == 0 && !m_object->RetTrainer()) - { - if ( m_camera->RetType() != CAMERA_ONBOARD ) - { - m_camera->SetType(CAMERA_ONBOARD); - } - err = StartTaskFire(0.0f); - } - if ( action == EVENT_OBJECT_TARGET && !m_object->RetTrainer() ) - { - err = StartTaskGunGoal((event.pos.y-0.50f)*1.3f, (event.pos.x-0.50f)*2.0f); - } - - if ( action == EVENT_OBJECT_FIREANT ) - { -//? err = StartTaskFireAnt(); - } - - if ( action == EVENT_OBJECT_PEN0 ) // up - { - err = StartTaskPen(FALSE, m_object->RetTraceColor()); - m_object->SetTraceDown(FALSE); - } - if ( action == EVENT_OBJECT_PEN1 ) // black - { - err = StartTaskPen(TRUE, 1); - m_object->SetTraceDown(TRUE); - m_object->SetTraceColor(1); - } - if ( action == EVENT_OBJECT_PEN2 ) // yellow - { - err = StartTaskPen(TRUE, 8); - m_object->SetTraceDown(TRUE); - m_object->SetTraceColor(8); - } - if ( action == EVENT_OBJECT_PEN3 ) // orange - { - err = StartTaskPen(TRUE, 7); - m_object->SetTraceDown(TRUE); - m_object->SetTraceColor(7); - } - if ( action == EVENT_OBJECT_PEN4 ) // red - { - err = StartTaskPen(TRUE, 4); - m_object->SetTraceDown(TRUE); - m_object->SetTraceColor(4); - } - if ( action == EVENT_OBJECT_PEN5 ) // violet - { - err = StartTaskPen(TRUE, 6); - m_object->SetTraceDown(TRUE); - m_object->SetTraceColor(6); - } - if ( action == EVENT_OBJECT_PEN6 ) // blue - { - err = StartTaskPen(TRUE, 14); - m_object->SetTraceDown(TRUE); - m_object->SetTraceColor(14); - } - if ( action == EVENT_OBJECT_PEN7 ) // green - { - err = StartTaskPen(TRUE, 12); - m_object->SetTraceDown(TRUE); - m_object->SetTraceColor(12); - } - if ( action == EVENT_OBJECT_PEN8 ) // brown - { - err = StartTaskPen(TRUE, 10); - m_object->SetTraceDown(TRUE); - m_object->SetTraceColor(10); - } - - if ( action == EVENT_OBJECT_REC ) // registered? - { - if ( m_bTraceRecord ) - { - m_bTraceRecord = FALSE; - TraceRecordStop(); - } - else - { - m_bTraceRecord = TRUE; - TraceRecordStart(); - } - UpdateInterface(); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw != 0 ) - { - UpdateScript(pw); - } - } - if ( action == EVENT_OBJECT_STOP ) // stops? - { - if ( m_bTraceRecord ) - { - m_bTraceRecord = FALSE; - TraceRecordStop(); - } - UpdateInterface(); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw != 0 ) - { - UpdateScript(pw); - } - } - - if ( action == EVENT_OBJECT_RESET ) - { - m_main->ResetObject(); // reset all objects - UpdateInterface(); - } - -#if 0 - if ( event.param == 'T' ) - { - D3DVECTOR p1, p2; - float h; - p1 = m_object->RetPosition(0); - h = m_terrain->RetFloorLevel(p1); - p2 = p1; - p1.x -= 20.0f; - p1.z -= 20.0f; - p2.x += 20.0f; - p2.z += 20.0f; - m_terrain->Terraform(p1, p2, h+1.0f); - } - if ( event.param == 'R' ) - { - D3DVECTOR p1, p2; - float h; - p1 = m_object->RetPosition(0); - h = m_terrain->RetFloorLevel(p1); - p2 = p1; - p1.x -= 20.0f; - p1.z -= 20.0f; - p2.x += 20.0f; - p2.z += 20.0f; - m_terrain->Terraform(p1, p2, h-1.0f); - } -#endif - } - - if ( err != ERR_OK ) - { - m_displayText->DisplayError(err, m_object); - } - - return TRUE; -} - - -// The brain is changing by time. - -BOOL CBrain::EventFrame(const Event &event) -{ - m_time += event.rTime; - if ( m_bBurn ) m_burnTime += event.rTime; - - if ( m_soundChannelAlarm != -1 ) - { - m_sound->Position(m_soundChannelAlarm, m_object->RetPosition(0)); - } - - if ( m_studio != 0 ) // �urrent edition? - { - m_studio->EventProcess(event); - } - - UpdateInterface(event.rTime); - - if ( m_engine->RetPause() ) return TRUE; - if ( !m_bActivity ) return TRUE; // expected if idle - if ( EndedTask() == ERR_CONTINUE ) return TRUE; // expected if not finished ... - - if ( m_program != -1 ) // current program? - { - if ( m_script[m_program]->Continue(event) ) - { - StopProgram(); - } - } - - if ( m_bTraceRecord ) // registration of the design in progress? - { - TraceRecordFrame(); - } - - return TRUE; -} - - -// Stops the running program. - -void CBrain::StopProgram() -{ - StopTask(); - - if ( m_object->RetType() == OBJECT_HUMAN || - m_object->RetType() == OBJECT_TECH ) return; - - if ( m_program != -1 && - m_script[m_program] != 0 ) - { - m_script[m_program]->Stop(); - } - - BlinkScript(FALSE); // stops flashing - - m_program = -1; - - m_physics->SetMotorSpeedX(0.0f); - m_physics->SetMotorSpeedY(0.0f); - m_physics->SetMotorSpeedZ(0.0f); - - m_motion->SetAction(-1); - - UpdateInterface(); - m_main->UpdateShortcuts(); - m_object->CreateSelectParticule(); -} - -// Stops the current task. - -void CBrain::StopTask() -{ - if ( m_primaryTask != 0 ) - { - m_primaryTask->Abort(); - delete m_primaryTask; // stops the current task - m_primaryTask = 0; - } -} - - -// Introduces a virus into a program. -// Returns TRUE if it was inserted. - -BOOL CBrain::IntroduceVirus() -{ - int i, j; - - for ( i=0 ; i<50 ; i++ ) - { - j = rand()%BRAINMAXSCRIPT; - if ( m_script[j] != 0 ) - { - if ( m_script[j]->IntroduceVirus() ) // tries to introduce - { - m_bActiveVirus = TRUE; // active virus - return TRUE; - } - } - } - return FALSE; -} - -// Active Virus indicates that the object is contaminated. Unlike ch'tites (??? - Programerus) -// letters which automatically disappear after a while, -// ActiveVirus does not disappear after you edit the program -// (Even if the virus is not fixed). - - -void CBrain::SetActiveVirus(BOOL bActive) -{ - m_bActiveVirus = bActive; - - if ( !m_bActiveVirus ) // virus disabled? - { - m_object->SetVirusMode(FALSE); // chtites (??? - Programerus) letters also - } -} - -BOOL CBrain::RetActiveVirus() -{ - return m_bActiveVirus; -} - - -// Start editing a program. - -void CBrain::StartEditScript(int rank, char* name) -{ - CreateInterface(FALSE); // removes the control buttons - - if ( m_script[rank] == 0 ) - { - m_script[rank] = new CScript(m_iMan, m_object, &m_secondaryTask); - } - - m_studio = new CStudio(m_iMan); - m_studio->StartEditScript(m_script[rank], name, rank); -} - -// End of editing a program. - -void CBrain::StopEditScript(BOOL bCancel) -{ - if ( !bCancel ) SetActiveVirus(FALSE); - - if ( !m_studio->StopEditScript(bCancel) ) return; - - delete m_studio; - m_studio = 0; - - CreateInterface(TRUE); // puts the control buttons -} - - - -// Move the manipulator arm. - -Error CBrain::StartTaskTake() -{ - Error err; - - if ( m_primaryTask != 0 ) - { - delete m_primaryTask; // stops the current task - m_primaryTask = 0; - } - - m_primaryTask = new CTaskManager(m_iMan, m_object); - err = m_primaryTask->StartTaskTake(); - UpdateInterface(); - return err; -} - -// Move the manipulator arm. - -Error CBrain::StartTaskManip(TaskManipOrder order, TaskManipArm arm) -{ - Error err; - - if ( m_primaryTask != 0 ) - { - delete m_primaryTask; // stops the current task - m_primaryTask = 0; - } - - m_primaryTask = new CTaskManager(m_iMan, m_object); - err = m_primaryTask->StartTaskManip(order, arm); - UpdateInterface(); - return err; -} - -// Puts or removes a flag. - -Error CBrain::StartTaskFlag(TaskFlagOrder order, int rank) -{ - Error err; - - if ( m_primaryTask != 0 ) - { - delete m_primaryTask; // stops the current task - m_primaryTask = 0; - } - - m_primaryTask = new CTaskManager(m_iMan, m_object); - err = m_primaryTask->StartTaskFlag(order, rank); - UpdateInterface(); - return err; -} - -// Built a building. - -Error CBrain::StartTaskBuild(ObjectType type) -{ - Error err; - - if ( m_primaryTask != 0 ) - { - delete m_primaryTask; // stops the current task - m_primaryTask = 0; - } - - m_primaryTask = new CTaskManager(m_iMan, m_object); - err = m_primaryTask->StartTaskBuild(type); - UpdateInterface(); - return err; -} - -// Probe the ground. - -Error CBrain::StartTaskSearch() -{ - Error err; - - if ( m_primaryTask != 0 ) - { - delete m_primaryTask; // stops the current task - m_primaryTask = 0; - } - - m_primaryTask = new CTaskManager(m_iMan, m_object); - err = m_primaryTask->StartTaskSearch(); - UpdateInterface(); - return err; -} - -// Terraformed the ground. - -Error CBrain::StartTaskTerraform() -{ - Error err; - - if ( m_primaryTask != 0 ) - { - delete m_primaryTask; // stops the current task - m_primaryTask = 0; - } - - m_primaryTask = new CTaskManager(m_iMan, m_object); - err = m_primaryTask->StartTaskTerraform(); - UpdateInterface(); - return err; -} - -// Change pencil. - -Error CBrain::StartTaskPen(BOOL bDown, int color) -{ - Error err; - - m_physics->SetMotorSpeedX(0.0f); - m_physics->SetMotorSpeedY(0.0f); - m_physics->SetMotorSpeedZ(0.0f); - - if ( m_primaryTask != 0 ) - { - delete m_primaryTask; // stops the current task - m_primaryTask = 0; - } - - m_primaryTask = new CTaskManager(m_iMan, m_object); - err = m_primaryTask->StartTaskPen(bDown, color); - UpdateInterface(); - return err; -} - -// Recovers a ruin. - -Error CBrain::StartTaskRecover() -{ - Error err; - - if ( m_primaryTask != 0 ) - { - delete m_primaryTask; // stops the current task - m_primaryTask = 0; - } - - m_primaryTask = new CTaskManager(m_iMan, m_object); - err = m_primaryTask->StartTaskRecover(); - UpdateInterface(); - return err; -} - -// Deploys the shield. - -Error CBrain::StartTaskShield(TaskShieldMode mode) -{ - Error err; - - if ( m_secondaryTask != 0 ) - { - delete m_secondaryTask; // stops the current task - m_secondaryTask = 0; - } - - m_secondaryTask = new CTaskManager(m_iMan, m_object); - err = m_secondaryTask->StartTaskShield(mode, 1000.0f); - UpdateInterface(); - return err; -} - -// Shoots. - -Error CBrain::StartTaskFire(float delay) -{ - Error err; - - if ( m_primaryTask != 0 ) - { - delete m_primaryTask; // stops the current task - m_primaryTask = 0; - } - - m_primaryTask = new CTaskManager(m_iMan, m_object); - err = m_primaryTask->StartTaskFire(delay); - UpdateInterface(); - return err; -} - -// Shoots to the ant. - -Error CBrain::StartTaskFireAnt(D3DVECTOR impact) -{ - Error err; - - if ( m_primaryTask != 0 ) - { - delete m_primaryTask; // stops the current task - m_primaryTask = 0; - } - - m_primaryTask = new CTaskManager(m_iMan, m_object); - err = m_primaryTask->StartTaskFireAnt(impact); - UpdateInterface(); - return err; -} - -// Adjusts upward. - -Error CBrain::StartTaskGunGoal(float dirV, float dirH) -{ - Error err; - - if ( m_secondaryTask != 0 ) - { - delete m_secondaryTask; // stops the current task - m_secondaryTask = 0; - } - - m_secondaryTask = new CTaskManager(m_iMan, m_object); - err = m_secondaryTask->StartTaskGunGoal(dirV, dirH); - UpdateInterface(); - return err; -} - -// Reset. - -Error CBrain::StartTaskReset(D3DVECTOR goal, D3DVECTOR angle) -{ - Error err; - - if ( m_primaryTask != 0 ) - { - delete m_primaryTask; // stops the current task - m_primaryTask = 0; - } - - m_primaryTask = new CTaskManager(m_iMan, m_object); - err = m_primaryTask->StartTaskReset(goal, angle); - UpdateInterface(); - return err; -} - -// Completes the task when the time came. - -Error CBrain::EndedTask() -{ - Error err; - - if ( m_secondaryTask != 0 ) // current task? - { - err = m_secondaryTask->IsEnded(); - if ( err != ERR_CONTINUE ) // job ended? - { - delete m_secondaryTask; - m_secondaryTask = 0; - UpdateInterface(); - } - } - - if ( m_primaryTask != 0 ) // current task? - { - err = m_primaryTask->IsEnded(); - if ( err != ERR_CONTINUE ) // job ended? - { - delete m_primaryTask; - m_primaryTask = 0; - UpdateInterface(); - } - return err; - } - return ERR_STOP; -} - - - -// Shows flat areas in the field. - -void CBrain::GroundFlat() -{ - D3DVECTOR pos, speed; - FPOINT dim; - Error err; - float level; - - if ( !m_physics->RetLand() ) - { - err = ERR_FLAG_FLY; - pos = m_object->RetPosition(0); - if ( pos.y < m_water->RetLevel() ) err = ERR_FLAG_WATER; - m_displayText->DisplayError(err, m_object); - return; - } - - pos = m_object->RetPosition(0); - m_terrain->GroundFlat(pos); - m_sound->Play(SOUND_GFLAT, pos); - - level = m_terrain->RetFloorLevel(pos)+2.0f; - if ( pos.y < level ) pos.y = level; // not below the soil - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 40.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGFLAT, 1.0f); -} - - -// Not below the soil. - -void CBrain::ColorFlag(int color) -{ - m_flagColor = color; - UpdateInterface(); -} - - -// Creates all the interface when the object is selected. - -BOOL CBrain::CreateInterface(BOOL bSelect) -{ - ObjectType type; - CWindow* pw; - CButton* pb; - CColor* pc; - CSlider* ps; - CTarget* pt; - CLabel* pl; - FPOINT pos, dim, ddim; - float ox, oy, sx, sy; - char name[100]; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw != 0 ) - { - pw->Flush(); // destroys the window buttons - m_interface->DeleteControl(EVENT_WINDOW0); // destroys the window - } - m_defaultEnter = EVENT_NULL; - - if ( !bSelect ) return TRUE; - - pos.x = 0.0f; - pos.y = 0.0f; - dim.x = 540.0f/640.0f; - if ( !m_main->RetShowMap() ) dim.x = 640.0f/640.0f; - dim.y = 86.0f/480.0f; - m_interface->CreateWindows(pos, dim, 3, EVENT_WINDOW0); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return FALSE; - - m_object->GetTooltipName(name); - pos.x = 0.0f; - pos.y = 64.0f/480.0f; - ddim.x = 540.0f/640.0f; - if ( !m_main->RetShowMap() ) ddim.x = 640.0f/640.0f; - ddim.y = 16.0f/480.0f; - pw->CreateLabel(pos, ddim, 0, EVENT_LABEL0, name); - - dim.x = 33.0f/640.0f; - dim.y = 33.0f/480.0f; - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - type = m_object->RetType(); - - if ( type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs || - type == OBJECT_MOBILEsa || - type == OBJECT_MOBILEtg || - type == OBJECT_MOBILEft || - type == OBJECT_MOBILEtt || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEit || - type == OBJECT_MOBILEdr || - type == OBJECT_MOTHER || - type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_BEE || - type == OBJECT_WORM ) // vehicle? - { - ddim.x = dim.x*5.1f; - ddim.y = dim.y*2.0f; - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0.0f; - pw->CreateList(pos, ddim, -1, EVENT_OBJECT_PROGLIST, 1.10f); - UpdateScript(pw); - - pos.x = ox+sx*5.2f; - pos.y = oy+sy*1.0f; - pw->CreateButton(pos, dim, 8, EVENT_OBJECT_PROGRUN); - pos.y = oy+sy*0.0f; - pw->CreateButton(pos, dim, 22, EVENT_OBJECT_PROGEDIT); - } - - if ( type == OBJECT_HUMAN || - type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEft || - type == OBJECT_BEE ) // driving? - { - pos.x = ox+sx*6.4f; - pos.y = oy+sy*0; - pb = pw->CreateButton(pos, dim, 29, EVENT_OBJECT_GASDOWN); - pb->SetImmediat(TRUE); - - pos.x = ox+sx*6.4f; - pos.y = oy+sy*1; - pb = pw->CreateButton(pos, dim, 28, EVENT_OBJECT_GASUP); - pb->SetImmediat(TRUE); - - if ( type != OBJECT_HUMAN || - m_object->RetOption() != 2 ) - { - pos.x = ox+sx*15.3f; - pos.y = oy+sy*0; - ddim.x = 14.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGauge(pos, ddim, 2, EVENT_OBJECT_GRANGE); - } - } - - if ( type == OBJECT_HUMAN || - type == OBJECT_TECH ) - { - pos.x = ox+sx*7.7f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 31, EVENT_OBJECT_HTAKE); - DefaultEnter(pw, EVENT_OBJECT_HTAKE); - } - - if ( (type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia ) && // arm? - !m_object->RetTrainer() ) - { - pos.x = ox+sx*7.7f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 32, EVENT_OBJECT_MTAKE); - DefaultEnter(pw, EVENT_OBJECT_MTAKE); - - pos.x = ox+sx*8.9f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 34, EVENT_OBJECT_MBACK); - - pos.x = ox+sx*9.9f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 35, EVENT_OBJECT_MPOWER); - - pos.x = ox+sx*10.9f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 33, EVENT_OBJECT_MFRONT); - } - - if ( type == OBJECT_MOBILEsa && // underwater? - !m_object->RetTrainer() ) - { - pos.x = ox+sx*7.7f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 32, EVENT_OBJECT_MTAKE); - DefaultEnter(pw, EVENT_OBJECT_MTAKE); - } - - if ( type == OBJECT_HUMAN ) // builder? - { - pos.x = 1.0f/640.0f; - pos.y = 4.0f/480.0f; - ddim.x = 212.0f/640.0f; - ddim.y = 64.0f/480.0f; - pw->CreateGroup(pos, ddim, 27, EVENT_NULL); - - ddim.x = dim.x*0.9f; - ddim.y = dim.y*0.9f; - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*1.0f; - pw->CreateButton(pos, ddim, 128+35, EVENT_OBJECT_BRESEARCH); - DeadInterface(pw, EVENT_OBJECT_BRESEARCH, g_build&BUILD_RESEARCH); - - pos.x = ox+sx*0.9f; - pos.y = oy+sy*1.0f; - pw->CreateButton(pos, ddim, 128+32, EVENT_OBJECT_BFACTORY); - DeadInterface(pw, EVENT_OBJECT_BFACTORY, g_build&BUILD_FACTORY); - - pos.x = ox+sx*1.8f; - pos.y = oy+sy*1.0f; - pw->CreateButton(pos, ddim, 128+34, EVENT_OBJECT_BCONVERT); - DeadInterface(pw, EVENT_OBJECT_BCONVERT, g_build&BUILD_CONVERT); - - pos.x = ox+sx*2.7f; - pos.y = oy+sy*1.0f; - pw->CreateButton(pos, ddim, 128+36, EVENT_OBJECT_BSTATION); - DeadInterface(pw, EVENT_OBJECT_BSTATION, g_build&BUILD_STATION); - - pos.x = ox+sx*3.6f; - pos.y = oy+sy*1.0f; - pw->CreateButton(pos, ddim, 128+40, EVENT_OBJECT_BRADAR); - DeadInterface(pw, EVENT_OBJECT_BRADAR, g_build&BUILD_RADAR); - - pos.x = ox+sx*4.5f; - pos.y = oy+sy*1.0f; - pw->CreateButton(pos, ddim, 128+41, EVENT_OBJECT_BREPAIR); - DeadInterface(pw, EVENT_OBJECT_BREPAIR, g_build&BUILD_REPAIR); - - pos.x = ox+sx*5.4f; - pos.y = oy+sy*1.0f; - pw->CreateButton(pos, ddim, 128+44, EVENT_OBJECT_BINFO); - DeadInterface(pw, EVENT_OBJECT_BINFO, g_build&BUILD_INFO); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0.1f; - pw->CreateButton(pos, ddim, 128+37, EVENT_OBJECT_BTOWER); - DeadInterface(pw, EVENT_OBJECT_BTOWER, - (g_build&BUILD_TOWER) && - (g_researchDone & RESEARCH_TOWER)); - - pos.x = ox+sx*0.9f; - pos.y = oy+sy*0.1f; - pw->CreateButton(pos, ddim, 128+39, EVENT_OBJECT_BENERGY); - DeadInterface(pw, EVENT_OBJECT_BENERGY, g_build&BUILD_ENERGY); - - pos.x = ox+sx*1.8f; - pos.y = oy+sy*0.1f; - pw->CreateButton(pos, ddim, 128+33, EVENT_OBJECT_BDERRICK); - DeadInterface(pw, EVENT_OBJECT_BDERRICK, g_build&BUILD_DERRICK); - - pos.x = ox+sx*2.7f; - pos.y = oy+sy*0.1f; - pw->CreateButton(pos, ddim, 128+42, EVENT_OBJECT_BNUCLEAR); - DeadInterface(pw, EVENT_OBJECT_BNUCLEAR, - (g_build&BUILD_NUCLEAR) && - (g_researchDone & RESEARCH_ATOMIC)); - - pos.x = ox+sx*3.6f; - pos.y = oy+sy*0.1f; - pw->CreateButton(pos, ddim, 128+38, EVENT_OBJECT_BLABO); - DeadInterface(pw, EVENT_OBJECT_BLABO, g_build&BUILD_LABO); - - pos.x = ox+sx*4.5f; - pos.y = oy+sy*0.1f; - pw->CreateButton(pos, ddim, 128+46, EVENT_OBJECT_BPARA); - DeadInterface(pw, EVENT_OBJECT_BPARA, g_build&BUILD_PARA); - - pos.x = ox+sx*5.4f; - pos.y = oy+sy*0.1f; - pw->CreateButton(pos, ddim, 128+56, EVENT_OBJECT_BXXXX); - DeadInterface(pw, EVENT_OBJECT_BXXXX, FALSE); - - if ( g_build&BUILD_GFLAT ) - { - pos.x = ox+sx*9.0f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 64+47, EVENT_OBJECT_GFLAT); - } - - if ( g_build&BUILD_FLAG ) - { - pos.x = ox+sx*10.1f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 64+54, EVENT_OBJECT_FCREATE); - - pos.x = ox+sx*11.1f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 64+55, EVENT_OBJECT_FDELETE); - - ddim.x = dim.x*0.4f; - ddim.y = dim.y*0.4f; - pos.x = ox+sx*10.1f; - pos.y = oy+sy*2.0f-ddim.y; - pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_FCOLORb); - pc->SetColor(RetColor((D3DCOLOR)0x004890ff)); - pos.x += ddim.x; - pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_FCOLORr); - pc->SetColor(RetColor((D3DCOLOR)0x00ff0000)); - pos.x += ddim.x; - pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_FCOLORg); - pc->SetColor(RetColor((D3DCOLOR)0x0000ce00)); - pos.x += ddim.x; - pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_FCOLORy); - pc->SetColor(RetColor((D3DCOLOR)0x00ffec00)); - pos.x += ddim.x; - pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_FCOLORv); - pc->SetColor(RetColor((D3DCOLOR)0x00d101fe)); - } - } - - if ( (type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEis ) && // Investigator? - !m_object->RetTrainer() ) - { - pos.x = ox+sx*7.7f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 40, EVENT_OBJECT_SEARCH); - DefaultEnter(pw, EVENT_OBJECT_SEARCH); - } - - if ( type == OBJECT_MOBILErt && // Terraformer? - !m_object->RetTrainer() ) - { - pos.x = ox+sx*7.7f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 128+18, EVENT_OBJECT_TERRAFORM); - DefaultEnter(pw, EVENT_OBJECT_TERRAFORM); - - pos.x = ox+sx*10.2f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 41, EVENT_OBJECT_LIMIT); - } - - if ( type == OBJECT_MOBILErr && // recoverer? - !m_object->RetTrainer() ) - { - pos.x = ox+sx*7.7f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 128+20, EVENT_OBJECT_RECOVER); - DefaultEnter(pw, EVENT_OBJECT_RECOVER); - } - - if ( type == OBJECT_MOBILErs && // shield? - !m_object->RetTrainer() ) - { - pos.x = ox+sx*7.7f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 39, EVENT_OBJECT_BEGSHIELD); - DefaultEnter(pw, EVENT_OBJECT_BEGSHIELD); - - pos.x = ox+sx*9.0f; - pos.y = oy+sy*0.5f; - pw->CreateButton(pos, dim, 47, EVENT_OBJECT_ENDSHIELD); - -//? pos.x = ox+sx*10.2f; -//? pos.y = oy+sy*0.5f; -//? pw->CreateButton(pos, dim, 41, EVENT_OBJECT_LIMIT); - - pos.x = ox+sx*10.5f; - pos.y = oy+sy*0.0f; - ddim.x = dim.x*0.5f; - ddim.y = dim.y*2.0f; - ps = pw->CreateSlider(pos, ddim, 0, EVENT_OBJECT_DIMSHIELD); - ps->SetState(STATE_VALUE); - ps->SetLimit((RADIUS_SHIELD_MIN/g_unit), (RADIUS_SHIELD_MAX/g_unit)); - ps->SetArrowStep(1.0f); - } - - if ( (type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILErc ) && // cannon? - !m_object->RetTrainer() ) - { - pos.x = ox+sx*7.7f; - pos.y = oy+sy*0.5f; - pb = pw->CreateButton(pos, dim, 42, EVENT_OBJECT_FIRE); - pb->SetImmediat(TRUE); - DefaultEnter(pw, EVENT_OBJECT_FIRE); - -//? pos.x = ox+sx*10.2f; -//? pos.y = oy+sy*0.5f; -//? pw->CreateButton(pos, dim, 41, EVENT_OBJECT_LIMIT); - } - - if ( type == OBJECT_MOBILEdr && - m_object->RetManual() ) // scribbler in manual mode? - { - pos.x = ox+sx*6.9f; - pos.y = oy+sy*0.0f; - ddim.x = dim.x*2.2f; - ddim.y = dim.y*2.0f; - pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue bottom - - pos.x = ox+sx*9.3f; - pos.y = oy+sy*0.0f; - ddim.x = dim.x*2.2f; - ddim.y = dim.y*2.0f; - pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue bottom - - pos.x = ox+sx*9.90f; - pos.y = oy+sy*0.50f; - pw->CreateButton(pos, dim, 43, EVENT_OBJECT_PEN0); - - ddim.x = dim.x*0.5f; - ddim.y = dim.y*0.5f; - pos.x = ox+sx*10.15f; - pos.y = oy+sy*1.50f; - pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN1); // black - pc->SetColor(RetColor((D3DCOLOR)0x00000000)); - pos.x = ox+sx*10.65f; - pos.y = oy+sy*1.25f; - pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN2); // yellow - pc->SetColor(RetColor((D3DCOLOR)0x00ffff00)); - pos.x = ox+sx*10.90f; - pos.y = oy+sy*0.75f; - pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN3); // orange - pc->SetColor(RetColor((D3DCOLOR)0x00ff8800)); - pos.x = ox+sx*10.65f; - pos.y = oy+sy*0.25f; - pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN4); // red - pc->SetColor(RetColor((D3DCOLOR)0x00ff0000)); - pos.x = ox+sx*10.15f; - pos.y = oy+sy*0.00f; - pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN5); // violet - pc->SetColor(RetColor((D3DCOLOR)0x00ff00ff)); - pos.x = ox+sx*9.65f; - pos.y = oy+sy*0.25f; - pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN6); // blue - pc->SetColor(RetColor((D3DCOLOR)0x000066ff)); - pos.x = ox+sx*9.40f; - pos.y = oy+sy*0.75f; - pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN7); // green - pc->SetColor(RetColor((D3DCOLOR)0x0000cc00)); - pos.x = ox+sx*9.65f; - pos.y = oy+sy*1.25f; - pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN8); // brown - pc->SetColor(RetColor((D3DCOLOR)0x00884400)); - - pos.x = ox+sx*6.9f; - pos.y = oy+sy*1.2f; - ddim.x = dim.x*2.2f; - ddim.y = dim.y*0.4f; - GetResource(RES_TEXT, RT_INTERFACE_REC, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name); - pl->SetFontSize(9.0f); - - pos.x = ox+sx*7.0f; - pos.y = oy+sy*0.3f; - pw->CreateButton(pos, dim, 44, EVENT_OBJECT_REC); - pos.x = ox+sx*8.0f; - pos.y = oy+sy*0.3f; - pw->CreateButton(pos, dim, 45, EVENT_OBJECT_STOP); - } - - if ( m_object->RetToy() ) - { - pos.x = ox+sx*12.1f; - pos.y = oy+sy*-0.1f; - ddim.x = dim.x*1.2f; - ddim.y = dim.y*2.1f; - pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue bottom - - pos.x = ox+sx*12.2f; - pos.y = oy+sy*1; - pw->CreateGroup(pos, dim, 19, EVENT_NULL); // sign SatCom - - pos.x = ox+sx*12.2f; - pos.y = oy+sy*0.0f; - pw->CreateButton(pos, dim, 128+57, EVENT_OBJECT_BHELP); - } - else - { - pos.x = ox+sx*12.3f; - pos.y = oy+sy*-0.1f; - ddim.x = dim.x*1.0f; - ddim.y = dim.y*2.1f; - pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue bottom - - pos.x = ox+sx*12.3f; - pos.y = oy+sy*1; - pw->CreateGroup(pos, dim, 19, EVENT_NULL); // sign SatCom - - pos.x = ox+sx*12.4f; - pos.y = oy+sy*0.5f; - ddim.x = dim.x*0.8f; - ddim.y = dim.y*0.5f; - pw->CreateButton(pos, ddim, 18, EVENT_OBJECT_BHELP); - pos.y = oy+sy*0.0f; - pw->CreateButton(pos, ddim, 19, EVENT_OBJECT_HELP); - } - - if ( type != OBJECT_HUMAN && - type != OBJECT_TECH && - !m_object->RetCameraLock() ) - { -//? if ( m_main->RetShowMap() ) - if ( TRUE ) - { - pos.x = ox+sx*13.4f; - pos.y = oy+sy*1; - pw->CreateButton(pos, dim, 13, EVENT_OBJECT_CAMERA); - } - else - { - ddim.x = dim.x*0.66f; - ddim.y = dim.y*0.66f; - pos.x = ox+sx*(17.0f+0.66f); - pos.y = oy+sy*0.66f; - pw->CreateButton(pos, ddim, 13, EVENT_OBJECT_CAMERA); - } - } - - if ( m_object->RetToy() && !m_object->RetManual() ) - { -#if 0 - ddim.x = dim.x*0.66f; - ddim.y = dim.y*0.66f; - pos.x = ox+sx*10.0f; - pos.y = oy+sy*0.66f; - pb = pw->CreateButton(pos, ddim, 55, EVENT_OBJECT_CAMERAleft); - pb->SetImmediat(TRUE); - pos.x = ox+sx*(10.0f+0.66f*2.0f); - pos.y = oy+sy*0.66f; - pb = pw->CreateButton(pos, ddim, 48, EVENT_OBJECT_CAMERAright); - pb->SetImmediat(TRUE); - pos.x = ox+sx*(10.0f+0.66f); - pos.y = oy+sy*(0.66f*2.0f); - pb = pw->CreateButton(pos, ddim, 49, EVENT_OBJECT_CAMERAnear); - pb->SetImmediat(TRUE); - pos.x = ox+sx*(10.0f+0.66f); - pos.y = oy+sy*0.0f; - pb = pw->CreateButton(pos, ddim, 50, EVENT_OBJECT_CAMERAaway); - pb->SetImmediat(TRUE); -#else - pos.x = ox+sx*9.0f; - pos.y = oy+sy*0; - pb = pw->CreateButton(pos, dim, 55, EVENT_OBJECT_CAMERAleft); - pb->SetImmediat(TRUE); - pos.x = ox+sx*11.0f; - pos.y = oy+sy*0; - pb = pw->CreateButton(pos, dim, 48, EVENT_OBJECT_CAMERAright); - pb->SetImmediat(TRUE); - pos.x = ox+sx*10.0f; - pos.y = oy+sy*1; - pb = pw->CreateButton(pos, dim, 49, EVENT_OBJECT_CAMERAnear); - pb->SetImmediat(TRUE); - pos.x = ox+sx*10.0f; - pos.y = oy+sy*0; - pb = pw->CreateButton(pos, dim, 50, EVENT_OBJECT_CAMERAaway); - pb->SetImmediat(TRUE); -#endif - } - - pos.x = ox+sx*13.4f; - pos.y = oy+sy*0; -#if _TEEN - pw->CreateButton(pos, dim, 9, EVENT_OBJECT_RESET); -#else - if ( m_object->RetTrainer() ) // Training? - { - pw->CreateButton(pos, dim, 9, EVENT_OBJECT_RESET); - } - else - { - pw->CreateButton(pos, dim, 10, EVENT_OBJECT_DESELECT); - } -#endif - - if ( type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs || - type == OBJECT_MOBILEsa || - type == OBJECT_MOBILEft || - type == OBJECT_MOBILEtt || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEit ) // vehicle? - { - pos.x = ox+sx*14.5f; - pos.y = oy+sy*0; - ddim.x = 14.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY); - } - - if ( type == OBJECT_HUMAN || - type == OBJECT_TECH || - type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs || - type == OBJECT_MOBILEsa || - type == OBJECT_MOBILEtg || - type == OBJECT_MOBILEft || - type == OBJECT_MOBILEtt || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEit ) // vehicle? - { - pos.x = ox+sx*14.9f; - pos.y = oy+sy*0; - ddim.x = 14.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGauge(pos, ddim, 3, EVENT_OBJECT_GSHIELD); - } - -#if 0 - if ( FALSE ) - { - pos.x = 505.0f/640.0f; - pos.y = 3.0f/480.0f; - ddim.x = 33.0f/640.0f; - ddim.y = 33.0f/480.0f; - pw->CreateCompass(pos, ddim, 0, EVENT_OBJECT_COMPASS); - - pc = (CCompass*)pw->SearchControl(EVENT_OBJECT_COMPASS); - if ( pc != 0 ) - { - pc->SetState(STATE_VISIBLE, m_main->RetShowMap()); - } - } -#endif - - if ( type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILErc ) // cannon? - { - ddim.x = 64.0f/640.0f; - ddim.y = 64.0f/480.0f; - pos.x = 0.5f-ddim.x/2.0f; - pos.y = 0.5f-ddim.y/2.0f; - pw->CreateGroup(pos, ddim, 12, EVENT_OBJECT_CROSSHAIR); - - pos.x = 20.0f/640.0f; - pos.y = 100.0f/480.0f; - ddim.x = 600.0f/640.0f; - ddim.y = 340.0f/480.0f; - pt = pw->CreateTarget(pos, ddim, 0, EVENT_OBJECT_TARGET); - pt->ClearState(STATE_GLINT); - } - - ddim.x = 64.0f/640.0f; - ddim.y = 64.0f/480.0f; - pos.x = 30.0f/640.0f; - pos.y = 430.0f/480.0f-ddim.y; - pw->CreateGroup(pos, ddim, 13, EVENT_OBJECT_CORNERul); - - ddim.x = 64.0f/640.0f; - ddim.y = 64.0f/480.0f; - pos.x = 610.0f/640.0f-ddim.x; - pos.y = 430.0f/480.0f-ddim.y; - pw->CreateGroup(pos, ddim, 14, EVENT_OBJECT_CORNERur); - - ddim.x = 64.0f/640.0f; - ddim.y = 64.0f/480.0f; - pos.x = 30.0f/640.0f; - pos.y = 110.0f/480.0f; - pw->CreateGroup(pos, ddim, 15, EVENT_OBJECT_CORNERdl); - - ddim.x = 64.0f/640.0f; - ddim.y = 64.0f/480.0f; - pos.x = 610.0f/640.0f-ddim.x; - pos.y = 110.0f/480.0f; - pw->CreateGroup(pos, ddim, 16, EVENT_OBJECT_CORNERdr); - - UpdateInterface(); - m_lastUpdateTime = 0.0f; - UpdateInterface(0.0f); - - return TRUE; -} - -// Updates the state of all buttons on the interface, -// following the time that elapses ... - -void CBrain::UpdateInterface(float rTime) -{ - CWindow* pw; -#if _TEEN - CButton* pb; -#endif - CGauge* pg; - CCompass* pc; - CGroup* pgr; - CTarget* ptg; - CObject* power; - D3DVECTOR pos, hPos; - FPOINT ppos; - float energy, limit, angle, range; - int icon; - BOOL bOnBoard; - - m_lastAlarmTime += rTime; - if ( m_time < m_lastUpdateTime+0.1f ) return; - m_lastUpdateTime = m_time; - - if ( !m_object->RetSelect() ) - { - if ( m_soundChannelAlarm != -1 ) - { - m_sound->FlushEnvelope(m_soundChannelAlarm); - m_sound->AddEnvelope(m_soundChannelAlarm, 0.0f, 1.0f, 0.1f, SOPER_STOP); - m_soundChannelAlarm = -1; - } - return; - } - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; - - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); - if ( pg != 0 ) - { - power = m_object->RetPower(); - if ( power == 0 ) - { - energy = 0.0f; - } - else - { - energy = power->RetEnergy(); - limit = energy*power->RetCapacity(); - } - icon = 0; // red/green - - if ( limit < 0.2f && energy != 0.0f ) // low but not zero? - { - if ( m_lastAlarmTime >= 0.8f ) // blinks? - { - energy = 1.0f; - icon = 1; // brun - } - if ( m_lastAlarmTime >= 1.0f ) - { - m_sound->Play(SOUND_ALARM, 0.5f); // bip-bip-bip - m_lastAlarmTime = 0.0f; - } - } - pg->SetLevel(energy); - pg->SetIcon(icon); - } - - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GSHIELD); - if ( pg != 0 ) - { - pg->SetLevel(m_object->RetShield()); - } - - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GRANGE); - if ( pg != 0 ) - { - icon = 2; // blue/red - range = m_physics->RetReactorRange(); - - if ( range < 0.2f && range != 0.0f && !m_physics->RetLand() ) - { - if ( Mod(m_time, 0.5f) >= 0.2f ) // blinks? - { - range = 1.0f; - icon = 1; // yellow - } - if ( m_soundChannelAlarm == -1 ) - { - m_soundChannelAlarm = m_sound->Play(SOUND_ALARMt, m_object->RetPosition(0), 0.0f, 0.1f, TRUE); - m_sound->AddEnvelope(m_soundChannelAlarm, 1.0f, 1.0f, 1.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannelAlarm, 1.0f, 1.0f, 1.0f, SOPER_LOOP); - } - } - else - { - if ( m_soundChannelAlarm != -1 ) - { - m_sound->FlushEnvelope(m_soundChannelAlarm); - m_sound->AddEnvelope(m_soundChannelAlarm, 0.0f, 0.1f, 1.0f, SOPER_STOP); - m_soundChannelAlarm = -1; - } - } - - pg->SetLevel(1.0f-range); - pg->SetIcon(icon); - } - - pc = (CCompass*)pw->SearchControl(EVENT_OBJECT_COMPASS); - if ( pc != 0 ) - { - angle = -(m_object->RetAngleY(0)+PI/2.0f); - pc->SetDirection(angle); - - pc->SetState(STATE_VISIBLE, m_main->RetShowMap()); - } - -#if _TEEN - pb = (CButton*)pw->SearchControl(EVENT_OBJECT_REC); - if ( pb != 0 ) - { - if ( m_bTraceRecord && Mod(m_time, 0.4f) >= 0.2f ) - { - pb->SetState(STATE_CHECK); - } - else - { - pb->ClearState(STATE_CHECK); - } - } -#endif - - bOnBoard = m_camera->RetType() == CAMERA_ONBOARD; - - pgr = (CGroup*)pw->SearchControl(EVENT_OBJECT_CROSSHAIR); - if ( pgr != 0 ) - { - if ( bOnBoard ) - { -#if 0 - angle = m_object->RetGunGoalV(); - if ( m_object->RetType() != OBJECT_MOBILErc ) - { - angle += 10.0f*PI/360.0f; - } - ppos.x = 0.5f-(64.0f/640.0f)/2.0f; - ppos.y = 0.5f-(64.0f/480.0f)/2.0f; - ppos.y += sinf(angle)*0.6f; - pgr->SetPos(ppos); -#else - ppos.x = 0.50f-(64.0f/640.0f)/2.0f; - ppos.y = 0.50f-(64.0f/480.0f)/2.0f; - ppos.x += m_object->RetGunGoalH()/2.0f; - ppos.y += m_object->RetGunGoalV()/1.3f; - pgr->SetPos(ppos); -#endif - pgr->SetState(STATE_VISIBLE, !m_main->RetFriendAim()); - } - else - { - pgr->ClearState(STATE_VISIBLE); - } - } - - ptg = (CTarget*)pw->SearchControl(EVENT_OBJECT_TARGET); - if ( ptg != 0 ) - { - if ( bOnBoard ) - { - ptg->SetState(STATE_VISIBLE); - } - else - { - ptg->ClearState(STATE_VISIBLE); - } - } - - pgr = (CGroup*)pw->SearchControl(EVENT_OBJECT_CORNERul); - if ( pgr != 0 ) - { - pgr->SetState(STATE_VISIBLE, bOnBoard); - } - - pgr = (CGroup*)pw->SearchControl(EVENT_OBJECT_CORNERur); - if ( pgr != 0 ) - { - pgr->SetState(STATE_VISIBLE, bOnBoard); - } - - pgr = (CGroup*)pw->SearchControl(EVENT_OBJECT_CORNERdl); - if ( pgr != 0 ) - { - pgr->SetState(STATE_VISIBLE, bOnBoard); - } - - pgr = (CGroup*)pw->SearchControl(EVENT_OBJECT_CORNERdr); - if ( pgr != 0 ) - { - pgr->SetState(STATE_VISIBLE, bOnBoard); - } -} - -// Updates the status of all interface buttons. - -void CBrain::UpdateInterface() -{ - ObjectType type; - CWindow* pw; - CButton* pb; - CSlider* ps; -#if _TEEN - CColor* pc; - int color; -#endif - BOOL bEnable, bFly, bRun; - char title[100]; - - if ( !m_object->RetSelect() ) return; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; - - type = m_object->RetType(); - - bEnable = ( m_secondaryTask == 0 && m_program == -1 ); - - bEnable = ( m_primaryTask == 0 && m_program == -1 ); - - EnableInterface(pw, EVENT_OBJECT_PROGEDIT, (m_primaryTask == 0 && !m_bTraceRecord)); - EnableInterface(pw, EVENT_OBJECT_PROGLIST, bEnable && !m_bTraceRecord); - EnableInterface(pw, EVENT_OBJECT_LEFT, bEnable); - EnableInterface(pw, EVENT_OBJECT_RIGHT, bEnable); - EnableInterface(pw, EVENT_OBJECT_UP, bEnable); - EnableInterface(pw, EVENT_OBJECT_DOWN, bEnable); - EnableInterface(pw, EVENT_OBJECT_HTAKE, bEnable); - EnableInterface(pw, EVENT_OBJECT_MTAKE, bEnable); - EnableInterface(pw, EVENT_OBJECT_MBACK, bEnable); - EnableInterface(pw, EVENT_OBJECT_MPOWER, bEnable); - EnableInterface(pw, EVENT_OBJECT_MFRONT, bEnable); - EnableInterface(pw, EVENT_OBJECT_GFLAT, bEnable); - EnableInterface(pw, EVENT_OBJECT_FCREATE, bEnable); - EnableInterface(pw, EVENT_OBJECT_FDELETE, bEnable); - EnableInterface(pw, EVENT_OBJECT_SEARCH, bEnable); - EnableInterface(pw, EVENT_OBJECT_TERRAFORM, bEnable); - EnableInterface(pw, EVENT_OBJECT_RECOVER, bEnable); - EnableInterface(pw, EVENT_OBJECT_FIRE, bEnable); - EnableInterface(pw, EVENT_OBJECT_RESET, bEnable); -#if _TEEN - EnableInterface(pw, EVENT_OBJECT_PEN0, bEnable); - EnableInterface(pw, EVENT_OBJECT_PEN1, bEnable); - EnableInterface(pw, EVENT_OBJECT_PEN2, bEnable); - EnableInterface(pw, EVENT_OBJECT_PEN3, bEnable); - EnableInterface(pw, EVENT_OBJECT_PEN4, bEnable); - EnableInterface(pw, EVENT_OBJECT_PEN5, bEnable); - EnableInterface(pw, EVENT_OBJECT_PEN6, bEnable); - EnableInterface(pw, EVENT_OBJECT_PEN7, bEnable); - EnableInterface(pw, EVENT_OBJECT_PEN8, bEnable); - EnableInterface(pw, EVENT_OBJECT_REC, bEnable); - EnableInterface(pw, EVENT_OBJECT_STOP, bEnable); -#endif - - if ( type == OBJECT_HUMAN ) // builder? - { - EnableInterface(pw, EVENT_OBJECT_BFACTORY, bEnable); - EnableInterface(pw, EVENT_OBJECT_BDERRICK, bEnable); - EnableInterface(pw, EVENT_OBJECT_BCONVERT, bEnable); - EnableInterface(pw, EVENT_OBJECT_BSTATION, bEnable); - EnableInterface(pw, EVENT_OBJECT_BREPAIR, bEnable); - EnableInterface(pw, EVENT_OBJECT_BTOWER, bEnable); - EnableInterface(pw, EVENT_OBJECT_BRESEARCH, bEnable); - EnableInterface(pw, EVENT_OBJECT_BRADAR, bEnable); - EnableInterface(pw, EVENT_OBJECT_BENERGY, bEnable); - EnableInterface(pw, EVENT_OBJECT_BLABO, bEnable); - EnableInterface(pw, EVENT_OBJECT_BNUCLEAR, bEnable); - EnableInterface(pw, EVENT_OBJECT_BPARA, bEnable); - EnableInterface(pw, EVENT_OBJECT_BINFO, bEnable); - EnableInterface(pw, EVENT_OBJECT_BXXXX, bEnable); - } - - pb = (CButton*)pw->SearchControl(EVENT_OBJECT_GFLAT); - if ( pb != 0 ) - { - pb->SetState(STATE_VISIBLE, m_engine->RetGroundSpot()); - } - - if ( type == OBJECT_HUMAN || // builder? - type == OBJECT_TECH ) - { - CheckInterface(pw, EVENT_OBJECT_FCOLORb, m_flagColor==0); - CheckInterface(pw, EVENT_OBJECT_FCOLORr, m_flagColor==1); - CheckInterface(pw, EVENT_OBJECT_FCOLORg, m_flagColor==2); - CheckInterface(pw, EVENT_OBJECT_FCOLORy, m_flagColor==3); - CheckInterface(pw, EVENT_OBJECT_FCOLORv, m_flagColor==4); - } - - if ( type == OBJECT_MOBILErs ) // shield? - { - if ( (m_secondaryTask == 0 || !m_secondaryTask->IsBusy()) && m_program == -1 ) - { - EnableInterface(pw, EVENT_OBJECT_BEGSHIELD, (m_secondaryTask == 0)); - EnableInterface(pw, EVENT_OBJECT_ENDSHIELD, (m_secondaryTask != 0)); - DefaultEnter (pw, EVENT_OBJECT_BEGSHIELD, (m_secondaryTask == 0)); - DefaultEnter (pw, EVENT_OBJECT_ENDSHIELD, (m_secondaryTask != 0)); - } - else - { - EnableInterface(pw, EVENT_OBJECT_BEGSHIELD, FALSE); - EnableInterface(pw, EVENT_OBJECT_ENDSHIELD, FALSE); - DefaultEnter (pw, EVENT_OBJECT_BEGSHIELD, FALSE); - DefaultEnter (pw, EVENT_OBJECT_ENDSHIELD, FALSE); - } - - ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_DIMSHIELD); - if ( ps != 0 ) - { - ps->SetVisibleValue((RADIUS_SHIELD_MIN/g_unit)+m_object->RetParam()*((RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)/g_unit)); - } - } - - bFly = bEnable; - if ( bFly && (type == OBJECT_HUMAN || type == OBJECT_TECH) ) - { - if ( m_object->RetFret() != 0 ) bFly = FALSE; // if holder -> not fly - } - EnableInterface(pw, EVENT_OBJECT_GASUP, bFly); - EnableInterface(pw, EVENT_OBJECT_GASDOWN, bFly); - if ( m_object->RetTrainer() ) // Training? - { - DeadInterface(pw, EVENT_OBJECT_GASUP, FALSE); - DeadInterface(pw, EVENT_OBJECT_GASDOWN, FALSE); - } - else - { - DeadInterface(pw, EVENT_OBJECT_GASUP, g_researchDone&RESEARCH_FLY); - DeadInterface(pw, EVENT_OBJECT_GASDOWN, g_researchDone&RESEARCH_FLY); - } - - if ( type == OBJECT_HUMAN || - type == OBJECT_TECH || - type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs || - type == OBJECT_MOBILEsa || - type == OBJECT_MOBILEtg || - type == OBJECT_MOBILEft || - type == OBJECT_MOBILEtt || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEit || - type == OBJECT_MOBILEdr || - type == OBJECT_MOTHER || - type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_BEE || - type == OBJECT_WORM ) // vehicle? - { - bRun = FALSE; - if ( m_script[m_selScript] != 0 ) - { - m_script[m_selScript]->GetTitle(title); - if ( title[0] != 0 ) - { - bRun = TRUE; - } - } - if ( !bEnable && m_program == -1 ) bRun = FALSE; - if ( m_bTraceRecord ) bRun = FALSE; - EnableInterface(pw, EVENT_OBJECT_PROGRUN, bRun); - - pb = (CButton*)pw->SearchControl(EVENT_OBJECT_PROGRUN); - if ( pb != 0 ) - { - pb->SetIcon(m_program==-1?21:8); // run/stop - } - -//? pb = (CButton*)pw->SearchControl(EVENT_OBJECT_PROGEDIT); -//? if ( pb != 0 ) -//? { -//? pb->SetIcon(m_program==-1?22:40); // edit/debug -//? } - - BlinkScript(m_program != -1); // blinks if script execution - } - - if ( type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia ) // arm? - { - CheckInterface(pw, EVENT_OBJECT_MPOWER, m_manipStyle==EVENT_OBJECT_MPOWER); - CheckInterface(pw, EVENT_OBJECT_MBACK, m_manipStyle==EVENT_OBJECT_MBACK); - CheckInterface(pw, EVENT_OBJECT_MFRONT, m_manipStyle==EVENT_OBJECT_MFRONT); - } - -#if _TEEN - if ( m_object->RetTraceDown() ) - { - pb = (CButton*)pw->SearchControl(EVENT_OBJECT_PEN0); - if ( pb != 0 ) - { - pb->ClearState(STATE_CHECK); - } - - color = m_object->RetTraceColor(); - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN1); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, color==1); - } - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN2); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, color==8); - } - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN3); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, color==7); - } - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN4); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, color==4); - } - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN5); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, color==6); - } - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN6); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, color==14); - } - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN7); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, color==12); - } - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN8); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, color==10); - } - } - else - { - pb = (CButton*)pw->SearchControl(EVENT_OBJECT_PEN0); - if ( pb != 0 ) - { - pb->SetState(STATE_CHECK); - } - - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN1); - if ( pc != 0 ) - { - pc->ClearState(STATE_CHECK); - } - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN2); - if ( pc != 0 ) - { - pc->ClearState(STATE_CHECK); - } - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN3); - if ( pc != 0 ) - { - pc->ClearState(STATE_CHECK); - } - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN4); - if ( pc != 0 ) - { - pc->ClearState(STATE_CHECK); - } - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN5); - if ( pc != 0 ) - { - pc->ClearState(STATE_CHECK); - } - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN6); - if ( pc != 0 ) - { - pc->ClearState(STATE_CHECK); - } - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN7); - if ( pc != 0 ) - { - pc->ClearState(STATE_CHECK); - } - pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN8); - if ( pc != 0 ) - { - pc->ClearState(STATE_CHECK); - } - } -#endif -} - -// Updates the list of programs. - -void CBrain::UpdateScript(CWindow *pw) -{ - CList* pl; - char name[100]; - char title[100]; - int i; - BOOL bSoluce; - - pl = (CList*)pw->SearchControl(EVENT_OBJECT_PROGLIST); - if ( pl == 0 ) return; - -#if _SCHOOL - bSoluce = m_main->RetSoluce4(); -#else - bSoluce = TRUE; -#endif - - for ( i=0 ; iGetTitle(title); - if ( !bSoluce && i == 3 ) - { - title[0] = 0; - } - if ( title[0] != 0 ) - { - sprintf(name, "%d: %s", i+1, title); - } - } - - pl->SetName(i, name); - } - - if ( !bSoluce ) - { - pl->SetEnable(3, FALSE); - } - - pl->SetSelect(m_selScript); - pl->ShowSelect(TRUE); -} - -// Returns the rank of selected script. - -int CBrain::RetSelScript() -{ - CWindow* pw; - CList* pl; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return -1; - - pl = (CList*)pw->SearchControl(EVENT_OBJECT_PROGLIST); - if ( pl == 0 ) return -1; - - return pl->RetSelect(); -} - -// Blinks the running program. - -void CBrain::BlinkScript(BOOL bEnable) -{ - CWindow* pw; - CList* pl; - - if ( !m_object->RetSelect() ) return; // robot not selected? - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; - - pl = (CList*)pw->SearchControl(EVENT_OBJECT_PROGLIST); - if ( pl == 0 ) return; - - pl->SetBlink(bEnable); -} - -// Check the status of a button interface. - -void CBrain::CheckInterface(CWindow *pw, EventMsg event, BOOL bState) -{ - CControl* control; - - control = pw->SearchControl(event); - if ( control == 0 ) return; - - control->SetState(STATE_CHECK, bState); -} - -// Changes the state of a button interface. - -void CBrain::EnableInterface(CWindow *pw, EventMsg event, BOOL bState) -{ - CControl* control; - - control = pw->SearchControl(event); - if ( control == 0 ) return; - - control->SetState(STATE_ENABLE, bState); -} - -// Changes the state of a button on the interface. - -void CBrain::DeadInterface(CWindow *pw, EventMsg event, BOOL bState) -{ - CControl* control; - - control = pw->SearchControl(event); - if ( control == 0 ) return; - - control->SetState(STATE_DEAD, !bState); -} - -// Change the default input state of a button interface. - -void CBrain::DefaultEnter(CWindow *pw, EventMsg event, BOOL bState) -{ - CControl* control; - - control = pw->SearchControl(event); - if ( control == 0 ) return; - - if ( bState ) - { - control->SetState(STATE_DEFAULT); - m_defaultEnter = event; - } - else - { - control->ClearState(STATE_DEFAULT); - } -} - - -// Indicates whether the object is busy with a task. - -BOOL CBrain::IsBusy() -{ - return (m_primaryTask != 0); -} - -// Management of the activity of an object. - -void CBrain::SetActivity(BOOL bMode) -{ - m_bActivity = bMode; -} - -BOOL CBrain::RetActivity() -{ - return m_bActivity; -} - -// Indicates whether a program is running. - -BOOL CBrain::IsProgram() -{ - return ( m_program != -1 ); -} - -// Indicates whether a program exists. - -BOOL CBrain::ProgramExist(int rank) -{ - return ( m_script[rank] != 0 ); -} - -// Starts a program. - -void CBrain::RunProgram(int rank) -{ - if ( rank < 0 ) return; - - if ( m_script[rank] != 0 && - m_script[rank]->Run() ) - { - m_program = rank; // start new program - BlinkScript(TRUE); // blink - m_object->CreateSelectParticule(); - m_main->UpdateShortcuts(); - } -} - -// Returns the first free program. - -int CBrain::FreeProgram() -{ - int i; - - for ( i=0 ; iCompare(m_script[rank]) ) // the same already? - { - delete m_script[rank]; - m_script[rank] = 0; - return FALSE; - } - } - - return TRUE; -} - -// Load a script with a text file. - -BOOL CBrain::ReadProgram(int rank, char* filename) -{ - if ( m_script[rank] == 0 ) - { - m_script[rank] = new CScript(m_iMan, m_object, &m_secondaryTask); - } - - if ( m_script[rank]->ReadScript(filename) ) return TRUE; - - delete m_script[rank]; - m_script[rank] = 0; - - return FALSE; -} - -// Indicates whether a program is compiled correctly. - -BOOL CBrain::RetCompile(int rank) -{ - if ( m_script[rank] == 0 ) return FALSE; - return m_script[rank]->RetCompile(); -} - -// Saves a script in a text file. - -BOOL CBrain::WriteProgram(int rank, char* filename) -{ - if ( m_script[rank] == 0 ) - { - m_script[rank] = new CScript(m_iMan, m_object, &m_secondaryTask); - } - - if ( m_script[rank]->WriteScript(filename) ) return TRUE; - - delete m_script[rank]; - m_script[rank] = 0; - - return FALSE; -} - - -// Load a stack of script implementation from a file. - -BOOL CBrain::ReadStack(FILE *file) -{ - short op; - - fRead(&op, sizeof(short), 1, file); - if ( op == 1 ) // run ? - { - fRead(&op, sizeof(short), 1, file); // program rank - if ( op >= 0 && op < BRAINMAXSCRIPT ) - { - m_program = op; // program restarts - m_selScript = op; - BlinkScript(TRUE); // blink - - if ( m_script[op] == 0 ) - { - m_script[op] = new CScript(m_iMan, m_object, &m_secondaryTask); - } - if ( !m_script[op]->ReadStack(file) ) return FALSE; - } - } - - return TRUE; -} - -// ave the script implementation stack of a file. - -BOOL CBrain::WriteStack(FILE *file) -{ - short op; - - if ( m_program != -1 && // current program? - m_script[m_program]->IsRunning() ) - { - op = 1; // run - fWrite(&op, sizeof(short), 1, file); - - op = m_program; - fWrite(&op, sizeof(short), 1, file); - - return m_script[m_program]->WriteStack(file); - } - - op = 0; // stop - fWrite(&op, sizeof(short), 1, file); - return TRUE; -} - - - -// Start of registration of the design. - -void CBrain::TraceRecordStart() -{ - m_traceOper = TO_STOP; - - m_tracePos = m_object->RetPosition(0); - m_traceAngle = m_object->RetAngleY(0); - - if ( m_object->RetTraceDown() ) // pencil down? - { - m_traceColor = m_object->RetTraceColor(); - } - else // pen up? - { - m_traceColor = -1; - } - - delete m_traceRecordBuffer; - m_traceRecordBuffer = (TraceRecord*)malloc(sizeof(TraceRecord)*MAXTRACERECORD); - m_traceRecordIndex = 0; -} - -// Saving the current drawing. - -void CBrain::TraceRecordFrame() -{ - TraceOper oper = TO_STOP; - D3DVECTOR pos; - float angle, len, speed; - int color; - - speed = m_physics->RetLinMotionX(MO_REASPEED); - if ( speed > 0.0f ) oper = TO_ADVANCE; - if ( speed < 0.0f ) oper = TO_RECEDE; - - speed = m_physics->RetCirMotionY(MO_REASPEED); - if ( speed != 0.0f ) oper = TO_TURN; - - if ( m_object->RetTraceDown() ) // pencil down? - { - color = m_object->RetTraceColor(); - } - else // pen up? - { - color = -1; - } - - if ( oper != m_traceOper || - color != m_traceColor ) - { - if ( m_traceOper == TO_ADVANCE || - m_traceOper == TO_RECEDE ) - { - pos = m_object->RetPosition(0); - len = Length2d(pos, m_tracePos); - TraceRecordOper(m_traceOper, len); - } - if ( m_traceOper == TO_TURN ) - { - angle = m_object->RetAngleY(0)-m_traceAngle; - TraceRecordOper(m_traceOper, angle); - } - - if ( color != m_traceColor ) - { - TraceRecordOper(TO_PEN, (float)color); - } - - m_traceOper = oper; - m_tracePos = m_object->RetPosition(0); - m_traceAngle = m_object->RetAngleY(0); - m_traceColor = color; - } -} - -// End of the registration of the design. Program generates the CBOT. - -void CBrain::TraceRecordStop() -{ - TraceOper lastOper, curOper; - float lastParam, curParam; - int max, i; - char* buffer; - - if ( m_traceRecordBuffer == 0 ) return; - - max = 10000; - buffer = (char*)malloc(max); - *buffer = 0; - strncat(buffer, "extern void object::AutoDraw()\n{\n", max-1); - - lastOper = TO_STOP; - lastParam = 0.0f; - for ( i=0 ; iSendScript(buffer); - delete buffer; -} - -// Saves an instruction CBOT. - -BOOL CBrain::TraceRecordOper(TraceOper oper, float param) -{ - int i; - - i = m_traceRecordIndex; - if ( i >= MAXTRACERECORD ) return FALSE; - - m_traceRecordBuffer[i].oper = oper; - m_traceRecordBuffer[i].param = param; - - m_traceRecordIndex = i+1; - return TRUE; -} - -// Generates an instruction CBOT. - -BOOL CBrain::TraceRecordPut(char *buffer, int max, TraceOper oper, float param) -{ - char line[100]; - int color; - - if ( oper == TO_ADVANCE ) - { - param /= g_unit; - sprintf(line, "\tmove(%.1f);\n", param); - strncat(buffer, line, max-1); - } - - if ( oper == TO_RECEDE ) - { - param /= g_unit; - sprintf(line, "\tmove(-%.1f);\n", param); - strncat(buffer, line, max-1); - } - - if ( oper == TO_TURN ) - { - param = -param*180.0f/PI; - sprintf(line, "\tturn(%d);\n", (int)param); -//? sprintf(line, "\tturn(%.1f);\n", param); - strncat(buffer, line, max-1); - } - - if ( oper == TO_PEN ) - { - color = (int)param; - if ( color == -1 ) strncat(buffer, "\tpenup();\n", max-1); - if ( color == 1 ) strncat(buffer, "\tpendown(Black);\n", max-1); - if ( color == 8 ) strncat(buffer, "\tpendown(Yellow);\n", max-1); - if ( color == 7 ) strncat(buffer, "\tpendown(Orange);\n", max-1); - if ( color == 4 ) strncat(buffer, "\tpendown(Red);\n", max-1); - if ( color == 6 ) strncat(buffer, "\tpendown(Purple);\n", max-1); - if ( color == 14 ) strncat(buffer, "\tpendown(Blue);\n", max-1); - if ( color == 12 ) strncat(buffer, "\tpendown(Green);\n", max-1); - if ( color == 10 ) strncat(buffer, "\tpendown(Brown);\n", max-1); - } - - return TRUE; -} - diff --git a/src/brain.h b/src/brain.h deleted file mode 100644 index 988a3cc..0000000 --- a/src/brain.h +++ /dev/null @@ -1,220 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// brain.h - -#ifndef _BRAIN_H_ -#define _BRAIN_H_ - - -#include "misc.h" -#include "event.h" -#include "object.h" -#include "taskmanip.h" -#include "taskflag.h" -#include "taskshield.h" - - -class CInstanceManager; -class CD3DEngine; -class CTerrain; -class CWater; -class CCamera; -class CObject; -class CPhysics; -class CMotion; -class CTaskManager; -class CInterface; -class CWindow; -class CDisplayText; -class CScript; -class CRobotMain; -class CStudio; -class CSound; -class CParticule; - - -#define BRAINMAXSCRIPT 10 - - - -enum TraceOper -{ - TO_STOP = 0, // stop - TO_ADVANCE = 1, // advance - TO_RECEDE = 2, // back - TO_TURN = 3, // rotate - TO_PEN = 4, // color change -}; - -typedef struct -{ - TraceOper oper; - float param; -} -TraceRecord; - - - -class CBrain -{ -public: - CBrain(CInstanceManager* iMan, CObject* object); - ~CBrain(); - - void DeleteObject(BOOL bAll=FALSE); - - void SetPhysics(CPhysics* physics); - void SetMotion(CMotion* motion); - - BOOL EventProcess(const Event &event); - BOOL CreateInterface(BOOL bSelect); - - BOOL Write(char *line); - BOOL Read(char *line); - - BOOL IsBusy(); - void SetActivity(BOOL bMode); - BOOL RetActivity(); - BOOL IsProgram(); - BOOL ProgramExist(int rank); - void RunProgram(int rank); - int FreeProgram(); - int RetProgram(); - void StopProgram(); - void StopTask(); - - BOOL IntroduceVirus(); - void SetActiveVirus(BOOL bActive); - BOOL RetActiveVirus(); - - void SetScriptRun(int rank); - int RetScriptRun(); - void SetScriptName(int rank, char *name); - char* RetScriptName(int rank); - void SetSoluceName(char *name); - char* RetSoluceName(); - - BOOL ReadSoluce(char* filename); - BOOL ReadProgram(int rank, char* filename); - BOOL RetCompile(int rank); - BOOL WriteProgram(int rank, char* filename); - BOOL ReadStack(FILE *file); - BOOL WriteStack(FILE *file); - - Error StartTaskTake(); - Error StartTaskManip(TaskManipOrder order, TaskManipArm arm); - Error StartTaskFlag(TaskFlagOrder order, int rank); - Error StartTaskBuild(ObjectType type); - Error StartTaskSearch(); - Error StartTaskTerraform(); - Error StartTaskPen(BOOL bDown, int color); - Error StartTaskRecover(); - Error StartTaskShield(TaskShieldMode mode); - Error StartTaskFire(float delay); - Error StartTaskFireAnt(D3DVECTOR impact); - Error StartTaskGunGoal(float dirV, float dirH); - Error StartTaskReset(D3DVECTOR goal, D3DVECTOR angle); - - void UpdateInterface(float rTime); - void UpdateInterface(); - -protected: - BOOL EventFrame(const Event &event); - - void StartEditScript(int rank, char* name); - void StopEditScript(BOOL bCancel); - - Error EndedTask(); - - void GroundFlat(); - void ColorFlag(int color); - - void UpdateScript(CWindow *pw); - int RetSelScript(); - void BlinkScript(BOOL bEnable); - - void CheckInterface(CWindow *pw, EventMsg event, BOOL bState); - void EnableInterface(CWindow *pw, EventMsg event, BOOL bState); - void DeadInterface(CWindow *pw, EventMsg event, BOOL bState); - void DefaultEnter(CWindow *pw, EventMsg event, BOOL bState=TRUE); - - void TraceRecordStart(); - void TraceRecordFrame(); - void TraceRecordStop(); - BOOL TraceRecordOper(TraceOper oper, float param); - BOOL TraceRecordPut(char *buffer, int max, TraceOper oper, float param); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CTerrain* m_terrain; - CWater* m_water; - CCamera* m_camera; - CObject* m_object; - CPhysics* m_physics; - CMotion* m_motion; - CInterface* m_interface; - CDisplayText* m_displayText; - CRobotMain* m_main; - CStudio* m_studio; - CSound* m_sound; - CParticule* m_particule; - CTaskManager* m_primaryTask; - CTaskManager* m_secondaryTask; - - CScript* m_script[BRAINMAXSCRIPT]; - int m_selScript; // rank of the selected script - int m_program; // rank of the executed program / ​​-1 - BOOL m_bActivity; - BOOL m_bBurn; - BOOL m_bActiveVirus; - - int m_scriptRun; - char m_scriptName[BRAINMAXSCRIPT][50]; - char m_soluceName[50]; - - EventMsg m_buttonAxe; - EventMsg m_manipStyle; - EventMsg m_defaultEnter; - EventMsg m_interfaceEvent[100]; - - CObject* m_antTarget; - CObject* m_beeBullet; - float m_beeBulletSpeed; - D3DVECTOR m_startPos; - float m_time; - float m_burnTime; - float m_lastUpdateTime; - float m_lastHumanTime; - float m_lastSpiderTime; - float m_lastWormTime; - float m_lastBulletTime; - float m_lastAlarmTime; - int m_soundChannelAlarm; - int m_flagColor; - - BOOL m_bTraceRecord; - TraceOper m_traceOper; - D3DVECTOR m_tracePos; - float m_traceAngle; - int m_traceColor; - int m_traceRecordIndex; - TraceRecord* m_traceRecordBuffer; -}; - - -#endif //_BRAIN_H_ diff --git a/src/bug.txt b/src/bug.txt deleted file mode 100644 index b598ad0..0000000 --- a/src/bug.txt +++ /dev/null @@ -1,94 +0,0 @@ -void CD3DApplication::StepSimul(float rTime) -{ - Event event; - - if ( m_pRobotMain == 0 ) return; - - if ( rTime > 0.5f ) rTime = 0.5f; // jamais plus de 0.5s ! - - ZeroMemory(&event, sizeof(Event)); - event.event = EVENT_FRAME; - event.rTime = rTime; - event.axeX = AxeLimit(m_axeKey.x + m_axeJoy.x); - event.axeY = AxeLimit(m_axeKey.y + m_axeJoy.y); - event.axeZ = AxeLimit(m_axeKey.z + m_axeJoy.z); - event.keyState = m_keyState; - -//?char s[100]; -//?sprintf(s, "StepSimul %.3f\n", event.rTime); -//?OutputDebugString(s); - m_pRobotMain->EventProcess(event); -} - - - -1347: void CD3DApplication::StepSimul(float rTime) -1348: { -0041E950 sub esp,24h -0041E953 push esi -0041E954 mov esi,ecx -1349: Event event; -1350: -1351: if ( m_pRobotMain == 0 ) return; -0041E956 mov eax,dword ptr [esi+0ECh] -0041E95C test eax,eax -0041E95E je CD3DApplication::StepSimul(0x0041ea08)+0B8h -1352: -1353: if ( rTime > 0.5f ) rTime = 0.5f; // jamais plus de 0.5s ! -0041E964 fld dword ptr [esp+2Ch] -0041E968 fcomp dword ptr [??_7CControl@@6B@(0x004b9ed4)+94h] -0041E96E push edi -0041E96F fnstsw ax -0041E971 test ah,41h -0041E974 jne CD3DApplication::StepSimul(0x0041e97e)+2Eh -0041E976 mov dword ptr [esp+30h],3F000000h -1354: -1355: ZeroMemory(&event, sizeof(Event)); -1356: event.event = EVENT_FRAME; -1357: event.rTime = rTime; -1358: event.axeX = AxeLimit(m_axeKey.x + m_axeJoy.x); -0041E97E fld dword ptr [esi+0F8h] -0041E984 fadd dword ptr [esi+104h] -0041E98A mov eax,dword ptr [esp+30h] -0041E98E mov ecx,9 -0041E993 mov dword ptr [esp+28h],eax -0041E997 push ecx -0041E998 xor eax,eax -0041E99A lea edi,dword ptr [esp+0Ch] -0041E99E fstp dword ptr [esp] -0041E9A1 rep stos dword ptr es:[edi] -0041E9A3 mov dword ptr [esp+0Ch],2 -0041E9AB call AxeLimit(0x0041cae0) -1359: event.axeY = AxeLimit(m_axeKey.y + m_axeJoy.y); -0041E9B0 fld dword ptr [esi+0FCh] -0041E9B6 fadd dword ptr [esi+108h] -0041E9BC fxch st(1) -0041E9BE fstp dword ptr [esp+1Ch] -0041E9C2 fstp dword ptr [esp] -0041E9C5 call AxeLimit(0x0041cae0) -1360: event.axeZ = AxeLimit(m_axeKey.z + m_axeJoy.z); -0041E9CA fld dword ptr [esi+100h] -0041E9D0 fadd dword ptr [esi+10Ch] -0041E9D6 fxch st(1) -0041E9D8 fstp dword ptr [esp+20h] -0041E9DC fstp dword ptr [esp] -0041E9DF call AxeLimit(0x0041cae0) -1361: event.keyState = m_keyState; -1362: -1363: //?char s[100]; -1364: //?sprintf(s, "StepSimul %.3f\n", event.rTime); -1365: //?OutputDebugString(s); -1366: m_pRobotMain->EventProcess(event); -0041E9E4 mov dx,word ptr [esi+0F4h] -0041E9EB mov ecx,dword ptr [esi+0ECh] -0041E9F1 fstp dword ptr [esp+24h] -0041E9F5 add esp,4 -0041E9F8 lea eax,dword ptr [esp+8] -0041E9FC mov word ptr [esp+24h],dx -0041EA01 push eax -0041EA02 call CRobotMain::EventProcess(0x0047fba0) -0041EA07 pop edi -1367: } -0041EA08 pop esi -0041EA09 add esp,24h -0041EA0C ret 4 diff --git a/src/bug1.txt b/src/bug1.txt deleted file mode 100644 index 59b0ca4..0000000 --- a/src/bug1.txt +++ /dev/null @@ -1,68 +0,0 @@ -extern void object::Solution( ) -{ - while ( true ) - { - object left, right; - - left = Radar(TypeMarkPath, -45, 120, 100); - right = Radar(TypeMarkPath, 45, 120, 100); - - if ( left == null && right == null ) - { - } - } -} - -CBotString::CBotString(const CBotString &) -CBotVar::GivName() -CBotStack::FindVar(CBotToken * &, int, int) -CBotStack::FindVar(CBotToken &, int, int) -CBotStack::CopyVar(CBotToken &, int) -CBotExpression::Execute(CBotStack * &) -CBotListInstr::Execute(CBotStack * &) -CBotWhile::Execute(CBotStack * &) -CBotListInstr::Execute(CBotStack * &) -CBotFunction::Execute(CBotVar * *, CBotStack * &) -CBotProgram::Run(void *) -CScript::Continue(const Event &) - - - -CBotString::CBotString(const CBotString &) : - m_token = 0xdddddddd - -CBotVar::GivName() : - return m_token->GivString(); - -CBotStack::FindVar(CBotToken * &, int, int) : - CBotStack* p = this; - CBotString name = pToken->GivString(); - - while (p != NULL) - { - CBotVar* pp = p->m_listVar; - while ( pp != NULL) - { - if (pp->GivName() == name) <- paf - - avec : - pp->__vfprt = 0xdddddddd - pp->m_token = 0xdddddddd - pp->m_next = 0xdddddddd - pp->m_type = -572662307 - pp->m_binit = -572662307 - pp->m_pMyThis = 0xdddddddd - pp->m_pUserPtr = 0xdddddddd - pp->m_InitExpr = 0xdddddddd - -CBotStack::FindVar(CBotToken &, int, int) : - CBotToken* pt = &Token; - pt->m_next = 0 - pt->m_prev = 0 - pt->m_type = 4 - pt->m_IdKeyWord = -1 - pt->m_Text = "right" - pt->m_Sep = " " - pt->m_start = 124 - pt->m_end = 129 - diff --git a/src/button.cpp b/src/button.cpp deleted file mode 100644 index 27fea9b..0000000 --- a/src/button.cpp +++ /dev/null @@ -1,248 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "language.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "restext.h" -#include "button.h" - - - -#define DELAY1 0.4f -#define DELAY2 0.1f - - - -// Object's constructor. - -CButton::CButton(CInstanceManager* iMan) : CControl(iMan) -{ - m_bCapture = FALSE; - m_bImmediat = FALSE; - m_bRepeat = FALSE; - m_repeat = 0.0f; -} - -// Object's destructor. - -CButton::~CButton() -{ -} - - -// Creates a new button. - -BOOL CButton::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - CControl::Create(pos, dim, icon, eventMsg); - - if ( icon == -1 ) - { - char name[100]; - char* p; - - GetResource(RES_EVENT, eventMsg, name); - p = strchr(name, '\\'); - if ( p != 0 ) *p = 0; - SetName(name); - } - - return TRUE; -} - - -// Management of an event. - -BOOL CButton::EventProcess(const Event &event) -{ - if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; - if ( m_state & STATE_DEAD ) return TRUE; - - CControl::EventProcess(event); - - if ( event.event == EVENT_FRAME ) - { - if ( m_bRepeat && m_repeat != 0.0f ) - { - m_repeat -= event.rTime; - if ( m_repeat <= 0.0f ) - { - m_repeat = DELAY2; - - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - return FALSE; - } - } - } - - if ( event.event == EVENT_LBUTTONDOWN && - (m_state & STATE_VISIBLE) && - (m_state & STATE_ENABLE) ) - { - if ( CControl::Detect(event.pos) ) - { - m_bCapture = TRUE; - m_repeat = DELAY1; - - if ( m_bImmediat || m_bRepeat ) - { - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - } - return FALSE; - } - } - - if ( event.event == EVENT_MOUSEMOVE && m_bCapture ) - { - } - - if ( event.event == EVENT_LBUTTONUP && m_bCapture ) - { - if ( CControl::Detect(event.pos) ) - { - if ( !m_bImmediat && !m_bRepeat ) - { - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - } - } - - m_bCapture = FALSE; - m_repeat = 0.0f; - } - - return TRUE; -} - - -// Draw button. - -void CButton::Draw() -{ - FPOINT pos, dim, uv1, uv2; -#if !_NEWLOOK - float dp; -#endif - - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - if ( m_state & STATE_WARNING ) // shading yellow-black? - { - pos.x = m_pos.x-( 8.0f/640.0f); - pos.y = m_pos.y-( 4.0f/480.0f); - dim.x = m_dim.x+(16.0f/640.0f); - dim.y = m_dim.y+( 8.0f/480.0f); - if ( m_state & STATE_SHADOW ) - { - DrawShadow(pos, dim); - } - DrawWarning(pos, dim); - } - - if ( m_state & STATE_SHADOW ) - { - DrawShadow(m_pos, m_dim); - } - - CControl::Draw(); - -#if !_NEWLOOK - if ( m_name[0] != 0 && // button with the name? - (m_state & STATE_CARD ) == 0 && - (m_state & STATE_SIMPLY) == 0 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - - dp = 0.5f/256.0f; - - uv1.x = 128.0f/256.0f; - uv1.y = 96.0f/256.0f; - uv2.x = 136.0f/256.0f; - uv2.y = 128.0f/256.0f; - - if ( (m_state & STATE_ENABLE) == 0 ) - { - uv1.x += 16.0f/256.0f; - uv2.x += 16.0f/256.0f; - } - - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - pos.y = m_pos.y+5.0f/480.0f; - dim.y = m_dim.y-10.0f/480.0f; - pos.x = m_pos.x+5.0f/640.0f; - dim.x = 3.0f/640.0f; - DrawIcon(pos, dim, uv1, uv2, 0.0f); - - uv1.x += 8.0f/256.0f; - uv2.x += 8.0f/256.0f; - pos.x = m_pos.x+m_dim.x-5.0f/640.0f-3.0f/640.0f; - DrawIcon(pos, dim, uv1, uv2, 0.0f); - } -#endif -} - - -// Management of immediate mode, which sends the event "press" -// before the mouse button is released. - -void CButton::SetImmediat(BOOL bImmediat) -{ - m_bImmediat = bImmediat; -} - -BOOL CButton::RetImmediat() -{ - return m_bImmediat; -} - - -// Mode management "autorepeat", when the button -// mouse is held down. - -void CButton::SetRepeat(BOOL bRepeat) -{ - m_bRepeat = bRepeat; -} - -BOOL CButton::RetRepeat() -{ - return m_bRepeat; -} - diff --git a/src/button.h b/src/button.h deleted file mode 100644 index 2d30eea..0000000 --- a/src/button.h +++ /dev/null @@ -1,58 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// button.h - -#ifndef _BUTTON_H_ -#define _BUTTON_H_ - - -#include "control.h" - - -class CD3DEngine; - - - -class CButton : public CControl -{ -public: - CButton(CInstanceManager* iMan); - virtual ~CButton(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - - BOOL EventProcess(const Event &event); - - void Draw(); - - void SetImmediat(BOOL bRepeat); - BOOL RetImmediat(); - - void SetRepeat(BOOL bRepeat); - BOOL RetRepeat(); - -protected: - -protected: - BOOL m_bCapture; - BOOL m_bImmediat; - BOOL m_bRepeat; - float m_repeat; -}; - - -#endif //_BUTTON_H_ diff --git a/src/camera.cpp b/src/camera.cpp deleted file mode 100644 index e526d6c..0000000 --- a/src/camera.cpp +++ /dev/null @@ -1,2109 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "language.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "terrain.h" -#include "water.h" -#include "object.h" -#include "physics.h" -#include "camera.h" - - - - -// Object's constructor. - -CCamera::CCamera(CInstanceManager* iMan) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_CAMERA, this); - - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - - m_type = CAMERA_FREE; - m_smooth = CS_NORM; - m_cameraObj = 0; - - m_eyeDistance = 10.0f; - m_initDelay = 0.0f; - - m_actualEye = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_actualLookat = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_finalEye = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_finalLookat = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_normEye = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_normLookat = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_focus = 1.0f; - - m_bRightDown = FALSE; - m_rightPosInit = FPOINT(0.5f, 0.5f); - m_rightPosCenter = FPOINT(0.5f, 0.5f); - m_rightPosMove = FPOINT(0.5f, 0.5f); - - m_eyePt = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_directionH = 0.0f; - m_directionV = 0.0f; - m_heightEye = 20.0f; - m_heightLookat = 0.0f; - m_speed = 2.0f; - - m_backDist = 0.0f; - m_backMin = 0.0f; - m_addDirectionH = 0.0f; - m_addDirectionV = 0.0f; - m_bTransparency = FALSE; - - m_fixDist = 0.0f; - m_fixDirectionH = 0.0f; - m_fixDirectionV = 0.0f; - - m_visitGoal = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_visitDist = 0.0f; - m_visitTime = 0.0f; - m_visitType = CAMERA_NULL; - m_visitDirectionH = 0.0f; - m_visitDirectionV = 0.0f; - - m_editHeight = 40.0f; - - m_remotePan = 0.0f; - m_remoteZoom = 0.0f; - - m_mouseDirH = 0.0f; - m_mouseDirV = 0.0f; - m_mouseMarging = 0.01f; - - m_motorTurn = 0.0f; - - m_centeringPhase = CP_NULL; - m_centeringAngleH = 0.0f; - m_centeringAngleV = 0.0f; - m_centeringDist = 0.0f; - m_centeringCurrentH = 0.0f; - m_centeringCurrentV = 0.0f; - m_centeringTime = 0.0f; - m_centeringProgress = 0.0f; - - m_effectType = CE_NULL; - m_effectPos = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_effectForce = 0.0f; - m_effectProgress = 0.0f; - m_effectOffset = D3DVECTOR(0.0f, 0.0f, 0.0f); - - m_scriptEye = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_scriptLookat = D3DVECTOR(0.0f, 0.0f, 0.0f); - - m_bEffect = TRUE; - m_bCameraScroll = TRUE; - m_bCameraInvertX = FALSE; - m_bCameraInvertY = FALSE; -} - -// Object's constructor. - -CCamera::~CCamera() -{ -} - - -void CCamera::SetEffect(BOOL bEnable) -{ - m_bEffect = bEnable; -} - -void CCamera::SetCameraScroll(BOOL bScroll) -{ - m_bCameraScroll = bScroll; -} - -void CCamera::SetCameraInvertX(BOOL bInvert) -{ - m_bCameraInvertX = bInvert; -} - -void CCamera::SetCameraInvertY(BOOL bInvert) -{ - m_bCameraInvertY = bInvert; -} - - -// Returns an additional force to turn. - -float CCamera::RetMotorTurn() -{ - if ( m_type == CAMERA_BACK ) return m_motorTurn; - return 0.0f; -} - - - -// Initializes the camera. - -void CCamera::Init(D3DVECTOR eye, D3DVECTOR lookat, float delay) -{ - D3DVECTOR vUpVec; - - m_initDelay = delay; - - eye.y += m_terrain->RetFloorLevel(eye, TRUE); - lookat.y += m_terrain->RetFloorLevel(lookat, TRUE); - - m_type = CAMERA_FREE; - m_eyePt = eye; - - m_directionH = RotateAngle(eye.x-lookat.x, eye.z-lookat.z)+PI/2.0f; - m_directionV = -RotateAngle(Length2d(eye, lookat), eye.y-lookat.y); - - m_eyeDistance = 10.0f; - m_heightLookat = 10.0f; - m_backDist = 30.0f; - m_backMin = 10.0f; - m_addDirectionH = 0.0f; - m_addDirectionV = -PI*0.05f; - m_fixDist = 50.0f; - m_fixDirectionH = PI*0.25f; - m_fixDirectionV = -PI*0.10f; - m_centeringPhase = CP_NULL; - m_actualEye = m_eyePt; - m_actualLookat = LookatPoint(m_eyePt, m_directionH, m_directionV, 50.0f); - m_finalEye = m_actualEye; - m_finalLookat = m_actualLookat; - m_scriptEye = m_actualEye; - m_scriptLookat = m_actualLookat; - m_focus = 1.00f; - m_remotePan = 0.0f; - m_remoteZoom = 0.0f; - - FlushEffect(); - FlushOver(); - SetType(CAMERA_FREE); -} - - -// Gives the object controlling the camera. - -void CCamera::SetObject(CObject* object) -{ - m_cameraObj = object; -} - -CObject* CCamera::RetObject() -{ - return m_cameraObj; -} - - -// Changes the level of transparency of an object and objects -// transported (battery & cargo). - -void SetTransparency(CObject* pObj, float value) -{ - CObject* pFret; - - pObj->SetTransparency(value); - - pFret = pObj->RetFret(); - if ( pFret != 0 ) - { - pFret->SetTransparency(value); - } - - pFret = pObj->RetPower(); - if ( pFret != 0 ) - { - pFret->SetTransparency(value); - } -} - -// Change the type of camera. - -void CCamera::SetType(CameraType type) -{ - CObject* pObj; - ObjectType oType; - D3DVECTOR vUpVec; - int i; - - m_remotePan = 0.0f; - m_remoteZoom = 0.0f; - - if ( m_type == CAMERA_BACK && m_bTransparency ) - { - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj->RetTruck() ) continue; // battery or cargo? - - SetTransparency(pObj, 0.0f); // opaque object - } - } - m_bTransparency = FALSE; - - if ( type == CAMERA_INFO || - type == CAMERA_VISIT ) // xx -> info ? - { - m_normEye = m_engine->RetEyePt(); - m_normLookat = m_engine->RetLookatPt(); - - m_engine->SetFocus(1.00f); // normal - m_type = type; - return; - } - - if ( m_type == CAMERA_INFO || - m_type == CAMERA_VISIT ) // info -> xx ? - { - m_engine->SetFocus(m_focus); // gives initial focus - m_type = type; - - vUpVec = D3DVECTOR(0.0f, 1.0f, 0.0f); - SetViewParams(m_normEye, m_normLookat, vUpVec); - return; - } - - if ( m_type == CAMERA_BACK && type == CAMERA_FREE ) // back -> free ? - { - m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, -50.0f); - } - - if ( m_type == CAMERA_BACK && type == CAMERA_EDIT ) // back -> edit ? - { - m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, -1.0f); - } - - if ( m_type == CAMERA_ONBOARD && type == CAMERA_FREE ) // onboard -> free ? - { - m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, -30.0f); - } - - if ( m_type == CAMERA_ONBOARD && type == CAMERA_EDIT ) // onboard -> edit ? - { - m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, -30.0f); - } - - if ( m_type == CAMERA_ONBOARD && type == CAMERA_EXPLO ) // onboard -> explo ? - { - m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, -50.0f); - } - - if ( m_type == CAMERA_BACK && type == CAMERA_EXPLO ) // back -> explo ? - { - m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, -20.0f); - } - - if ( type == CAMERA_FIX || - type == CAMERA_PLANE ) - { - AbortCentering(); // Special stops framing - } - - m_fixDist = 50.0f; - if ( type == CAMERA_PLANE ) - { - m_fixDist = 60.0f; - } - - if ( type == CAMERA_BACK ) - { - AbortCentering(); // Special stops framing - m_addDirectionH = 0.0f; - m_addDirectionV = -PI*0.05f; - - if ( m_cameraObj == 0 ) oType = OBJECT_NULL; - else oType = m_cameraObj->RetType(); - - m_backDist = 30.0f; - if ( oType == OBJECT_BASE ) m_backDist = 200.0f; - if ( oType == OBJECT_HUMAN ) m_backDist = 20.0f; - if ( oType == OBJECT_TECH ) m_backDist = 20.0f; - if ( oType == OBJECT_FACTORY ) m_backDist = 50.0f; - if ( oType == OBJECT_RESEARCH ) m_backDist = 40.0f; - if ( oType == OBJECT_DERRICK ) m_backDist = 40.0f; - if ( oType == OBJECT_REPAIR ) m_backDist = 35.0f; - if ( oType == OBJECT_DESTROYER) m_backDist = 35.0f; - if ( oType == OBJECT_TOWER ) m_backDist = 45.0f; - if ( oType == OBJECT_NUCLEAR ) m_backDist = 70.0f; - if ( oType == OBJECT_PARA ) m_backDist = 180.0f; - if ( oType == OBJECT_SAFE ) m_backDist = 50.0f; - if ( oType == OBJECT_HUSTON ) m_backDist = 120.0f; - - m_backMin = m_backDist/3.0f; - if ( oType == OBJECT_HUMAN ) m_backMin = 10.0f; - if ( oType == OBJECT_TECH ) m_backMin = 10.0f; - if ( oType == OBJECT_FACTORY ) m_backMin = 30.0f; - if ( oType == OBJECT_RESEARCH ) m_backMin = 20.0f; - if ( oType == OBJECT_NUCLEAR ) m_backMin = 32.0f; - if ( oType == OBJECT_PARA ) m_backMin = 40.0f; - if ( oType == OBJECT_SAFE ) m_backMin = 25.0f; - if ( oType == OBJECT_HUSTON ) m_backMin = 80.0f; - } - - if ( type != CAMERA_ONBOARD && m_cameraObj != 0 ) - { - m_cameraObj->SetGunGoalH(0.0f); // puts the cannon right - } - - if ( type == CAMERA_ONBOARD ) - { - m_focus = 1.50f; // Wide - } - else - { - m_focus = 1.00f; // normal - } - m_engine->SetFocus(m_focus); - - m_type = type; - - SetSmooth(CS_NORM); -} - -CameraType CCamera::RetType() -{ - return m_type; -} - - -// Management of the smoothing mode. - -void CCamera::SetSmooth(CameraSmooth type) -{ - m_smooth = type; -} - -CameraSmooth CCamera::RetSmoth() -{ - return m_smooth; -} - - -// Management of the setback distance. - -void CCamera::SetDist(float dist) -{ - m_fixDist = dist; -} - -float CCamera::RetDist() -{ - return m_fixDist; -} - - -// Manage angle mode CAMERA_FIX. - -void CCamera::SetFixDirection(float angle) -{ - m_fixDirectionH = angle; -} - -float CCamera::RetFixDirection() -{ - return m_fixDirectionH; -} - - -// Managing the triggering mode of the camera panning. - -void CCamera::SetRemotePan(float value) -{ - m_remotePan = value; -} - -float CCamera::RetRemotePan() -{ - return m_remotePan; -} - -// Management of the remote zoom (0 .. 1) of the camera. - -void CCamera::SetRemoteZoom(float value) -{ - value = Norm(value); - - if ( m_type == CAMERA_BACK ) - { - m_backDist = m_backMin+(200.0f-m_backMin)*value; - } - - if ( m_type == CAMERA_FIX || - m_type == CAMERA_PLANE ) - { - m_fixDist = 10.0f+(200.0f-10.0f)*value; - } -} - -float CCamera::RetRemoteZoom() -{ - if ( m_type == CAMERA_BACK ) - { - return (m_backDist-m_backMin)/(200.0f-m_backMin); - } - - if ( m_type == CAMERA_FIX || - m_type == CAMERA_PLANE ) - { - return (m_fixDist-10.0f)/(200.0f-10.0f); - } - return 0.0f; -} - - - -// Start with a tour round the camera. - -void CCamera::StartVisit(D3DVECTOR goal, float dist) -{ - m_visitType = m_type; - SetType(CAMERA_VISIT); - m_visitGoal = goal; - m_visitDist = dist; - m_visitTime = 0.0f; - m_visitDirectionH = 0.0f; - m_visitDirectionV = -PI*0.10f; -} - -// Circular end of a visit with the camera. - -void CCamera::StopVisit() -{ - SetType(m_visitType); // presents the initial type -} - - -// Returns the point of view of the camera. - -void CCamera::RetCamera(D3DVECTOR &eye, D3DVECTOR &lookat) -{ - eye = m_eyePt; - lookat = LookatPoint(m_eyePt, m_directionH, m_directionV, 50.0f); -} - - -// Specifies a special movement of camera to frame action. - -BOOL CCamera::StartCentering(CObject *object, float angleH, float angleV, - float dist, float time) -{ - if ( m_type != CAMERA_BACK ) return FALSE; - if ( object != m_cameraObj ) return FALSE; - - if ( m_centeringPhase != CP_NULL ) return FALSE; - - if ( m_addDirectionH > PI ) - { - angleH = PI*2.0f-angleH; - } - - m_centeringPhase = CP_START; - m_centeringAngleH = angleH; - m_centeringAngleV = angleV; - m_centeringDist = dist; - m_centeringCurrentH = 0.0f; - m_centeringCurrentV = 0.0f; - m_centeringTime = time; - m_centeringProgress = 0.0f; - - return TRUE; -} - -// Ends a special movement of camera to frame action. - -BOOL CCamera::StopCentering(CObject *object, float time) -{ - if ( m_type != CAMERA_BACK ) return FALSE; - if ( object != m_cameraObj ) return FALSE; - - if ( m_centeringPhase != CP_START && - m_centeringPhase != CP_WAIT ) return FALSE; - - m_centeringPhase = CP_STOP; - - if ( m_centeringAngleH != 99.9f ) - { - m_centeringAngleH = m_centeringCurrentH; - } - if ( m_centeringAngleV != 99.9f ) - { - m_centeringAngleV = m_centeringCurrentV; - } - - m_centeringTime = time; - m_centeringProgress = 0.0f; - - return TRUE; -} - -// Stop framing special in the current position. - -void CCamera::AbortCentering() -{ - if ( m_type == CAMERA_INFO || - m_type == CAMERA_VISIT ) return; - - if ( m_centeringPhase == CP_NULL ) return; - - m_centeringPhase = CP_NULL; - - if ( m_centeringAngleH != 99.9f ) - { - m_addDirectionH = m_centeringCurrentH; - } - if ( m_centeringAngleV != 99.9f ) - { - m_addDirectionV = m_centeringCurrentV; - } -} - - - -// Removes the special effect with the camera - -void CCamera::FlushEffect() -{ - m_effectType = CE_NULL; - m_effectForce = 0.0f; - m_effectProgress = 0.0f; - m_effectOffset = D3DVECTOR(0.0f, 0.0f, 0.0f); -} - -// Starts a special effect with the camera. - -void CCamera::StartEffect(CameraEffect effect, D3DVECTOR pos, float force) -{ - if ( !m_bEffect ) return; - - m_effectType = effect; - m_effectPos = pos; - m_effectForce = force; - m_effectProgress = 0.0f; -} - -// Advances the effect of the camera. - -void CCamera::EffectFrame(const Event &event) -{ - float dist, force; - - if ( m_type == CAMERA_INFO || - m_type == CAMERA_VISIT ) return; - - if ( m_effectType == CE_NULL ) return; - - m_effectOffset = D3DVECTOR(0.0f, 0.0f, 0.0f); - force = m_effectForce; - - if ( m_effectType == CE_TERRAFORM ) - { - m_effectProgress += event.rTime*0.7f; - m_effectOffset.x = (Rand()-0.5f)*10.0f; - m_effectOffset.y = (Rand()-0.5f)*10.0f; - m_effectOffset.z = (Rand()-0.5f)*10.0f; - - force *= 1.0f-m_effectProgress; - } - - if ( m_effectType == CE_EXPLO ) - { - m_effectProgress += event.rTime*1.0f; - m_effectOffset.x = (Rand()-0.5f)*5.0f; - m_effectOffset.y = (Rand()-0.5f)*5.0f; - m_effectOffset.z = (Rand()-0.5f)*5.0f; - - force *= 1.0f-m_effectProgress; - } - - if ( m_effectType == CE_SHOT ) - { - m_effectProgress += event.rTime*1.0f; - m_effectOffset.x = (Rand()-0.5f)*2.0f; - m_effectOffset.y = (Rand()-0.5f)*2.0f; - m_effectOffset.z = (Rand()-0.5f)*2.0f; - - force *= 1.0f-m_effectProgress; - } - - if ( m_effectType == CE_CRASH ) - { - m_effectProgress += event.rTime*5.0f; - m_effectOffset.y = sinf(m_effectProgress*PI)*1.5f; - m_effectOffset.x = (Rand()-0.5f)*1.0f*(1.0f-m_effectProgress); - m_effectOffset.z = (Rand()-0.5f)*1.0f*(1.0f-m_effectProgress); - } - - if ( m_effectType == CE_VIBRATION ) - { - m_effectProgress += event.rTime*0.1f; - m_effectOffset.y = (Rand()-0.5f)*1.0f*(1.0f-m_effectProgress); - m_effectOffset.x = (Rand()-0.5f)*1.0f*(1.0f-m_effectProgress); - m_effectOffset.z = (Rand()-0.5f)*1.0f*(1.0f-m_effectProgress); - } - - if ( m_effectType == CE_PET ) - { - m_effectProgress += event.rTime*5.0f; - m_effectOffset.x = (Rand()-0.5f)*0.2f; - m_effectOffset.y = (Rand()-0.5f)*2.0f; - m_effectOffset.z = (Rand()-0.5f)*0.2f; - } - - dist = Length(m_eyePt, m_effectPos); - dist = Norm((dist-100.f)/100.0f); - - force *= 1.0f-dist; -#if _TEEN - force *= 2.0f; -#endif - m_effectOffset *= force; - - if ( m_effectProgress >= 1.0f ) - { - FlushEffect(); - } -} - - -// Removes the effect of superposition in the foreground. - -void CCamera::FlushOver() -{ - m_overType = OE_NULL; - m_overColorBase.r = 0.0f; // black - m_overColorBase.g = 0.0f; - m_overColorBase.b = 0.0f; - m_overColorBase.a = 0.0f; - m_engine->SetOverColor(); // nothing -} - -// Specifies the base color. - -void CCamera::SetOverBaseColor(D3DCOLORVALUE color) -{ - m_overColorBase = color; -} - -// Starts a layering effect in the foreground. - -void CCamera::StartOver(OverEffect effect, D3DVECTOR pos, float force) -{ - D3DCOLOR color; - float dist, decay; - - m_overType = effect; - m_overTime = 0.0f; - - if ( m_overType == OE_BLITZ ) decay = 400.0f; - else decay = 100.0f; - dist = Length(m_eyePt, pos); - dist = (dist-decay)/decay; - if ( dist < 0.0f ) dist = 0.0f; - if ( dist > 1.0f ) dist = 1.0f; - - m_overForce = force * (1.0f-dist); - - if ( m_overType == OE_BLOOD ) - { - m_overColor.r = 0.8f; - m_overColor.g = 0.1f; - m_overColor.b = 0.1f; // red - m_overMode = D3DSTATETCb; - - m_overFadeIn = 0.4f; - m_overFadeOut = 0.8f; - m_overForce = 1.0f; - } - - if ( m_overType == OE_FADEINw ) - { - m_overColor.r = 1.0f; - m_overColor.g = 1.0f; - m_overColor.b = 1.0f; // white - m_overMode = D3DSTATETCb; - - m_overFadeIn = 0.0f; - m_overFadeOut =20.0f; - m_overForce = 1.0f; - } - - if ( m_overType == OE_FADEOUTw ) - { - m_overColor.r = 1.0f; - m_overColor.g = 1.0f; - m_overColor.b = 1.0f; // white - m_overMode = D3DSTATETCb; - - m_overFadeIn = 6.0f; - m_overFadeOut = 100000.0f; - m_overForce = 1.0f; - } - - if ( m_overType == OE_FADEOUTb ) - { - color = m_engine->RetFogColor(1); // fog color underwater - m_overColor = RetColor(color); - m_overMode = D3DSTATETCw; - - m_overFadeIn = 4.0f; - m_overFadeOut = 100000.0f; - m_overForce = 1.0f; - } - - if ( m_overType == OE_BLITZ ) - { - m_overColor.r = 0.9f; - m_overColor.g = 1.0f; - m_overColor.b = 1.0f; // white-cyan - m_overMode = D3DSTATETCb; - - m_overFadeIn = 0.0f; - m_overFadeOut = 1.0f; - } -} - -// Advanced overlay effect in the foreground. - -void CCamera::OverFrame(const Event &event) -{ - D3DCOLORVALUE color; - float intensity; - - if ( m_type == CAMERA_INFO || - m_type == CAMERA_VISIT ) return; - - if ( m_overType == OE_NULL ) - { - return; - } - - m_overTime += event.rTime; - - if ( m_overType == OE_BLITZ ) - { - if ( rand()%2 == 0 ) - { - color.r = m_overColor.r*m_overForce; - color.g = m_overColor.g*m_overForce; - color.b = m_overColor.b*m_overForce; - } - else - { - color.r = 0.0f; - color.g = 0.0f; - color.b = 0.0f; - } - color.a = 0.0f; - m_engine->SetOverColor(RetColor(color), m_overMode); - } - else - { - if ( m_overFadeIn > 0.0f && m_overTime < m_overFadeIn ) - { - intensity = m_overTime/m_overFadeIn; - intensity *= m_overForce; - - if ( m_overMode == D3DSTATETCw ) - { - color.r = 1.0f-(1.0f-m_overColor.r)*intensity; - color.g = 1.0f-(1.0f-m_overColor.g)*intensity; - color.b = 1.0f-(1.0f-m_overColor.b)*intensity; - } - else - { - color.r = m_overColor.r*intensity; - color.g = m_overColor.g*intensity; - color.b = m_overColor.b*intensity; - - color.r = 1.0f-(1.0f-color.r)*(1.0f-m_overColorBase.r); - color.g = 1.0f-(1.0f-color.g)*(1.0f-m_overColorBase.g); - color.b = 1.0f-(1.0f-color.b)*(1.0f-m_overColorBase.b); - } - color.a = 0.0f; - m_engine->SetOverColor(RetColor(color), m_overMode); - } - else if ( m_overFadeOut > 0.0f && m_overTime-m_overFadeIn < m_overFadeOut ) - { - intensity = 1.0f-(m_overTime-m_overFadeIn)/m_overFadeOut; - intensity *= m_overForce; - - if ( m_overMode == D3DSTATETCw ) - { - color.r = 1.0f-(1.0f-m_overColor.r)*intensity; - color.g = 1.0f-(1.0f-m_overColor.g)*intensity; - color.b = 1.0f-(1.0f-m_overColor.b)*intensity; - } - else - { - color.r = m_overColor.r*intensity; - color.g = m_overColor.g*intensity; - color.b = m_overColor.b*intensity; - - color.r = 1.0f-(1.0f-color.r)*(1.0f-m_overColorBase.r); - color.g = 1.0f-(1.0f-color.g)*(1.0f-m_overColorBase.g); - color.b = 1.0f-(1.0f-color.b)*(1.0f-m_overColorBase.b); - } - color.a = 0.0f; - m_engine->SetOverColor(RetColor(color), m_overMode); - } - } - - if ( m_overTime >= m_overFadeIn+m_overFadeOut ) - { - FlushOver(); - return; - } -} - - - -// Sets the soft movement of the camera. - -void CCamera::FixCamera() -{ - m_initDelay = 0.0f; - m_actualEye = m_finalEye = m_scriptEye; - m_actualLookat = m_finalLookat = m_scriptLookat; - SetViewTime(m_scriptEye, m_scriptLookat, 0.0f); -} - -// Specifies the location and direction of view to the 3D engine. - -void CCamera::SetViewTime(const D3DVECTOR &vEyePt, - const D3DVECTOR &vLookatPt, - float rTime) -{ - D3DVECTOR vUpVec, eye, lookat; - float prog, dist, h; - - if ( m_type == CAMERA_INFO ) - { - eye = vEyePt; - lookat = vLookatPt; - } - else - { - if ( m_initDelay > 0.0f ) - { - m_initDelay -= rTime; - if ( m_initDelay < 0.0f ) m_initDelay = 0.0f; - rTime /= 1.0f+m_initDelay; - } - - eye = vEyePt; - lookat = vLookatPt; - if ( !IsCollision(eye, lookat) ) - { - m_finalEye = eye; - m_finalLookat = lookat; - } - - dist = Length(m_finalEye, m_actualEye); - if ( m_smooth == CS_NONE ) prog = dist; - if ( m_smooth == CS_NORM ) prog = powf(dist, 1.5f)*rTime*0.5f; - if ( m_smooth == CS_HARD ) prog = powf(dist, 1.0f)*rTime*4.0f; - if ( m_smooth == CS_SPEC ) prog = powf(dist, 1.0f)*rTime*0.05f; - if ( dist == 0.0f ) - { - m_actualEye = m_finalEye; - } - else - { - if ( prog > dist ) prog = dist; - m_actualEye = (m_finalEye-m_actualEye)/dist*prog + m_actualEye; - } - - dist = Length(m_finalLookat, m_actualLookat); - if ( m_smooth == CS_NONE ) prog = dist; - if ( m_smooth == CS_NORM ) prog = powf(dist, 1.5f)*rTime*2.0f; - if ( m_smooth == CS_HARD ) prog = powf(dist, 1.0f)*rTime*4.0f; - if ( m_smooth == CS_SPEC ) prog = powf(dist, 1.0f)*rTime*4.0f; - if ( dist == 0.0f ) - { - m_actualLookat = m_finalLookat; - } - else - { - if ( prog > dist ) prog = dist; - m_actualLookat = (m_finalLookat-m_actualLookat)/dist*prog + m_actualLookat; - } - - eye = m_effectOffset+m_actualEye; - m_water->AdjustEye(eye); - - h = m_terrain->RetFloorLevel(eye); - if ( eye.y < h+4.0f ) - { - eye.y = h+4.0f; - } - - lookat = m_effectOffset+m_actualLookat; - } - - vUpVec = D3DVECTOR(0.0f, 1.0f, 0.0f); - SetViewParams(eye, lookat, vUpVec); -} - - -// Avoid the obstacles. - -BOOL CCamera::IsCollision(D3DVECTOR &eye, D3DVECTOR lookat) -{ - if ( m_type == CAMERA_BACK ) return IsCollisionBack(eye, lookat); - if ( m_type == CAMERA_FIX ) return IsCollisionFix(eye, lookat); - if ( m_type == CAMERA_PLANE ) return IsCollisionFix(eye, lookat); - return FALSE; -} - -// Avoid the obstacles. - -BOOL CCamera::IsCollisionBack(D3DVECTOR &eye, D3DVECTOR lookat) -{ -#if 0 - CObject *pObj; - D3DVECTOR oPos, min, max, proj; - ObjectType oType, iType; - float oRadius, dpp, dpl, del, dist, len, prox; - int i; - - if ( m_cameraObj == 0 ) - { - iType = OBJECT_NULL; - } - else - { - iType = m_cameraObj->RetType(); - } - - min.x = Min(eye.x, lookat.x); - min.y = Min(eye.y, lookat.y); - min.z = Min(eye.z, lookat.z); - - max.x = Max(eye.x, lookat.x); - max.y = Max(eye.y, lookat.y); - max.z = Max(eye.z, lookat.z); - - prox = 8.0f; // maximum proximity of the vehicle - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj == m_cameraObj ) continue; - - oType = pObj->RetType(); - if ( oType == OBJECT_TOTO || - oType == OBJECT_FIX || - oType == OBJECT_FRET || - oType == OBJECT_STONE || - oType == OBJECT_URANIUM || - oType == OBJECT_METAL || - oType == OBJECT_POWER || - oType == OBJECT_ATOMIC || - oType == OBJECT_BULLET || - oType == OBJECT_BBOX || - oType == OBJECT_TNT || - oType == OBJECT_BOMB || - oType == OBJECT_WAYPOINTb || - oType == OBJECT_WAYPOINTr || - oType == OBJECT_WAYPOINTg || - oType == OBJECT_WAYPOINTy || - oType == OBJECT_WAYPOINTv || - oType == OBJECT_FLAGb || - oType == OBJECT_FLAGr || - oType == OBJECT_FLAGg || - oType == OBJECT_FLAGy || - oType == OBJECT_FLAGv || - oType == OBJECT_ANT || - oType == OBJECT_SPIDER || - oType == OBJECT_BEE || - oType == OBJECT_WORM ) continue; - - pObj->GetGlobalSphere(oPos, oRadius); - if ( oRadius <= 0.0f ) continue; - - if ( oPos.x+oRadius < min.x || - oPos.y+oRadius < min.y || - oPos.z+oRadius < min.z || - oPos.x-oRadius > max.x || - oPos.y-oRadius > max.y || - oPos.z-oRadius > max.z ) continue; - - if ( iType == OBJECT_FACTORY ) - { - dpl = Length(oPos, lookat); - if ( dpl < oRadius ) continue; - } - - proj = Projection(eye, lookat, oPos); - dpp = Length(proj, oPos); - if ( dpp > oRadius ) continue; - - del = Length(eye, lookat); - len = Length(eye, proj); - if ( len > del ) continue; - - dist = sqrtf(oRadius*oRadius + dpp*dpp)-3.0f; - if ( dist < 0.0f ) dist = 0.0f; - proj = (lookat-eye)*dist/del + proj; - len = Length(eye, proj); - - if ( len < del-prox ) - { - eye = proj; - eye.y += len/5.0f; - return FALSE; - } - else - { - eye = (eye-lookat)*prox/del + lookat; - eye.y += (del-prox)/5.0f; - return FALSE; - } - } - return FALSE; -#else - CObject *pObj; - D3DVECTOR oPos, min, max, proj; - ObjectType oType, iType; - float oRadius, dpp, del, len, angle; - int i; - - if ( m_cameraObj == 0 ) - { - iType = OBJECT_NULL; - } - else - { - iType = m_cameraObj->RetType(); - } - - min.x = Min(m_actualEye.x, m_actualLookat.x); - min.y = Min(m_actualEye.y, m_actualLookat.y); - min.z = Min(m_actualEye.z, m_actualLookat.z); - - max.x = Max(m_actualEye.x, m_actualLookat.x); - max.y = Max(m_actualEye.y, m_actualLookat.y); - max.z = Max(m_actualEye.z, m_actualLookat.z); - - m_bTransparency = FALSE; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj->RetTruck() ) continue; // battery or cargo? - - SetTransparency(pObj, 0.0f); // opaque object - - if ( pObj == m_cameraObj ) continue; - - if ( iType == OBJECT_BASE || // building? - iType == OBJECT_DERRICK || - iType == OBJECT_FACTORY || - iType == OBJECT_STATION || - iType == OBJECT_CONVERT || - iType == OBJECT_REPAIR || - iType == OBJECT_DESTROYER|| - iType == OBJECT_TOWER || - iType == OBJECT_RESEARCH || - iType == OBJECT_RADAR || - iType == OBJECT_ENERGY || - iType == OBJECT_LABO || - iType == OBJECT_NUCLEAR || - iType == OBJECT_PARA || - iType == OBJECT_SAFE || - iType == OBJECT_HUSTON ) continue; - - oType = pObj->RetType(); - if ( oType == OBJECT_HUMAN || - oType == OBJECT_TECH || - oType == OBJECT_TOTO || - oType == OBJECT_FIX || - oType == OBJECT_FRET || - oType == OBJECT_ANT || - oType == OBJECT_SPIDER || - oType == OBJECT_BEE || - oType == OBJECT_WORM ) continue; - - pObj->GetGlobalSphere(oPos, oRadius); - if ( oRadius <= 2.0f ) continue; // ignores small objects - - if ( oPos.x+oRadius < min.x || - oPos.y+oRadius < min.y || - oPos.z+oRadius < min.z || - oPos.x-oRadius > max.x || - oPos.y-oRadius > max.y || - oPos.z-oRadius > max.z ) continue; - - proj = Projection(m_actualEye, m_actualLookat, oPos); - dpp = Length(proj, oPos); - if ( dpp > oRadius ) continue; - - if ( oType == OBJECT_FACTORY ) - { - angle = RotateAngle(m_actualEye.x-oPos.x, oPos.z-m_actualEye.z); // CW ! - angle = Direction(angle, pObj->RetAngleY(0)); - if ( Abs(angle) < 30.0f*PI/180.0f ) continue; // in the gate? - } - - del = Length(m_actualEye, m_actualLookat); - if ( oType == OBJECT_FACTORY ) - { - del += oRadius; - } - - len = Length(m_actualEye, proj); - if ( len > del ) continue; - - SetTransparency(pObj, 1.0f); // transparent object - m_bTransparency = TRUE; - } - return FALSE; -#endif -} - -// Avoid the obstacles. - -BOOL CCamera::IsCollisionFix(D3DVECTOR &eye, D3DVECTOR lookat) -{ - CObject *pObj; - D3DVECTOR oPos, proj; - ObjectType type; - float oRadius, dist; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj == m_cameraObj ) continue; - - type = pObj->RetType(); - if ( type == OBJECT_TOTO || - type == OBJECT_FRET || - type == OBJECT_STONE || - type == OBJECT_URANIUM || - type == OBJECT_METAL || - type == OBJECT_POWER || - type == OBJECT_ATOMIC || - type == OBJECT_BULLET || - type == OBJECT_BBOX || - type == OBJECT_KEYa || - type == OBJECT_KEYb || - type == OBJECT_KEYc || - type == OBJECT_KEYd || - type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_BEE || - type == OBJECT_WORM ) continue; - - pObj->GetGlobalSphere(oPos, oRadius); - if ( oRadius == 0.0f ) continue; - - dist = Length(eye, oPos); - if ( dist < oRadius ) - { - dist = Length(eye, lookat); - proj = Projection(eye, lookat, oPos); - eye = (lookat-eye)*oRadius/dist + proj; - return FALSE; - } - } - return FALSE; -} - - -// Management of an event. - -BOOL CCamera::EventProcess(const Event &event) -{ - switch( event.event ) - { - case EVENT_FRAME: - EventFrame(event); - break; - -#if 0 - case EVENT_RBUTTONDOWN: - m_bRightDown = TRUE; - m_rightPosInit = event.pos; - m_rightPosCenter = FPOINT(0.5f, 0.5f); - m_engine->MoveMousePos(m_rightPosCenter); -//? m_engine->SetMouseHide(TRUE); // cache la souris - break; - - case EVENT_RBUTTONUP: - m_bRightDown = FALSE; - m_engine->MoveMousePos(m_rightPosInit); -//? m_engine->SetMouseHide(FALSE); // remontre la souris - m_addDirectionH = 0.0f; - m_addDirectionV = -PI*0.05f; - break; -#endif - - case EVENT_MOUSEMOVE: - EventMouseMove(event); - break; - - case EVENT_KEYDOWN: - if ( event.param == VK_WHEELUP ) EventMouseWheel(+1); - if ( event.param == VK_WHEELDOWN ) EventMouseWheel(-1); - break; - } - return TRUE; -} - -// Changed the camera according to the mouse moved. - -BOOL CCamera::EventMouseMove(const Event &event) -{ - m_mousePos = event.pos; - return TRUE; -} - -// Mouse wheel operated. - -void CCamera::EventMouseWheel(int dir) -{ - if ( m_type == CAMERA_BACK ) - { - if ( dir > 0 ) - { - m_backDist -= 8.0f; - if ( m_backDist < m_backMin ) m_backDist = m_backMin; - } - if ( dir < 0 ) - { - m_backDist += 8.0f; - if ( m_backDist > 200.0f ) m_backDist = 200.0f; - } - } - - if ( m_type == CAMERA_FIX || - m_type == CAMERA_PLANE ) - { - if ( dir > 0 ) - { - m_fixDist -= 8.0f; - if ( m_fixDist < 10.0f ) m_fixDist = 10.0f; - } - if ( dir < 0 ) - { - m_fixDist += 8.0f; - if ( m_fixDist > 200.0f ) m_fixDist = 200.0f; - } - } - - if ( m_type == CAMERA_VISIT ) - { - if ( dir > 0 ) - { - m_visitDist -= 8.0f; - if ( m_visitDist < 20.0f ) m_visitDist = 20.0f; - } - if ( dir < 0 ) - { - m_visitDist += 8.0f; - if ( m_visitDist > 200.0f ) m_visitDist = 200.0f; - } - } -} - -// Changed the camera according to the time elapsed. - -BOOL CCamera::EventFrame(const Event &event) -{ - EffectFrame(event); - OverFrame(event); - - if ( m_type == CAMERA_FREE ) - { - return EventFrameFree(event); - } - if ( m_type == CAMERA_EDIT ) - { - return EventFrameEdit(event); - } - if ( m_type == CAMERA_DIALOG ) - { - return EventFrameDialog(event); - } - if ( m_type == CAMERA_BACK ) - { - return EventFrameBack(event); - } - if ( m_type == CAMERA_FIX || - m_type == CAMERA_PLANE ) - { - return EventFrameFix(event); - } - if ( m_type == CAMERA_EXPLO ) - { - return EventFrameExplo(event); - } - if ( m_type == CAMERA_ONBOARD ) - { - return EventFrameOnBoard(event); - } - if ( m_type == CAMERA_SCRIPT ) - { - return EventFrameScript(event); - } - if ( m_type == CAMERA_INFO ) - { - return EventFrameInfo(event); - } - if ( m_type == CAMERA_VISIT ) - { - return EventFrameVisit(event); - } - - return TRUE; -} - - -// Returns the default sprite to use for the mouse. - -D3DMouse CCamera::RetMouseDef(FPOINT pos) -{ - D3DMouse type; - - type = D3DMOUSENORM; - m_mousePos = pos; - - if ( m_type == CAMERA_INFO ) return type; - - if ( m_bRightDown ) // the right button pressed? - { - m_rightPosMove.x = pos.x - m_rightPosCenter.x; - m_rightPosMove.y = pos.y - m_rightPosCenter.y; - type = D3DMOUSEMOVE; - } - else - { - if ( !m_bCameraScroll ) return type; - - m_mouseDirH = 0.0f; - m_mouseDirV = 0.0f; - - if ( pos.x < m_mouseMarging ) - { - m_mouseDirH = pos.x/m_mouseMarging - 1.0f; - } - - if ( pos.x > 1.0f-m_mouseMarging ) - { - m_mouseDirH = 1.0f - (1.0f-pos.x)/m_mouseMarging; - } - - if ( pos.y < m_mouseMarging ) - { - m_mouseDirV = pos.y/m_mouseMarging - 1.0f; - } - - if ( pos.y > 1.0f-m_mouseMarging ) - { - m_mouseDirV = 1.0f - (1.0f-pos.y)/m_mouseMarging; - } - - if ( m_type == CAMERA_FREE || - m_type == CAMERA_EDIT || - m_type == CAMERA_BACK || - m_type == CAMERA_FIX || - m_type == CAMERA_PLANE || - m_type == CAMERA_EXPLO ) - { - if ( m_mouseDirH > 0.0f ) - { - type = D3DMOUSESCROLLR; - } - if ( m_mouseDirH < 0.0f ) - { - type = D3DMOUSESCROLLL; - } - } - - if ( m_type == CAMERA_FREE || - m_type == CAMERA_EDIT ) - { - if ( m_mouseDirV > 0.0f ) - { - type = D3DMOUSESCROLLU; - } - if ( m_mouseDirV < 0.0f ) - { - type = D3DMOUSESCROLLD; - } - } - - if ( m_bCameraInvertX ) - { - m_mouseDirH = -m_mouseDirH; - } - } - - return type; -} - - - -// Moves the point of view. - -BOOL CCamera::EventFrameFree(const Event &event) -{ - D3DVECTOR pos, vLookatPt; - float factor; - - factor = m_heightEye*0.5f+30.0f; - - if ( m_mouseDirH != 0.0f ) - { - m_directionH -= m_mouseDirH*event.rTime*0.7f*m_speed; - } - if ( m_mouseDirV != 0.0f ) - { - m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, m_mouseDirV*event.rTime*factor*m_speed); - } - - // Up/Down. - m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, event.axeY*event.rTime*factor*m_speed); - - // Left/Right. - if ( event.keyState & KS_CONTROL ) - { - if ( event.axeX < 0.0f ) - { - m_eyePt = LookatPoint(m_eyePt, m_directionH+PI/2.0f, m_directionV, -event.axeX*event.rTime*factor*m_speed); - } - if ( event.axeX > 0.0f ) - { - m_eyePt = LookatPoint(m_eyePt, m_directionH-PI/2.0f, m_directionV, event.axeX*event.rTime*factor*m_speed); - } - } - else - { - m_directionH -= event.axeX*event.rTime*0.7f*m_speed; - } - - // PageUp/PageDown. - if ( event.keyState & KS_NUMMINUS ) - { - if ( m_heightEye < 500.0f ) - { - m_heightEye += event.rTime*factor*m_speed; - } - } - if ( event.keyState & KS_NUMPLUS ) - { - if ( m_heightEye > -2.0f ) - { - m_heightEye -= event.rTime*factor*m_speed; - } - } - - m_terrain->ValidPosition(m_eyePt, 10.0f); - - if ( m_terrain->MoveOnFloor(m_eyePt, TRUE) ) - { - m_eyePt.y += m_heightEye; - - pos = m_eyePt; - if ( m_terrain->MoveOnFloor(pos, TRUE) ) - { - pos.y -= 2.0f; - if ( m_eyePt.y < pos.y ) - { - m_eyePt.y = pos.y; - } - } - - } - - vLookatPt = LookatPoint( m_eyePt, m_directionH, m_directionV, 50.0f ); - - if ( m_terrain->MoveOnFloor(vLookatPt, TRUE) ) - { - vLookatPt.y += m_heightLookat; - } - - SetViewTime(m_eyePt, vLookatPt, event.rTime); - - return TRUE; -} - -// Moves the point of view. - -BOOL CCamera::EventFrameEdit(const Event &event) -{ - D3DVECTOR pos, vLookatPt; - float factor; - - factor = m_editHeight*0.5f+30.0f; - - if ( m_mouseDirH != 0.0f ) - { - m_directionH -= m_mouseDirH*event.rTime*0.7f*m_speed; - } - if ( m_mouseDirV != 0.0f ) - { - m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, m_mouseDirV*event.rTime*factor*m_speed); - } - - if ( m_bCameraScroll ) - { - // Left/Right. - m_fixDirectionH += m_mouseDirH*event.rTime*1.0f*m_speed; - m_fixDirectionH = NormAngle(m_fixDirectionH); - - // Up/Down. -//? m_fixDirectionV -= m_mouseDirV*event.rTime*0.5f*m_speed; -//? if ( m_fixDirectionV < -PI*0.40f ) m_fixDirectionV = -PI*0.40f; -//? if ( m_fixDirectionV > PI*0.20f ) m_fixDirectionV = PI*0.20f; - } - - m_terrain->ValidPosition(m_eyePt, 10.0f); - - if ( m_terrain->MoveOnFloor(m_eyePt, FALSE) ) - { - m_eyePt.y += m_editHeight; - - pos = m_eyePt; - if ( m_terrain->MoveOnFloor(pos, FALSE) ) - { - pos.y += 2.0f; - if ( m_eyePt.y < pos.y ) - { - m_eyePt.y = pos.y; - } - } - - } - - vLookatPt = LookatPoint( m_eyePt, m_directionH, m_directionV, 50.0f ); - - if ( m_terrain->MoveOnFloor(vLookatPt, TRUE) ) - { - vLookatPt.y += m_heightLookat; - } - - SetViewTime(m_eyePt, vLookatPt, event.rTime); - - return TRUE; -} - -// Moves the point of view. - -BOOL CCamera::EventFrameDialog(const Event &event) -{ - return TRUE; -} - -// Moves the point of view. - -BOOL CCamera::EventFrameBack(const Event &event) -{ - CPhysics* physics; - ObjectType type; - D3DVECTOR pos, vLookatPt; - FPOINT mouse; - float centeringH, centeringV, centeringD, h, v, d, floor; - - if ( m_cameraObj == 0 ) - { - type = OBJECT_NULL; - } - else - { - type = m_cameraObj->RetType(); - } - - // +/-. - if ( event.keyState & KS_NUMPLUS ) - { - m_backDist -= event.rTime*30.0f*m_speed; - if ( m_backDist < m_backMin ) m_backDist = m_backMin; - } - if ( event.keyState & KS_NUMMINUS ) - { - m_backDist += event.rTime*30.0f*m_speed; - if ( m_backDist > 200.0f ) m_backDist = 200.0f; - } - - m_motorTurn = 0.0f; - - if ( m_bRightDown ) - { - m_addDirectionH = m_rightPosMove.x*6.0f; - m_addDirectionV = -m_rightPosMove.y*2.0f; - } - else - { - if ( m_bCameraScroll ) - { -#if 1 - // Left/Right. - m_addDirectionH += m_mouseDirH*event.rTime*1.0f*m_speed; - m_addDirectionH = NormAngle(m_addDirectionH); - - // Up/Down. -//? m_backDist -= m_mouseDirV*event.rTime*30.0f*m_speed; -//? if ( m_backDist < 10.0f ) m_backDist = 10.0f; -//? if ( m_backDist > 200.0f ) m_backDist = 200.0f; -#else - if ( m_mousePos.y >= 0.18f && m_mousePos.y <= 0.93f ) - { -//? m_addDirectionH = -(m_mousePos.x-0.5f)*4.0f; - m_addDirectionV = (m_mousePos.y-0.5f)*2.0f; -//? if ( m_bCameraInvertX ) m_addDirectionH = -m_addDirectionH; - if ( m_bCameraInvertY ) m_addDirectionV = -m_addDirectionV; - - if ( m_mousePos.x < 0.5f ) m_motorTurn = -1.0f; - if ( m_mousePos.x > 0.5f ) m_motorTurn = 1.0f; - - mouse = m_mousePos; - mouse.x = 0.5f; - m_engine->MoveMousePos(mouse); - } - else - { - m_addDirectionH = 0.0f; - m_addDirectionV = 0.0f; - } -#endif - } - } - - if ( m_mouseDirH != 0 || m_mouseDirV != 0 ) - { - AbortCentering(); // special stops framing - } - - // Increase the special framework. - centeringH = 0.0f; - centeringV = 0.0f; - centeringD = 0.0f; - - if ( m_centeringPhase == CP_START ) - { - m_centeringProgress += event.rTime/m_centeringTime; - if ( m_centeringProgress > 1.0f ) m_centeringProgress = 1.0f; - centeringH = m_centeringProgress; - centeringV = m_centeringProgress; - centeringD = m_centeringProgress; - if ( m_centeringProgress >= 1.0f ) - { - m_centeringPhase = CP_WAIT; - } - } - - if ( m_centeringPhase == CP_WAIT ) - { - centeringH = 1.0f; - centeringV = 1.0f; - centeringD = 1.0f; - } - - if ( m_centeringPhase == CP_STOP ) - { - m_centeringProgress += event.rTime/m_centeringTime; - if ( m_centeringProgress > 1.0f ) m_centeringProgress = 1.0f; - centeringH = 1.0f-m_centeringProgress; - centeringV = 1.0f-m_centeringProgress; - centeringD = 1.0f-m_centeringProgress; - if ( m_centeringProgress >= 1.0f ) - { - m_centeringPhase = CP_NULL; - } - } - - if ( m_centeringAngleH == 99.9f ) centeringH = 0.0f; - if ( m_centeringAngleV == 99.9f ) centeringV = 0.0f; - if ( m_centeringDist == 0.0f ) centeringD = 0.0f; - - if ( m_cameraObj != 0 ) - { - vLookatPt = m_cameraObj->RetPosition(0); - if ( type == OBJECT_BASE ) vLookatPt.y += 40.0f; - else if ( type == OBJECT_HUMAN ) vLookatPt.y += 1.0f; - else if ( type == OBJECT_TECH ) vLookatPt.y += 1.0f; - else vLookatPt.y += 4.0f; - - h = -m_cameraObj->RetAngleY(0); // angle vehicle / building - - if ( type == OBJECT_DERRICK || - type == OBJECT_FACTORY || - type == OBJECT_REPAIR || - type == OBJECT_DESTROYER|| - type == OBJECT_STATION || - type == OBJECT_CONVERT || - type == OBJECT_TOWER || - type == OBJECT_RESEARCH || - type == OBJECT_RADAR || - type == OBJECT_INFO || - type == OBJECT_ENERGY || - type == OBJECT_LABO || - type == OBJECT_NUCLEAR || - type == OBJECT_PARA || - type == OBJECT_SAFE || - type == OBJECT_HUSTON || - type == OBJECT_START || - type == OBJECT_END ) // building? - { - h += PI*0.20f; // nearly face - } - else // vehicle? - { - h += PI; // back - } - h = NormAngle(h)+m_remotePan; - v = 0.0f; //? - - h += m_centeringCurrentH; - h += m_addDirectionH*(1.0f-centeringH); - h = NormAngle(h); - - if ( type == OBJECT_MOBILEdr ) // designer? - { - v -= 0.3f; // Camera top - } - - v += m_centeringCurrentV; - v += m_addDirectionV*(1.0f-centeringV); - - d = m_backDist; - d += m_centeringDist*centeringD; - - m_centeringCurrentH = m_centeringAngleH*centeringH; - m_centeringCurrentV = m_centeringAngleV*centeringV; - - m_eyePt = RotateView(vLookatPt, h, v, d); - - physics = m_cameraObj->RetPhysics(); - if ( physics != 0 && physics->RetLand() ) // ground? - { - pos = vLookatPt+(vLookatPt-m_eyePt); - floor = m_terrain->RetFloorHeight(pos)-4.0f; - if ( floor > 0.0f ) - { - m_eyePt.y += floor; // shows the descent in front - } - } - - m_eyePt = ExcludeTerrain(m_eyePt, vLookatPt, h, v); - m_eyePt = ExcludeObject(m_eyePt, vLookatPt, h, v); - - SetViewTime(m_eyePt, vLookatPt, event.rTime); - - m_directionH = h+PI/2.0f; - m_directionV = v; - } - - return TRUE; -} - -// Moves the point of view. - -BOOL CCamera::EventFrameFix(const Event &event) -{ - D3DVECTOR pos, vLookatPt; - float h, v, d; - - // +/-. - if ( event.keyState & KS_NUMPLUS ) - { - m_fixDist -= event.rTime*30.0f*m_speed; - if ( m_fixDist < 10.0f ) m_fixDist = 10.0f; - } - if ( event.keyState & KS_NUMMINUS ) - { - m_fixDist += event.rTime*30.0f*m_speed; - if ( m_fixDist > 200.0f ) m_fixDist = 200.0f; - } - - if ( m_bCameraScroll ) - { - // Left/Right. - m_fixDirectionH += m_mouseDirH*event.rTime*1.0f*m_speed; - m_fixDirectionH = NormAngle(m_fixDirectionH); - - // Up/Down. -//? m_fixDist -= m_mouseDirV*event.rTime*30.0f*m_speed; -//? if ( m_fixDist < 10.0f ) m_fixDist = 10.0f; -//? if ( m_fixDist > 200.0f ) m_fixDist = 200.0f; - } - - if ( m_mouseDirH != 0 || m_mouseDirV != 0 ) - { - AbortCentering(); // special stops framing - } - - if ( m_cameraObj != 0 ) - { - vLookatPt = m_cameraObj->RetPosition(0); - - h = m_fixDirectionH+m_remotePan; - v = m_fixDirectionV; - - d = m_fixDist; -//- if ( m_type == CAMERA_PLANE ) d += 20.0f; - m_eyePt = RotateView(vLookatPt, h, v, d); -//- if ( m_type == CAMERA_PLANE ) m_eyePt.y += 50.0f; - if ( m_type == CAMERA_PLANE ) m_eyePt.y += m_fixDist/2.0f; - m_eyePt = ExcludeTerrain(m_eyePt, vLookatPt, h, v); - m_eyePt = ExcludeObject(m_eyePt, vLookatPt, h, v); - - SetViewTime(m_eyePt, vLookatPt, event.rTime); - - m_directionH = h+PI/2.0f; - m_directionV = v; - } - - return TRUE; -} - -// Moves the point of view. - -BOOL CCamera::EventFrameExplo(const Event &event) -{ - D3DVECTOR pos, vLookatPt; - float factor; - - factor = m_heightEye*0.5f+30.0f; - - if ( m_mouseDirH != 0.0f ) - { - m_directionH -= m_mouseDirH*event.rTime*0.7f*m_speed; - } - - m_terrain->ValidPosition(m_eyePt, 10.0f); - - if ( m_terrain->MoveOnFloor(m_eyePt, FALSE) ) - { - m_eyePt.y += m_heightEye; - - pos = m_eyePt; - if ( m_terrain->MoveOnFloor(pos, FALSE) ) - { - pos.y += 2.0f; - if ( m_eyePt.y < pos.y ) - { - m_eyePt.y = pos.y; - } - } - - } - - vLookatPt = LookatPoint( m_eyePt, m_directionH, m_directionV, 50.0f ); - - if ( m_terrain->MoveOnFloor(vLookatPt, TRUE) ) - { - vLookatPt.y += m_heightLookat; - } - - SetViewTime(m_eyePt, vLookatPt, event.rTime); - - return TRUE; -} - -// Moves the point of view. - -BOOL CCamera::EventFrameOnBoard(const Event &event) -{ - D3DVECTOR vLookatPt, vUpVec, eye, lookat, pos; - - if ( m_cameraObj != 0 ) - { - m_cameraObj->SetViewFromHere(m_eyePt, m_directionH, m_directionV, - vLookatPt, vUpVec, m_type); - eye = m_effectOffset*0.3f+m_eyePt; - lookat = m_effectOffset*0.3f+vLookatPt; - - SetViewParams(eye, lookat, vUpVec); - m_actualEye = eye; - m_actualLookat = lookat; - } - return TRUE; -} - -// Moves the point of view. - -BOOL CCamera::EventFrameInfo(const Event &event) -{ - SetViewTime(D3DVECTOR(0.0f, 0.0f, 0.0f), - D3DVECTOR(0.0f, 0.0f, 1.0f), - event.rTime); - return TRUE; -} - -// Moves the point of view. - -BOOL CCamera::EventFrameVisit(const Event &event) -{ - D3DVECTOR eye; - float angleH, angleV; - - m_visitTime += event.rTime; - - // +/-. - if ( event.keyState & KS_NUMPLUS ) - { - m_visitDist -= event.rTime*50.0f*m_speed; - if ( m_visitDist < 20.0f ) m_visitDist = 20.0f; - } - if ( event.keyState & KS_NUMMINUS ) - { - m_visitDist += event.rTime*50.0f*m_speed; - if ( m_visitDist > 200.0f ) m_visitDist = 200.0f; - } - - // PageUp/Down. - if ( event.keyState & KS_PAGEUP ) - { - m_visitDirectionV -= event.rTime*1.0f*m_speed; - if ( m_visitDirectionV < -PI*0.40f ) m_visitDirectionV = -PI*0.40f; - } - if ( event.keyState & KS_PAGEDOWN ) - { - m_visitDirectionV += event.rTime*1.0f*m_speed; - if ( m_visitDirectionV > 0.0f ) m_visitDirectionV = 0.0f; - } - - if ( m_bCameraScroll ) - { - m_visitDist -= m_mouseDirV*event.rTime*30.0f*m_speed; - if ( m_visitDist < 20.0f ) m_visitDist = 20.0f; - if ( m_visitDist > 200.0f ) m_visitDist = 200.0f; - } - - angleH = (m_visitTime/10.0f)*(PI*2.0f); - angleV = m_visitDirectionV; - eye = RotateView(m_visitGoal, angleH, angleV, m_visitDist); - eye = ExcludeTerrain(eye, m_visitGoal, angleH, angleV); - eye = ExcludeObject(eye, m_visitGoal, angleH, angleV); - SetViewTime(eye, m_visitGoal, event.rTime); - - return TRUE; -} - -// Moves the point of view. - -BOOL CCamera::EventFrameScript(const Event &event) -{ - SetViewTime(m_scriptEye+m_effectOffset, - m_scriptLookat+m_effectOffset, event.rTime); - return TRUE; -} - -void CCamera::SetScriptEye(D3DVECTOR eye) -{ - m_scriptEye = eye; -} - -void CCamera::SetScriptLookat(D3DVECTOR lookat) -{ - m_scriptLookat = lookat; -} - - -// Specifies the location and direction of view. - -void CCamera::SetViewParams(const D3DVECTOR &eye, const D3DVECTOR &lookat, - const D3DVECTOR &up) -{ - BOOL bUnder; - - m_engine->SetViewParams(eye, lookat, up, m_eyeDistance); - - bUnder = (eye.y < m_water->RetLevel()); // Is it underwater? - if ( m_type == CAMERA_INFO ) bUnder = FALSE; - m_engine->SetRankView(bUnder?1:0); -} - - -// Adjusts the camera not to enter the field. - -D3DVECTOR CCamera::ExcludeTerrain(D3DVECTOR eye, D3DVECTOR lookat, - float &angleH, float &angleV) -{ - D3DVECTOR pos; - float dist; - - pos = eye; - if ( m_terrain->MoveOnFloor(pos) ) - { - dist = Length2d(lookat, pos); - pos.y += 2.0f+dist*0.1f; - if ( pos.y > eye.y ) - { - angleV = -RotateAngle(dist, pos.y-lookat.y); - eye = RotateView(lookat, angleH, angleV, dist); - } - } - return eye; -} - -// Adjusts the camera not to enter an object. - -D3DVECTOR CCamera::ExcludeObject(D3DVECTOR eye, D3DVECTOR lookat, - float &angleH, float &angleV) -{ - CObject* pObj; - D3DVECTOR oPos; - float oRad, dist; - int i, j; - -return eye; -//? - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - j = 0; - while ( pObj->GetCrashSphere(j++, oPos, oRad) ) - { - dist = Length(oPos, eye); - if ( dist < oRad+2.0f ) - { - eye.y = oPos.y+oRad+2.0f; - } - } - } - - return eye; -} - - diff --git a/src/camera.h b/src/camera.h deleted file mode 100644 index f38db1a..0000000 --- a/src/camera.h +++ /dev/null @@ -1,271 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// camera.h - -#ifndef _CAMERA_H_ -#define _CAMERA_H_ - - -#include "d3dengine.h" -#include "struct.h" - - -class CInstanceManager; -class CD3DEngine; -class CTerrain; -class CWater; -class CObject; - - -enum CameraType -{ - CAMERA_NULL = 0, // camera undefined - CAMERA_FREE = 1, // camera free (never in principle) - CAMERA_EDIT = 2, // camera while editing a program - CAMERA_ONBOARD = 3, // camera on board a robot - CAMERA_BACK = 4, // camera behind a robot - CAMERA_FIX = 5, // static camera following robot - CAMERA_EXPLO = 6, // camera steady after explosion - CAMERA_SCRIPT = 7, // camera during a film script - CAMERA_INFO = 8, // camera for displaying information - CAMERA_VISIT = 9, // visit instead of an error - CAMERA_DIALOG = 10, // camera for dialogue - CAMERA_PLANE = 11, // static camera height -}; - -enum CameraSmooth -{ - CS_NONE = 0, // sharp - CS_NORM = 1, // normal - CS_HARD = 2, // hard - CS_SPEC = 3, // special -}; - -enum CenteringPhase -{ - CP_NULL = 0, - CP_START = 1, - CP_WAIT = 2, - CP_STOP = 3, -}; - -enum CameraEffect -{ - CE_NULL = 0, // no effect - CE_TERRAFORM = 1, // digging in - CE_CRASH = 2, // Vehicle driving is severely - CE_EXPLO = 3, // explosion - CE_SHOT = 4, // not mortal shot - CE_VIBRATION = 5, // vibration during construction - CE_PET = 6, // spleen reactor -}; - -enum OverEffect -{ - OE_NULL = 0, // no effect - OE_BLOOD = 1, // flash red - OE_FADEINw = 2, // white -> nothing - OE_FADEOUTw = 3, // nothing -> white - OE_FADEOUTb = 4, // nothing -> blue - OE_BLITZ = 5, // lightning -}; - - - -class CCamera -{ -public: - CCamera(CInstanceManager* iMan); - ~CCamera(); - - BOOL EventProcess(const Event &event); - - void Init(D3DVECTOR eye, D3DVECTOR lookat, float delay); - - void SetObject(CObject* object); - CObject* RetObject(); - - void SetType(CameraType type); - CameraType RetType(); - - void SetSmooth(CameraSmooth type); - CameraSmooth RetSmoth(); - - void SetDist(float dist); - float RetDist(); - - void SetFixDirection(float angle); - float RetFixDirection(); - - void SetRemotePan(float value); - float RetRemotePan(); - - void SetRemoteZoom(float value); - float RetRemoteZoom(); - - void StartVisit(D3DVECTOR goal, float dist); - void StopVisit(); - - void RetCamera(D3DVECTOR &eye, D3DVECTOR &lookat); - - BOOL StartCentering(CObject *object, float angleH, float angleV, float dist, float time); - BOOL StopCentering(CObject *object, float time); - void AbortCentering(); - - void FlushEffect(); - void StartEffect(CameraEffect effect, D3DVECTOR pos, float force); - - void FlushOver(); - void SetOverBaseColor(D3DCOLORVALUE color); - void StartOver(OverEffect effect, D3DVECTOR pos, float force); - - void FixCamera(); - void SetScriptEye(D3DVECTOR eye); - void SetScriptLookat(D3DVECTOR lookat); - - void SetEffect(BOOL bEnable); - void SetCameraScroll(BOOL bScroll); - void SetCameraInvertX(BOOL bInvert); - void SetCameraInvertY(BOOL bInvert); - - float RetMotorTurn(); - D3DMouse RetMouseDef(FPOINT pos); - -protected: - BOOL EventMouseMove(const Event &event); - void EventMouseWheel(int dir); - BOOL EventFrame(const Event &event); - BOOL EventFrameFree(const Event &event); - BOOL EventFrameEdit(const Event &event); - BOOL EventFrameDialog(const Event &event); - BOOL EventFrameBack(const Event &event); - BOOL EventFrameFix(const Event &event); - BOOL EventFrameExplo(const Event &event); - BOOL EventFrameOnBoard(const Event &event); - BOOL EventFrameInfo(const Event &event); - BOOL EventFrameVisit(const Event &event); - BOOL EventFrameScript(const Event &event); - - void SetViewTime(const D3DVECTOR &vEyePt, const D3DVECTOR &vLookatPt, float rTime); - BOOL IsCollision(D3DVECTOR &eye, D3DVECTOR lookat); - BOOL IsCollisionBack(D3DVECTOR &eye, D3DVECTOR lookat); - BOOL IsCollisionFix(D3DVECTOR &eye, D3DVECTOR lookat); - - D3DVECTOR ExcludeTerrain(D3DVECTOR eye, D3DVECTOR lookat, float &angleH, float &angleV); - D3DVECTOR ExcludeObject(D3DVECTOR eye, D3DVECTOR lookat, float &angleH, float &angleV); - - void SetViewParams(const D3DVECTOR &eye, const D3DVECTOR &lookat, const D3DVECTOR &up); - void EffectFrame(const Event &event); - void OverFrame(const Event &event); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CTerrain* m_terrain; - CWater* m_water; - - CameraType m_type; // the type of camera (CAMERA *) - CameraSmooth m_smooth; // type of smoothing - CObject* m_cameraObj; // object linked to the camera - - float m_eyeDistance; // distance between the eyes - float m_initDelay; // time of initial centering - - D3DVECTOR m_actualEye; // current eye - D3DVECTOR m_actualLookat; // aim current - D3DVECTOR m_finalEye; // final eye - D3DVECTOR m_finalLookat; // aim final - D3DVECTOR m_normEye; // normal eye - D3DVECTOR m_normLookat; // aim normal - float m_focus; - - BOOL m_bRightDown; - FPOINT m_rightPosInit; - FPOINT m_rightPosCenter; - FPOINT m_rightPosMove; - - D3DVECTOR m_eyePt; // CAMERA_FREE: eye - float m_directionH; // CAMERA_FREE: horizontal direction - float m_directionV; // CAMERA_FREE: vertical direction - float m_heightEye; // CAMERA_FREE: height above the ground - float m_heightLookat; // CAMERA_FREE: height above the ground - float m_speed; // CAMERA_FREE: speed of movement - - float m_backDist; // CAMERA_BACK: distance - float m_backMin; // CAMERA_BACK: distance minimal - float m_addDirectionH; // CAMERA_BACK: additional direction - float m_addDirectionV; // CAMERA_BACK: additional direction - BOOL m_bTransparency; - - float m_fixDist; // CAMERA_FIX: distance - float m_fixDirectionH; // CAMERA_FIX: direction - float m_fixDirectionV; // CAMERA_FIX: direction - - D3DVECTOR m_visitGoal; // CAMERA_VISIT: target position - float m_visitDist; // CAMERA_VISIT: distance - float m_visitTime; // CAMERA_VISIT: relative time - CameraType m_visitType; // CAMERA_VISIT: initial type - float m_visitDirectionH; // CAMERA_VISIT: direction - float m_visitDirectionV; // CAMERA_VISIT: direction - - float m_editHeight; // CAMERA_EDIT: height - - float m_remotePan; - float m_remoteZoom; - - FPOINT m_mousePos; - float m_mouseDirH; - float m_mouseDirV; - float m_mouseMarging; - - float m_motorTurn; - - CenteringPhase m_centeringPhase; - float m_centeringAngleH; - float m_centeringAngleV; - float m_centeringDist; - float m_centeringCurrentH; - float m_centeringCurrentV; - float m_centeringTime; - float m_centeringProgress; - - CameraEffect m_effectType; - D3DVECTOR m_effectPos; - float m_effectForce; - float m_effectProgress; - D3DVECTOR m_effectOffset; - - OverEffect m_overType; - float m_overForce; - float m_overTime; - D3DCOLORVALUE m_overColorBase; - D3DCOLORVALUE m_overColor; - int m_overMode; - float m_overFadeIn; - float m_overFadeOut; - - D3DVECTOR m_scriptEye; - D3DVECTOR m_scriptLookat; - - BOOL m_bEffect; // shocks if explosion? - BOOL m_bCameraScroll; // scroll in the edges? - BOOL m_bCameraInvertX; // X inversion in the edges? - BOOL m_bCameraInvertY; // Y inversion in the edges? -}; - - -#endif //_CAMERA_H_ diff --git a/src/cbottoken.cpp b/src/cbottoken.cpp deleted file mode 100644 index d97239d..0000000 --- a/src/cbottoken.cpp +++ /dev/null @@ -1,521 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "language.h" -#include "global.h" -#include "event.h" -#include "object.h" -#include "cbottoken.h" - - - - -// Seeking the name of an object. - -char* RetObjectName(ObjectType type) -{ - if ( type == OBJECT_PORTICO ) return "Portico"; - if ( type == OBJECT_BASE ) return "SpaceShip"; - if ( type == OBJECT_DERRICK ) return "Derrick"; - if ( type == OBJECT_FACTORY ) return "BotFactory"; - if ( type == OBJECT_STATION ) return "PowerStation"; - if ( type == OBJECT_CONVERT ) return "Converter"; - if ( type == OBJECT_REPAIR ) return "RepairCenter"; - if ( type == OBJECT_DESTROYER ) return "Destroyer"; - if ( type == OBJECT_TOWER ) return "DefenseTower"; - if ( type == OBJECT_NEST ) return "AlienNest"; - if ( type == OBJECT_RESEARCH ) return "ResearchCenter"; - if ( type == OBJECT_RADAR ) return "RadarStation"; - if ( type == OBJECT_INFO ) return "ExchangePost"; - if ( type == OBJECT_ENERGY ) return "PowerPlant"; - if ( type == OBJECT_LABO ) return "AutoLab"; - if ( type == OBJECT_NUCLEAR ) return "NuclearPlant"; - if ( type == OBJECT_PARA ) return "PowerCaptor"; - if ( type == OBJECT_SAFE ) return "Vault"; - if ( type == OBJECT_HUSTON ) return "Houston"; - if ( type == OBJECT_TARGET1 ) return "Target1"; - if ( type == OBJECT_TARGET2 ) return "Target2"; - if ( type == OBJECT_START ) return "StartArea"; - if ( type == OBJECT_END ) return "GoalArea"; - if ( type == OBJECT_TEEN34 ) return "Stone"; - if ( type == OBJECT_STONE ) return "TitaniumOre"; - if ( type == OBJECT_URANIUM ) return "UraniumOre"; - if ( type == OBJECT_METAL ) return "Titanium"; - if ( type == OBJECT_POWER ) return "PowerCell"; - if ( type == OBJECT_ATOMIC ) return "NuclearCell"; - if ( type == OBJECT_BULLET ) return "OrgaMatter"; - if ( type == OBJECT_BBOX ) return "BlackBox"; - if ( type == OBJECT_KEYa ) return "KeyA"; - if ( type == OBJECT_KEYb ) return "KeyB"; - if ( type == OBJECT_KEYc ) return "KeyC"; - if ( type == OBJECT_KEYd ) return "KeyD"; - if ( type == OBJECT_TNT ) return "TNT"; - if ( type == OBJECT_SCRAP1 ) return "Scrap"; - if ( type == OBJECT_BOMB ) return "Mine"; - if ( type == OBJECT_BARRIER1 ) return "Barrier"; - if ( type == OBJECT_WAYPOINT ) return "WayPoint"; - if ( type == OBJECT_FLAGb ) return "BlueFlag"; - if ( type == OBJECT_FLAGr ) return "RedFlag"; - if ( type == OBJECT_FLAGg ) return "GreenFlag"; - if ( type == OBJECT_FLAGy ) return "YellowFlag"; - if ( type == OBJECT_FLAGv ) return "VioletFlag"; - if ( type == OBJECT_MARKPOWER ) return "PowerSpot"; - if ( type == OBJECT_MARKSTONE ) return "TitaniumSpot"; - if ( type == OBJECT_MARKURANIUM ) return "UraniumSpot"; - if ( type == OBJECT_MARKKEYa ) return "KeyASpot"; - if ( type == OBJECT_MARKKEYb ) return "KeyBSpot"; - if ( type == OBJECT_MARKKEYc ) return "KeyCSpot"; - if ( type == OBJECT_MARKKEYd ) return "KeyDSpot"; - if ( type == OBJECT_MOBILEwt ) return "PracticeBot"; - if ( type == OBJECT_MOBILEwa ) return "WheeledGrabber"; - if ( type == OBJECT_MOBILEta ) return "TrackedGrabber"; - if ( type == OBJECT_MOBILEfa ) return "WingedGrabber"; - if ( type == OBJECT_MOBILEia ) return "LeggedGrabber"; - if ( type == OBJECT_MOBILEwc ) return "WheeledShooter"; - if ( type == OBJECT_MOBILEtc ) return "TrackedShooter"; - if ( type == OBJECT_MOBILEfc ) return "WingedShooter"; - if ( type == OBJECT_MOBILEic ) return "LeggedShooter"; - if ( type == OBJECT_MOBILEwi ) return "WheeledOrgaShooter"; - if ( type == OBJECT_MOBILEti ) return "TrackedOrgaShooter"; - if ( type == OBJECT_MOBILEfi ) return "WingedOrgaShooter"; - if ( type == OBJECT_MOBILEii ) return "LeggedOrgaShooter"; - if ( type == OBJECT_MOBILEws ) return "WheeledSniffer"; - if ( type == OBJECT_MOBILEts ) return "TrackedSniffer"; - if ( type == OBJECT_MOBILEfs ) return "WingedSniffer"; - if ( type == OBJECT_MOBILEis ) return "LeggedSniffer"; - if ( type == OBJECT_MOBILErt ) return "Thumper"; - if ( type == OBJECT_MOBILErc ) return "PhazerShooter"; - if ( type == OBJECT_MOBILErr ) return "Recycler"; - if ( type == OBJECT_MOBILErs ) return "Shielder"; - if ( type == OBJECT_MOBILEsa ) return "Subber"; - if ( type == OBJECT_MOBILEtg ) return "TargetBot"; - if ( type == OBJECT_MOBILEdr ) return "Scribbler"; - if ( type == OBJECT_HUMAN ) return "Me"; - if ( type == OBJECT_TECH ) return "Tech"; - if ( type == OBJECT_MOTHER ) return "AlienQueen"; - if ( type == OBJECT_EGG ) return "AlienEgg"; - if ( type == OBJECT_ANT ) return "AlienAnt"; - if ( type == OBJECT_SPIDER ) return "AlienSpider"; - if ( type == OBJECT_BEE ) return "AlienWasp"; - if ( type == OBJECT_WORM ) return "AlienWorm"; - if ( type == OBJECT_RUINmobilew1) return "Wreck"; - return ""; -} - -// Seeking the name of a secondary object. -// (because Otto thinks that Germans do not like nuclear power) - -char* RetObjectAlias(ObjectType type) -{ - if ( type == OBJECT_NUCLEAR ) return "FuelCellPlant"; - if ( type == OBJECT_URANIUM ) return "PlatinumOre"; - if ( type == OBJECT_ATOMIC ) return "FuelCell"; - if ( type == OBJECT_MARKURANIUM ) return "PlatinumSpot"; - if ( type == OBJECT_ENERGY ) return "Disintegrator"; // for K-CeeBot - return ""; -} - - -// Returns the help file to use for the object. - -char* RetHelpFilename(ObjectType type) -{ - if ( type == OBJECT_BASE ) return "help\\object\\base.txt"; - if ( type == OBJECT_DERRICK ) return "help\\object\\derrick.txt"; - if ( type == OBJECT_FACTORY ) return "help\\object\\factory.txt"; - if ( type == OBJECT_STATION ) return "help\\object\\station.txt"; - if ( type == OBJECT_CONVERT ) return "help\\object\\convert.txt"; - if ( type == OBJECT_REPAIR ) return "help\\object\\repair.txt"; - if ( type == OBJECT_DESTROYER ) return "help\\object\\destroy.txt"; - if ( type == OBJECT_TOWER ) return "help\\object\\tower.txt"; - if ( type == OBJECT_NEST ) return "help\\object\\nest.txt"; - if ( type == OBJECT_RESEARCH ) return "help\\object\\research.txt"; - if ( type == OBJECT_RADAR ) return "help\\object\\radar.txt"; - if ( type == OBJECT_INFO ) return "help\\object\\exchange.txt"; - if ( type == OBJECT_ENERGY ) return "help\\object\\energy.txt"; - if ( type == OBJECT_LABO ) return "help\\object\\labo.txt"; - if ( type == OBJECT_NUCLEAR ) return "help\\object\\nuclear.txt"; - if ( type == OBJECT_PARA ) return "help\\object\\captor.txt"; - if ( type == OBJECT_SAFE ) return "help\\object\\safe.txt"; - if ( type == OBJECT_HUSTON ) return "help\\object\\huston.txt"; - if ( type == OBJECT_START ) return "help\\object\\start.txt"; - if ( type == OBJECT_END ) return "help\\object\\goal.txt"; - if ( type == OBJECT_STONE ) return "help\\object\\titanore.txt"; - if ( type == OBJECT_URANIUM ) return "help\\object\\uranore.txt"; - if ( type == OBJECT_METAL ) return "help\\object\\titan.txt"; - if ( type == OBJECT_POWER ) return "help\\object\\power.txt"; - if ( type == OBJECT_ATOMIC ) return "help\\object\\atomic.txt"; - if ( type == OBJECT_BULLET ) return "help\\object\\bullet.txt"; - if ( type == OBJECT_BBOX ) return "help\\object\\bbox.txt"; - if ( type == OBJECT_KEYa ) return "help\\object\\key.txt"; - if ( type == OBJECT_KEYb ) return "help\\object\\key.txt"; - if ( type == OBJECT_KEYc ) return "help\\object\\key.txt"; - if ( type == OBJECT_KEYd ) return "help\\object\\key.txt"; - if ( type == OBJECT_TNT ) return "help\\object\\tnt.txt"; - if ( type == OBJECT_SCRAP1 ) return "help\\object\\scrap.txt"; - if ( type == OBJECT_BOMB ) return "help\\object\\mine.txt"; - if ( type == OBJECT_BARRIER1 ) return "help\\object\\barrier.txt"; - if ( type == OBJECT_WAYPOINT ) return "help\\object\\waypoint.txt"; - if ( type == OBJECT_FLAGb ) return "help\\object\\flag.txt"; - if ( type == OBJECT_FLAGr ) return "help\\object\\flag.txt"; - if ( type == OBJECT_FLAGg ) return "help\\object\\flag.txt"; - if ( type == OBJECT_FLAGy ) return "help\\object\\flag.txt"; - if ( type == OBJECT_FLAGv ) return "help\\object\\flag.txt"; - if ( type == OBJECT_MARKPOWER ) return "help\\object\\enerspot.txt"; - if ( type == OBJECT_MARKSTONE ) return "help\\object\\stonspot.txt"; - if ( type == OBJECT_MARKURANIUM ) return "help\\object\\uranspot.txt"; - if ( type == OBJECT_MOBILEwa ) return "help\\object\\botgr.txt"; - if ( type == OBJECT_MOBILEta ) return "help\\object\\botgc.txt"; - if ( type == OBJECT_MOBILEfa ) return "help\\object\\botgj.txt"; - if ( type == OBJECT_MOBILEia ) return "help\\object\\botgs.txt"; - if ( type == OBJECT_MOBILEws ) return "help\\object\\botsr.txt"; - if ( type == OBJECT_MOBILEts ) return "help\\object\\botsc.txt"; - if ( type == OBJECT_MOBILEfs ) return "help\\object\\botsj.txt"; - if ( type == OBJECT_MOBILEis ) return "help\\object\\botss.txt"; - if ( type == OBJECT_MOBILEwi ) return "help\\object\\botor.txt"; - if ( type == OBJECT_MOBILEti ) return "help\\object\\botoc.txt"; - if ( type == OBJECT_MOBILEfi ) return "help\\object\\botoj.txt"; - if ( type == OBJECT_MOBILEii ) return "help\\object\\botos.txt"; - if ( type == OBJECT_MOBILEwc ) return "help\\object\\botfr.txt"; - if ( type == OBJECT_MOBILEtc ) return "help\\object\\botfc.txt"; - if ( type == OBJECT_MOBILEfc ) return "help\\object\\botfj.txt"; - if ( type == OBJECT_MOBILEic ) return "help\\object\\botfs.txt"; - if ( type == OBJECT_MOBILErt ) return "help\\object\\bottump.txt"; - if ( type == OBJECT_MOBILErc ) return "help\\object\\botphaz.txt"; - if ( type == OBJECT_MOBILErr ) return "help\\object\\botrecy.txt"; - if ( type == OBJECT_MOBILErs ) return "help\\object\\botshld.txt"; - if ( type == OBJECT_MOBILEsa ) return "help\\object\\botsub.txt"; - if ( type == OBJECT_MOBILEwt ) return "help\\object\\bottr.txt"; - if ( type == OBJECT_MOBILEtg ) return "help\\object\\bottarg.txt"; - if ( type == OBJECT_MOBILEdr ) return "help\\object\\botdraw.txt"; - if ( type == OBJECT_APOLLO2 ) return "help\\object\\lrv.txt"; - if ( type == OBJECT_HUMAN ) return "help\\object\\human.txt"; - if ( type == OBJECT_MOTHER ) return "help\\object\\mother.txt"; - if ( type == OBJECT_EGG ) return "help\\object\\egg.txt"; - if ( type == OBJECT_ANT ) return "help\\object\\ant.txt"; - if ( type == OBJECT_SPIDER ) return "help\\object\\spider.txt"; - if ( type == OBJECT_BEE ) return "help\\object\\wasp.txt"; - if ( type == OBJECT_WORM ) return "help\\object\\worm.txt"; - if ( type == OBJECT_RUINmobilew1) return "help\\object\\wreck.txt"; - return ""; -} - - -// Returns the help file to use for instruction. - -char* RetHelpFilename(const char *token) -{ - if ( strcmp(token, "if" ) == 0 ) return "help\\cbot\\if.txt"; - if ( strcmp(token, "else" ) == 0 ) return "help\\cbot\\if.txt"; - if ( strcmp(token, "repeat" ) == 0 ) return "help\\cbot\\repeat.txt"; - if ( strcmp(token, "for" ) == 0 ) return "help\\cbot\\for.txt"; - if ( strcmp(token, "while" ) == 0 ) return "help\\cbot\\while.txt"; - if ( strcmp(token, "do" ) == 0 ) return "help\\cbot\\do.txt"; - if ( strcmp(token, "break" ) == 0 ) return "help\\cbot\\break.txt"; - if ( strcmp(token, "continue" ) == 0 ) return "help\\cbot\\continue.txt"; - if ( strcmp(token, "return" ) == 0 ) return "help\\cbot\\return.txt"; - if ( strcmp(token, "sizeof" ) == 0 ) return "help\\cbot\\sizeof.txt"; - if ( strcmp(token, "int" ) == 0 ) return "help\\cbot\\int.txt"; - if ( strcmp(token, "float" ) == 0 ) return "help\\cbot\\float.txt"; - if ( strcmp(token, "bool" ) == 0 ) return "help\\cbot\\bool.txt"; - if ( strcmp(token, "string" ) == 0 ) return "help\\cbot\\string.txt"; - if ( strcmp(token, "point" ) == 0 ) return "help\\cbot\\point.txt"; - if ( strcmp(token, "object" ) == 0 ) return "help\\cbot\\object.txt"; - if ( strcmp(token, "file" ) == 0 ) return "help\\cbot\\file.txt"; - if ( strcmp(token, "void" ) == 0 ) return "help\\cbot\\void.txt"; - if ( strcmp(token, "null" ) == 0 ) return "help\\cbot\\null.txt"; - if ( strcmp(token, "nan" ) == 0 ) return "help\\cbot\\nan.txt"; - if ( strcmp(token, "true" ) == 0 ) return "help\\cbot\\true.txt"; - if ( strcmp(token, "false" ) == 0 ) return "help\\cbot\\false.txt"; - if ( strcmp(token, "sin" ) == 0 ) return "help\\cbot\\expr.txt"; - if ( strcmp(token, "cos" ) == 0 ) return "help\\cbot\\expr.txt"; - if ( strcmp(token, "tan" ) == 0 ) return "help\\cbot\\expr.txt"; - if ( strcmp(token, "asin" ) == 0 ) return "help\\cbot\\expr.txt"; - if ( strcmp(token, "acos" ) == 0 ) return "help\\cbot\\expr.txt"; - if ( strcmp(token, "atan" ) == 0 ) return "help\\cbot\\expr.txt"; - if ( strcmp(token, "sqrt" ) == 0 ) return "help\\cbot\\expr.txt"; - if ( strcmp(token, "pow" ) == 0 ) return "help\\cbot\\expr.txt"; - if ( strcmp(token, "rand" ) == 0 ) return "help\\cbot\\expr.txt"; - if ( strcmp(token, "abs" ) == 0 ) return "help\\cbot\\expr.txt"; - if ( strcmp(token, "retobject" ) == 0 ) return "help\\cbot\\retobj.txt"; - if ( strcmp(token, "search" ) == 0 ) return "help\\cbot\\search.txt"; - if ( strcmp(token, "radar" ) == 0 ) return "help\\cbot\\radar.txt"; - if ( strcmp(token, "direction" ) == 0 ) return "help\\cbot\\direct.txt"; - if ( strcmp(token, "distance" ) == 0 ) return "help\\cbot\\dist.txt"; - if ( strcmp(token, "distance2d" ) == 0 ) return "help\\cbot\\dist2d.txt"; - if ( strcmp(token, "space" ) == 0 ) return "help\\cbot\\space.txt"; - if ( strcmp(token, "flatground" ) == 0 ) return "help\\cbot\\flatgrnd.txt"; - if ( strcmp(token, "wait" ) == 0 ) return "help\\cbot\\wait.txt"; - if ( strcmp(token, "move" ) == 0 ) return "help\\cbot\\move.txt"; - if ( strcmp(token, "turn" ) == 0 ) return "help\\cbot\\turn.txt"; - if ( strcmp(token, "goto" ) == 0 ) return "help\\cbot\\goto.txt"; - if ( strcmp(token, "find" ) == 0 ) return "help\\cbot\\find.txt"; - if ( strcmp(token, "grab" ) == 0 ) return "help\\cbot\\grab.txt"; - if ( strcmp(token, "drop" ) == 0 ) return "help\\cbot\\drop.txt"; - if ( strcmp(token, "sniff" ) == 0 ) return "help\\cbot\\sniff.txt"; - if ( strcmp(token, "receive" ) == 0 ) return "help\\cbot\\receive.txt"; - if ( strcmp(token, "send" ) == 0 ) return "help\\cbot\\send.txt"; - if ( strcmp(token, "deleteinfo" ) == 0 ) return "help\\cbot\\delinfo.txt"; - if ( strcmp(token, "testinfo" ) == 0 ) return "help\\cbot\\testinfo.txt"; - if ( strcmp(token, "thump" ) == 0 ) return "help\\cbot\\thump.txt"; - if ( strcmp(token, "recycle" ) == 0 ) return "help\\cbot\\recycle.txt"; - if ( strcmp(token, "shield" ) == 0 ) return "help\\cbot\\shield.txt"; - if ( strcmp(token, "fire" ) == 0 ) return "help\\cbot\\fire.txt"; - if ( strcmp(token, "antfire" ) == 0 ) return "help\\cbot\\antfire.txt"; - if ( strcmp(token, "aim" ) == 0 ) return "help\\cbot\\aim.txt"; - if ( strcmp(token, "motor" ) == 0 ) return "help\\cbot\\motor.txt"; - if ( strcmp(token, "jet" ) == 0 ) return "help\\cbot\\jet.txt"; - if ( strcmp(token, "topo" ) == 0 ) return "help\\cbot\\topo.txt"; - if ( strcmp(token, "message" ) == 0 ) return "help\\cbot\\message.txt"; - if ( strcmp(token, "abstime" ) == 0 ) return "help\\cbot\\abstime.txt"; - if ( strcmp(token, "BlackArrow" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "RedArrow" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "White" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "Black" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "Gray" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "LightGray" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "Red" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "Pink" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "Purple" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "Orange" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "Yellow" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "Beige" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "Brown" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "Skin" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "Green" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "LightGreen" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "Blue" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "LightBlue" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "InFront" ) == 0 ) return "help\\cbot\\grab.txt"; - if ( strcmp(token, "Behind" ) == 0 ) return "help\\cbot\\grab.txt"; - if ( strcmp(token, "EnergyCell" ) == 0 ) return "help\\cbot\\grab.txt"; - if ( strcmp(token, "DisplayError" ) == 0 ) return "help\\cbot\\message.txt"; - if ( strcmp(token, "DisplayWarning") == 0 ) return "help\\cbot\\message.txt"; - if ( strcmp(token, "DisplayInfo" ) == 0 ) return "help\\cbot\\message.txt"; - if ( strcmp(token, "DisplayMessage") == 0 ) return "help\\cbot\\message.txt"; - if ( strcmp(token, "strlen" ) == 0 ) return "help\\cbot\\string.txt"; - if ( strcmp(token, "strleft" ) == 0 ) return "help\\cbot\\string.txt"; - if ( strcmp(token, "strright" ) == 0 ) return "help\\cbot\\string.txt"; - if ( strcmp(token, "strmid" ) == 0 ) return "help\\cbot\\string.txt"; - if ( strcmp(token, "strval" ) == 0 ) return "help\\cbot\\string.txt"; - if ( strcmp(token, "strfind" ) == 0 ) return "help\\cbot\\string.txt"; - if ( strcmp(token, "strlower" ) == 0 ) return "help\\cbot\\string.txt"; - if ( strcmp(token, "strupper" ) == 0 ) return "help\\cbot\\string.txt"; - if ( strcmp(token, "open" ) == 0 ) return "help\\cbot\\open.txt"; - if ( strcmp(token, "close" ) == 0 ) return "help\\cbot\\close.txt"; - if ( strcmp(token, "writeln" ) == 0 ) return "help\\cbot\\writeln.txt"; - if ( strcmp(token, "readln " ) == 0 ) return "help\\cbot\\readln.txt"; - if ( strcmp(token, "eof" ) == 0 ) return "help\\cbot\\eof.txt"; - if ( strcmp(token, "deletefile" ) == 0 ) return "help\\cbot\\deletef.txt"; - if ( strcmp(token, "openfile" ) == 0 ) return "help\\cbot\\openfile.txt"; - if ( strcmp(token, "pendown" ) == 0 ) return "help\\cbot\\pendown.txt"; - if ( strcmp(token, "penup" ) == 0 ) return "help\\cbot\\penup.txt"; - if ( strcmp(token, "pencolor" ) == 0 ) return "help\\cbot\\pencolor.txt"; - if ( strcmp(token, "penwidth" ) == 0 ) return "help\\cbot\\penwidth.txt"; - if ( strcmp(token, "extern" ) == 0 ) return "help\\cbot\\extern.txt"; - if ( strcmp(token, "class" ) == 0 ) return "help\\cbot\\class.txt"; - if ( strcmp(token, "static" ) == 0 ) return "help\\cbot\\static.txt"; - if ( strcmp(token, "public" ) == 0 ) return "help\\cbot\\public.txt"; - if ( strcmp(token, "private" ) == 0 ) return "help\\cbot\\private.txt"; - if ( strcmp(token, "synchronized" ) == 0 ) return "help\\cbot\\synchro.txt"; - if ( strcmp(token, "new" ) == 0 ) return "help\\cbot\\new.txt"; - if ( strcmp(token, "this" ) == 0 ) return "help\\cbot\\this.txt"; - return ""; -} - - -// Test if a keyword is a type of variable. - -BOOL IsType(const char *token) -{ - if ( strcmp(token, "void" ) == 0 ) return TRUE; - if ( strcmp(token, "int" ) == 0 ) return TRUE; - if ( strcmp(token, "float" ) == 0 ) return TRUE; - if ( strcmp(token, "bool" ) == 0 ) return TRUE; - if ( strcmp(token, "string" ) == 0 ) return TRUE; - if ( strcmp(token, "point" ) == 0 ) return TRUE; - if ( strcmp(token, "object" ) == 0 ) return TRUE; - if ( strcmp(token, "file" ) == 0 ) return TRUE; - if ( strcmp(token, "this" ) == 0 ) return TRUE; - return FALSE; -} - -// Test if a keyword is a function. - -BOOL IsFunction(const char *token) -{ - if ( strcmp(token, "sin" ) == 0 ) return TRUE; - if ( strcmp(token, "cos" ) == 0 ) return TRUE; - if ( strcmp(token, "tan" ) == 0 ) return TRUE; - if ( strcmp(token, "asin" ) == 0 ) return TRUE; - if ( strcmp(token, "acos" ) == 0 ) return TRUE; - if ( strcmp(token, "atan" ) == 0 ) return TRUE; - if ( strcmp(token, "sqrt" ) == 0 ) return TRUE; - if ( strcmp(token, "pow" ) == 0 ) return TRUE; - if ( strcmp(token, "rand" ) == 0 ) return TRUE; - if ( strcmp(token, "abs" ) == 0 ) return TRUE; - if ( strcmp(token, "retobject" ) == 0 ) return TRUE; - if ( strcmp(token, "search" ) == 0 ) return TRUE; - if ( strcmp(token, "radar" ) == 0 ) return TRUE; - if ( strcmp(token, "detect" ) == 0 ) return TRUE; - if ( strcmp(token, "direction" ) == 0 ) return TRUE; - if ( strcmp(token, "distance" ) == 0 ) return TRUE; - if ( strcmp(token, "distance2d" ) == 0 ) return TRUE; - if ( strcmp(token, "space" ) == 0 ) return TRUE; - if ( strcmp(token, "flatground" ) == 0 ) return TRUE; - if ( strcmp(token, "wait" ) == 0 ) return TRUE; - if ( strcmp(token, "move" ) == 0 ) return TRUE; - if ( strcmp(token, "turn" ) == 0 ) return TRUE; - if ( strcmp(token, "goto" ) == 0 ) return TRUE; - if ( strcmp(token, "find" ) == 0 ) return TRUE; - if ( strcmp(token, "grab" ) == 0 ) return TRUE; - if ( strcmp(token, "drop" ) == 0 ) return TRUE; - if ( strcmp(token, "sniff" ) == 0 ) return TRUE; - if ( strcmp(token, "receive" ) == 0 ) return TRUE; - if ( strcmp(token, "send" ) == 0 ) return TRUE; - if ( strcmp(token, "deleteinfo" ) == 0 ) return TRUE; - if ( strcmp(token, "testinfo" ) == 0 ) return TRUE; - if ( strcmp(token, "thump" ) == 0 ) return TRUE; - if ( strcmp(token, "recycle" ) == 0 ) return TRUE; - if ( strcmp(token, "shield" ) == 0 ) return TRUE; - if ( strcmp(token, "fire" ) == 0 ) return TRUE; - if ( strcmp(token, "antfire" ) == 0 ) return TRUE; - if ( strcmp(token, "aim" ) == 0 ) return TRUE; - if ( strcmp(token, "motor" ) == 0 ) return TRUE; - if ( strcmp(token, "jet" ) == 0 ) return TRUE; - if ( strcmp(token, "topo" ) == 0 ) return TRUE; - if ( strcmp(token, "message" ) == 0 ) return TRUE; - if ( strcmp(token, "abstime" ) == 0 ) return TRUE; - if ( strcmp(token, "ismovie" ) == 0 ) return TRUE; - if ( strcmp(token, "errmode" ) == 0 ) return TRUE; - if ( strcmp(token, "ipf" ) == 0 ) return TRUE; - if ( strcmp(token, "strlen" ) == 0 ) return TRUE; - if ( strcmp(token, "strleft" ) == 0 ) return TRUE; - if ( strcmp(token, "strright" ) == 0 ) return TRUE; - if ( strcmp(token, "strmid" ) == 0 ) return TRUE; - if ( strcmp(token, "strval" ) == 0 ) return TRUE; - if ( strcmp(token, "strfind" ) == 0 ) return TRUE; - if ( strcmp(token, "strlower" ) == 0 ) return TRUE; - if ( strcmp(token, "strupper" ) == 0 ) return TRUE; - if ( strcmp(token, "open" ) == 0 ) return TRUE; - if ( strcmp(token, "close" ) == 0 ) return TRUE; - if ( strcmp(token, "writeln" ) == 0 ) return TRUE; - if ( strcmp(token, "readln" ) == 0 ) return TRUE; - if ( strcmp(token, "eof" ) == 0 ) return TRUE; - if ( strcmp(token, "deletefile" ) == 0 ) return TRUE; - if ( strcmp(token, "openfile" ) == 0 ) return TRUE; - if ( strcmp(token, "pendown" ) == 0 ) return TRUE; - if ( strcmp(token, "penup" ) == 0 ) return TRUE; - if ( strcmp(token, "pencolor" ) == 0 ) return TRUE; - if ( strcmp(token, "penwidth" ) == 0 ) return TRUE; - if ( strcmp(token, "sizeof" ) == 0 ) return TRUE; - return FALSE; -} - - -// Returns using a compact instruction. - -char* RetHelpText(const char *token) -{ - if ( strcmp(token, "if" ) == 0 ) return "if ( condition ) { bloc }"; - if ( strcmp(token, "else" ) == 0 ) return "else { bloc }"; - if ( strcmp(token, "repeat" ) == 0 ) return "repeat ( number )"; - if ( strcmp(token, "for" ) == 0 ) return "for ( before ; condition ; end )"; - if ( strcmp(token, "while" ) == 0 ) return "while ( condition ) { bloc }"; - if ( strcmp(token, "do" ) == 0 ) return "do { bloc } while ( condition );"; - if ( strcmp(token, "break" ) == 0 ) return "break;"; - if ( strcmp(token, "continue" ) == 0 ) return "continue;"; - if ( strcmp(token, "return" ) == 0 ) return "return;"; - if ( strcmp(token, "sizeof" ) == 0 ) return "sizeof( array );"; - if ( strcmp(token, "int" ) == 0 ) return "int"; - if ( strcmp(token, "sin" ) == 0 ) return "sin ( angle );"; - if ( strcmp(token, "cos" ) == 0 ) return "cos ( angle );"; - if ( strcmp(token, "tan" ) == 0 ) return "tan ( angle );"; - if ( strcmp(token, "asin" ) == 0 ) return "asin ( value );"; - if ( strcmp(token, "acos" ) == 0 ) return "acos ( value );"; - if ( strcmp(token, "atan" ) == 0 ) return "atan ( value );"; - if ( strcmp(token, "sqrt" ) == 0 ) return "sqrt ( value );"; - if ( strcmp(token, "pow" ) == 0 ) return "pow ( x, y );"; - if ( strcmp(token, "rand" ) == 0 ) return "rand ( );"; - if ( strcmp(token, "abs" ) == 0 ) return "abs ( value );"; - if ( strcmp(token, "retobject" ) == 0 ) return "retobjet ( );"; - if ( strcmp(token, "search" ) == 0 ) return "search ( );"; - if ( strcmp(token, "radar" ) == 0 ) return "radar ( cat, angle, focus, min, max, sens );"; - if ( strcmp(token, "detect" ) == 0 ) return "detect ( cat );"; - if ( strcmp(token, "direction" ) == 0 ) return "direction ( position );"; - if ( strcmp(token, "distance2d") == 0 ) return "distance2d ( p1, p2 );"; - if ( strcmp(token, "distance" ) == 0 ) return "distance ( p1, p2 );"; - if ( strcmp(token, "space" ) == 0 ) return "space ( center, rmin, rmax, dist );"; - if ( strcmp(token, "flatground") == 0 ) return "flatground ( center, rmax );"; - if ( strcmp(token, "wait" ) == 0 ) return "wait ( time );"; - if ( strcmp(token, "move" ) == 0 ) return "move ( distance );"; - if ( strcmp(token, "turn" ) == 0 ) return "turn ( angle );"; - if ( strcmp(token, "goto" ) == 0 ) return "goto ( position, altitude );"; - if ( strcmp(token, "find" ) == 0 ) return "find ( cat );"; - if ( strcmp(token, "grab" ) == 0 ) return "grab ( order );"; - if ( strcmp(token, "drop" ) == 0 ) return "drop ( order );"; - if ( strcmp(token, "sniff" ) == 0 ) return "sniff ( );"; - if ( strcmp(token, "receive" ) == 0 ) return "receive ( name, power );"; - if ( strcmp(token, "send" ) == 0 ) return "send ( name, value, power );"; - if ( strcmp(token, "deleteinfo") == 0 ) return "deleteinfo ( name, power );"; - if ( strcmp(token, "testinfo" ) == 0 ) return "testinfo ( name, power );"; - if ( strcmp(token, "thump" ) == 0 ) return "thump ( );"; - if ( strcmp(token, "recycle" ) == 0 ) return "recycle ( );"; - if ( strcmp(token, "shield" ) == 0 ) return "shield ( oper, radius );"; - if ( strcmp(token, "fire" ) == 0 ) return "fire ( time );"; - if ( strcmp(token, "antfire" ) == 0 ) return "antfire ( );"; - if ( strcmp(token, "aim" ) == 0 ) return "aim ( angle );"; - if ( strcmp(token, "motor" ) == 0 ) return "motor ( left, right );"; - if ( strcmp(token, "jet" ) == 0 ) return "jet ( power );"; - if ( strcmp(token, "topo" ) == 0 ) return "topo ( position );"; - if ( strcmp(token, "message" ) == 0 ) return "message ( string, type );"; - if ( strcmp(token, "abstime" ) == 0 ) return "abstime ( );"; - if ( strcmp(token, "ismovie" ) == 0 ) return "ismovie ( );"; - if ( strcmp(token, "errmode" ) == 0 ) return "errmode ( mdoe );"; - if ( strcmp(token, "ipf" ) == 0 ) return "ipf ( number );"; - if ( strcmp(token, "strlen" ) == 0 ) return "strlen ( string );"; - if ( strcmp(token, "strleft" ) == 0 ) return "strleft ( string, len );"; - if ( strcmp(token, "strright" ) == 0 ) return "strright ( string, len );"; - if ( strcmp(token, "strmid" ) == 0 ) return "strmid ( string, pos, len );"; - if ( strcmp(token, "strval" ) == 0 ) return "strval ( string );"; - if ( strcmp(token, "strfind" ) == 0 ) return "strfind ( string, substring );"; - if ( strcmp(token, "strlower" ) == 0 ) return "strlower ( string );"; - if ( strcmp(token, "strupper" ) == 0 ) return "strupper ( string );"; - if ( strcmp(token, "open" ) == 0 ) return "open ( filename, mode );"; - if ( strcmp(token, "close" ) == 0 ) return "close ( );"; - if ( strcmp(token, "writeln" ) == 0 ) return "writeln ( string );"; - if ( strcmp(token, "readln" ) == 0 ) return "readln ( );"; - if ( strcmp(token, "eof" ) == 0 ) return "eof ( );"; - if ( strcmp(token, "deletefile") == 0 ) return "deletefile ( filename );"; - if ( strcmp(token, "openfile" ) == 0 ) return "openfile ( filename, mode );"; - if ( strcmp(token, "pendown" ) == 0 ) return "pendown ( color, width );"; - if ( strcmp(token, "penup" ) == 0 ) return "penup ( );"; - if ( strcmp(token, "pencolor" ) == 0 ) return "pencolor ( color );"; - if ( strcmp(token, "penwidth" ) == 0 ) return "penwidth ( width );"; - return ""; -} - - diff --git a/src/cbottoken.h b/src/cbottoken.h deleted file mode 100644 index 0767b04..0000000 --- a/src/cbottoken.h +++ /dev/null @@ -1,39 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// cbottoken.h - -#ifndef _CBOTTOKEN_H_ -#define _CBOTTOKEN_H_ - - -#include "object.h" - - - -// Procedures. - -extern char* RetObjectName(ObjectType type); -extern char* RetObjectAlias(ObjectType type); -extern char* RetHelpFilename(ObjectType type); -extern char* RetHelpFilename(const char *token); -extern BOOL IsType(const char *token); -extern BOOL IsFunction(const char *token); -extern char* RetHelpText(const char *token); - - - -#endif //_CBOTTOKEN_H_ diff --git a/src/ceebot.ini b/src/ceebot.ini deleted file mode 100644 index 0de7a32..0000000 --- a/src/ceebot.ini +++ /dev/null @@ -1,66 +0,0 @@ -[Directory] -scene=scene -savegame=savegame -public=program -user=user -files=files -[Setup] -TotoMode=1 -Tooltips=1 -InterfaceGlint=1 -NiceMouse=0 -Movies=1 -NiceReset=1 -HimselfDamage=1 -CameraScroll=0 -CameraInvertX=0 -InterfaceEffect=1 -GroundShadow=1 -GroundSpot=1 -ObjectDirty=1 -FogMode=1 -LensMode=1 -SkyMode=1 -PlanetMode=1 -LightMode=1 -UseJoystick=0 -ParticuleDensity=1.00 -ClippingDistance=1.00 -ObjectDetail=2.00 -GadgetQuantity=1.00 -TextureQuality=1 -AudioVolume=4 -MidiVolume=15 -Sound3D=0 -EditIndentMode=1 -EditIndentValue=4 -KeyMap=37+0 39+0 38+0 40+0 16+0 17+0 32+258 96+262 13+257 107+261 109+260 9+259 36+263 27+0 112+0 113+0 110+0 115+0 116+0 117+0 -DeleteGamer=1 -Soluce4=1 -[Engine] -AlphaMode=1 -StateColor=-1 -BlackSrcBlend=0 -BlackDestBlend=0 -WhiteSrcBlend=0 -WhiteDestBlend=0 -DiffuseSrcBlend=0 -DiffuseDestBlend=0 -AlphaSrcBlend=0 -AlphaDestBlend=0 -[Gamer] -LastName=Linda -[Edit] -FontSize=9.00 -WindowPos.x=0.09 -WindowPos.y=0.08 -WindowDim.x=0.69 -WindowDim.y=0.84 -IOPos.x=0.36 -IOPos.y=0.15 -IODim.x=0.50 -IODim.y=0.55 -[Device] -Name=Direct3D HAL -Mode=1600 x 1200 x 32 -FullScreen=0 diff --git a/src/check.cpp b/src/check.cpp deleted file mode 100644 index f485921..0000000 --- a/src/check.cpp +++ /dev/null @@ -1,168 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "restext.h" -#include "text.h" -#include "check.h" - - - - -// Object's constructor. - -CCheck::CCheck(CInstanceManager* iMan) : CControl(iMan) -{ -} - -// Object's destructor. - -CCheck::~CCheck() -{ -} - - -// Creates a new button. - -BOOL CCheck::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - char name[100]; - char* p; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - CControl::Create(pos, dim, icon, eventMsg); - - GetResource(RES_EVENT, eventMsg, name); - p = strchr(name, '\\'); - if ( p != 0 ) *p = 0; - SetName(name); - - return TRUE; -} - - -// Management of an event. - -BOOL CCheck::EventProcess(const Event &event) -{ - if ( m_state & STATE_DEAD ) return TRUE; - - CControl::EventProcess(event); - - if ( event.event == EVENT_LBUTTONDOWN && - (m_state & STATE_VISIBLE) && - (m_state & STATE_ENABLE) ) - { - if ( CControl::Detect(event.pos) ) - { - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - return FALSE; - } - } - - return TRUE; -} - - -// Draw button. - -void CCheck::Draw() -{ - FPOINT iDim, pos; - float zoomExt, zoomInt; - int icon; - - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - iDim = m_dim; - m_dim.x = m_dim.y*0.75f; // square - - if ( m_state & STATE_SHADOW ) - { - DrawShadow(m_pos, m_dim); - } - - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATENORMAL); - - zoomExt = 1.00f; - zoomInt = 0.95f; - - icon = 2; - if ( m_state & STATE_DEFAULT ) - { - DrawPart(23, 1.3f, 0.0f); - - zoomExt *= 1.15f; - zoomInt *= 1.15f; - } - if ( m_state & STATE_HILIGHT ) - { - icon = 1; - } - if ( m_state & STATE_PRESS ) - { - icon = 3; - zoomInt *= 0.9f; - } - if ( (m_state & STATE_ENABLE) == 0 ) - { - icon = 7; - } - if ( m_state & STATE_DEAD ) - { - icon = 17; - } - DrawPart(icon, zoomExt, 0.0f); // draws the button - - if ( (m_state & STATE_DEAD) == 0 ) - { - m_engine->SetState(D3DSTATETTw); - - if ( m_state & STATE_CHECK ) - { - icon = 16; // seen - DrawPart(icon, zoomInt, 0.0f); // draw the icon - } - } - - m_dim = iDim; - - if ( m_state & STATE_DEAD ) return; - - // Draw the name. - pos.x = m_pos.x+m_dim.y/0.9f; - pos.y = m_pos.y+m_dim.y*0.50f; - pos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; - m_engine->RetText()->DrawText(m_name, pos, m_dim.x, 1, m_fontSize, m_fontStretch, m_fontType, 0); -} - - diff --git a/src/check.h b/src/check.h deleted file mode 100644 index 118b6cb..0000000 --- a/src/check.h +++ /dev/null @@ -1,48 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// check.h - -#ifndef _CHECK_H_ -#define _CHECK_H_ - - -#include "control.h" - - -class CD3DEngine; - - - -class CCheck : public CControl -{ -public: - CCheck(CInstanceManager* iMan); - virtual ~CCheck(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - - BOOL EventProcess(const Event &event); - - void Draw(); - -protected: - -protected: -}; - - -#endif //_CHECK_H_ diff --git a/src/cloud.cpp b/src/cloud.cpp deleted file mode 100644 index 8d6aeae..0000000 --- a/src/cloud.cpp +++ /dev/null @@ -1,332 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "d3dutil.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "terrain.h" -#include "object.h" -#include "cloud.h" - - - -#define DIMEXPAND 4 // extension of the dimensions - - - -// Constructor of clouds. - -CCloud::CCloud(CInstanceManager* iMan, CD3DEngine* engine) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_CLOUD, this); - - m_engine = engine; - m_terrain = 0; - - m_level = 0.0f; - m_wind = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_subdiv = 8; - m_filename[0] = 0; - m_bEnable = TRUE; -} - -// Destructor of clouds. - -CCloud::~CCloud() -{ -} - - -BOOL CCloud::EventProcess(const Event &event) -{ - if ( event.event == EVENT_FRAME ) - { - return EventFrame(event); - } - - return TRUE; -} - -// Makes the clouds evolve. - -BOOL CCloud::EventFrame(const Event &event) -{ - if ( m_engine->RetPause() ) return TRUE; - - m_time += event.rTime; - - if ( m_level == 0.0f ) return TRUE; - - if ( m_time-m_lastTest < 0.2f ) return TRUE; - m_lastTest = m_time; - - return TRUE; -} - - -// Adjusts the position to normal, to imitate the clouds -// at movement. - -void CCloud::AdjustLevel(D3DVECTOR &pos, D3DVECTOR &eye, float deep, - FPOINT &uv1, FPOINT &uv2) -{ - float dist, factor; - - uv1.x = (pos.x+20000.0f)/1280.0f; - uv1.y = (pos.z+20000.0f)/1280.0f; - uv1.x -= m_time*(m_wind.x/100.0f); - uv1.y -= m_time*(m_wind.z/100.0f); - - uv2.x = 0.0f; - uv2.y = 0.0f; - - dist = Length2d(pos, eye); - factor = powf(dist/deep, 2.0f); - pos.y -= m_level*factor*10.0f; -} - -inline DWORD F2DW( FLOAT f ) -{ - return *((DWORD*)&f); -} - -// Draw the clouds. - -void CCloud::Draw() -{ - LPDIRECT3DDEVICE7 device; - D3DVERTEX2* vertex; - D3DMATRIX* matView; - D3DMATERIAL7 material; - D3DMATRIX matrix; - D3DVECTOR n, pos, p, eye; - FPOINT uv1, uv2; - float iDeep, deep, size, fogStart, fogEnd; - int i, j, u; - - if ( !m_bEnable ) return; - if ( m_level == 0.0f ) return; - if ( m_lineUsed == 0 ) return; - - vertex = (D3DVERTEX2*)malloc(sizeof(D3DVERTEX2)*(m_brick+2)*2); - - iDeep = m_engine->RetDeepView(); - deep = (m_brick*m_size)/2.0f; - m_engine->SetDeepView(deep); - m_engine->SetFocus(m_engine->RetFocus()); - m_engine->UpdateMatProj(); // increases the depth of view - -//? fogStart = deep*0.10f; -//? fogEnd = deep*0.16f; - fogStart = deep*0.15f; - fogEnd = deep*0.24f; - - device = m_engine->RetD3DDevice(); - device->SetRenderState(D3DRENDERSTATE_AMBIENT, 0x00000000); - device->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE); - device->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); -//? device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE); - device->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE); - device->SetRenderState(D3DRENDERSTATE_FOGSTART, F2DW(fogStart)); - device->SetRenderState(D3DRENDERSTATE_FOGEND, F2DW(fogEnd)); - - matView = m_engine->RetMatView(); - device->SetTransform(D3DTRANSFORMSTATE_VIEW, matView); - - ZeroMemory( &material, sizeof(D3DMATERIAL7) ); - material.diffuse = m_diffuse; - material.ambient = m_ambient; - m_engine->SetMaterial(material); - - m_engine->SetTexture(m_filename, 0); - m_engine->SetTexture(m_filename, 1); - -//? m_engine->SetState(D3DSTATETTb|D3DSTATEDUALw|D3DSTATEWRAP); - m_engine->SetState(D3DSTATETTb|D3DSTATEFOG|D3DSTATEWRAP); -//? m_engine->SetState(D3DSTATEWRAP); - - D3DUtil_SetIdentityMatrix(matrix); - device->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); - - size = m_size/2.0f; - eye = m_engine->RetEyePt(); - n = D3DVECTOR(0.0f, -1.0f, 0.0f); - - // Draws all the lines. - for ( i=0 ; iDrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, u, NULL); - m_engine->AddStatisticTriangle(u-2); - } - - m_engine->SetDeepView(iDeep); - m_engine->SetFocus(m_engine->RetFocus()); - m_engine->UpdateMatProj(); // gives depth to initial - - free(vertex); -} - - -// Updates the positions, relative to the ground. - -BOOL CCloud::CreateLine(int x, int y, int len) -{ - float offset; - - m_line[m_lineUsed].x = x; - m_line[m_lineUsed].y = y; - m_line[m_lineUsed].len = len; - - offset = m_brick*m_size/2.0f - m_size/2.0f; - - m_line[m_lineUsed].px1 = m_size* m_line[m_lineUsed].x - offset; - m_line[m_lineUsed].px2 = m_size*(m_line[m_lineUsed].x+m_line[m_lineUsed].len) - offset; - m_line[m_lineUsed].pz = m_size* m_line[m_lineUsed].y - offset; - - m_lineUsed ++; - - return ( m_lineUsed < MAXCLOUDLINE ); -} - -// Creates all areas of cloud. - -BOOL CCloud::Create(const char *filename, - D3DCOLORVALUE diffuse, D3DCOLORVALUE ambient, - float level) -{ - int y; - - m_diffuse = diffuse; - m_ambient = ambient; - m_level = level; - m_time = 0.0f; - m_lastTest = 0.0f; - strcpy(m_filename, filename); - - if ( m_filename[0] != 0 ) - { - m_engine->LoadTexture(m_filename, 0); - m_engine->LoadTexture(m_filename, 1); - } - - if ( m_terrain == 0 ) - { - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - } - - m_wind = m_terrain->RetWind(); - - m_brick = m_terrain->RetBrick()*m_terrain->RetMosaic()*DIMEXPAND; - m_size = m_terrain->RetSize(); - - m_brick /= m_subdiv*DIMEXPAND; - m_size *= m_subdiv*DIMEXPAND; - - if ( m_level == 0.0f ) return TRUE; - - m_lineUsed = 0; - for ( y=0 ; y -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "language.h" -#include "global.h" -#include "event.h" -#include "water.h" -#include "pyro.h" -#include "camera.h" -#include "object.h" -#include "cmdtoken.h" - - - - - -// Skips spaces. - -char* SkipSpace(char *line) -{ - while ( *line == ' ' ) - { - line ++; - } - return line; -} - -// Checks if a line contains a command. - -BOOL Cmd(char *line, char *token) -{ - char* p; - - line = SkipSpace(line); - p = strstr(line, token); - return ( p == line ); // command at the beginning? -} - -// Seeking an operator. - -char* SearchOp(char *line, char *op) -{ - char opeq[50]; - char* p; - - strcpy(opeq, " "); - strcat(opeq, op); - strcat(opeq, "="); - - p = strstr(line, opeq); - if ( p == 0 ) // not found? - { - return line+strlen(line); // point zero terminator - } - return p+strlen(opeq); // after the point "=" -} - -// Seeks the argument. - -char* SearchArg(char *line, int rank) -{ - int i; - char c; - - for ( i=0 ; i= '0' && *p <= '9' ) - { - n *= 16; - n += (*p++)-'0'; - continue; - } - if ( *p >= 'a' && *p <= 'f' ) - { - n *= 16; - n += (*p++)-'a'+10; - continue; - } - break; - } - } - else // integer? - { - sscanf(p, "%d", &n); - } - return n; -} - -// Reads a float number. - -float GetFloat(char *line, int rank, float def) -{ - char* p; - float n = 0.0f; - - p = SearchArg(line, rank); - if ( *p == 0 ) return def; - - sscanf(p, "%f", &n); - return n; -} - -// Reads a string. - -void GetString(char *line, int rank, char *buffer) -{ - char* p; - - p = SearchArg(line, rank); - *buffer = 0; - if ( *p++ != '"' ) return; - - while ( p[0] != 0 ) - { - if ( p[0] == '"' && - p[1] == '"' ) - { - *buffer++ = *p++; - p++; - continue; - } - if ( p[0] == '"' ) break; - - *buffer++ = *p++; - } - *buffer = 0; -} - -// Returns the type of an object. - -ObjectType GetTypeObject(char *line, int rank, ObjectType def) -{ - char* p; - - p = SearchArg(line, rank); - if ( *p == 0 ) return def; - - if ( Cmd(p, "All" ) ) return OBJECT_NULL; - if ( Cmd(p, "Portico" ) ) return OBJECT_PORTICO; - if ( Cmd(p, "SpaceShip" ) ) return OBJECT_BASE; - if ( Cmd(p, "PracticeBot" ) ) return OBJECT_MOBILEwt; - if ( Cmd(p, "WingedGrabber" ) ) return OBJECT_MOBILEfa; - if ( Cmd(p, "TrackedGrabber" ) ) return OBJECT_MOBILEta; - if ( Cmd(p, "WheeledGrabber" ) ) return OBJECT_MOBILEwa; - if ( Cmd(p, "LeggedGrabber" ) ) return OBJECT_MOBILEia; - if ( Cmd(p, "WingedShooter" ) ) return OBJECT_MOBILEfc; - if ( Cmd(p, "TrackedShooter" ) ) return OBJECT_MOBILEtc; - if ( Cmd(p, "WheeledShooter" ) ) return OBJECT_MOBILEwc; - if ( Cmd(p, "LeggedShooter" ) ) return OBJECT_MOBILEic; - if ( Cmd(p, "WingedOrgaShooter" ) ) return OBJECT_MOBILEfi; - if ( Cmd(p, "TrackedOrgaShooter") ) return OBJECT_MOBILEti; - if ( Cmd(p, "WheeledOrgaShooter") ) return OBJECT_MOBILEwi; - if ( Cmd(p, "LeggedOrgaShooter" ) ) return OBJECT_MOBILEii; - if ( Cmd(p, "WingedSniffer" ) ) return OBJECT_MOBILEfs; - if ( Cmd(p, "TrackedSniffer" ) ) return OBJECT_MOBILEts; - if ( Cmd(p, "WheeledSniffer" ) ) return OBJECT_MOBILEws; - if ( Cmd(p, "LeggedSniffer" ) ) return OBJECT_MOBILEis; - if ( Cmd(p, "Thumper" ) ) return OBJECT_MOBILErt; - if ( Cmd(p, "PhazerShooter" ) ) return OBJECT_MOBILErc; - if ( Cmd(p, "Recycler" ) ) return OBJECT_MOBILErr; - if ( Cmd(p, "Shielder" ) ) return OBJECT_MOBILErs; - if ( Cmd(p, "Subber" ) ) return OBJECT_MOBILEsa; - if ( Cmd(p, "TargetBot" ) ) return OBJECT_MOBILEtg; - if ( Cmd(p, "Scribbler" ) ) return OBJECT_MOBILEdr; - if ( Cmd(p, "PowerSpot" ) ) return OBJECT_MARKPOWER; - if ( Cmd(p, "TitaniumSpot" ) ) return OBJECT_MARKSTONE; - if ( Cmd(p, "UraniumSpot" ) ) return OBJECT_MARKURANIUM; - if ( Cmd(p, "PlatinumSpot" ) ) return OBJECT_MARKURANIUM; - if ( Cmd(p, "KeyASpot" ) ) return OBJECT_MARKKEYa; - if ( Cmd(p, "KeyBSpot" ) ) return OBJECT_MARKKEYb; - if ( Cmd(p, "KeyCSpot" ) ) return OBJECT_MARKKEYc; - if ( Cmd(p, "KeyDSpot" ) ) return OBJECT_MARKKEYd; - if ( Cmd(p, "WayPoint" ) ) return OBJECT_WAYPOINT; - if ( Cmd(p, "BlueFlag" ) ) return OBJECT_FLAGb; - if ( Cmd(p, "RedFlag" ) ) return OBJECT_FLAGr; - if ( Cmd(p, "GreenFlag" ) ) return OBJECT_FLAGg; - if ( Cmd(p, "YellowFlag" ) ) return OBJECT_FLAGy; - if ( Cmd(p, "VioletFlag" ) ) return OBJECT_FLAGv; - if ( Cmd(p, "PowerCell" ) ) return OBJECT_POWER; - if ( Cmd(p, "FuelCellPlant" ) ) return OBJECT_NUCLEAR; - if ( Cmd(p, "FuelCell" ) ) return OBJECT_ATOMIC; - if ( Cmd(p, "NuclearCell" ) ) return OBJECT_ATOMIC; - if ( Cmd(p, "TitaniumOre" ) ) return OBJECT_STONE; - if ( Cmd(p, "UraniumOre" ) ) return OBJECT_URANIUM; - if ( Cmd(p, "PlatinumOre" ) ) return OBJECT_URANIUM; - if ( Cmd(p, "Titanium" ) ) return OBJECT_METAL; - if ( Cmd(p, "OrgaMatter" ) ) return OBJECT_BULLET; - if ( Cmd(p, "BlackBox" ) ) return OBJECT_BBOX; - if ( Cmd(p, "KeyA" ) ) return OBJECT_KEYa; - if ( Cmd(p, "KeyB" ) ) return OBJECT_KEYb; - if ( Cmd(p, "KeyC" ) ) return OBJECT_KEYc; - if ( Cmd(p, "KeyD" ) ) return OBJECT_KEYd; - if ( Cmd(p, "TNT" ) ) return OBJECT_TNT; - if ( Cmd(p, "Scrap1" ) ) return OBJECT_SCRAP1; - if ( Cmd(p, "Scrap2" ) ) return OBJECT_SCRAP2; - if ( Cmd(p, "Scrap3" ) ) return OBJECT_SCRAP3; - if ( Cmd(p, "Scrap4" ) ) return OBJECT_SCRAP4; - if ( Cmd(p, "Scrap5" ) ) return OBJECT_SCRAP5; - if ( Cmd(p, "Mine" ) ) return OBJECT_BOMB; - if ( Cmd(p, "Firework" ) ) return OBJECT_WINFIRE; - if ( Cmd(p, "Bag" ) ) return OBJECT_BAG; - if ( Cmd(p, "Greenery10" ) ) return OBJECT_PLANT10; - if ( Cmd(p, "Greenery11" ) ) return OBJECT_PLANT11; - if ( Cmd(p, "Greenery12" ) ) return OBJECT_PLANT12; - if ( Cmd(p, "Greenery13" ) ) return OBJECT_PLANT13; - if ( Cmd(p, "Greenery14" ) ) return OBJECT_PLANT14; - if ( Cmd(p, "Greenery15" ) ) return OBJECT_PLANT15; - if ( Cmd(p, "Greenery16" ) ) return OBJECT_PLANT16; - if ( Cmd(p, "Greenery17" ) ) return OBJECT_PLANT17; - if ( Cmd(p, "Greenery18" ) ) return OBJECT_PLANT18; - if ( Cmd(p, "Greenery19" ) ) return OBJECT_PLANT19; - if ( Cmd(p, "Greenery0" ) ) return OBJECT_PLANT0; - if ( Cmd(p, "Greenery1" ) ) return OBJECT_PLANT1; - if ( Cmd(p, "Greenery2" ) ) return OBJECT_PLANT2; - if ( Cmd(p, "Greenery3" ) ) return OBJECT_PLANT3; - if ( Cmd(p, "Greenery4" ) ) return OBJECT_PLANT4; - if ( Cmd(p, "Greenery5" ) ) return OBJECT_PLANT5; - if ( Cmd(p, "Greenery6" ) ) return OBJECT_PLANT6; - if ( Cmd(p, "Greenery7" ) ) return OBJECT_PLANT7; - if ( Cmd(p, "Greenery8" ) ) return OBJECT_PLANT8; - if ( Cmd(p, "Greenery9" ) ) return OBJECT_PLANT9; - if ( Cmd(p, "Tree0" ) ) return OBJECT_TREE0; - if ( Cmd(p, "Tree1" ) ) return OBJECT_TREE1; - if ( Cmd(p, "Tree2" ) ) return OBJECT_TREE2; - if ( Cmd(p, "Tree3" ) ) return OBJECT_TREE3; - if ( Cmd(p, "Tree4" ) ) return OBJECT_TREE4; - if ( Cmd(p, "Tree5" ) ) return OBJECT_TREE5; - if ( Cmd(p, "Tree6" ) ) return OBJECT_TREE6; - if ( Cmd(p, "Tree7" ) ) return OBJECT_TREE7; - if ( Cmd(p, "Tree8" ) ) return OBJECT_TREE8; - if ( Cmd(p, "Tree9" ) ) return OBJECT_TREE9; - if ( Cmd(p, "Mushroom0" ) ) return OBJECT_MUSHROOM0; - if ( Cmd(p, "Mushroom1" ) ) return OBJECT_MUSHROOM1; - if ( Cmd(p, "Mushroom2" ) ) return OBJECT_MUSHROOM2; - if ( Cmd(p, "Mushroom3" ) ) return OBJECT_MUSHROOM3; - if ( Cmd(p, "Mushroom4" ) ) return OBJECT_MUSHROOM4; - if ( Cmd(p, "Mushroom5" ) ) return OBJECT_MUSHROOM5; - if ( Cmd(p, "Mushroom6" ) ) return OBJECT_MUSHROOM6; - if ( Cmd(p, "Mushroom7" ) ) return OBJECT_MUSHROOM7; - if ( Cmd(p, "Mushroom8" ) ) return OBJECT_MUSHROOM8; - if ( Cmd(p, "Mushroom9" ) ) return OBJECT_MUSHROOM9; - if ( Cmd(p, "Home" ) ) return OBJECT_HOME1; - if ( Cmd(p, "Derrick" ) ) return OBJECT_DERRICK; - if ( Cmd(p, "BotFactory" ) ) return OBJECT_FACTORY; - if ( Cmd(p, "PowerStation" ) ) return OBJECT_STATION; - if ( Cmd(p, "Converter" ) ) return OBJECT_CONVERT; - if ( Cmd(p, "RepairCenter" ) ) return OBJECT_REPAIR; - if ( Cmd(p, "Destroyer" ) ) return OBJECT_DESTROYER; - if ( Cmd(p, "DefenseTower" ) ) return OBJECT_TOWER; - if ( Cmd(p, "AlienNest" ) ) return OBJECT_NEST; - if ( Cmd(p, "ResearchCenter" ) ) return OBJECT_RESEARCH; - if ( Cmd(p, "RadarStation" ) ) return OBJECT_RADAR; - if ( Cmd(p, "ExchangePost" ) ) return OBJECT_INFO; - if ( Cmd(p, "PowerPlant" ) ) return OBJECT_ENERGY; - if ( Cmd(p, "AutoLab" ) ) return OBJECT_LABO; - if ( Cmd(p, "NuclearPlant" ) ) return OBJECT_NUCLEAR; - if ( Cmd(p, "PowerCaptor" ) ) return OBJECT_PARA; - if ( Cmd(p, "Vault" ) ) return OBJECT_SAFE; - if ( Cmd(p, "Houston" ) ) return OBJECT_HUSTON; - if ( Cmd(p, "Target1" ) ) return OBJECT_TARGET1; - if ( Cmd(p, "Target2" ) ) return OBJECT_TARGET2; - if ( Cmd(p, "StartArea" ) ) return OBJECT_START; - if ( Cmd(p, "GoalArea" ) ) return OBJECT_END; - if ( Cmd(p, "AlienQueen" ) ) return OBJECT_MOTHER; - if ( Cmd(p, "AlienEgg" ) ) return OBJECT_EGG; - if ( Cmd(p, "AlienAnt" ) ) return OBJECT_ANT; - if ( Cmd(p, "AlienSpider" ) ) return OBJECT_SPIDER; - if ( Cmd(p, "AlienWasp" ) ) return OBJECT_BEE; - if ( Cmd(p, "AlienWorm" ) ) return OBJECT_WORM; - if ( Cmd(p, "WreckBotw1" ) ) return OBJECT_RUINmobilew1; - if ( Cmd(p, "WreckBotw2" ) ) return OBJECT_RUINmobilew2; - if ( Cmd(p, "WreckBott1" ) ) return OBJECT_RUINmobilet1; - if ( Cmd(p, "WreckBott2" ) ) return OBJECT_RUINmobilet2; - if ( Cmd(p, "WreckBotr1" ) ) return OBJECT_RUINmobiler1; - if ( Cmd(p, "WreckBotr2" ) ) return OBJECT_RUINmobiler2; - if ( Cmd(p, "RuinBotFactory" ) ) return OBJECT_RUINfactory; - if ( Cmd(p, "RuinDoor" ) ) return OBJECT_RUINdoor; - if ( Cmd(p, "RuinSupport" ) ) return OBJECT_RUINsupport; - if ( Cmd(p, "RuinRadar" ) ) return OBJECT_RUINradar; - if ( Cmd(p, "RuinConvert" ) ) return OBJECT_RUINconvert; - if ( Cmd(p, "RuinBaseCamp" ) ) return OBJECT_RUINbase; - if ( Cmd(p, "RuinHeadCamp" ) ) return OBJECT_RUINhead; - if ( Cmd(p, "Barrier0" ) ) return OBJECT_BARRIER0; - if ( Cmd(p, "Barrier1" ) ) return OBJECT_BARRIER1; - if ( Cmd(p, "Barrier2" ) ) return OBJECT_BARRIER2; - if ( Cmd(p, "Barrier3" ) ) return OBJECT_BARRIER3; - if ( Cmd(p, "Barrier4" ) ) return OBJECT_BARRIER4; - if ( Cmd(p, "Teen40" ) ) return OBJECT_TEEN40; - if ( Cmd(p, "Teen41" ) ) return OBJECT_TEEN41; - if ( Cmd(p, "Teen42" ) ) return OBJECT_TEEN42; - if ( Cmd(p, "Teen43" ) ) return OBJECT_TEEN43; - if ( Cmd(p, "Teen44" ) ) return OBJECT_TEEN44; - if ( Cmd(p, "Teen45" ) ) return OBJECT_TEEN45; - if ( Cmd(p, "Teen46" ) ) return OBJECT_TEEN46; - if ( Cmd(p, "Teen47" ) ) return OBJECT_TEEN47; - if ( Cmd(p, "Teen48" ) ) return OBJECT_TEEN48; - if ( Cmd(p, "Teen49" ) ) return OBJECT_TEEN49; - if ( Cmd(p, "Teen30" ) ) return OBJECT_TEEN30; - if ( Cmd(p, "Teen31" ) ) return OBJECT_TEEN31; - if ( Cmd(p, "Teen32" ) ) return OBJECT_TEEN32; - if ( Cmd(p, "Teen33" ) ) return OBJECT_TEEN33; - if ( Cmd(p, "Stone" ) ) return OBJECT_TEEN34; - if ( Cmd(p, "Teen35" ) ) return OBJECT_TEEN35; - if ( Cmd(p, "Teen36" ) ) return OBJECT_TEEN36; - if ( Cmd(p, "Teen37" ) ) return OBJECT_TEEN37; - if ( Cmd(p, "Teen38" ) ) return OBJECT_TEEN38; - if ( Cmd(p, "Teen39" ) ) return OBJECT_TEEN39; - if ( Cmd(p, "Teen20" ) ) return OBJECT_TEEN20; - if ( Cmd(p, "Teen21" ) ) return OBJECT_TEEN21; - if ( Cmd(p, "Teen22" ) ) return OBJECT_TEEN22; - if ( Cmd(p, "Teen23" ) ) return OBJECT_TEEN23; - if ( Cmd(p, "Teen24" ) ) return OBJECT_TEEN24; - if ( Cmd(p, "Teen25" ) ) return OBJECT_TEEN25; - if ( Cmd(p, "Teen26" ) ) return OBJECT_TEEN26; - if ( Cmd(p, "Teen27" ) ) return OBJECT_TEEN27; - if ( Cmd(p, "Teen28" ) ) return OBJECT_TEEN28; - if ( Cmd(p, "Teen29" ) ) return OBJECT_TEEN29; - if ( Cmd(p, "Teen10" ) ) return OBJECT_TEEN10; - if ( Cmd(p, "Teen11" ) ) return OBJECT_TEEN11; - if ( Cmd(p, "Teen12" ) ) return OBJECT_TEEN12; - if ( Cmd(p, "Teen13" ) ) return OBJECT_TEEN13; - if ( Cmd(p, "Teen14" ) ) return OBJECT_TEEN14; - if ( Cmd(p, "Teen15" ) ) return OBJECT_TEEN15; - if ( Cmd(p, "Teen16" ) ) return OBJECT_TEEN16; - if ( Cmd(p, "Teen17" ) ) return OBJECT_TEEN17; - if ( Cmd(p, "Teen18" ) ) return OBJECT_TEEN18; - if ( Cmd(p, "Teen19" ) ) return OBJECT_TEEN19; - if ( Cmd(p, "Teen0" ) ) return OBJECT_TEEN0; - if ( Cmd(p, "Teen1" ) ) return OBJECT_TEEN1; - if ( Cmd(p, "Teen2" ) ) return OBJECT_TEEN2; - if ( Cmd(p, "Teen3" ) ) return OBJECT_TEEN3; - if ( Cmd(p, "Teen4" ) ) return OBJECT_TEEN4; - if ( Cmd(p, "Teen5" ) ) return OBJECT_TEEN5; - if ( Cmd(p, "Teen6" ) ) return OBJECT_TEEN6; - if ( Cmd(p, "Teen7" ) ) return OBJECT_TEEN7; - if ( Cmd(p, "Teen8" ) ) return OBJECT_TEEN8; - if ( Cmd(p, "Teen9" ) ) return OBJECT_TEEN9; - if ( Cmd(p, "Quartz0" ) ) return OBJECT_QUARTZ0; - if ( Cmd(p, "Quartz1" ) ) return OBJECT_QUARTZ1; - if ( Cmd(p, "Quartz2" ) ) return OBJECT_QUARTZ2; - if ( Cmd(p, "Quartz3" ) ) return OBJECT_QUARTZ3; - if ( Cmd(p, "Quartz4" ) ) return OBJECT_QUARTZ4; - if ( Cmd(p, "Quartz5" ) ) return OBJECT_QUARTZ5; - if ( Cmd(p, "Quartz6" ) ) return OBJECT_QUARTZ6; - if ( Cmd(p, "Quartz7" ) ) return OBJECT_QUARTZ7; - if ( Cmd(p, "Quartz8" ) ) return OBJECT_QUARTZ8; - if ( Cmd(p, "Quartz9" ) ) return OBJECT_QUARTZ9; - if ( Cmd(p, "MegaStalk0" ) ) return OBJECT_ROOT0; - if ( Cmd(p, "MegaStalk1" ) ) return OBJECT_ROOT1; - if ( Cmd(p, "MegaStalk2" ) ) return OBJECT_ROOT2; - if ( Cmd(p, "MegaStalk3" ) ) return OBJECT_ROOT3; - if ( Cmd(p, "MegaStalk4" ) ) return OBJECT_ROOT4; - if ( Cmd(p, "MegaStalk5" ) ) return OBJECT_ROOT5; - if ( Cmd(p, "MegaStalk6" ) ) return OBJECT_ROOT6; - if ( Cmd(p, "MegaStalk7" ) ) return OBJECT_ROOT7; - if ( Cmd(p, "MegaStalk8" ) ) return OBJECT_ROOT8; - if ( Cmd(p, "MegaStalk9" ) ) return OBJECT_ROOT9; - if ( Cmd(p, "ApolloLEM" ) ) return OBJECT_APOLLO1; - if ( Cmd(p, "ApolloJeep" ) ) return OBJECT_APOLLO2; - if ( Cmd(p, "ApolloFlag" ) ) return OBJECT_APOLLO3; - if ( Cmd(p, "ApolloModule" ) ) return OBJECT_APOLLO4; - if ( Cmd(p, "ApolloAntenna" ) ) return OBJECT_APOLLO5; - if ( Cmd(p, "Me" ) ) return OBJECT_HUMAN; - if ( Cmd(p, "Tech" ) ) return OBJECT_TECH; - - return def; -} - -// Returns the name of an object type. - -char* GetTypeObject(ObjectType type) -{ - if ( type == OBJECT_PORTICO ) return "Portico"; - if ( type == OBJECT_BASE ) return "SpaceShip"; - if ( type == OBJECT_MOBILEwt ) return "PracticeBot"; - if ( type == OBJECT_MOBILEfa ) return "WingedGrabber"; - if ( type == OBJECT_MOBILEta ) return "TrackedGrabber"; - if ( type == OBJECT_MOBILEwa ) return "WheeledGrabber"; - if ( type == OBJECT_MOBILEia ) return "LeggedGrabber"; - if ( type == OBJECT_MOBILEfc ) return "WingedShooter"; - if ( type == OBJECT_MOBILEtc ) return "TrackedShooter"; - if ( type == OBJECT_MOBILEwc ) return "WheeledShooter"; - if ( type == OBJECT_MOBILEic ) return "LeggedShooter"; - if ( type == OBJECT_MOBILEfi ) return "WingedOrgaShooter"; - if ( type == OBJECT_MOBILEti ) return "TrackedOrgaShooter"; - if ( type == OBJECT_MOBILEwi ) return "WheeledOrgaShooter"; - if ( type == OBJECT_MOBILEii ) return "LeggedOrgaShooter"; - if ( type == OBJECT_MOBILEfs ) return "WingedSniffer"; - if ( type == OBJECT_MOBILEts ) return "TrackedSniffer"; - if ( type == OBJECT_MOBILEws ) return "WheeledSniffer"; - if ( type == OBJECT_MOBILEis ) return "LeggedSniffer"; - if ( type == OBJECT_MOBILErt ) return "Thumper"; - if ( type == OBJECT_MOBILErc ) return "PhazerShooter"; - if ( type == OBJECT_MOBILErr ) return "Recycler"; - if ( type == OBJECT_MOBILErs ) return "Shielder"; - if ( type == OBJECT_MOBILEsa ) return "Subber"; - if ( type == OBJECT_MOBILEtg ) return "TargetBot"; - if ( type == OBJECT_MOBILEdr ) return "Scribbler"; - if ( type == OBJECT_MARKPOWER ) return "PowerSpot"; - if ( type == OBJECT_MARKSTONE ) return "TitaniumSpot"; -#if _GERMAN | _WG - if ( type == OBJECT_MARKURANIUM ) return "PlatinumSpot"; -#else - if ( type == OBJECT_MARKURANIUM ) return "UraniumSpot"; -#endif - if ( type == OBJECT_MARKKEYa ) return "KeyASpot"; - if ( type == OBJECT_MARKKEYb ) return "KeyBSpot"; - if ( type == OBJECT_MARKKEYc ) return "KeyCSpot"; - if ( type == OBJECT_MARKKEYd ) return "KeyDSpot"; - if ( type == OBJECT_WAYPOINT ) return "WayPoint"; - if ( type == OBJECT_FLAGb ) return "BlueFlag"; - if ( type == OBJECT_FLAGr ) return "RedFlag"; - if ( type == OBJECT_FLAGg ) return "GreenFlag"; - if ( type == OBJECT_FLAGy ) return "YellowFlag"; - if ( type == OBJECT_FLAGv ) return "VioletFlag"; - if ( type == OBJECT_POWER ) return "PowerCell"; -#if _GERMAN | _WG - if ( type == OBJECT_ATOMIC ) return "FuelCell"; -#else - if ( type == OBJECT_ATOMIC ) return "NuclearCell"; -#endif - if ( type == OBJECT_STONE ) return "TitaniumOre"; -#if _GERMAN | _WG - if ( type == OBJECT_URANIUM ) return "PlatinumOre"; -#else - if ( type == OBJECT_URANIUM ) return "UraniumOre"; -#endif - if ( type == OBJECT_METAL ) return "Titanium"; - if ( type == OBJECT_BULLET ) return "OrgaMatter"; - if ( type == OBJECT_BBOX ) return "BlackBox"; - if ( type == OBJECT_KEYa ) return "KeyA"; - if ( type == OBJECT_KEYb ) return "KeyB"; - if ( type == OBJECT_KEYc ) return "KeyC"; - if ( type == OBJECT_KEYd ) return "KeyD"; - if ( type == OBJECT_TNT ) return "TNT"; - if ( type == OBJECT_SCRAP1 ) return "Scrap1"; - if ( type == OBJECT_SCRAP2 ) return "Scrap2"; - if ( type == OBJECT_SCRAP3 ) return "Scrap3"; - if ( type == OBJECT_SCRAP4 ) return "Scrap4"; - if ( type == OBJECT_SCRAP5 ) return "Scrap5"; - if ( type == OBJECT_BOMB ) return "Mine"; - if ( type == OBJECT_WINFIRE ) return "Firework"; - if ( type == OBJECT_BAG ) return "Bag"; - if ( type == OBJECT_PLANT0 ) return "Greenery0"; - if ( type == OBJECT_PLANT1 ) return "Greenery1"; - if ( type == OBJECT_PLANT2 ) return "Greenery2"; - if ( type == OBJECT_PLANT3 ) return "Greenery3"; - if ( type == OBJECT_PLANT4 ) return "Greenery4"; - if ( type == OBJECT_PLANT5 ) return "Greenery5"; - if ( type == OBJECT_PLANT6 ) return "Greenery6"; - if ( type == OBJECT_PLANT7 ) return "Greenery7"; - if ( type == OBJECT_PLANT8 ) return "Greenery8"; - if ( type == OBJECT_PLANT9 ) return "Greenery9"; - if ( type == OBJECT_PLANT10 ) return "Greenery10"; - if ( type == OBJECT_PLANT11 ) return "Greenery11"; - if ( type == OBJECT_PLANT12 ) return "Greenery12"; - if ( type == OBJECT_PLANT13 ) return "Greenery13"; - if ( type == OBJECT_PLANT14 ) return "Greenery14"; - if ( type == OBJECT_PLANT15 ) return "Greenery15"; - if ( type == OBJECT_PLANT16 ) return "Greenery16"; - if ( type == OBJECT_PLANT17 ) return "Greenery17"; - if ( type == OBJECT_PLANT18 ) return "Greenery18"; - if ( type == OBJECT_PLANT19 ) return "Greenery19"; - if ( type == OBJECT_TREE0 ) return "Tree0"; - if ( type == OBJECT_TREE1 ) return "Tree1"; - if ( type == OBJECT_TREE2 ) return "Tree2"; - if ( type == OBJECT_TREE3 ) return "Tree3"; - if ( type == OBJECT_TREE4 ) return "Tree4"; - if ( type == OBJECT_TREE5 ) return "Tree5"; - if ( type == OBJECT_TREE6 ) return "Tree6"; - if ( type == OBJECT_TREE7 ) return "Tree7"; - if ( type == OBJECT_TREE8 ) return "Tree8"; - if ( type == OBJECT_TREE9 ) return "Tree9"; - if ( type == OBJECT_MUSHROOM0 ) return "Mushroom0"; - if ( type == OBJECT_MUSHROOM1 ) return "Mushroom1"; - if ( type == OBJECT_MUSHROOM2 ) return "Mushroom2"; - if ( type == OBJECT_MUSHROOM3 ) return "Mushroom3"; - if ( type == OBJECT_MUSHROOM4 ) return "Mushroom4"; - if ( type == OBJECT_MUSHROOM5 ) return "Mushroom5"; - if ( type == OBJECT_MUSHROOM6 ) return "Mushroom6"; - if ( type == OBJECT_MUSHROOM7 ) return "Mushroom7"; - if ( type == OBJECT_MUSHROOM8 ) return "Mushroom8"; - if ( type == OBJECT_MUSHROOM9 ) return "Mushroom9"; - if ( type == OBJECT_HOME1 ) return "Home"; - if ( type == OBJECT_DERRICK ) return "Derrick"; - if ( type == OBJECT_FACTORY ) return "BotFactory"; - if ( type == OBJECT_STATION ) return "PowerStation"; - if ( type == OBJECT_CONVERT ) return "Converter"; - if ( type == OBJECT_REPAIR ) return "RepairCenter"; - if ( type == OBJECT_DESTROYER ) return "Destroyer"; - if ( type == OBJECT_TOWER ) return "DefenseTower"; - if ( type == OBJECT_NEST ) return "AlienNest"; - if ( type == OBJECT_RESEARCH ) return "ResearchCenter"; - if ( type == OBJECT_RADAR ) return "RadarStation"; - if ( type == OBJECT_INFO ) return "ExchangePost"; - if ( type == OBJECT_ENERGY ) return "PowerPlant"; - if ( type == OBJECT_LABO ) return "AutoLab"; -#if _GERMAN | _WG - if ( type == OBJECT_NUCLEAR ) return "FuelCellPlant"; -#else - if ( type == OBJECT_NUCLEAR ) return "NuclearPlant"; -#endif - if ( type == OBJECT_PARA ) return "PowerCaptor"; - if ( type == OBJECT_SAFE ) return "Vault"; - if ( type == OBJECT_HUSTON ) return "Houston"; - if ( type == OBJECT_TARGET1 ) return "Target1"; - if ( type == OBJECT_TARGET2 ) return "Target2"; - if ( type == OBJECT_START ) return "StartArea"; - if ( type == OBJECT_END ) return "GoalArea"; - if ( type == OBJECT_MOTHER ) return "AlienQueen"; - if ( type == OBJECT_EGG ) return "AlienEgg"; - if ( type == OBJECT_ANT ) return "AlienAnt"; - if ( type == OBJECT_SPIDER ) return "AlienSpider"; - if ( type == OBJECT_BEE ) return "AlienWasp"; - if ( type == OBJECT_WORM ) return "AlienWorm"; - if ( type == OBJECT_RUINmobilew1 ) return "WreckBotw1"; - if ( type == OBJECT_RUINmobilew2 ) return "WreckBotw2"; - if ( type == OBJECT_RUINmobilet1 ) return "WreckBott1"; - if ( type == OBJECT_RUINmobilet2 ) return "WreckBott2"; - if ( type == OBJECT_RUINmobiler1 ) return "WreckBotr1"; - if ( type == OBJECT_RUINmobiler2 ) return "WreckBotr2"; - if ( type == OBJECT_RUINfactory ) return "RuinBotFactory"; - if ( type == OBJECT_RUINdoor ) return "RuinDoor"; - if ( type == OBJECT_RUINsupport ) return "RuinSupport"; - if ( type == OBJECT_RUINradar ) return "RuinRadar"; - if ( type == OBJECT_RUINconvert ) return "RuinConvert"; - if ( type == OBJECT_RUINbase ) return "RuinBaseCamp"; - if ( type == OBJECT_RUINhead ) return "RuinHeadCamp"; - if ( type == OBJECT_BARRIER0 ) return "Barrier0"; - if ( type == OBJECT_BARRIER1 ) return "Barrier1"; - if ( type == OBJECT_BARRIER2 ) return "Barrier2"; - if ( type == OBJECT_BARRIER3 ) return "Barrier3"; - if ( type == OBJECT_BARRIER4 ) return "Barrier4"; - if ( type == OBJECT_TEEN0 ) return "Teen0"; - if ( type == OBJECT_TEEN1 ) return "Teen1"; - if ( type == OBJECT_TEEN2 ) return "Teen2"; - if ( type == OBJECT_TEEN3 ) return "Teen3"; - if ( type == OBJECT_TEEN4 ) return "Teen4"; - if ( type == OBJECT_TEEN5 ) return "Teen5"; - if ( type == OBJECT_TEEN6 ) return "Teen6"; - if ( type == OBJECT_TEEN7 ) return "Teen7"; - if ( type == OBJECT_TEEN8 ) return "Teen8"; - if ( type == OBJECT_TEEN9 ) return "Teen9"; - if ( type == OBJECT_TEEN10 ) return "Teen10"; - if ( type == OBJECT_TEEN11 ) return "Teen11"; - if ( type == OBJECT_TEEN12 ) return "Teen12"; - if ( type == OBJECT_TEEN13 ) return "Teen13"; - if ( type == OBJECT_TEEN14 ) return "Teen14"; - if ( type == OBJECT_TEEN15 ) return "Teen15"; - if ( type == OBJECT_TEEN16 ) return "Teen16"; - if ( type == OBJECT_TEEN17 ) return "Teen17"; - if ( type == OBJECT_TEEN18 ) return "Teen18"; - if ( type == OBJECT_TEEN19 ) return "Teen19"; - if ( type == OBJECT_TEEN20 ) return "Teen20"; - if ( type == OBJECT_TEEN21 ) return "Teen21"; - if ( type == OBJECT_TEEN22 ) return "Teen22"; - if ( type == OBJECT_TEEN23 ) return "Teen23"; - if ( type == OBJECT_TEEN24 ) return "Teen24"; - if ( type == OBJECT_TEEN25 ) return "Teen25"; - if ( type == OBJECT_TEEN26 ) return "Teen26"; - if ( type == OBJECT_TEEN27 ) return "Teen27"; - if ( type == OBJECT_TEEN28 ) return "Teen28"; - if ( type == OBJECT_TEEN29 ) return "Teen29"; - if ( type == OBJECT_TEEN30 ) return "Teen30"; - if ( type == OBJECT_TEEN31 ) return "Teen31"; - if ( type == OBJECT_TEEN32 ) return "Teen32"; - if ( type == OBJECT_TEEN33 ) return "Teen33"; - if ( type == OBJECT_TEEN34 ) return "Stone"; - if ( type == OBJECT_TEEN35 ) return "Teen35"; - if ( type == OBJECT_TEEN36 ) return "Teen36"; - if ( type == OBJECT_TEEN37 ) return "Teen37"; - if ( type == OBJECT_TEEN38 ) return "Teen38"; - if ( type == OBJECT_TEEN39 ) return "Teen39"; - if ( type == OBJECT_TEEN40 ) return "Teen40"; - if ( type == OBJECT_TEEN41 ) return "Teen41"; - if ( type == OBJECT_TEEN42 ) return "Teen42"; - if ( type == OBJECT_TEEN43 ) return "Teen43"; - if ( type == OBJECT_TEEN44 ) return "Teen44"; - if ( type == OBJECT_TEEN45 ) return "Teen45"; - if ( type == OBJECT_TEEN46 ) return "Teen46"; - if ( type == OBJECT_TEEN47 ) return "Teen47"; - if ( type == OBJECT_TEEN48 ) return "Teen48"; - if ( type == OBJECT_TEEN49 ) return "Teen49"; - if ( type == OBJECT_QUARTZ0 ) return "Quartz0"; - if ( type == OBJECT_QUARTZ1 ) return "Quartz1"; - if ( type == OBJECT_QUARTZ2 ) return "Quartz2"; - if ( type == OBJECT_QUARTZ3 ) return "Quartz3"; - if ( type == OBJECT_QUARTZ4 ) return "Quartz4"; - if ( type == OBJECT_QUARTZ5 ) return "Quartz5"; - if ( type == OBJECT_QUARTZ6 ) return "Quartz6"; - if ( type == OBJECT_QUARTZ7 ) return "Quartz7"; - if ( type == OBJECT_QUARTZ8 ) return "Quartz8"; - if ( type == OBJECT_QUARTZ9 ) return "Quartz9"; - if ( type == OBJECT_ROOT0 ) return "MegaStalk0"; - if ( type == OBJECT_ROOT1 ) return "MegaStalk1"; - if ( type == OBJECT_ROOT2 ) return "MegaStalk2"; - if ( type == OBJECT_ROOT3 ) return "MegaStalk3"; - if ( type == OBJECT_ROOT4 ) return "MegaStalk4"; - if ( type == OBJECT_ROOT5 ) return "MegaStalk5"; - if ( type == OBJECT_ROOT6 ) return "MegaStalk6"; - if ( type == OBJECT_ROOT7 ) return "MegaStalk7"; - if ( type == OBJECT_ROOT8 ) return "MegaStalk8"; - if ( type == OBJECT_ROOT9 ) return "MegaStalk9"; - if ( type == OBJECT_APOLLO1 ) return "ApolloLEM"; - if ( type == OBJECT_APOLLO2 ) return "ApolloJeep"; - if ( type == OBJECT_APOLLO3 ) return "ApolloFlag"; - if ( type == OBJECT_APOLLO4 ) return "ApolloModule"; - if ( type == OBJECT_APOLLO5 ) return "ApolloAntenna"; - if ( type == OBJECT_HUMAN ) return "Me"; - if ( type == OBJECT_TECH ) return "Tech"; - return ""; -} - -// Returns the type of water. - -WaterType GetTypeWater(char *line, int rank, WaterType def) -{ - char* p; - - p = SearchArg(line, rank); - if ( *p == 0 ) return def; - - if ( Cmd(p, "NULL" ) ) return WATER_NULL; - if ( Cmd(p, "TT" ) ) return WATER_TT; - if ( Cmd(p, "TO" ) ) return WATER_TO; - if ( Cmd(p, "CT" ) ) return WATER_CT; - if ( Cmd(p, "CO" ) ) return WATER_CO; - - return def; -} - -// Returns the type of terrain. - -D3DTypeObj GetTypeTerrain(char *line, int rank, D3DTypeObj def) -{ - char* p; - - p = SearchArg(line, rank); - if ( *p == 0 ) return def; - - if ( Cmd(p, "Terrain" ) ) return TYPETERRAIN; - if ( Cmd(p, "Object" ) ) return TYPEFIX; - if ( Cmd(p, "Quartz" ) ) return TYPEQUARTZ; - if ( Cmd(p, "Metal" ) ) return TYPEMETAL; - - return def; -} - -// Returns the type of a building. - -int GetBuild(char *line, int rank) -{ - char* p; - - p = SearchArg(line, rank); - if ( *p == 0 ) return 0; - - if ( Cmd(p, "BotFactory" ) ) return BUILD_FACTORY; - if ( Cmd(p, "Derrick" ) ) return BUILD_DERRICK; - if ( Cmd(p, "Converter" ) ) return BUILD_CONVERT; - if ( Cmd(p, "RadarStation" ) ) return BUILD_RADAR; - if ( Cmd(p, "PowerPlant" ) ) return BUILD_ENERGY; - if ( Cmd(p, "NuclearPlant" ) ) return BUILD_NUCLEAR; - if ( Cmd(p, "FuelCellPlant" ) ) return BUILD_NUCLEAR; - if ( Cmd(p, "PowerStation" ) ) return BUILD_STATION; - if ( Cmd(p, "RepairCenter" ) ) return BUILD_REPAIR; - if ( Cmd(p, "DefenseTower" ) ) return BUILD_TOWER; - if ( Cmd(p, "ResearchCenter") ) return BUILD_RESEARCH; - if ( Cmd(p, "AutoLab" ) ) return BUILD_LABO; - if ( Cmd(p, "PowerCaptor" ) ) return BUILD_PARA; - if ( Cmd(p, "ExchangePost" ) ) return BUILD_INFO; - if ( Cmd(p, "FlatGround" ) ) return BUILD_GFLAT; - if ( Cmd(p, "Flag" ) ) return BUILD_FLAG; - - return 0; -} - -// Returns the type of search. - -int GetResearch(char *line, int rank) -{ - char* p; - - p = SearchArg(line, rank); - if ( *p == 0 ) return 0; - - if ( Cmd(p, "TRACKER" ) ) return RESEARCH_TANK; - if ( Cmd(p, "WINGER" ) ) return RESEARCH_FLY; - if ( Cmd(p, "THUMPER" ) ) return RESEARCH_THUMP; - if ( Cmd(p, "SHOOTER" ) ) return RESEARCH_CANON; - if ( Cmd(p, "TOWER" ) ) return RESEARCH_TOWER; - if ( Cmd(p, "PHAZER" ) ) return RESEARCH_PHAZER; - if ( Cmd(p, "SHIELDER") ) return RESEARCH_SHIELD; - if ( Cmd(p, "ATOMIC" ) ) return RESEARCH_ATOMIC; - if ( Cmd(p, "iPAW" ) ) return RESEARCH_iPAW; - if ( Cmd(p, "iGUN" ) ) return RESEARCH_iGUN; - if ( Cmd(p, "RECYCLER") ) return RESEARCH_RECYCLER; - if ( Cmd(p, "SUBBER" ) ) return RESEARCH_SUBM; - if ( Cmd(p, "SNIFFER" ) ) return RESEARCH_SNIFFER; - - return 0; -} - -// Returns the type of pyrotechnic effect. - -PyroType GetPyro(char *line, int rank) -{ - char* p; - - p = SearchArg(line, rank); - if ( *p == 0 ) return PT_NULL; - - if ( Cmd(p, "FRAGt" ) ) return PT_FRAGT; - if ( Cmd(p, "FRAGo" ) ) return PT_FRAGO; - if ( Cmd(p, "FRAGw" ) ) return PT_FRAGW; - if ( Cmd(p, "EXPLOt" ) ) return PT_EXPLOT; - if ( Cmd(p, "EXPLOo" ) ) return PT_EXPLOO; - if ( Cmd(p, "EXPLOw" ) ) return PT_EXPLOW; - if ( Cmd(p, "SHOTt" ) ) return PT_SHOTT; - if ( Cmd(p, "SHOTh" ) ) return PT_SHOTH; - if ( Cmd(p, "SHOTm" ) ) return PT_SHOTM; - if ( Cmd(p, "SHOTw" ) ) return PT_SHOTW; - if ( Cmd(p, "EGG" ) ) return PT_EGG; - if ( Cmd(p, "BURNt" ) ) return PT_BURNT; - if ( Cmd(p, "BURNo" ) ) return PT_BURNO; - if ( Cmd(p, "SPIDER" ) ) return PT_SPIDER; - if ( Cmd(p, "FALL" ) ) return PT_FALL; - if ( Cmd(p, "RESET" ) ) return PT_RESET; - if ( Cmd(p, "WIN" ) ) return PT_WIN; - if ( Cmd(p, "LOST" ) ) return PT_LOST; - - return PT_NULL; -} - -// Returns the type of camera. - -CameraType GetCamera(char *line, int rank) -{ - char* p; - - p = SearchArg(line, rank); - if ( *p == 0 ) return CAMERA_NULL; - - if ( Cmd(p, "BACK" ) ) return CAMERA_BACK; - if ( Cmd(p, "PLANE" ) ) return CAMERA_PLANE; - if ( Cmd(p, "ONBOARD" ) ) return CAMERA_ONBOARD; - if ( Cmd(p, "FIX" ) ) return CAMERA_FIX; - - return CAMERA_NULL; -} - -// Returns the name of a camera. - -char* GetCamera(CameraType type) -{ - if ( type == CAMERA_ONBOARD ) return "ONBOARD"; - if ( type == CAMERA_FIX ) return "FIX"; - return "BACK"; -} - -// Returns an integer. - -int OpInt(char *line, char *op, int def) -{ - line = SearchOp(line, op); - if ( *line == 0 ) return def; - return GetInt(line, 0, def); -} - -// Returns a float number. - -float OpFloat(char *line, char *op, float def) -{ - line = SearchOp(line, op); - if ( *line == 0 ) return def; - return GetFloat(line, 0, def); -} - -// Returns a string. - -void OpString(char *line, char *op, char *buffer) -{ - line = SearchOp(line, op); - if ( *line == 0 ) - { - buffer[0] = 0; - } - else - { - GetString(line, 0, buffer); - } -} - -// Returns the type of an object. - -ObjectType OpTypeObject(char *line, char *op, ObjectType def) -{ - line = SearchOp(line, op); - if ( *line == 0 ) return def; - return GetTypeObject(line, 0, def); -} - -// Returns the type of a water. - -WaterType OpTypeWater(char *line, char *op, WaterType def) -{ - line = SearchOp(line, op); - if ( *line == 0 ) return def; - return GetTypeWater(line, 0, def); -} - -// Returns the type of a terrain. - -D3DTypeObj OpTypeTerrain(char *line, char *op, D3DTypeObj def) -{ - line = SearchOp(line, op); - if ( *line == 0 ) return def; - return GetTypeTerrain(line, 0, def); -} - -// Returns the type of research. - -int OpResearch(char *line, char *op) -{ - line = SearchOp(line, op); - if ( *line == 0 ) return 0; - return GetResearch(line, 0); -} - -// Returns the type of pyrotechnic effect. - -PyroType OpPyro(char *line, char *op) -{ - line = SearchOp(line, op); - if ( *line == 0 ) return PT_NULL; - return GetPyro(line, 0); -} - -// Returns the type of camera. - -CameraType OpCamera(char *line, char *op) -{ - line = SearchOp(line, op); - if ( *line == 0 ) return CAMERA_NULL; - return GetCamera(line, 0); -} - -// Returns the type of a building. - -int OpBuild(char *line, char *op) -{ - line = SearchOp(line, op); - if ( *line == 0 ) return 0; - return GetBuild(line, 0); -} - -// Returns a position in the XZ plane (top view). - -D3DVECTOR OpPos(char *line, char *op) -{ - D3DVECTOR pos; - - line = SearchOp(line, op); - if ( *line == 0 ) - { - pos = D3DVECTOR(0.0f, 0.0f, 0.0f); - return pos; - } - pos.x = GetFloat(line, 0, 0.0f); - pos.y = 0.0f; - pos.z = GetFloat(line, 1, 0.0f); - return pos; -} - -// Returns a direction. - -D3DVECTOR OpDir(char *line, char *op) -{ - D3DVECTOR dir; - - line = SearchOp(line, op); - if ( *line == 0 ) - { - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - return dir; - } - dir.x = GetFloat(line, 0, 0.0f); - dir.y = GetFloat(line, 1, 0.0f); - dir.z = GetFloat(line, 2, 0.0f); - return dir; -} - -// Reads a color (0 .. 255). - -D3DCOLOR OpColor(char *line, char *op, D3DCOLOR def) -{ - D3DCOLOR color; - - line = SearchOp(line, op); - if ( *line == 0 ) return def; - - color = 0; - color |= (GetInt(line, 0, 0)&0xff)<<16; // r - color |= (GetInt(line, 1, 0)&0xff)<<8; // g - color |= (GetInt(line, 2, 0)&0xff)<<0; // b - color |= (GetInt(line, 3, 0)&0xff)<<24; // a - return color; -} - -// Reads a color (-1 .. 1). - -D3DCOLORVALUE OpColorValue(char *line, char *op, D3DCOLORVALUE def) -{ - D3DCOLORVALUE color; - - line = SearchOp(line, op); - if ( *line == 0 ) return def; - - color.r = GetFloat(line, 0, 0.0f); - color.g = GetFloat(line, 1, 0.0f); - color.b = GetFloat(line, 2, 0.0f); - color.a = GetFloat(line, 3, 0.0f); - return color; -} - - diff --git a/src/cmdtoken.h b/src/cmdtoken.h deleted file mode 100644 index 40fb36a..0000000 --- a/src/cmdtoken.h +++ /dev/null @@ -1,67 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// cmdtoken.h - -#ifndef _CMDTOKEN_H_ -#define _CMDTOKEN_H_ - - -#include "d3denum.h" -#include "d3dengine.h" -#include "object.h" -#include "water.h" -#include "pyro.h" -#include "camera.h" - - - -// Procedures. - -extern BOOL Cmd(char *line, char *token); -extern char* SearchOp(char *line, char *op); - -extern int GetInt(char *line, int rank, int def); -extern float GetFloat(char *line, int rank, float def); -extern void GetString(char *line, int rank, char *buffer); -extern ObjectType GetTypeObject(char *line, int rank, ObjectType def); -extern char* GetTypeObject(ObjectType type); -extern WaterType GetTypeWater(char *line, int rank, WaterType def); -extern D3DTypeObj GetTypeTerrain(char *line, int rank, D3DTypeObj def); -extern int GetBuild(char *line, int rank); -extern int GetResearch(char *line, int rank); -extern PyroType GetPyro(char *line, int rank); -extern CameraType GetCamera(char *line, int rank); -extern char* GetCamera(CameraType type); - -extern int OpInt(char *line, char *op, int def); -extern float OpFloat(char *line, char *op, float def); -extern void OpString(char *line, char *op, char *buffer); -extern ObjectType OpTypeObject(char *line, char *op, ObjectType def); -extern WaterType OpTypeWater(char *line, char *op, WaterType def); -extern D3DTypeObj OpTypeTerrain(char *line, char *op, D3DTypeObj def); -extern int OpResearch(char *line, char *op); -extern PyroType OpPyro(char *line, char *op); -extern CameraType OpCamera(char *line, char *op); -extern int OpBuild(char *line, char *op); -extern D3DVECTOR OpPos(char *line, char *op); -extern D3DVECTOR OpDir(char *line, char *op); -extern D3DCOLOR OpColor(char *line, char *op, D3DCOLOR def); -extern D3DCOLORVALUE OpColorValue(char *line, char *op, D3DCOLORVALUE def); - - - -#endif //_CMDTOKEN_H_ diff --git a/src/colobot.ini b/src/colobot.ini deleted file mode 100644 index de547ec..0000000 --- a/src/colobot.ini +++ /dev/null @@ -1,75 +0,0 @@ -[Gamer] -LastName=Joueur - -[Setup] -TotoMode=1 -Tooltips=1 -InterfaceGlint=1 -NiceMouse=0 -Movies=1 -NiceReset=1 -HimselfDamage=1 -CameraScroll=1 -CameraInvertX=0 -InterfaceEffect=1 -GroundShadow=1 -GroundSpot=1 -ObjectDirty=1 -FogMode=1 -LensMode=1 -SkyMode=1 -PlanetMode=1 -LightMode=1 -UseJoystick=0 -ParticuleDensity=1.00 -ClippingDistance=1.00 -ObjectDetail=2.00 -GadgetQuantity=1.00 -TextureQuality=1 -AudioVolume=15 -MidiVolume=20 -Sound3D=0 -EditIndentMode=1 -EditIndentValue=4 -KeyMap=37+0 39+0 38+0 40+0 16+0 17+0 32+258 96+262 13+257 107+261 109+260 9+259 36+263 27+0 112+0 113+0 110+0 115+0 116+0 117+0 -FullScreenActivateEnable=0 -AccessMission=1 -AccessUser=1 -DeleteGamer=1 -Soluce4=1 - -[Engine] -StateColor=-1 -BlackSrcBlend=0 -BlackDestBlend=0 -WhiteSrcBlend=0 -WhiteDestBlend=0 -DiffuseSrcBlend=0 -DiffuseDestBlend=0 -AlphaSrcBlend=0 -AlphaDestBlend=0 -AlphaMode=1 - -[Device] -Name=Direct3D HAL -Mode=1600 x 1200 x 32 -FullScreen=0 - -[Edit] -WindowPos.x=0.19 -WindowPos.y=0.15 -WindowDim.x=0.66 -WindowDim.y=0.69 -FontSize=9.00 -IOPos.x=0.29 -IOPos.y=0.34 -IODim.x=0.50 -IODim.y=0.55 -IOPublic=0 - -[Directory] -scene=scene -savegame=savegame -public=program -user=user -files=files diff --git a/src/color.cpp b/src/color.cpp deleted file mode 100644 index cf69b0d..0000000 --- a/src/color.cpp +++ /dev/null @@ -1,226 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "language.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "restext.h" -#include "color.h" - - - -#define DELAY1 0.4f -#define DELAY2 0.1f - - - -// Object's constructor. - -CColor::CColor(CInstanceManager* iMan) : CControl(iMan) -{ - m_bRepeat = FALSE; - m_repeat = 0.0f; - - m_color.r = 0.0f; - m_color.g = 0.0f; - m_color.b = 0.0f; - m_color.a = 0.0f; -} - -// Object's destructor. - -CColor::~CColor() -{ -} - - -// Creates a new button. - -BOOL CColor::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - CControl::Create(pos, dim, icon, eventMsg); - - if ( icon == -1 ) - { - char name[100]; - char* p; - - GetResource(RES_EVENT, eventMsg, name); - p = strchr(name, '\\'); - if ( p != 0 ) *p = 0; - SetName(name); - } - - return TRUE; -} - - -// Management of an event. - -BOOL CColor::EventProcess(const Event &event) -{ - if ( m_state & STATE_DEAD ) return TRUE; - - CControl::EventProcess(event); - - if ( event.event == EVENT_FRAME && m_bRepeat ) - { - if ( m_repeat != 0.0f ) - { - m_repeat -= event.rTime; - if ( m_repeat <= 0.0f ) - { - m_repeat = DELAY2; - - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - return FALSE; - } - } - } - - if ( event.event == EVENT_LBUTTONDOWN && - (m_state & STATE_VISIBLE) && - (m_state & STATE_ENABLE) ) - { - if ( CControl::Detect(event.pos) ) - { - m_repeat = DELAY1; - - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - return FALSE; - } - } - - if ( event.event == EVENT_LBUTTONUP ) - { - m_repeat = 0.0f; - } - - return TRUE; -} - - -// Dessine le bouton. - -void CColor::Draw() -{ - LPDIRECT3DDEVICE7 device; - D3DLVERTEX vertex[4]; // 2 triangles - D3DCOLOR color; - FPOINT p1, p2; - - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - if ( m_state & STATE_SHADOW ) - { - DrawShadow(m_pos, m_dim); - } - - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATENORMAL); - CControl::Draw(); - -#if _TEEN - color = ::RetColor(m_color); - - m_engine->SetTexture("xxx.tga"); // no texture - m_engine->SetState(D3DSTATENORMAL); - - device = m_engine->RetD3DDevice(); - - p1.x = m_pos.x+(4.0f/640.0f); - p1.y = m_pos.y+(4.0f/480.0f); - p2.x = m_pos.x+m_dim.x-(4.0f/640.0f); - p2.y = m_pos.y+m_dim.y-(4.0f/480.0f); - vertex[0] = D3DLVERTEX(D3DVECTOR(p1.x, p1.y, 0.0f), 0x00000000,0x00000000, 0.0f,0.0f); - vertex[1] = D3DLVERTEX(D3DVECTOR(p1.x, p2.y, 0.0f), 0x00000000,0x00000000, 0.0f,0.0f); - vertex[2] = D3DLVERTEX(D3DVECTOR(p2.x, p1.y, 0.0f), 0x00000000,0x00000000, 0.0f,0.0f); - vertex[3] = D3DLVERTEX(D3DVECTOR(p2.x, p2.y, 0.0f), 0x00000000,0x00000000, 0.0f,0.0f); - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, vertex, 4, NULL); - - p1.x = m_pos.x+(5.0f/640.0f); - p1.y = m_pos.y+(5.0f/480.0f); - p2.x = m_pos.x+m_dim.x-(5.0f/640.0f); - p2.y = m_pos.y+m_dim.y-(5.0f/480.0f); - vertex[0] = D3DLVERTEX(D3DVECTOR(p1.x, p1.y, 0.0f), color,0x00000000, 0.0f,0.0f); - vertex[1] = D3DLVERTEX(D3DVECTOR(p1.x, p2.y, 0.0f), color,0x00000000, 0.0f,0.0f); - vertex[2] = D3DLVERTEX(D3DVECTOR(p2.x, p1.y, 0.0f), color,0x00000000, 0.0f,0.0f); - vertex[3] = D3DLVERTEX(D3DVECTOR(p2.x, p2.y, 0.0f), color,0x00000000, 0.0f,0.0f); - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, vertex, 4, NULL); - - m_engine->AddStatisticTriangle(4); -#else - p1.x = m_pos.x+(3.0f/640.0f); - p1.y = m_pos.y+(3.0f/480.0f); - p2.x = m_pos.x+m_dim.x-(3.0f/640.0f); - p2.y = m_pos.y+m_dim.y-(3.0f/480.0f); - - color = ::RetColor(m_color); - - m_engine->SetTexture("xxx.tga"); // no texture - m_engine->SetState(D3DSTATENORMAL); - - vertex[0] = D3DLVERTEX(D3DVECTOR(p1.x, p1.y, 0.0f), color,0x00000000, 0.0f,0.0f); - vertex[1] = D3DLVERTEX(D3DVECTOR(p1.x, p2.y, 0.0f), color,0x00000000, 0.0f,0.0f); - vertex[2] = D3DLVERTEX(D3DVECTOR(p2.x, p1.y, 0.0f), color,0x00000000, 0.0f,0.0f); - vertex[3] = D3DLVERTEX(D3DVECTOR(p2.x, p2.y, 0.0f), color,0x00000000, 0.0f,0.0f); - - device = m_engine->RetD3DDevice(); - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); -#endif -} - - -void CColor::SetRepeat(BOOL bRepeat) -{ - m_bRepeat = bRepeat; -} - -BOOL CColor::RetRepeat() -{ - return m_bRepeat; -} - - -void CColor::SetColor(D3DCOLORVALUE color) -{ - m_color = color; -} - -D3DCOLORVALUE CColor::RetColor() -{ - return m_color; -} - - diff --git a/src/color.h b/src/color.h deleted file mode 100644 index fec01c4..0000000 --- a/src/color.h +++ /dev/null @@ -1,58 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// color.h - -#ifndef _COLOR_H_ -#define _COLOR_H_ - - -#include "control.h" -#include "d3dengine.h" - - -class CD3DEngine; - - - -class CColor : public CControl -{ -public: - CColor(CInstanceManager* iMan); - virtual ~CColor(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - - BOOL EventProcess(const Event &event); - - void Draw(); - - void SetRepeat(BOOL bRepeat); - BOOL RetRepeat(); - - void SetColor(D3DCOLORVALUE color); - D3DCOLORVALUE RetColor(); - -protected: - -protected: - BOOL m_bRepeat; - float m_repeat; - D3DCOLORVALUE m_color; -}; - - -#endif //_COLOR_H_ diff --git a/src/common/README.txt b/src/common/README.txt new file mode 100644 index 0000000..36653cc --- /dev/null +++ b/src/common/README.txt @@ -0,0 +1,3 @@ +src/common + +Contains headers and modules with common structs and enums. diff --git a/src/common/event.cpp b/src/common/event.cpp new file mode 100644 index 0000000..2eeddb4 --- /dev/null +++ b/src/common/event.cpp @@ -0,0 +1,91 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// event.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include + +#include "struct.h" +#include "iman.h" +#include "event.h" + + + + +// Object's constructor. + +CEvent::CEvent(CInstanceManager* iMan) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_EVENT, this); + + Flush(); +} + +// Object's destructor. + +CEvent::~CEvent() +{ +} + + +// Empty the FIFO of events. + +void CEvent::Flush() +{ + m_head = 0; + m_tail = 0; + m_total = 0; +} + +// Produces an event. + +void CEvent::MakeEvent(Event &event, EventMsg msg) +{ + ZeroMemory(&event, sizeof(Event)); + event.event = msg; +} + +// Adds an event in the FIFO. + +BOOL CEvent::AddEvent(const Event &event) +{ + if ( m_total >= MAXEVENT ) return FALSE; + + m_fifo[m_head++] = event; + if ( m_head >= MAXEVENT ) m_head = 0; + m_total ++; + + return TRUE; +} + +// Removes an event from the FIFO. + +BOOL CEvent::GetEvent(Event &event) +{ + if ( m_head == m_tail ) return FALSE; + + event = m_fifo[m_tail++]; + if ( m_tail >= MAXEVENT ) m_tail = 0; + m_total --; + + return TRUE; +} + diff --git a/src/common/event.h b/src/common/event.h new file mode 100644 index 0000000..8da2600 --- /dev/null +++ b/src/common/event.h @@ -0,0 +1,636 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// event.h + +#ifndef _EVENT_H_ +#define _EVENT_H_ + + +#include "struct.h" + + +#if !defined (WM_XBUTTONDOWN) +#define WM_XBUTTONDOWN 0x020B +#define WM_XBUTTONUP 0x020C +#define XBUTTON1 0x0001 +#define XBUTTON2 0x0002 +#endif + + + +class CInstanceManager; + + +#define MAXEVENT 100 + +// Events. + +enum EventMsg +{ + EVENT_NULL = 0, + + EVENT_QUIT = 1, + EVENT_FRAME = 2, + EVENT_LBUTTONDOWN = 3, + EVENT_RBUTTONDOWN = 4, + EVENT_LBUTTONUP = 5, + EVENT_RBUTTONUP = 6, + EVENT_MOUSEMOVE = 7, + EVENT_KEYDOWN = 8, + EVENT_KEYUP = 9, + EVENT_CHAR = 10, + EVENT_FOCUS = 11, + + EVENT_UPDINTERFACE = 20, + EVENT_WIN = 30, + EVENT_LOST = 31, + + EVENT_BUTTON_OK = 40, + EVENT_BUTTON_CANCEL = 41, + EVENT_BUTTON_NEXT = 42, + EVENT_BUTTON_PREV = 43, + EVENT_BUTTON_QUIT = 44, + + EVENT_BUTTON0 = 50, + EVENT_BUTTON1 = 51, + EVENT_BUTTON2 = 52, + EVENT_BUTTON3 = 53, + EVENT_BUTTON4 = 54, + EVENT_BUTTON5 = 55, + EVENT_BUTTON6 = 56, + EVENT_BUTTON7 = 57, + EVENT_BUTTON8 = 58, + EVENT_BUTTON9 = 59, + EVENT_BUTTON10 = 60, + EVENT_BUTTON11 = 61, + EVENT_BUTTON12 = 62, + EVENT_BUTTON13 = 63, + EVENT_BUTTON14 = 64, + EVENT_BUTTON15 = 65, + EVENT_BUTTON16 = 66, + EVENT_BUTTON17 = 67, + EVENT_BUTTON18 = 68, + EVENT_BUTTON19 = 69, + + EVENT_EDIT0 = 70, + EVENT_EDIT1 = 71, + EVENT_EDIT2 = 72, + EVENT_EDIT3 = 73, + EVENT_EDIT4 = 74, + EVENT_EDIT5 = 75, + EVENT_EDIT6 = 76, + EVENT_EDIT7 = 77, + EVENT_EDIT8 = 78, + EVENT_EDIT9 = 79, + + EVENT_WINDOW0 = 80, // the bottom panel + EVENT_WINDOW1 = 81, // map + EVENT_WINDOW2 = 82, // CDisplayText + EVENT_WINDOW3 = 83, // CStudio + EVENT_WINDOW4 = 84, // DisplayInfo + EVENT_WINDOW5 = 85, // setup + EVENT_WINDOW6 = 86, + EVENT_WINDOW7 = 87, + EVENT_WINDOW8 = 88, + EVENT_WINDOW9 = 89, // dialogue + + EVENT_LABEL0 = 90, + EVENT_LABEL1 = 91, + EVENT_LABEL2 = 92, + EVENT_LABEL3 = 93, + EVENT_LABEL4 = 94, + EVENT_LABEL5 = 95, + EVENT_LABEL6 = 96, + EVENT_LABEL7 = 97, + EVENT_LABEL8 = 98, + EVENT_LABEL9 = 99, + EVENT_LABEL10 = 100, + EVENT_LABEL11 = 101, + EVENT_LABEL12 = 102, + EVENT_LABEL13 = 103, + EVENT_LABEL14 = 104, + EVENT_LABEL15 = 105, + EVENT_LABEL16 = 106, + EVENT_LABEL17 = 107, + EVENT_LABEL18 = 108, + EVENT_LABEL19 = 109, + + EVENT_LIST0 = 110, + EVENT_LIST1 = 111, + EVENT_LIST2 = 112, + EVENT_LIST3 = 113, + EVENT_LIST4 = 114, + EVENT_LIST5 = 115, + EVENT_LIST6 = 116, + EVENT_LIST7 = 117, + EVENT_LIST8 = 118, + EVENT_LIST9 = 119, + + EVENT_TOOLTIP = 200, + + EVENT_DIALOG_OK = 300, + EVENT_DIALOG_CANCEL = 301, + EVENT_DIALOG_LABEL = 302, + EVENT_DIALOG_LABEL1 = 303, + EVENT_DIALOG_LABEL2 = 304, + EVENT_DIALOG_LABEL3 = 305, + EVENT_DIALOG_LIST = 306, + EVENT_DIALOG_EDIT = 307, + EVENT_DIALOG_CHECK1 = 308, + EVENT_DIALOG_CHECK2 = 309, + + EVENT_INTERFACE_TRAINER = 400, + EVENT_INTERFACE_DEFI = 401, + EVENT_INTERFACE_MISSION = 402, + EVENT_INTERFACE_FREE = 403, + EVENT_INTERFACE_PROTO = 404, + EVENT_INTERFACE_NAME = 405, + EVENT_INTERFACE_SETUP = 406, + EVENT_INTERFACE_QUIT = 407, + EVENT_INTERFACE_BACK = 408, + EVENT_INTERFACE_AGAIN = 409, + EVENT_INTERFACE_WRITE = 410, + EVENT_INTERFACE_READ = 411, + EVENT_INTERFACE_ABORT = 412, + EVENT_INTERFACE_USER = 413, + EVENT_INTERFACE_TEEN = 414, + + EVENT_INTERFACE_CHAP = 420, + EVENT_INTERFACE_LIST = 421, + EVENT_INTERFACE_RESUME = 422, + EVENT_INTERFACE_PLAY = 423, + + EVENT_INTERFACE_SETUPd = 430, + EVENT_INTERFACE_SETUPg = 431, + EVENT_INTERFACE_SETUPp = 432, + EVENT_INTERFACE_SETUPc = 433, + EVENT_INTERFACE_SETUPs = 434, + + EVENT_INTERFACE_DEVICE = 440, + EVENT_INTERFACE_RESOL = 441, + EVENT_INTERFACE_FULL = 442, + EVENT_INTERFACE_APPLY = 443, + + EVENT_INTERFACE_TOTO = 450, + EVENT_INTERFACE_SHADOW = 451, + EVENT_INTERFACE_DIRTY = 452, + EVENT_INTERFACE_LENS = 453, + EVENT_INTERFACE_SKY = 454, + EVENT_INTERFACE_PLANET = 456, + EVENT_INTERFACE_LIGHT = 457, + EVENT_INTERFACE_PARTI = 458, + EVENT_INTERFACE_CLIP = 459, + EVENT_INTERFACE_DETAIL = 460, + EVENT_INTERFACE_TEXTURE = 461, + EVENT_INTERFACE_RAIN = 462, + EVENT_INTERFACE_GLINT = 463, + EVENT_INTERFACE_TOOLTIP = 464, + EVENT_INTERFACE_MOVIES = 465, + EVENT_INTERFACE_NICERST = 466, + EVENT_INTERFACE_SCROLL = 467, + EVENT_INTERFACE_INVERTX = 468, + EVENT_INTERFACE_INVERTY = 469, + EVENT_INTERFACE_EFFECT = 470, + EVENT_INTERFACE_MOUSE = 471, + EVENT_INTERFACE_GROUND = 472, + EVENT_INTERFACE_GADGET = 473, + EVENT_INTERFACE_FOG = 474, + EVENT_INTERFACE_HIMSELF = 475, + EVENT_INTERFACE_EDITMODE= 476, + EVENT_INTERFACE_EDITVALUE= 477, + EVENT_INTERFACE_SOLUCE4 = 478, + + EVENT_INTERFACE_KINFO1 = 500, + EVENT_INTERFACE_KINFO2 = 501, + EVENT_INTERFACE_KGROUP = 502, + EVENT_INTERFACE_KSCROLL = 503, + EVENT_INTERFACE_KDEF = 504, + EVENT_INTERFACE_KLEFT = 505, + EVENT_INTERFACE_KRIGHT = 506, + EVENT_INTERFACE_KUP = 507, + EVENT_INTERFACE_KDOWN = 508, + EVENT_INTERFACE_KGUP = 509, + EVENT_INTERFACE_KGDOWN = 510, + EVENT_INTERFACE_KCAMERA = 511, + EVENT_INTERFACE_KDESEL = 512, + EVENT_INTERFACE_KACTION = 513, + EVENT_INTERFACE_KNEAR = 514, + EVENT_INTERFACE_KAWAY = 515, + EVENT_INTERFACE_KNEXT = 516, + EVENT_INTERFACE_KHUMAN = 517, + EVENT_INTERFACE_KQUIT = 518, + EVENT_INTERFACE_KHELP = 519, + EVENT_INTERFACE_KPROG = 520, + EVENT_INTERFACE_KCBOT = 521, + EVENT_INTERFACE_KVISIT = 522, + EVENT_INTERFACE_KSPEED10= 523, + EVENT_INTERFACE_KSPEED15= 524, + EVENT_INTERFACE_KSPEED20= 525, + EVENT_INTERFACE_KSPEED30= 526, + + EVENT_INTERFACE_VOLSOUND= 530, + EVENT_INTERFACE_VOLMUSIC= 531, + EVENT_INTERFACE_SOUND3D = 532, + + EVENT_INTERFACE_MIN = 540, + EVENT_INTERFACE_NORM = 541, + EVENT_INTERFACE_MAX = 542, + + EVENT_INTERFACE_SILENT = 550, + EVENT_INTERFACE_NOISY = 551, + + EVENT_INTERFACE_JOYSTICK= 560, + EVENT_INTERFACE_SOLUCE = 561, + + EVENT_INTERFACE_GLINTl = 570, + EVENT_INTERFACE_GLINTr = 571, + EVENT_INTERFACE_GLINTu = 572, + EVENT_INTERFACE_GLINTb = 573, + + EVENT_INTERFACE_NEDIT = 580, + EVENT_INTERFACE_NLIST = 581, + EVENT_INTERFACE_NOK = 582, + EVENT_INTERFACE_NCANCEL = 583, + EVENT_INTERFACE_NDELETE = 584, + EVENT_INTERFACE_NLABEL = 585, + + EVENT_INTERFACE_IOWRITE = 600, + EVENT_INTERFACE_IOREAD = 601, + EVENT_INTERFACE_IOLIST = 602, + EVENT_INTERFACE_IONAME = 603, + EVENT_INTERFACE_IOLABEL = 604, + EVENT_INTERFACE_IOIMAGE = 605, + EVENT_INTERFACE_IODELETE= 606, + + EVENT_INTERFACE_PERSO = 620, + EVENT_INTERFACE_POK = 621, + EVENT_INTERFACE_PCANCEL = 622, + EVENT_INTERFACE_PDEF = 623, + EVENT_INTERFACE_PHEAD = 624, + EVENT_INTERFACE_PBODY = 625, + EVENT_INTERFACE_PLROT = 626, + EVENT_INTERFACE_PRROT = 627, + EVENT_INTERFACE_PC0a = 640, + EVENT_INTERFACE_PC1a = 641, + EVENT_INTERFACE_PC2a = 642, + EVENT_INTERFACE_PC3a = 643, + EVENT_INTERFACE_PC4a = 644, + EVENT_INTERFACE_PC5a = 645, + EVENT_INTERFACE_PC6a = 646, + EVENT_INTERFACE_PC7a = 647, + EVENT_INTERFACE_PC8a = 648, + EVENT_INTERFACE_PC9a = 649, + EVENT_INTERFACE_PCRa = 650, + EVENT_INTERFACE_PCGa = 651, + EVENT_INTERFACE_PCBa = 652, + EVENT_INTERFACE_PC0b = 660, + EVENT_INTERFACE_PC1b = 661, + EVENT_INTERFACE_PC2b = 662, + EVENT_INTERFACE_PC3b = 663, + EVENT_INTERFACE_PC4b = 664, + EVENT_INTERFACE_PC5b = 665, + EVENT_INTERFACE_PC6b = 666, + EVENT_INTERFACE_PC7b = 667, + EVENT_INTERFACE_PC8b = 668, + EVENT_INTERFACE_PC9b = 669, + EVENT_INTERFACE_PCRb = 670, + EVENT_INTERFACE_PCGb = 671, + EVENT_INTERFACE_PCBb = 672, + EVENT_INTERFACE_PFACE1 = 680, + EVENT_INTERFACE_PFACE2 = 681, + EVENT_INTERFACE_PFACE3 = 682, + EVENT_INTERFACE_PFACE4 = 683, + EVENT_INTERFACE_PGLASS0 = 690, + EVENT_INTERFACE_PGLASS1 = 691, + EVENT_INTERFACE_PGLASS2 = 692, + EVENT_INTERFACE_PGLASS3 = 693, + EVENT_INTERFACE_PGLASS4 = 694, + EVENT_INTERFACE_PGLASS5 = 695, + EVENT_INTERFACE_PGLASS6 = 696, + EVENT_INTERFACE_PGLASS7 = 697, + EVENT_INTERFACE_PGLASS8 = 698, + EVENT_INTERFACE_PGLASS9 = 699, + + EVENT_DT_GROUP0 = 700, + EVENT_DT_GROUP1 = 701, + EVENT_DT_GROUP2 = 702, + EVENT_DT_GROUP3 = 703, + EVENT_DT_GROUP4 = 704, + EVENT_DT_LABEL0 = 710, + EVENT_DT_LABEL1 = 711, + EVENT_DT_LABEL2 = 712, + EVENT_DT_LABEL3 = 713, + EVENT_DT_LABEL4 = 714, + EVENT_DT_VISIT0 = 720, + EVENT_DT_VISIT1 = 721, + EVENT_DT_VISIT2 = 722, + EVENT_DT_VISIT3 = 723, + EVENT_DT_VISIT4 = 724, + EVENT_DT_END = 725, + + EVENT_CMD = 800, + EVENT_SPEED = 801, + + EVENT_HYPER_PREV = 900, + EVENT_HYPER_NEXT = 901, + EVENT_HYPER_HOME = 902, + EVENT_HYPER_COPY = 903, + EVENT_HYPER_SIZE1 = 904, + EVENT_HYPER_SIZE2 = 905, + EVENT_HYPER_SIZE3 = 906, + EVENT_HYPER_SIZE4 = 907, + EVENT_HYPER_SIZE5 = 908, + + EVENT_SATCOM_HUSTON = 920, + EVENT_SATCOM_SAT = 921, + EVENT_SATCOM_LOADING = 922, + EVENT_SATCOM_OBJECT = 923, + EVENT_SATCOM_PROG = 924, + EVENT_SATCOM_SOLUCE = 925, + + EVENT_OBJECT_DESELECT = 1000, + EVENT_OBJECT_LEFT = 1001, + EVENT_OBJECT_RIGHT = 1002, + EVENT_OBJECT_UP = 1003, + EVENT_OBJECT_DOWN = 1004, + EVENT_OBJECT_GASUP = 1005, + EVENT_OBJECT_GASDOWN = 1006, + EVENT_OBJECT_HTAKE = 1020, + EVENT_OBJECT_MTAKE = 1021, + EVENT_OBJECT_MFRONT = 1022, + EVENT_OBJECT_MBACK = 1023, + EVENT_OBJECT_MPOWER = 1024, + EVENT_OBJECT_BHELP = 1040, + EVENT_OBJECT_BTAKEOFF = 1041, + EVENT_OBJECT_BDERRICK = 1050, + EVENT_OBJECT_BSTATION = 1051, + EVENT_OBJECT_BFACTORY = 1052, + EVENT_OBJECT_BCONVERT = 1053, + EVENT_OBJECT_BTOWER = 1054, + EVENT_OBJECT_BREPAIR = 1055, + EVENT_OBJECT_BRESEARCH = 1056, + EVENT_OBJECT_BRADAR = 1057, + EVENT_OBJECT_BENERGY = 1058, + EVENT_OBJECT_BLABO = 1059, + EVENT_OBJECT_BNUCLEAR = 1060, + EVENT_OBJECT_BPARA = 1061, + EVENT_OBJECT_BINFO = 1062, + EVENT_OBJECT_BXXXX = 1063, + EVENT_OBJECT_GFLAT = 1070, + EVENT_OBJECT_FCREATE = 1071, + EVENT_OBJECT_FDELETE = 1072, + EVENT_OBJECT_FCOLORb = 1073, + EVENT_OBJECT_FCOLORr = 1074, + EVENT_OBJECT_FCOLORg = 1075, + EVENT_OBJECT_FCOLORy = 1076, + EVENT_OBJECT_FCOLORv = 1077, + EVENT_OBJECT_FACTORYwa = 1080, + EVENT_OBJECT_FACTORYta = 1081, + EVENT_OBJECT_FACTORYfa = 1082, + EVENT_OBJECT_FACTORYia = 1083, + EVENT_OBJECT_FACTORYwc = 1084, + EVENT_OBJECT_FACTORYtc = 1085, + EVENT_OBJECT_FACTORYfc = 1086, + EVENT_OBJECT_FACTORYic = 1087, + EVENT_OBJECT_FACTORYwi = 1088, + EVENT_OBJECT_FACTORYti = 1089, + EVENT_OBJECT_FACTORYfi = 1090, + EVENT_OBJECT_FACTORYii = 1091, + EVENT_OBJECT_FACTORYws = 1092, + EVENT_OBJECT_FACTORYts = 1093, + EVENT_OBJECT_FACTORYfs = 1094, + EVENT_OBJECT_FACTORYis = 1095, + EVENT_OBJECT_FACTORYrt = 1096, + EVENT_OBJECT_FACTORYrc = 1097, + EVENT_OBJECT_FACTORYrr = 1098, + EVENT_OBJECT_FACTORYrs = 1099, + EVENT_OBJECT_FACTORYsa = 1100, + EVENT_OBJECT_SEARCH = 1200, + EVENT_OBJECT_TERRAFORM = 1201, + EVENT_OBJECT_FIRE = 1202, + EVENT_OBJECT_FIREANT = 1203, + EVENT_OBJECT_RECOVER = 1220, + EVENT_OBJECT_BEGSHIELD = 1221, + EVENT_OBJECT_ENDSHIELD = 1222, + EVENT_OBJECT_RTANK = 1223, + EVENT_OBJECT_RFLY = 1224, + EVENT_OBJECT_RTHUMP = 1225, + EVENT_OBJECT_RCANON = 1226, + EVENT_OBJECT_RTOWER = 1227, + EVENT_OBJECT_RPHAZER = 1228, + EVENT_OBJECT_RSHIELD = 1229, + EVENT_OBJECT_RATOMIC = 1230, + EVENT_OBJECT_RiPAW = 1231, + EVENT_OBJECT_RiGUN = 1232, + EVENT_OBJECT_RESET = 1233, + EVENT_OBJECT_DIMSHIELD = 1234, + EVENT_OBJECT_TARGET = 1235, + EVENT_OBJECT_PROGLIST = 1310, + EVENT_OBJECT_PROGRUN = 1311, + EVENT_OBJECT_PROGEDIT = 1312, + EVENT_OBJECT_PROGSTART = 1313, + EVENT_OBJECT_PROGSTOP = 1314, + EVENT_OBJECT_INFOOK = 1340, + EVENT_OBJECT_DELETE = 1350, + EVENT_OBJECT_GENERGY = 1360, + EVENT_OBJECT_GSHIELD = 1361, + EVENT_OBJECT_GRANGE = 1362, + EVENT_OBJECT_COMPASS = 1363, + EVENT_OBJECT_MAP = 1364, + EVENT_OBJECT_MAPZOOM = 1365, + EVENT_OBJECT_GPROGRESS = 1366, + EVENT_OBJECT_GRADAR = 1367, + EVENT_OBJECT_GINFO = 1368, + EVENT_OBJECT_TYPE = 1369, + EVENT_OBJECT_CROSSHAIR = 1370, + EVENT_OBJECT_CORNERul = 1371, + EVENT_OBJECT_CORNERur = 1372, + EVENT_OBJECT_CORNERdl = 1373, + EVENT_OBJECT_CORNERdr = 1374, + EVENT_OBJECT_MAPi = 1375, + EVENT_OBJECT_MAPg = 1376, + EVENT_OBJECT_CAMERA = 1400, + EVENT_OBJECT_HELP = 1401, + EVENT_OBJECT_SOLUCE = 1402, + EVENT_OBJECT_CAMERAleft = 1403, + EVENT_OBJECT_CAMERAright= 1404, + EVENT_OBJECT_CAMERAnear = 1405, + EVENT_OBJECT_CAMERAaway = 1406, + EVENT_OBJECT_SHORTCUT00 = 1500, + EVENT_OBJECT_SHORTCUT01 = 1501, + EVENT_OBJECT_SHORTCUT02 = 1502, + EVENT_OBJECT_SHORTCUT03 = 1503, + EVENT_OBJECT_SHORTCUT04 = 1504, + EVENT_OBJECT_SHORTCUT05 = 1505, + EVENT_OBJECT_SHORTCUT06 = 1506, + EVENT_OBJECT_SHORTCUT07 = 1507, + EVENT_OBJECT_SHORTCUT08 = 1508, + EVENT_OBJECT_SHORTCUT09 = 1509, + EVENT_OBJECT_SHORTCUT10 = 1510, + EVENT_OBJECT_SHORTCUT11 = 1511, + EVENT_OBJECT_SHORTCUT12 = 1512, + EVENT_OBJECT_SHORTCUT13 = 1513, + EVENT_OBJECT_SHORTCUT14 = 1514, + EVENT_OBJECT_SHORTCUT15 = 1515, + EVENT_OBJECT_SHORTCUT16 = 1516, + EVENT_OBJECT_SHORTCUT17 = 1517, + EVENT_OBJECT_SHORTCUT18 = 1518, + EVENT_OBJECT_SHORTCUT19 = 1519, + EVENT_OBJECT_MOVIELOCK = 1550, + EVENT_OBJECT_EDITLOCK = 1551, + EVENT_OBJECT_LIMIT = 1560, + + EVENT_OBJECT_PEN0 = 1570, + EVENT_OBJECT_PEN1 = 1571, + EVENT_OBJECT_PEN2 = 1572, + EVENT_OBJECT_PEN3 = 1573, + EVENT_OBJECT_PEN4 = 1574, + EVENT_OBJECT_PEN5 = 1575, + EVENT_OBJECT_PEN6 = 1576, + EVENT_OBJECT_PEN7 = 1577, + EVENT_OBJECT_PEN8 = 1578, + EVENT_OBJECT_REC = 1580, + EVENT_OBJECT_STOP = 1581, + + EVENT_STUDIO_OK = 2000, + EVENT_STUDIO_CANCEL = 2001, + EVENT_STUDIO_EDIT = 2002, + EVENT_STUDIO_LIST = 2003, + EVENT_STUDIO_NEW = 2010, + EVENT_STUDIO_OPEN = 2011, + EVENT_STUDIO_SAVE = 2012, + EVENT_STUDIO_UNDO = 2013, + EVENT_STUDIO_CUT = 2014, + EVENT_STUDIO_COPY = 2015, + EVENT_STUDIO_PASTE = 2016, + EVENT_STUDIO_SIZE = 2017, + EVENT_STUDIO_TOOL = 2018, + EVENT_STUDIO_HELP = 2019, + EVENT_STUDIO_COMPILE = 2050, + EVENT_STUDIO_RUN = 2051, + EVENT_STUDIO_REALTIME = 2052, + EVENT_STUDIO_STEP = 2053, + + EVENT_USER = 10000, + EVENT_FORCE_DWORD = 0x7fffffff +}; + +typedef struct +{ + EventMsg event; // event (EVENT *) + long param; // parameter + FPOINT pos; // mouse position (0 .. 1) + float axeX; // control the X axis (-1 .. 1) + float axeY; // control of the Y axis (-1 .. 1) + float axeZ; // control the Z axis (-1 .. 1) + short keyState; // state of the keyboard (KS_ *) + float rTime; // relative time +} +Event; + + +#define VK_BUTTON1 (0x100+1) // joystick button 1 +#define VK_BUTTON2 (0x100+2) // joystick button 2 +#define VK_BUTTON3 (0x100+3) // joystick button 3 +#define VK_BUTTON4 (0x100+4) // joystick button 4 +#define VK_BUTTON5 (0x100+5) // joystick button 5 +#define VK_BUTTON6 (0x100+6) // joystick button 6 +#define VK_BUTTON7 (0x100+7) // joystick button 7 +#define VK_BUTTON8 (0x100+8) // joystick button 8 +#define VK_BUTTON9 (0x100+9) // joystick button 9 +#define VK_BUTTON10 (0x100+10) // joystick button 10 +#define VK_BUTTON11 (0x100+11) // joystick button 11 +#define VK_BUTTON12 (0x100+12) // joystick button 12 +#define VK_BUTTON13 (0x100+13) // joystick button 13 +#define VK_BUTTON14 (0x100+14) // joystick button 14 +#define VK_BUTTON15 (0x100+15) // joystick button 15 +#define VK_BUTTON16 (0x100+16) // joystick button 16 +#define VK_BUTTON17 (0x100+17) // joystick button 17 +#define VK_BUTTON18 (0x100+18) // joystick button 18 +#define VK_BUTTON19 (0x100+19) // joystick button 19 +#define VK_BUTTON20 (0x100+20) // joystick button 20 +#define VK_BUTTON21 (0x100+21) // joystick button 21 +#define VK_BUTTON22 (0x100+22) // joystick button 22 +#define VK_BUTTON23 (0x100+23) // joystick button 23 +#define VK_BUTTON24 (0x100+24) // joystick button 24 +#define VK_BUTTON25 (0x100+25) // joystick button 25 +#define VK_BUTTON26 (0x100+26) // joystick button 26 +#define VK_BUTTON27 (0x100+27) // joystick button 27 +#define VK_BUTTON28 (0x100+28) // joystick button 28 +#define VK_BUTTON29 (0x100+29) // joystick button 29 +#define VK_BUTTON30 (0x100+30) // joystick button 30 +#define VK_BUTTON31 (0x100+31) // joystick button 31 +#define VK_BUTTON32 (0x100+32) // joystick button 32 + +#define VK_WHEELUP (0x200+1) // Mousewheel up +#define VK_WHEELDOWN (0x200+2) // Mousewheel down + + +enum KeyRank +{ + KEYRANK_LEFT = 0, + KEYRANK_RIGHT = 1, + KEYRANK_UP = 2, + KEYRANK_DOWN = 3, + KEYRANK_GUP = 4, + KEYRANK_GDOWN = 5, + KEYRANK_CAMERA = 6, + KEYRANK_DESEL = 7, + KEYRANK_ACTION = 8, + KEYRANK_NEAR = 9, + KEYRANK_AWAY = 10, + KEYRANK_NEXT = 11, + KEYRANK_HUMAN = 12, + KEYRANK_QUIT = 13, + KEYRANK_HELP = 14, + KEYRANK_PROG = 15, + KEYRANK_VISIT = 16, + KEYRANK_SPEED10 = 17, + KEYRANK_SPEED15 = 18, + KEYRANK_SPEED20 = 19, + KEYRANK_SPEED30 = 20, + KEYRANK_AIMUP = 21, + KEYRANK_AIMDOWN = 22, + KEYRANK_CBOT = 23, +}; + + + +class CEvent +{ +public: + CEvent(CInstanceManager* iMan); + ~CEvent(); + + void Flush(); + void MakeEvent(Event &event, EventMsg msg); + BOOL AddEvent(const Event &event); + BOOL GetEvent(Event &event); + +protected: + +protected: + CInstanceManager* m_iMan; + + Event m_fifo[MAXEVENT]; + int m_head; + int m_tail; + int m_total; +}; + + +#endif //_EVENT_H_ diff --git a/src/common/global.h b/src/common/global.h new file mode 100644 index 0000000..32aefdc --- /dev/null +++ b/src/common/global.h @@ -0,0 +1,64 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// global.h + +#ifndef _GLOBAL_H_ +#define _GLOBAL_H_ + + +#define BUILD_FACTORY (1<<0) // factory +#define BUILD_DERRICK (1<<1) // derrick +#define BUILD_CONVERT (1<<2) // converter +#define BUILD_RADAR (1<<3) // radar +#define BUILD_ENERGY (1<<4) // factory of cells +#define BUILD_NUCLEAR (1<<5) // nuclear power plant +#define BUILD_STATION (1<<6) // base station +#define BUILD_REPAIR (1<<7) // repair center +#define BUILD_TOWER (1<<8) // defense tower +#define BUILD_RESEARCH (1<<9) // research center +#define BUILD_LABO (1<<10) // laboratory +#define BUILD_PARA (1<<11) // lightning protection +#define BUILD_INFO (1<<12) // information terminal +#define BUILD_GFLAT (1<<16) // flat floor +#define BUILD_FLAG (1<<17) // puts / removes colored flag + + +// Do not change values ​​was because of backups (bits = ...). + +#define RESEARCH_TANK (1<<0) // caterpillars +#define RESEARCH_FLY (1<<1) // wings +#define RESEARCH_CANON (1<<2) // cannon +#define RESEARCH_TOWER (1<<3) // defense tower +#define RESEARCH_ATOMIC (1<<4) // nuclear +#define RESEARCH_THUMP (1<<5) // thumper +#define RESEARCH_SHIELD (1<<6) // shield +#define RESEARCH_PHAZER (1<<7) // phazer gun +#define RESEARCH_iPAW (1<<8) // legs of insects +#define RESEARCH_iGUN (1<<9) // cannon of insects +#define RESEARCH_RECYCLER (1<<10) // recycler +#define RESEARCH_SUBM (1<<11) // submarine +#define RESEARCH_SNIFFER (1<<12) // sniffer + +extern long g_id; // unique identifier +extern long g_build; // constructible buildings +extern long g_researchDone; // research done +extern long g_researchEnable; // research available +extern float g_unit; // conversion factor + + + +#endif //_GLOBAL_H_ diff --git a/src/common/iman.cpp b/src/common/iman.cpp new file mode 100644 index 0000000..eacb3f4 --- /dev/null +++ b/src/common/iman.cpp @@ -0,0 +1,165 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// iman.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include + +#include "struct.h" +#include "iman.h" + + + + +// Object's constructor. + +CInstanceManager::CInstanceManager() +{ + int i; + + for ( i=0 ; i= CLASS_MAX ) return; + if ( m_table[classType].classPointer == 0 ) return; + + free(m_table[classType].classPointer); + m_table[classType].classPointer = 0; +} + + +// Adds a new instance of a class. + +BOOL CInstanceManager::AddInstance(ClassType classType, void* pointer, int max) +{ + int i; + + if ( classType < 0 || classType >= CLASS_MAX ) return FALSE; + + if ( m_table[classType].classPointer == 0 ) + { + m_table[classType].classPointer = (void**)malloc(max*sizeof(void*)); + m_table[classType].totalPossible = max; + m_table[classType].totalUsed = 0; + } + + if ( m_table[classType].totalUsed >= m_table[classType].totalPossible ) return FALSE; + + i = m_table[classType].totalUsed++; + m_table[classType].classPointer[i] = pointer; + return TRUE; +} + +// Deletes an instance of a class. + +BOOL CInstanceManager::DeleteInstance(ClassType classType, void* pointer) +{ + int i; + + if ( classType < 0 || classType >= CLASS_MAX ) return FALSE; + + for ( i=0 ; i= CLASS_MAX ) return 0; + if ( m_table[classType].classPointer == 0 ) return 0; +#endif + if ( rank >= m_table[classType].totalUsed ) return 0; + + return m_table[classType].classPointer[rank]; +} + + +// Fills holes in a table. + +void CInstanceManager::Compress(ClassType classType) +{ + int i, j; + + if ( classType < 0 || classType >= CLASS_MAX ) return; + + j = 0; + for ( i=0 ; i no version chosen! +#endif + +#if _SCHOOL +#if !_EDU & !_PERSO & !_CEEBOTDEMO +-> EDU or PERSO or CEEBOTDEMO? +#endif +#if _EDU & _PERSO & _CEEBOTDEMO +-> EDU and PERSO and CEEBOTDEMO not at the same time!!! +#endif +#endif diff --git a/src/common/metafile.cpp b/src/common/metafile.cpp new file mode 100644 index 0000000..d7e260e --- /dev/null +++ b/src/common/metafile.cpp @@ -0,0 +1,418 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// metafile.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include + +#include "language.h" +#include "metafile.h" + + + + +#if _FULL | _NET +static unsigned char table_codec[23] = +{ + 0x85, 0x91, 0x73, 0xcf, 0xa2, 0xbb, 0xf4, 0x77, + 0x58, 0x39, 0x37, 0xfd, 0x2a, 0xcc, 0x5f, 0x55, + 0x96, 0x90, 0x07, 0xcd, 0x11, 0x88, 0x21, +}; + +void Codec(void* buffer, int len, int start) +{ + unsigned char *b = (unsigned char*)buffer; + int i; + + for ( i=0 ; i + + +#define METAMAX 5 + +typedef struct +{ + char name[14]; // file name (8.3 max) + int start; // position from the beginning of the metafile + int len; // length of the file +} +MetaHeader; + +typedef struct +{ + char name[50]; // name of the metafile + FILE* stream; // channel + int total; // number of files + MetaHeader* headers; // headers of files +} +MetaFile; + + + +class CMetaFile +{ +public: + CMetaFile(); + ~CMetaFile(); + + BOOL IsExist(char *metaname, char *filename); + int Open(char *metaname, char *filename); + int RetLength(); + int Seek(int offset); + int Read(void *buffer, int size); + int GetByte(); + int GetWord(); + int Close(); + int MetaClose(); + +protected: + int MetaOpen(char *metaname); + int MetaSearch(char *metaname); + +protected: + MetaFile m_list[METAMAX]; // metafile open + BOOL m_bOpen; // open file + BOOL m_bMeta; // metafile open + FILE* m_stream; // channel + int m_start; // position from the beginning + int m_pos; // current position + int m_len; // length of the file +}; + + +#endif //_METAFILE_H_ diff --git a/src/common/misc.cpp b/src/common/misc.cpp new file mode 100644 index 0000000..ce42de0 --- /dev/null +++ b/src/common/misc.cpp @@ -0,0 +1,443 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// misc.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include +#include +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "d3dutil.h" +#include "language.h" +#include "event.h" +#include "misc.h" + + + +CMetaFile g_metafile; + +static EventMsg g_uniqueEventMsg = EVENT_USER; +static BOOL g_bUserDir = FALSE; +static char g_userDir[100] = ""; + + + +// Gives a single user event. + +EventMsg GetUniqueEventMsg() +{ + int i; + + i = (int)g_uniqueEventMsg+1; + g_uniqueEventMsg = (EventMsg)i; + return g_uniqueEventMsg; +} + + + +// Returns a non-accented letter. + +char RetNoAccent(char letter) +{ + if ( letter < 0 ) + { + if ( letter == 'á' || + letter == 'à' || + letter == 'â' || + letter == 'ä' || + letter == 'ã' ) return 'a'; + + if ( letter == 'é' || + letter == 'è' || + letter == 'ê' || + letter == 'ë' ) return 'e'; + + if ( letter == 'í' || + letter == 'ì' || + letter == 'î' || + letter == 'ï' ) return 'i'; + + if ( letter == 'ó' || + letter == 'ò' || + letter == 'ô' || + letter == 'ö' || + letter == 'õ' ) return 'o'; + + if ( letter == 'ú' || + letter == 'ù' || + letter == 'û' || + letter == 'ü' ) return 'u'; + + if ( letter == 'ç' ) return 'c'; + + if ( letter == 'ñ' ) return 'n'; + + if ( letter == 'Á' || + letter == 'À' || + letter == 'Â' || + letter == 'Ä' || + letter == 'Ã' ) return 'A'; + + if ( letter == 'É' || + letter == 'È' || + letter == 'Ê' || + letter == 'Ë' ) return 'E'; + + if ( letter == 'Í' || + letter == 'Ì' || + letter == 'Î' || + letter == 'Ï' ) return 'I'; + + if ( letter == 'Ó' || + letter == 'Ò' || + letter == 'Ô' || + letter == 'Ö' || + letter == 'Õ' ) return 'O'; + + if ( letter == 'Ú' || + letter == 'Ù' || + letter == 'Û' || + letter == 'Ü' ) return 'U'; + + if ( letter == 'Ç' ) return 'C'; + + if ( letter == 'Ñ' ) return 'N'; + } + + return letter; +} + +// Returns an uppercase letter. + +char RetToUpper(char letter) +{ + if ( letter < 0 ) + { + if ( letter == 'á' ) return 'Á'; + if ( letter == 'à' ) return 'À'; + if ( letter == 'â' ) return 'Â'; + if ( letter == 'ä' ) return 'Ä'; + if ( letter == 'ã' ) return 'Ã'; + + if ( letter == 'é' ) return 'É'; + if ( letter == 'è' ) return 'È'; + if ( letter == 'ê' ) return 'Ê'; + if ( letter == 'ë' ) return 'Ë'; + + if ( letter == 'í' ) return 'Í'; + if ( letter == 'ì' ) return 'Ì'; + if ( letter == 'î' ) return 'Î'; + if ( letter == 'ï' ) return 'Ï'; + + if ( letter == 'ó' ) return 'Ó'; + if ( letter == 'ò' ) return 'Ò'; + if ( letter == 'ô' ) return 'Ô'; + if ( letter == 'ö' ) return 'Ö'; + if ( letter == 'õ' ) return 'Õ'; + + if ( letter == 'ú' ) return 'Ú'; + if ( letter == 'ù' ) return 'Ù'; + if ( letter == 'û' ) return 'Û'; + if ( letter == 'ü' ) return 'Ü'; + + if ( letter == 'ç' ) return 'Ç'; + + if ( letter == 'ñ' ) return 'Ñ'; + } + + return toupper(letter); +} + +// Returns a lowercase letter. + +char RetToLower(char letter) +{ + if ( letter < 0 ) + { + if ( letter == 'Á' ) return 'á'; + if ( letter == 'À' ) return 'à'; + if ( letter == 'Â' ) return 'â'; + if ( letter == 'Ä' ) return 'ä'; + if ( letter == 'Ã' ) return 'ã'; + + if ( letter == 'É' ) return 'é'; + if ( letter == 'È' ) return 'è'; + if ( letter == 'Ê' ) return 'ê'; + if ( letter == 'Ë' ) return 'ë'; + + if ( letter == 'Í' ) return 'í'; + if ( letter == 'Ì' ) return 'ì'; + if ( letter == 'Î' ) return 'î'; + if ( letter == 'Ï' ) return 'ï'; + + if ( letter == 'Ó' ) return 'ó'; + if ( letter == 'Ò' ) return 'ò'; + if ( letter == 'Ô' ) return 'ô'; + if ( letter == 'Ö' ) return 'ö'; + if ( letter == 'Õ' ) return 'õ'; + + if ( letter == 'Ú' ) return 'ú'; + if ( letter == 'Ù' ) return 'ù'; + if ( letter == 'Û' ) return 'û'; + if ( letter == 'Ü' ) return 'ü'; + + if ( letter == 'Ç' ) return 'ç'; + + if ( letter == 'Ñ' ) return 'ñ'; + } + + return tolower(letter); +} + + +// Converting time to string. + +void TimeToAscii(time_t time, char *buffer) +{ + struct tm when; + int year; + + when = *localtime(&time); + year = when.tm_year+1900; + if ( year < 2000 ) year -= 1900; + else year -= 2000; +#if _FRENCH + sprintf(buffer, "%.2d.%.2d.%.2d %.2d:%.2d", + when.tm_mday, when.tm_mon+1, year, + when.tm_hour, when.tm_min); +#endif +#if _GERMAN | _WG + sprintf(buffer, "%.2d.%.2d.%.2d %.2d:%.2d", + when.tm_mday, when.tm_mon+1, year, + when.tm_hour, when.tm_min); +#endif +#if _ENGLISH + char format[10]; + int hour; + + hour = when.tm_hour; // 0..23 + if ( hour < 12 ) // morning? + { + strcpy(format, "am"); + } + else // afternoon? + { + strcpy(format, "pm"); + hour -= 12; // 0..11 + } + if ( hour == 0 ) hour = 12; + + sprintf(buffer, "%.2d.%.2d.%.2d %.2d:%.2d %s", + when.tm_mon+1, when.tm_mday, year, + hour, when.tm_min, format); +#endif +#if _POLISH + sprintf(buffer, "%.2d.%.2d.%.2d %.2d:%.2d", + when.tm_mday, when.tm_mon+1, year, + when.tm_hour, when.tm_min); +#endif +} + + +// Makes a copy of a file. + +BOOL Xfer(char* src, char* dst) +{ + FILE *fs, *fd; + char *buffer; + int len; + + fs = fopen(src, "rb"); + if ( fs == 0 ) + { + return FALSE; + } + + fd = fopen(dst, "wb"); + if ( fd == 0 ) + { + fclose(fs); + return FALSE; + } + + buffer = (char*)malloc(10000); + + while ( TRUE ) + { + len = fread(buffer, 1, 10000, fs); + if ( len == 0 ) break; + fwrite(buffer, 1, len, fd); + } + + free(buffer); + fclose(fs); + fclose(fd); + return TRUE; +} + +// Copy a file into the temporary folder. + +BOOL CopyFileToTemp(char* filename) +{ + char src[100]; + char dst[100]; + char save[100]; + + UserDir(src, filename, "textures"); + + strcpy(save, g_userDir); + strcpy(g_userDir, "temp"); + UserDir(dst, filename, "textures"); + strcpy(g_userDir, save); + + _mkdir("temp"); + if ( !Xfer(src, dst) ) return FALSE; + + strcpy(filename, dst); + return TRUE; +} + +// Copy a list of numbered files into the temporary folder. + +BOOL CopyFileListToTemp(char* filename, int* list, int total) +{ + char name[100]; + char ext[10]; + char file[100]; + char save[100]; + char* p; + int i; + + strcpy(name, filename); + p = strchr(name, '.'); + if ( p == 0 ) + { + strcpy(ext, ".tga"); + } + else + { + strcpy(ext, p); + *p = 0; + } + + for ( i=0 ; i + + +#include "metafile.h" +#include "event.h" + + +extern CMetaFile g_metafile; + + + +// Existing classes. + +enum ClassType +{ + CLASS_EVENT = 1, + CLASS_INTERFACE = 2, + CLASS_MAIN = 3, + CLASS_ENGINE = 4, + CLASS_TERRAIN = 5, + CLASS_OBJECT = 6, + CLASS_PHYSICS = 7, + CLASS_BRAIN = 8, + CLASS_CAMERA = 9, + CLASS_LIGHT = 10, + CLASS_PARTICULE = 11, + CLASS_AUTO = 12, + CLASS_DISPLAYTEXT = 13, + CLASS_PYRO = 14, + CLASS_SCRIPT = 15, + CLASS_TEXT = 16, + CLASS_STUDIO = 17, + CLASS_WATER = 18, + CLASS_CLOUD = 19, + CLASS_MOTION = 20, + CLASS_SOUND = 21, + CLASS_PLANET = 22, + CLASS_TASKMANAGER = 23, + CLASS_DIALOG = 24, + CLASS_MAP = 25, + CLASS_SHORT = 26, + CLASS_BLITZ = 27, +}; + +#define CLASS_MAX 30 + + + +enum Error +{ + ERR_OK = 0, // ok + ERR_GENERIC = 1, // any error + ERR_CONTINUE = 2, // continues + ERR_STOP = 3, // stops + ERR_CMD = 4, // unknown command + ERR_INSTALL = 20, // incorrectly installed program + ERR_NOCD = 21, // CD not found + ERR_MANIP_VEH = 100, // inappropriate vehicle + ERR_MANIP_FLY = 101, // impossible in flight + ERR_MANIP_BUSY = 102, // taking: hands already occupied + ERR_MANIP_NIL = 103, // taking: nothing has to take + ERR_MANIP_MOTOR = 105, // busy: impossible to move + ERR_MANIP_OCC = 106, // busy: location already occupied + ERR_MANIP_FRIEND = 107, // no other vehicle + ERR_MANIP_RADIO = 108, // impossible because radioactive + ERR_MANIP_WATER = 109, // not possible under water + ERR_MANIP_EMPTY = 110, // nothing to deposit + ERR_BUILD_FLY = 120, // not possible in flight + ERR_BUILD_WATER = 121, // not possible under water + ERR_BUILD_ENERGY = 122, // not enough energy + ERR_BUILD_METALAWAY = 123, // lack of metal (too far) + ERR_BUILD_METALNEAR = 124, // lack of metal (too close) + ERR_BUILD_METALINEX = 125, // lack of metal + ERR_BUILD_FLAT = 126, // not enough flat ground + ERR_BUILD_FLATLIT = 127, // not enough flat ground space + ERR_BUILD_BUSY = 128, // location occupied + ERR_BUILD_BASE = 129, // too close to the rocket + ERR_BUILD_NARROW = 130, // buildings too close + ERR_BUILD_MOTOR = 131, // built: not possible in movement + ERR_SEARCH_FLY = 140, // not possible in flight + ERR_SEARCH_VEH = 141, // inappropriate vehicle + ERR_SEARCH_MOTOR = 142, // impossible in movement + ERR_TERRA_VEH = 150, // inappropriate vehicle + ERR_TERRA_ENERGY = 151, // not enough energy + ERR_TERRA_FLOOR = 152, // inappropriate ground + ERR_TERRA_BUILDING = 153, // building too close + ERR_TERRA_OBJECT = 154, // object too close + ERR_FIRE_VEH = 160, // inappropriate vehicle + ERR_FIRE_ENERGY = 161, // not enough energy + ERR_FIRE_FLY = 162, // not possible in flight + ERR_RECOVER_VEH = 170, // inappropriate vehicle + ERR_RECOVER_ENERGY = 171, // not enough energy + ERR_RECOVER_NULL = 172, // lack of ruin + ERR_CONVERT_EMPTY = 180, // no stone was transformed + ERR_SHIELD_VEH = 190, // inappropriate vehicle + ERR_SHIELD_ENERGY = 191, // not enough energy + ERR_MOVE_IMPOSSIBLE = 200, // move impossible + ERR_FIND_IMPOSSIBLE = 201, // find impossible + ERR_GOTO_IMPOSSIBLE = 210, // goto impossible + ERR_GOTO_ITER = 211, // goto too complicated + ERR_GOTO_BUSY = 212, // goto destination occupied + ERR_DERRICK_NULL = 300, // no ore underground + ERR_STATION_NULL = 301, // no energy underground + ERR_TOWER_POWER = 310, // no battery + ERR_TOWER_ENERGY = 311, // more energy + ERR_RESEARCH_POWER = 320, // no battery + ERR_RESEARCH_ENERGY = 321, // more energy + ERR_RESEARCH_TYPE = 322, // the wrong type of battery + ERR_RESEARCH_ALREADY = 323, // research already done + ERR_ENERGY_NULL = 330, // no energy underground + ERR_ENERGY_LOW = 331, // not enough energy + ERR_ENERGY_EMPTY = 332, // lack of metal + ERR_ENERGY_BAD = 333, // transforms only the metal + ERR_BASE_DLOCK = 340, // doors locked + ERR_BASE_DHUMAN = 341, // you must be on spaceship + ERR_LABO_NULL = 350, // nothing to analyze + ERR_LABO_BAD = 351, // analyzes only organic ball + ERR_LABO_ALREADY = 352, // analysis already made + ERR_NUCLEAR_NULL = 360, // no energy underground + ERR_NUCLEAR_LOW = 361, // not enough energy + ERR_NUCLEAR_EMPTY = 362, // lack of uranium + ERR_NUCLEAR_BAD = 363, // transforms only uranium + ERR_FACTORY_NULL = 370, // no metal + ERR_FACTORY_NEAR = 371, // vehicle too close + ERR_RESET_NEAR = 380, // vehicle too close + ERR_INFO_NULL = 390, // no information terminal + ERR_VEH_VIRUS = 400, // vehicle infected by a virus + ERR_BAT_VIRUS = 401, // building infected by a virus + ERR_VEH_POWER = 500, // no battery + ERR_VEH_ENERGY = 501, // more energy + ERR_FLAG_FLY = 510, // impossible in flight + ERR_FLAG_WATER = 511, // impossible during swimming + ERR_FLAG_MOTOR = 512, // impossible in movement + ERR_FLAG_BUSY = 513, // taking: already creating flag + ERR_FLAG_CREATE = 514, // too many flags + ERR_FLAG_PROXY = 515, // too close + ERR_FLAG_DELETE = 516, // nothing to remove + ERR_MISSION_NOTERM = 600, // Mission not completed + ERR_DELETEMOBILE = 700, // vehicle destroyed + ERR_DELETEBUILDING = 701, // building destroyed + ERR_TOOMANY = 702, // too many objects + ERR_OBLIGATORYTOKEN = 800, // compulsory instruction missing + ERR_PROHIBITEDTOKEN = 801, // instruction prohibited + + INFO_FIRST = 10000, // first information + INFO_BUILD = 10001, // construction builded + INFO_CONVERT = 10002, // metal available + INFO_RESEARCH = 10003, // search ended + INFO_FACTORY = 10004, // vehicle manufactured + INFO_LABO = 10005, // analysis ended + INFO_ENERGY = 10006, // battery available + INFO_NUCLEAR = 10007, // nuclear battery available + INFO_FINDING = 10008, // nuclear battery available + INFO_MARKPOWER = 10020, // location for station found + INFO_MARKURANIUM = 10021, // location for derrick found + INFO_MARKSTONE = 10022, // location for derrick found + INFO_MARKKEYa = 10023, // location for derrick found + INFO_MARKKEYb = 10024, // location for derrick found + INFO_MARKKEYc = 10025, // location for derrick found + INFO_MARKKEYd = 10026, // location for derrick found + INFO_RESEARCHTANK = 10030, // research ended + INFO_RESEARCHFLY = 10031, // research ended + INFO_RESEARCHTHUMP = 10032, // research ended + INFO_RESEARCHCANON = 10033, // research ended + INFO_RESEARCHTOWER = 10034, // research ended + INFO_RESEARCHPHAZER = 10035, // research ended + INFO_RESEARCHSHIELD = 10036, // research ended + INFO_RESEARCHATOMIC = 10037, // research ended + INFO_WIN = 10040, // win + INFO_LOST = 10041, // lost + INFO_LOSTq = 10042, // lost immediately + INFO_WRITEOK = 10043, // record done + INFO_DELETEPATH = 10050, // way mark deleted + INFO_DELETEMOTHER = 10100, // insect killed + INFO_DELETEANT = 10101, // insect killed + INFO_DELETEBEE = 10102, // insect killed + INFO_DELETEWORM = 10103, // insect killed + INFO_DELETESPIDER = 10104, // insect killed + INFO_BEGINSATCOM = 10105, // use your SatCom +}; + + +// Keyboard state. + +#define KS_PAGEUP (1<<4) +#define KS_PAGEDOWN (1<<5) +#define KS_SHIFT (1<<6) +#define KS_CONTROL (1<<7) +#define KS_MLEFT (1<<8) +#define KS_MRIGHT (1<<9) +#define KS_NUMUP (1<<10) +#define KS_NUMDOWN (1<<11) +#define KS_NUMLEFT (1<<12) +#define KS_NUMRIGHT (1<<13) +#define KS_NUMPLUS (1<<14) +#define KS_NUMMINUS (1<<15) + + +// Procedures. + +extern EventMsg GetUniqueEventMsg(); + +extern char RetNoAccent(char letter); +extern char RetToUpper(char letter); +extern char RetToLower(char letter); + +extern void TimeToAscii(time_t time, char *buffer); + +extern BOOL CopyFileToTemp(char* filename); +extern BOOL CopyFileListToTemp(char* filename, int* list, int total); +extern void AddExt(char* filename, char* ext); +extern void UserDir(BOOL bUser, char* dir); +extern void UserDir(char* buffer, char* dir, char* def); + +extern char RetLanguageLetter(); + + + +#endif //_MISC_H_ diff --git a/src/common/modfile.cpp b/src/common/modfile.cpp new file mode 100644 index 0000000..08fb89d --- /dev/null +++ b/src/common/modfile.cpp @@ -0,0 +1,697 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// modfile.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "language.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "modfile.h" + + + +#define MAX_VERTICES 2000 + + + +// Object's constructor. + +CModFile::CModFile(CInstanceManager* iMan) +{ + m_iMan = iMan; + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + + m_triangleUsed = 0; + m_triangleTable = (ModelTriangle*)malloc(sizeof(ModelTriangle)*MAX_VERTICES); + ZeroMemory(m_triangleTable, sizeof(ModelTriangle)*MAX_VERTICES); +} + +// Object's destructor. + +CModFile::~CModFile() +{ + free(m_triangleTable); +} + + + + +// Creates a triangle in the internal structure. + +BOOL CModFile::CreateTriangle(D3DVECTOR p1, D3DVECTOR p2, D3DVECTOR p3, + float min, float max) +{ + D3DVECTOR n; + int i; + + if ( m_triangleUsed >= MAX_VERTICES ) + { + OutputDebugString("ERROR: CreateTriangle::Too many triangles\n"); + return FALSE; + } + + i = m_triangleUsed++; + + ZeroMemory(&m_triangleTable[i], sizeof(ModelTriangle)); + + m_triangleTable[i].bUsed = TRUE; + m_triangleTable[i].bSelect = FALSE; + + n = ComputeNormal(p3, p2, p1); + m_triangleTable[i].p1 = D3DVERTEX2( p1, n); + m_triangleTable[i].p2 = D3DVERTEX2( p2, n); + m_triangleTable[i].p3 = D3DVERTEX2( p3, n); + + m_triangleTable[i].material.diffuse.r = 1.0f; + m_triangleTable[i].material.diffuse.g = 1.0f; + m_triangleTable[i].material.diffuse.b = 1.0f; // white + m_triangleTable[i].material.ambient.r = 0.5f; + m_triangleTable[i].material.ambient.g = 0.5f; + m_triangleTable[i].material.ambient.b = 0.5f; + + m_triangleTable[i].min = min; + m_triangleTable[i].max = max; + + return TRUE; +} + +// Reads a DXF file. + +BOOL CModFile::ReadDXF(char *filename, float min, float max) +{ + FILE* file = NULL; + char line[100]; + int command, rankSommet, nbSommet, nbFace; + D3DVECTOR table[MAX_VERTICES]; + BOOL bWaitNbSommet; + BOOL bWaitNbFace; + BOOL bWaitSommetX; + BOOL bWaitSommetY; + BOOL bWaitSommetZ; + BOOL bWaitFaceX; + BOOL bWaitFaceY; + BOOL bWaitFaceZ; + float x,y,z; + int p1,p2,p3; + + file = fopen(filename, "r"); + if ( file == NULL ) return FALSE; + + m_triangleUsed = 0; + + rankSommet = 0; + bWaitNbSommet = FALSE; + bWaitNbFace = FALSE; + bWaitSommetX = FALSE; + bWaitSommetY = FALSE; + bWaitSommetZ = FALSE; + bWaitFaceX = FALSE; + bWaitFaceY = FALSE; + bWaitFaceZ = FALSE; + + while ( fgets(line, 100, file) != NULL ) + { + sscanf(line, "%d", &command); + if ( fgets(line, 100, file) == NULL ) break; + + if ( command == 66 ) + { + bWaitNbSommet = TRUE; + } + + if ( command == 71 && bWaitNbSommet ) + { + bWaitNbSommet = FALSE; + sscanf(line, "%d", &nbSommet); + if ( nbSommet > MAX_VERTICES ) nbSommet = MAX_VERTICES; + rankSommet = 0; + bWaitNbFace = TRUE; + +//? sprintf(s, "Waiting for %d sommets\n", nbSommet); +//? OutputDebugString(s); + } + + if ( command == 72 && bWaitNbFace ) + { + bWaitNbFace = FALSE; + sscanf(line, "%d", &nbFace); + bWaitSommetX = TRUE; + +//? sprintf(s, "Waiting for %d faces\n", nbFace); +//? OutputDebugString(s); + } + + if ( command == 10 && bWaitSommetX ) + { + bWaitSommetX = FALSE; + sscanf(line, "%f", &x); + bWaitSommetY = TRUE; + } + + if ( command == 20 && bWaitSommetY ) + { + bWaitSommetY = FALSE; + sscanf(line, "%f", &y); + bWaitSommetZ = TRUE; + } + + if ( command == 30 && bWaitSommetZ ) + { + bWaitSommetZ = FALSE; + sscanf(line, "%f", &z); + + nbSommet --; + if ( nbSommet >= 0 ) + { + D3DVECTOR p(x,z,y); // permutation of Y and Z! + table[rankSommet++] = p; + bWaitSommetX = TRUE; + +//? sprintf(s, "Sommet[%d]=%f;%f;%f\n", rankSommet, p.x,p.y,p.z); +//? OutputDebugString(s); + } + else + { + bWaitFaceX = TRUE; + } + } + + if ( command == 71 && bWaitFaceX ) + { + bWaitFaceX = FALSE; + sscanf(line, "%d", &p1); + if ( p1 < 0 ) p1 = -p1; + bWaitFaceY = TRUE; + } + + if ( command == 72 && bWaitFaceY ) + { + bWaitFaceY = FALSE; + sscanf(line, "%d", &p2); + if ( p2 < 0 ) p2 = -p2; + bWaitFaceZ = TRUE; + } + + if ( command == 73 && bWaitFaceZ ) + { + bWaitFaceZ = FALSE; + sscanf(line, "%d", &p3); + if ( p3 < 0 ) p3 = -p3; + + nbFace --; + if ( nbFace >= 0 ) + { + CreateTriangle( table[p3-1], table[p2-1], table[p1-1], min,max ); + bWaitFaceX = TRUE; + +//? sprintf(s, "Face=%d;%d;%d\n", p1,p2,p3); +//? OutputDebugString(s); + } + } + + } + + fclose(file); + return TRUE; +} + + + +typedef struct +{ + int rev; + int vers; + int total; + int reserve[10]; +} +InfoMOD; + + +// Change nom.bmp to nom.tga + +void ChangeBMPtoTGA(char *filename) +{ + char* p; + + p = strstr(filename, ".bmp"); + if ( p != 0 ) strcpy(p, ".tga"); +} + + +// Reads a MOD file. + +BOOL CModFile::AddModel(char *filename, int first, BOOL bEdit, BOOL bMeta) +{ + FILE* file; + InfoMOD info; + float limit[2]; + int i, nb, err; + char* p; + + if ( m_engine->RetDebugMode() ) + { + bMeta = FALSE; + } + + if ( bMeta ) + { + p = strchr(filename, '\\'); + if ( p == 0 ) + { +#if _SCHOOL + err = g_metafile.Open("ceebot2.dat", filename); +#else + err = g_metafile.Open("colobot2.dat", filename); +#endif + } + else + { +#if _SCHOOL + err = g_metafile.Open("ceebot2.dat", p+1); +#else + err = g_metafile.Open("colobot2.dat", p+1); +#endif + } + if ( err != 0 ) bMeta = FALSE; + } + if ( !bMeta ) + { + file = fopen(filename, "rb"); + if ( file == NULL ) return FALSE; + } + + if ( bMeta ) + { + g_metafile.Read(&info, sizeof(InfoMOD)); + } + else + { + fread(&info, sizeof(InfoMOD), 1, file); + } + nb = info.total; + m_triangleUsed += nb; + + if ( info.rev == 1 && info.vers == 0 ) + { + OldModelTriangle1 old; + + for ( i=first ; iRetLimitLOD(0); // frontier AB as config + limit[1] = m_engine->RetLimitLOD(1); // frontier BC as config + + // Standard frontiers -> config. + for ( i=first ; iRetSecondTexture(); + } + else + { + texNum = m_triangleTable[i].texNum2; + } + + if ( texNum >= 1 && texNum <= 10 ) + { + state = m_triangleTable[i].state|D3DSTATEDUALb; + } + if ( texNum >= 11 && texNum <= 20 ) + { + state = m_triangleTable[i].state|D3DSTATEDUALw; + } + sprintf(texName2, "dirty%.2d.bmp", texNum); + } + + m_engine->AddTriangle(objRank, &m_triangleTable[i].p1, 3, + m_triangleTable[i].material, + state+addState, + m_triangleTable[i].texName, texName2, + m_triangleTable[i].min, + m_triangleTable[i].max, FALSE); + } + return TRUE; +#else + char texName1[20]; + char texName2[20]; + int texNum, i, state; + + for ( i=0 ; iRetSecondTexture(); + } + else + { + texNum = m_triangleTable[i].texNum2; + } + + if ( texNum >= 1 && texNum <= 10 ) + { + state |= D3DSTATEDUALb; + } + if ( texNum >= 11 && texNum <= 20 ) + { + state |= D3DSTATEDUALw; + } + sprintf(texName2, "dirty%.2d.tga", texNum); + } + + m_engine->AddTriangle(objRank, &m_triangleTable[i].p1, 3, + m_triangleTable[i].material, + state+addState, + texName1, texName2, + m_triangleTable[i].min, + m_triangleTable[i].max, FALSE); + } + return TRUE; +#endif +} + + +// Performs a mirror according to Z. + +void CModFile::Mirror() +{ + D3DVERTEX2 t; + int i; + + for ( i=0 ; i using + char bSelect; // TRUE -> selected + D3DVERTEX p1; + D3DVERTEX p2; + D3DVERTEX p3; + D3DMATERIAL7 material; + char texName[20]; + float min; + float max; +} +OldModelTriangle1; // length = 196 bytes + +typedef struct +{ + char bUsed; // TRUE -> used + char bSelect; // TRUE -> selected + D3DVERTEX p1; + D3DVERTEX p2; + D3DVERTEX p3; + D3DMATERIAL7 material; + char texName[20]; + float min; + float max; + long state; + short reserve1; + short reserve2; + short reserve3; + short reserve4; +} +OldModelTriangle2; + +typedef struct +{ + char bUsed; // TRUE -> used + char bSelect; // TRUE -> selected + D3DVERTEX2 p1; + D3DVERTEX2 p2; + D3DVERTEX2 p3; + D3DMATERIAL7 material; + char texName[20]; + float min; + float max; + long state; + short texNum2; + short reserve2; + short reserve3; + short reserve4; +} +ModelTriangle; // length = 208 bytes + + + + +class CModFile +{ +public: + CModFile(CInstanceManager* iMan); + ~CModFile(); + + BOOL ReadDXF(char *filename, float min, float max); + BOOL AddModel(char *filename, int first, BOOL bEdit=FALSE, BOOL bMeta=TRUE); + BOOL ReadModel(char *filename, BOOL bEdit=FALSE, BOOL bMeta=TRUE); + BOOL WriteModel(char *filename); + + BOOL CreateEngineObject(int objRank, int addState=0); + void Mirror(); + + void SetTriangleUsed(int total); + int RetTriangleUsed(); + int RetTriangleMax(); + ModelTriangle* RetTriangleList(); + + float RetHeight(D3DVECTOR pos); + +protected: + BOOL CreateTriangle(D3DVECTOR p1, D3DVECTOR p2, D3DVECTOR p3, float min, float max); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + + ModelTriangle* m_triangleTable; + int m_triangleUsed; +}; + + +#endif //_MODFILE_H_ diff --git a/src/common/profile.cpp b/src/common/profile.cpp new file mode 100644 index 0000000..2baffb0 --- /dev/null +++ b/src/common/profile.cpp @@ -0,0 +1,116 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// profile.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "language.h" +#include "struct.h" +#include "profile.h" + + + +static char g_filename[100]; + + + +BOOL InitCurrentDirectory() +{ +#if _SCHOOL + _fullpath(g_filename, "ceebot.ini", 100); +#else + _fullpath(g_filename, "colobot.ini", 100); +#endif + return TRUE; +} + + +BOOL SetProfileString(char* section, char* key, char* string) +{ + WritePrivateProfileString(section, key, string, g_filename); + return TRUE; +} + +BOOL GetProfileString(char* section, char* key, char* buffer, int max) +{ + int nb; + + nb = GetPrivateProfileString(section, key, "", buffer, max, g_filename); + if ( nb == 0 ) + { + buffer[0] = 0; + return FALSE; + } + return TRUE; +} + + +BOOL SetProfileInt(char* section, char* key, int value) +{ + char s[20]; + + sprintf(s, "%d", value); + WritePrivateProfileString(section, key, s, g_filename); + return TRUE; +} + +BOOL GetProfileInt(char* section, char* key, int &value) +{ + char s[20]; + int nb; + + nb = GetPrivateProfileString(section, key, "", s, 20, g_filename); + if ( nb == 0 ) + { + value = 0; + return FALSE; + } + sscanf(s, "%d", &value); + return TRUE; +} + + +BOOL SetProfileFloat(char* section, char* key, float value) +{ + char s[20]; + + sprintf(s, "%.2f", value); + WritePrivateProfileString(section, key, s, g_filename); + return TRUE; +} + +BOOL GetProfileFloat(char* section, char* key, float &value) +{ + char s[20]; + int nb; + + nb = GetPrivateProfileString(section, key, "", s, 20, g_filename); + if ( nb == 0 ) + { + value = 0.0f; + return FALSE; + } + sscanf(s, "%f", &value); + return TRUE; +} + + diff --git a/src/common/profile.h b/src/common/profile.h new file mode 100644 index 0000000..969b764 --- /dev/null +++ b/src/common/profile.h @@ -0,0 +1,36 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// profile.h + +#ifndef _PROFILE_H_ +#define _PROFILE_H_ + + +#define STRICT +#define D3D_OVERLOADS + + +extern BOOL InitCurrentDirectory(); +extern BOOL SetProfileString(char* section, char* key, char* string); +extern BOOL GetProfileString(char* section, char* key, char* buffer, int max); +extern BOOL SetProfileInt(char* section, char* key, int value); +extern BOOL GetProfileInt(char* section, char* key, int &value); +extern BOOL SetProfileFloat(char* section, char* key, float value); +extern BOOL GetProfileFloat(char* section, char* key, float &value); + + +#endif //_PROFILE_H_ diff --git a/src/common/restext.cpp b/src/common/restext.cpp new file mode 100644 index 0000000..7422990 --- /dev/null +++ b/src/common/restext.cpp @@ -0,0 +1,3663 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/.// restext.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include "struct.h" +#include "d3dengine.h" +#include "language.h" +#include "misc.h" +#include "event.h" +#include "object.h" +#include "CBot/resource.h" +#include "restext.h" + + + +//** -> text to translate! + + + +// Gives the pointer to the engine. + +void SetEngine(CD3DEngine *engine) +{ + g_engine = engine; +} + +// Give the player's name. + +void SetGlobalGamerName(char *name) +{ + strcpy(g_gamerName, name); +} + + + +typedef struct +{ + KeyRank key; + char name[20]; +} +KeyDesc; + +static KeyDesc keyTable[22] = +{ + { KEYRANK_LEFT, "left;" }, + { KEYRANK_RIGHT, "right;" }, + { KEYRANK_UP, "up;" }, + { KEYRANK_DOWN, "down;" }, + { KEYRANK_GUP, "gup;" }, + { KEYRANK_GDOWN, "gdown;" }, + { KEYRANK_CAMERA, "camera;" }, + { KEYRANK_DESEL, "desel;" }, + { KEYRANK_ACTION, "action;" }, + { KEYRANK_NEAR, "near;" }, + { KEYRANK_AWAY, "away;" }, + { KEYRANK_NEXT, "next;" }, + { KEYRANK_HUMAN, "human;" }, + { KEYRANK_QUIT, "quit;" }, + { KEYRANK_HELP, "help;" }, + { KEYRANK_PROG, "prog;" }, + { KEYRANK_CBOT, "cbot;" }, + { KEYRANK_VISIT, "visit;" }, + { KEYRANK_SPEED10, "speed10;" }, + { KEYRANK_SPEED15, "speed15;" }, + { KEYRANK_SPEED20, "speed20;" }, + { KEYRANK_SPEED30, "speed30;" }, +}; + +// Seeks a key. + +BOOL SearchKey(char *cmd, KeyRank &key) +{ + int i; + + for ( i=0 ; i<22 ; i++ ) + { + if ( strstr(cmd, keyTable[i].name) == cmd ) + { + key = keyTable[i].key; + return TRUE; + } + } + return FALSE; +} + +// Replaces the commands "\key name;" in a text. + +void PutKeyName(char* dst, char* src) +{ + KeyRank key; + char name[50]; + int s, d, n, res; + + s = d = 0; + while ( src[s] != 0 ) + { + if ( src[s+0] == '\\' && + src[s+1] == 'k' && + src[s+2] == 'e' && + src[s+3] == 'y' && + src[s+4] == ' ' ) + { + if ( SearchKey(src+s+5, key) ) + { + res = g_engine->RetKey(key, 0); + if ( res != 0 ) + { + if ( GetResource(RES_KEY, res, name) ) + { + n = 0; + while ( name[n] != 0 ) + { + dst[d++] = name[n++]; + } + while ( src[s++] != ';' ); + continue; + } + } + } + } + + dst[d++] = src[s++]; + } + dst[d++] = 0; +} + + +// Returns the text of a resource. + +BOOL GetResource(ResType type, int num, char* text) +{ + char buffer[100]; + + if ( !GetResourceBase(type, num, buffer) ) + { + text[0] = 0; + return FALSE; + } + + PutKeyName(text, buffer); + return TRUE; +} + + +// Returns the text of a resource. + +BOOL GetResourceBase(ResType type, int num, char* text) +{ + text[0] = 0; + +#if _ENGLISH + if ( type == RES_TEXT ) + { + #if _FULL + if ( num == RT_VERSION_ID ) strcpy(text, "1.18 /e"); + #endif + #if _NET + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A 1.18"); + #endif + #if _SCHOOL & _EDU + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen EDU 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A EDU 1.18"); + #endif + #endif + #if _SCHOOL & _PERSO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen PERSO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A PERSO 1.18"); + #endif + #endif + #if _SCHOOL & _CEEBOTDEMO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen DEMO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A DEMO 1.18"); + #endif + #endif + #if _DEMO + if ( num == RT_VERSION_ID ) strcpy(text, "Demo 1.18 /e"); + #endif + if ( num == RT_DISINFO_TITLE ) strcpy(text, "SatCom"); + if ( num == RT_WINDOW_MAXIMIZED ) strcpy(text, "Maximize"); + if ( num == RT_WINDOW_MINIMIZED ) strcpy(text, "Minimize"); + if ( num == RT_WINDOW_STANDARD ) strcpy(text, "Normal size"); + if ( num == RT_WINDOW_CLOSE ) strcpy(text, "Close"); + + if ( num == RT_STUDIO_TITLE ) strcpy(text, "Program editor"); + if ( num == RT_SCRIPT_NEW ) strcpy(text, "New"); + if ( num == RT_NAME_DEFAULT ) strcpy(text, "Player"); + if ( num == RT_IO_NEW ) strcpy(text, "New ..."); + if ( num == RT_KEY_OR ) strcpy(text, " or "); + +#if _NEWLOOK + if ( num == RT_TITLE_BASE ) strcpy(text, "CeeBot"); + if ( num == RT_TITLE_INIT ) strcpy(text, "CeeBot"); +#else + if ( num == RT_TITLE_BASE ) strcpy(text, "COLOBOT"); + if ( num == RT_TITLE_INIT ) strcpy(text, "COLOBOT"); +#endif + if ( num == RT_TITLE_TRAINER ) strcpy(text, "Programming exercises"); + if ( num == RT_TITLE_DEFI ) strcpy(text, "Challenges"); + if ( num == RT_TITLE_MISSION ) strcpy(text, "Missions"); + if ( num == RT_TITLE_FREE ) strcpy(text, "Free game"); + if ( num == RT_TITLE_TEEN ) strcpy(text, "Free game"); + if ( num == RT_TITLE_USER ) strcpy(text, "User levels"); + if ( num == RT_TITLE_PROTO ) strcpy(text, "Prototypes"); + if ( num == RT_TITLE_SETUP ) strcpy(text, "Options"); + if ( num == RT_TITLE_NAME ) strcpy(text, "Player's name"); + if ( num == RT_TITLE_PERSO ) strcpy(text, "Customize your appearance"); + if ( num == RT_TITLE_WRITE ) strcpy(text, "Save the current mission"); + if ( num == RT_TITLE_READ ) strcpy(text, "Load a saved mission"); + + if ( num == RT_PLAY_CHAPt ) strcpy(text, " Chapters:"); + if ( num == RT_PLAY_CHAPd ) strcpy(text, " Chapters:"); + if ( num == RT_PLAY_CHAPm ) strcpy(text, " Planets:"); + if ( num == RT_PLAY_CHAPf ) strcpy(text, " Planets:"); + if ( num == RT_PLAY_CHAPu ) strcpy(text, " User levels:"); + if ( num == RT_PLAY_CHAPp ) strcpy(text, " Planets:"); + if ( num == RT_PLAY_CHAPte ) strcpy(text, " Chapters:"); + if ( num == RT_PLAY_LISTt ) strcpy(text, " Exercises in the chapter:"); + if ( num == RT_PLAY_LISTd ) strcpy(text, " Challenges in the chapter:"); + if ( num == RT_PLAY_LISTm ) strcpy(text, " Missions on this planet:"); + if ( num == RT_PLAY_LISTf ) strcpy(text, " Free game on this planet:"); + if ( num == RT_PLAY_LISTu ) strcpy(text, " Missions on this level:"); + if ( num == RT_PLAY_LISTp ) strcpy(text, " Prototypes on this planet:"); + if ( num == RT_PLAY_LISTk ) strcpy(text, " Free game on this chapter:"); + if ( num == RT_PLAY_RESUME ) strcpy(text, " Summary:"); + + if ( num == RT_SETUP_DEVICE ) strcpy(text, " Drivers:"); + if ( num == RT_SETUP_MODE ) strcpy(text, " Resolution:"); + if ( num == RT_SETUP_KEY1 ) strcpy(text, "1) First click on the key you want to redefine."); + if ( num == RT_SETUP_KEY2 ) strcpy(text, "2) Then press the key you want to use instead."); + + if ( num == RT_PERSO_FACE ) strcpy(text, "Face type:"); + if ( num == RT_PERSO_GLASSES ) strcpy(text, "Eyeglasses:"); + if ( num == RT_PERSO_HAIR ) strcpy(text, "Hair color:"); + if ( num == RT_PERSO_COMBI ) strcpy(text, "Suit color:"); + if ( num == RT_PERSO_BAND ) strcpy(text, "Strip color:"); + +#if _NEWLOOK + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Do you want to quit CeeBot ?"); + if ( num == RT_DIALOG_TITLE ) strcpy(text, "CeeBot"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Quit\\Quit CeeBot"); +#else + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Do you want to quit COLOBOT ?"); + if ( num == RT_DIALOG_TITLE ) strcpy(text, "COLOBOT"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Quit\\Quit COLOBOT"); +#endif + if ( num == RT_DIALOG_ABORT ) strcpy(text, "Quit the mission?"); + if ( num == RT_DIALOG_YES ) strcpy(text, "Abort\\Abort the current mission"); + if ( num == RT_DIALOG_NO ) strcpy(text, "Continue\\Continue the current mission"); + if ( num == RT_DIALOG_NOQUIT ) strcpy(text, "Continue\\Continue the game"); + if ( num == RT_DIALOG_DELOBJ ) strcpy(text, "Do you really want to destroy the selected building?"); + if ( num == RT_DIALOG_DELGAME ) strcpy(text, "Do you want to delete %s's saved games? "); + if ( num == RT_DIALOG_YESDEL ) strcpy(text, "Delete"); + if ( num == RT_DIALOG_NODEL ) strcpy(text, "Cancel"); + if ( num == RT_DIALOG_LOADING ) strcpy(text, "LOADING"); + + if ( num == RT_STUDIO_LISTTT ) strcpy(text, "Keyword help(\\key cbot;)"); + if ( num == RT_STUDIO_COMPOK ) strcpy(text, "Compilation ok (0 errors)"); + if ( num == RT_STUDIO_PROGSTOP ) strcpy(text, "Program finished"); + + if ( num == RT_SATCOM_LIST ) strcpy(text, "\\b;List of objects\n"); + if ( num == RT_SATCOM_BOT ) strcpy(text, "\\b;Robots\n"); + if ( num == RT_SATCOM_BUILDING ) strcpy(text, "\\b;Buildings\n"); + if ( num == RT_SATCOM_FRET ) strcpy(text, "\\b;Moveable objects\n"); + if ( num == RT_SATCOM_ALIEN ) strcpy(text, "\\b;Aliens\n"); + if ( num == RT_SATCOM_NULL ) strcpy(text, "\\c; (none)\\n;\n"); + if ( num == RT_SATCOM_ERROR1 ) strcpy(text, "\\b;Error\n"); + if ( num == RT_SATCOM_ERROR2 ) strcpy(text, "The list is only available if a \\l;radar station\\u object\\radar; is working.\n"); + + if ( num == RT_IO_OPEN ) strcpy(text, "Open"); + if ( num == RT_IO_SAVE ) strcpy(text, "Save"); + if ( num == RT_IO_LIST ) strcpy(text, "Folder: %s"); + if ( num == RT_IO_NAME ) strcpy(text, "Name:"); + if ( num == RT_IO_DIR ) strcpy(text, "Folder:"); + if ( num == RT_IO_PRIVATE ) strcpy(text, "Private\\Private folder"); + if ( num == RT_IO_PUBLIC ) strcpy(text, "Public\\Common folder"); + + if ( num == RT_GENERIC_DEV1 ) strcpy(text, "Developed by :"); + if ( num == RT_GENERIC_DEV2 ) strcpy(text, "www.epsitec.com"); +//? if ( num == RT_GENERIC_EDIT1 ) strcpy(text, "English version published by:"); +//? if ( num == RT_GENERIC_EDIT2 ) strcpy(text, "www.?.com"); + if ( num == RT_GENERIC_EDIT1 ) strcpy(text, " "); + if ( num == RT_GENERIC_EDIT2 ) strcpy(text, " "); + + if ( num == RT_INTERFACE_REC ) strcpy(text, "Recorder"); + } + + if ( type == RES_EVENT ) + { + if ( num == EVENT_BUTTON_OK ) strcpy(text, "OK"); + if ( num == EVENT_BUTTON_CANCEL ) strcpy(text, "Cancel"); + if ( num == EVENT_BUTTON_NEXT ) strcpy(text, "Next"); + if ( num == EVENT_BUTTON_PREV ) strcpy(text, "Previous"); + if ( num == EVENT_BUTTON_QUIT ) strcpy(text, "Menu (\\key quit;)"); + + if ( num == EVENT_DIALOG_OK ) strcpy(text, "OK"); + if ( num == EVENT_DIALOG_CANCEL ) strcpy(text, "Cancel"); + + if ( num == EVENT_INTERFACE_TRAINER) strcpy(text, "Exercises\\Programming exercises"); + if ( num == EVENT_INTERFACE_DEFI ) strcpy(text, "Challenges\\Programming challenges"); + if ( num == EVENT_INTERFACE_MISSION) strcpy(text, "Missions\\Select mission"); + if ( num == EVENT_INTERFACE_FREE ) strcpy(text, "Free game\\Free game without a specific goal"); + if ( num == EVENT_INTERFACE_TEEN ) strcpy(text, "Free game\\Free game without a specific goal"); + if ( num == EVENT_INTERFACE_USER ) strcpy(text, "User\\User levels"); + if ( num == EVENT_INTERFACE_PROTO ) strcpy(text, "Proto\\Prototypes under development"); + if ( num == EVENT_INTERFACE_NAME ) strcpy(text, "New player\\Choose player's name"); + if ( num == EVENT_INTERFACE_SETUP ) strcpy(text, "Options\\Preferences"); + if ( num == EVENT_INTERFACE_AGAIN ) strcpy(text, "Restart\\Restart the mission from the beginning"); + if ( num == EVENT_INTERFACE_WRITE ) strcpy(text, "Save\\Save the current mission "); + if ( num == EVENT_INTERFACE_READ ) strcpy(text, "Load\\Load a saved mission"); +#if _NEWLOOK + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Return to CeeBot"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Quit\\Quit CeeBot"); +#else + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Return to COLOBOT"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Quit\\Quit COLOBOT"); +#endif + if ( num == EVENT_INTERFACE_BACK ) strcpy(text, "<< Back \\Back to the previous screen"); + if ( num == EVENT_INTERFACE_PLAY ) strcpy(text, "Play\\Start mission!"); + if ( num == EVENT_INTERFACE_SETUPd ) strcpy(text, "Device\\Driver and resolution settings"); + if ( num == EVENT_INTERFACE_SETUPg ) strcpy(text, "Graphics\\Graphics settings"); + if ( num == EVENT_INTERFACE_SETUPp ) strcpy(text, "Game\\Game settings"); + if ( num == EVENT_INTERFACE_SETUPc ) strcpy(text, "Controls\\Keyboard, joystick and mouse settings"); + if ( num == EVENT_INTERFACE_SETUPs ) strcpy(text, "Sound\\Music and game sound volume"); + if ( num == EVENT_INTERFACE_DEVICE ) strcpy(text, "Unit"); + if ( num == EVENT_INTERFACE_RESOL ) strcpy(text, "Resolution"); + if ( num == EVENT_INTERFACE_FULL ) strcpy(text, "Full screen\\Full screen or window mode"); + if ( num == EVENT_INTERFACE_APPLY ) strcpy(text, "Apply changes\\Activates the changed settings"); + + if ( num == EVENT_INTERFACE_TOTO ) strcpy(text, "Robbie\\Your assistant"); + if ( num == EVENT_INTERFACE_SHADOW ) strcpy(text, "Shadows\\Shadows on the ground"); + if ( num == EVENT_INTERFACE_GROUND ) strcpy(text, "Marks on the ground\\Marks on the ground"); + if ( num == EVENT_INTERFACE_DIRTY ) strcpy(text, "Dust\\Dust and dirt on bots and buildings"); + if ( num == EVENT_INTERFACE_FOG ) strcpy(text, "Fog\\Fog"); + if ( num == EVENT_INTERFACE_LENS ) strcpy(text, "Sunbeams\\Sunbeams in the sky"); + if ( num == EVENT_INTERFACE_SKY ) strcpy(text, "Sky\\Clouds and nebulae"); + if ( num == EVENT_INTERFACE_PLANET ) strcpy(text, "Planets and stars\\Astronomical objects in the sky"); + if ( num == EVENT_INTERFACE_LIGHT ) strcpy(text, "Dynamic lighting\\Mobile light sources"); + if ( num == EVENT_INTERFACE_PARTI ) strcpy(text, "Number of particles\\Explosions, dust, reflections, etc."); + if ( num == EVENT_INTERFACE_CLIP ) strcpy(text, "Depth of field\\Maximum visibility"); + if ( num == EVENT_INTERFACE_DETAIL ) strcpy(text, "Details\\Visual quality of 3D objects"); + if ( num == EVENT_INTERFACE_TEXTURE) strcpy(text, "Textures\\Quality of textures "); + if ( num == EVENT_INTERFACE_GADGET ) strcpy(text, "Num of decorative objects\\Number of purely ornamental objects"); + if ( num == EVENT_INTERFACE_RAIN ) strcpy(text, "Particles in the interface\\Steam clouds and sparks in the interface"); + if ( num == EVENT_INTERFACE_GLINT ) strcpy(text, "Reflections on the buttons \\Shiny buttons"); + if ( num == EVENT_INTERFACE_TOOLTIP) strcpy(text, "Help balloons\\Explain the function of the buttons"); + if ( num == EVENT_INTERFACE_MOVIES ) strcpy(text, "Film sequences\\Films before and after the missions"); + if ( num == EVENT_INTERFACE_NICERST) strcpy(text, "Exit film\\Film at the exit of exercises"); + if ( num == EVENT_INTERFACE_HIMSELF) strcpy(text, "Friendly fire\\Your shooting can damage your own objects "); + if ( num == EVENT_INTERFACE_SCROLL ) strcpy(text, "Scrolling\\Scrolling when the mouse touches right or left border"); + if ( num == EVENT_INTERFACE_INVERTX) strcpy(text, "Mouse inversion X\\Inversion of the scrolling direction on the X axis"); + if ( num == EVENT_INTERFACE_INVERTY) strcpy(text, "Mouse inversion Y\\Inversion of the scrolling direction on the Y axis"); + if ( num == EVENT_INTERFACE_EFFECT ) strcpy(text, "Quake at explosions\\The screen shakes at explosions"); + if ( num == EVENT_INTERFACE_MOUSE ) strcpy(text, "Mouse shadow\\Gives the mouse a shadow"); + if ( num == EVENT_INTERFACE_EDITMODE) strcpy(text, "Automatic indent\\When program editing"); + if ( num == EVENT_INTERFACE_EDITVALUE)strcpy(text, "Big indent\\Indent 2 or 4 spaces per level defined by braces"); + if ( num == EVENT_INTERFACE_SOLUCE4) strcpy(text, "Access to solutions\\Show program \"4: Solution\" in the exercises"); //** + + if ( num == EVENT_INTERFACE_KDEF ) strcpy(text, "Standard controls\\Standard key functions"); + if ( num == EVENT_INTERFACE_KLEFT ) strcpy(text, "Turn left\\turns the bot to the left"); + if ( num == EVENT_INTERFACE_KRIGHT ) strcpy(text, "Turn right\\turns the bot to the right"); + if ( num == EVENT_INTERFACE_KUP ) strcpy(text, "Forward\\Moves forward"); + if ( num == EVENT_INTERFACE_KDOWN ) strcpy(text, "Backward\\Moves backward"); + if ( num == EVENT_INTERFACE_KGUP ) strcpy(text, "Climb\\Increases the power of the jet"); + if ( num == EVENT_INTERFACE_KGDOWN ) strcpy(text, "Descend\\Reduces the power of the jet"); + if ( num == EVENT_INTERFACE_KCAMERA) strcpy(text, "Change camera\\Switches between onboard camera and following camera"); + if ( num == EVENT_INTERFACE_KDESEL ) strcpy(text, "Previous object\\Selects the previous object"); + if ( num == EVENT_INTERFACE_KACTION) strcpy(text, "Standard action\\Standard action of the bot (take/grab, shoot, sniff, etc)"); + if ( num == EVENT_INTERFACE_KNEAR ) strcpy(text, "Camera closer\\Moves the camera forward"); + if ( num == EVENT_INTERFACE_KAWAY ) strcpy(text, "Camera back\\Moves the camera backward"); + if ( num == EVENT_INTERFACE_KNEXT ) strcpy(text, "Next object\\Selects the next object"); + if ( num == EVENT_INTERFACE_KHUMAN ) strcpy(text, "Select the astronaut\\Selects the astronaut"); + if ( num == EVENT_INTERFACE_KQUIT ) strcpy(text, "Quit\\Quit the current mission or exercise"); + if ( num == EVENT_INTERFACE_KHELP ) strcpy(text, "Instructions\\Shows the instructions for the current mission"); + if ( num == EVENT_INTERFACE_KPROG ) strcpy(text, "Programming help\\Gives more detailed help with programming"); + if ( num == EVENT_INTERFACE_KCBOT ) strcpy(text, "Key word help\\More detailed help about key words"); + if ( num == EVENT_INTERFACE_KVISIT ) strcpy(text, "Origin of last message\\Shows where the last message was sent from"); + if ( num == EVENT_INTERFACE_KSPEED10) strcpy(text, "Speed 1.0x\\Normal speed"); + if ( num == EVENT_INTERFACE_KSPEED15) strcpy(text, "Speed 1.5x\\1.5 times faster"); + if ( num == EVENT_INTERFACE_KSPEED20) strcpy(text, "Speed 2.0x\\Double speed"); + if ( num == EVENT_INTERFACE_KSPEED30) strcpy(text, "Speed 3.0x\\Three times faster"); + + if ( num == EVENT_INTERFACE_VOLSOUND) strcpy(text, "Sound effects:\\Volume of engines, voice, shooting, etc."); + if ( num == EVENT_INTERFACE_VOLMUSIC) strcpy(text, "Background sound :\\Volume of audio tracks on the CD"); + if ( num == EVENT_INTERFACE_SOUND3D) strcpy(text, "3D sound\\3D positioning of the sound"); + + if ( num == EVENT_INTERFACE_MIN ) strcpy(text, "Lowest\\Minimum graphic quality (highest frame rate)"); + if ( num == EVENT_INTERFACE_NORM ) strcpy(text, "Normal\\Normal graphic quality"); + if ( num == EVENT_INTERFACE_MAX ) strcpy(text, "Highest\\Highest graphic quality (lowest frame rate)"); + + if ( num == EVENT_INTERFACE_SILENT ) strcpy(text, "Mute\\No sound"); + if ( num == EVENT_INTERFACE_NOISY ) strcpy(text, "Normal\\Normal sound volume"); + + if ( num == EVENT_INTERFACE_JOYSTICK) strcpy(text, "Use a joystick\\Joystick or keyboard"); + if ( num == EVENT_INTERFACE_SOLUCE ) strcpy(text, "Access to solution\\Shows the solution (detailed instructions for missions)"); + + if ( num == EVENT_INTERFACE_NEDIT ) strcpy(text, "\\New player name"); + if ( num == EVENT_INTERFACE_NOK ) strcpy(text, "OK\\Choose the selected player"); + if ( num == EVENT_INTERFACE_NCANCEL) strcpy(text, "Cancel\\Keep current player name"); + if ( num == EVENT_INTERFACE_NDELETE) strcpy(text, "Delete player\\Deletes the player from the list"); + if ( num == EVENT_INTERFACE_NLABEL ) strcpy(text, "Player name"); + + if ( num == EVENT_INTERFACE_IOWRITE) strcpy(text, "Save\\Saves the current mission"); + if ( num == EVENT_INTERFACE_IOREAD ) strcpy(text, "Load\\Loads the selected mission"); + if ( num == EVENT_INTERFACE_IOLIST ) strcpy(text, "List of saved missions"); + if ( num == EVENT_INTERFACE_IOLABEL) strcpy(text, "Filename:"); + if ( num == EVENT_INTERFACE_IONAME ) strcpy(text, "Mission name"); + if ( num == EVENT_INTERFACE_IOIMAGE) strcpy(text, "Photography"); + if ( num == EVENT_INTERFACE_IODELETE) strcpy(text, "Delete\\Deletes the selected file"); + + if ( num == EVENT_INTERFACE_PERSO ) strcpy(text, "Appearance\\Choose your appearance"); + if ( num == EVENT_INTERFACE_POK ) strcpy(text, "OK"); + if ( num == EVENT_INTERFACE_PCANCEL) strcpy(text, "Cancel"); + if ( num == EVENT_INTERFACE_PDEF ) strcpy(text, "Standard\\Standard appearance settings"); + if ( num == EVENT_INTERFACE_PHEAD ) strcpy(text, "Head\\Face and hair"); + if ( num == EVENT_INTERFACE_PBODY ) strcpy(text, "Suit\\Astronaut suit"); + if ( num == EVENT_INTERFACE_PLROT ) strcpy(text, "\\Turn left"); + if ( num == EVENT_INTERFACE_PRROT ) strcpy(text, "\\Turn right"); + if ( num == EVENT_INTERFACE_PCRa ) strcpy(text, "Red"); + if ( num == EVENT_INTERFACE_PCGa ) strcpy(text, "Green"); + if ( num == EVENT_INTERFACE_PCBa ) strcpy(text, "Blue"); + if ( num == EVENT_INTERFACE_PCRb ) strcpy(text, "Red"); + if ( num == EVENT_INTERFACE_PCGb ) strcpy(text, "Green"); + if ( num == EVENT_INTERFACE_PCBb ) strcpy(text, "Blue"); + if ( num == EVENT_INTERFACE_PFACE1 ) strcpy(text, "\\Face 1"); + if ( num == EVENT_INTERFACE_PFACE2 ) strcpy(text, "\\Face 4"); + if ( num == EVENT_INTERFACE_PFACE3 ) strcpy(text, "\\Face 3"); + if ( num == EVENT_INTERFACE_PFACE4 ) strcpy(text, "\\Face 2"); + if ( num == EVENT_INTERFACE_PGLASS0) strcpy(text, "\\No eyeglasses"); + if ( num == EVENT_INTERFACE_PGLASS1) strcpy(text, "\\Eyeglasses 1"); + if ( num == EVENT_INTERFACE_PGLASS2) strcpy(text, "\\Eyeglasses 2"); + if ( num == EVENT_INTERFACE_PGLASS3) strcpy(text, "\\Eyeglasses 3"); + if ( num == EVENT_INTERFACE_PGLASS4) strcpy(text, "\\Eyeglasses 4"); + if ( num == EVENT_INTERFACE_PGLASS5) strcpy(text, "\\Eyeglasses 5"); + + if ( num == EVENT_OBJECT_DESELECT ) strcpy(text, "Previous selection (\\key desel;)"); + if ( num == EVENT_OBJECT_LEFT ) strcpy(text, "Turn left (\\key left;)"); + if ( num == EVENT_OBJECT_RIGHT ) strcpy(text, "Turn right (\\key right;)"); + if ( num == EVENT_OBJECT_UP ) strcpy(text, "Forward (\\key up;)"); + if ( num == EVENT_OBJECT_DOWN ) strcpy(text, "Backward (\\key down;)"); + if ( num == EVENT_OBJECT_GASUP ) strcpy(text, "Up (\\key gup;)"); + if ( num == EVENT_OBJECT_GASDOWN ) strcpy(text, "Down (\\key gdown;)"); + if ( num == EVENT_OBJECT_HTAKE ) strcpy(text, "Grab or drop (\\key action;)"); + if ( num == EVENT_OBJECT_MTAKE ) strcpy(text, "Grab or drop (\\key action;)"); + if ( num == EVENT_OBJECT_MFRONT ) strcpy(text, "..in front"); + if ( num == EVENT_OBJECT_MBACK ) strcpy(text, "..behind"); + if ( num == EVENT_OBJECT_MPOWER ) strcpy(text, "..power cell"); + if ( num == EVENT_OBJECT_BHELP ) strcpy(text, "Instructions for the mission (\\key help;)"); + if ( num == EVENT_OBJECT_BTAKEOFF ) strcpy(text, "Take off to finish the mission"); + if ( num == EVENT_OBJECT_BDERRICK ) strcpy(text, "Build a derrick"); + if ( num == EVENT_OBJECT_BSTATION ) strcpy(text, "Build a power station"); + if ( num == EVENT_OBJECT_BFACTORY ) strcpy(text, "Build a bot factory"); + if ( num == EVENT_OBJECT_BREPAIR ) strcpy(text, "Build a repair center"); + if ( num == EVENT_OBJECT_BCONVERT ) strcpy(text, "Build a converter"); + if ( num == EVENT_OBJECT_BTOWER ) strcpy(text, "Build a defense tower"); + if ( num == EVENT_OBJECT_BRESEARCH ) strcpy(text, "Build a research center"); + if ( num == EVENT_OBJECT_BRADAR ) strcpy(text, "Build a radar station"); + if ( num == EVENT_OBJECT_BENERGY ) strcpy(text, "Build a power cell factory"); + if ( num == EVENT_OBJECT_BLABO ) strcpy(text, "Build an autolab"); + if ( num == EVENT_OBJECT_BNUCLEAR ) strcpy(text, "Build a nuclear power plant"); + if ( num == EVENT_OBJECT_BPARA ) strcpy(text, "Build a lightning conductor"); + if ( num == EVENT_OBJECT_BINFO ) strcpy(text, "Build a exchange post"); + if ( num == EVENT_OBJECT_GFLAT ) strcpy(text, "Show if the ground is flat"); + if ( num == EVENT_OBJECT_FCREATE ) strcpy(text, "Plant a flag"); + if ( num == EVENT_OBJECT_FDELETE ) strcpy(text, "Remove a flag"); + if ( num == EVENT_OBJECT_FCOLORb ) strcpy(text, "\\Blue flags"); + if ( num == EVENT_OBJECT_FCOLORr ) strcpy(text, "\\Red flags"); + if ( num == EVENT_OBJECT_FCOLORg ) strcpy(text, "\\Green flags"); + if ( num == EVENT_OBJECT_FCOLORy ) strcpy(text, "\\Yellow flags"); + if ( num == EVENT_OBJECT_FCOLORv ) strcpy(text, "\\Violet flags"); + if ( num == EVENT_OBJECT_FACTORYfa ) strcpy(text, "Build a winged grabber"); + if ( num == EVENT_OBJECT_FACTORYta ) strcpy(text, "Build a tracked grabber"); + if ( num == EVENT_OBJECT_FACTORYwa ) strcpy(text, "Build a wheeled grabber"); + if ( num == EVENT_OBJECT_FACTORYia ) strcpy(text, "Build a legged grabber"); + if ( num == EVENT_OBJECT_FACTORYfc ) strcpy(text, "Build a winged shooter"); + if ( num == EVENT_OBJECT_FACTORYtc ) strcpy(text, "Build a tracked shooter"); + if ( num == EVENT_OBJECT_FACTORYwc ) strcpy(text, "Build a wheeled shooter"); + if ( num == EVENT_OBJECT_FACTORYic ) strcpy(text, "Build a legged shooter"); + if ( num == EVENT_OBJECT_FACTORYfi ) strcpy(text, "Build a winged orga shooter"); + if ( num == EVENT_OBJECT_FACTORYti ) strcpy(text, "Build a tracked orga shooter"); + if ( num == EVENT_OBJECT_FACTORYwi ) strcpy(text, "Build a wheeled orga shooter"); + if ( num == EVENT_OBJECT_FACTORYii ) strcpy(text, "Build a legged orga shooter"); + if ( num == EVENT_OBJECT_FACTORYfs ) strcpy(text, "Build a winged sniffer"); + if ( num == EVENT_OBJECT_FACTORYts ) strcpy(text, "Build a tracked sniffer"); + if ( num == EVENT_OBJECT_FACTORYws ) strcpy(text, "Build a wheeled sniffer"); + if ( num == EVENT_OBJECT_FACTORYis ) strcpy(text, "Build a legged sniffer"); + if ( num == EVENT_OBJECT_FACTORYrt ) strcpy(text, "Build a thumper"); + if ( num == EVENT_OBJECT_FACTORYrc ) strcpy(text, "Build a phazer shooter"); + if ( num == EVENT_OBJECT_FACTORYrr ) strcpy(text, "Build a recycler"); + if ( num == EVENT_OBJECT_FACTORYrs ) strcpy(text, "Build a shielder"); + if ( num == EVENT_OBJECT_FACTORYsa ) strcpy(text, "Build a subber"); + if ( num == EVENT_OBJECT_RTANK ) strcpy(text, "Run research program for tracked bots"); + if ( num == EVENT_OBJECT_RFLY ) strcpy(text, "Run research program for winged bots"); + if ( num == EVENT_OBJECT_RTHUMP ) strcpy(text, "Run research program for thumper"); + if ( num == EVENT_OBJECT_RCANON ) strcpy(text, "Run research program for shooter"); + if ( num == EVENT_OBJECT_RTOWER ) strcpy(text, "Run research program for defense tower"); + if ( num == EVENT_OBJECT_RPHAZER ) strcpy(text, "Run research program for phazer shooter"); + if ( num == EVENT_OBJECT_RSHIELD ) strcpy(text, "Run research program for shielder"); + if ( num == EVENT_OBJECT_RATOMIC ) strcpy(text, "Run research program for nuclear power"); + if ( num == EVENT_OBJECT_RiPAW ) strcpy(text, "Run research program for legged bots"); + if ( num == EVENT_OBJECT_RiGUN ) strcpy(text, "Run research program for orga shooter"); + if ( num == EVENT_OBJECT_RESET ) strcpy(text, "Return to start"); + if ( num == EVENT_OBJECT_SEARCH ) strcpy(text, "Sniff (\\key action;)"); + if ( num == EVENT_OBJECT_TERRAFORM ) strcpy(text, "Thump (\\key action;)"); + if ( num == EVENT_OBJECT_FIRE ) strcpy(text, "Shoot (\\key action;)"); + if ( num == EVENT_OBJECT_RECOVER ) strcpy(text, "Recycle (\\key action;)"); + if ( num == EVENT_OBJECT_BEGSHIELD ) strcpy(text, "Extend shield (\\key action;)"); + if ( num == EVENT_OBJECT_ENDSHIELD ) strcpy(text, "Withdraw shield (\\key action;)"); + if ( num == EVENT_OBJECT_DIMSHIELD ) strcpy(text, "Shield radius"); + if ( num == EVENT_OBJECT_PROGRUN ) strcpy(text, "Execute the selected program"); + if ( num == EVENT_OBJECT_PROGEDIT ) strcpy(text, "Edit the selected program"); + if ( num == EVENT_OBJECT_INFOOK ) strcpy(text, "\\SatCom on standby"); + if ( num == EVENT_OBJECT_DELETE ) strcpy(text, "Destroy the building"); + if ( num == EVENT_OBJECT_GENERGY ) strcpy(text, "Energy level"); + if ( num == EVENT_OBJECT_GSHIELD ) strcpy(text, "Shield level"); + if ( num == EVENT_OBJECT_GRANGE ) strcpy(text, "Jet temperature"); + if ( num == EVENT_OBJECT_GPROGRESS ) strcpy(text, "Still working ..."); + if ( num == EVENT_OBJECT_GRADAR ) strcpy(text, "Number of insects detected"); + if ( num == EVENT_OBJECT_GINFO ) strcpy(text, "Transmitted information"); + if ( num == EVENT_OBJECT_COMPASS ) strcpy(text, "Compass"); +//? if ( num == EVENT_OBJECT_MAP ) strcpy(text, "Mini-map"); + if ( num == EVENT_OBJECT_MAPZOOM ) strcpy(text, "Zoom mini-map"); + if ( num == EVENT_OBJECT_CAMERA ) strcpy(text, "Camera (\\key camera;)"); + if ( num == EVENT_OBJECT_CAMERAleft) strcpy(text, "Camera to left"); + if ( num == EVENT_OBJECT_CAMERAright) strcpy(text, "Camera to right"); + if ( num == EVENT_OBJECT_CAMERAnear) strcpy(text, "Camera nearest"); + if ( num == EVENT_OBJECT_CAMERAaway) strcpy(text, "Camera awayest"); + if ( num == EVENT_OBJECT_HELP ) strcpy(text, "Help about selected object"); + if ( num == EVENT_OBJECT_SOLUCE ) strcpy(text, "Show the solution"); + if ( num == EVENT_OBJECT_SHORTCUT00) strcpy(text, "Switch bots <-> buildings"); + if ( num == EVENT_OBJECT_LIMIT ) strcpy(text, "Show the range"); + if ( num == EVENT_OBJECT_PEN0 ) strcpy(text, "\\Raise the pencil"); + if ( num == EVENT_OBJECT_PEN1 ) strcpy(text, "\\Use the black pencil"); + if ( num == EVENT_OBJECT_PEN2 ) strcpy(text, "\\Use the yellow pencil"); + if ( num == EVENT_OBJECT_PEN3 ) strcpy(text, "\\Use the orange pencil"); + if ( num == EVENT_OBJECT_PEN4 ) strcpy(text, "\\Use the red pencil"); + if ( num == EVENT_OBJECT_PEN5 ) strcpy(text, "\\Use the purple pencil"); + if ( num == EVENT_OBJECT_PEN6 ) strcpy(text, "\\Use the blue pencil"); + if ( num == EVENT_OBJECT_PEN7 ) strcpy(text, "\\Use the green pencil"); + if ( num == EVENT_OBJECT_PEN8 ) strcpy(text, "\\Use the brown pencil"); + if ( num == EVENT_OBJECT_REC ) strcpy(text, "\\Start recording"); + if ( num == EVENT_OBJECT_STOP ) strcpy(text, "\\Stop recording"); + if ( num == EVENT_DT_VISIT0 || + num == EVENT_DT_VISIT1 || + num == EVENT_DT_VISIT2 || + num == EVENT_DT_VISIT3 || + num == EVENT_DT_VISIT4 ) strcpy(text, "Show the place"); + if ( num == EVENT_DT_END ) strcpy(text, "Continue"); + if ( num == EVENT_CMD ) strcpy(text, "Command line"); + if ( num == EVENT_SPEED ) strcpy(text, "Game speed"); + + if ( num == EVENT_HYPER_PREV ) strcpy(text, "Back"); + if ( num == EVENT_HYPER_NEXT ) strcpy(text, "Forward"); + if ( num == EVENT_HYPER_HOME ) strcpy(text, "Home"); + if ( num == EVENT_HYPER_COPY ) strcpy(text, "Copy"); + if ( num == EVENT_HYPER_SIZE1 ) strcpy(text, "Size 1"); + if ( num == EVENT_HYPER_SIZE2 ) strcpy(text, "Size 2"); + if ( num == EVENT_HYPER_SIZE3 ) strcpy(text, "Size 3"); + if ( num == EVENT_HYPER_SIZE4 ) strcpy(text, "Size 4"); + if ( num == EVENT_HYPER_SIZE5 ) strcpy(text, "Size 5"); + if ( num == EVENT_SATCOM_HUSTON ) strcpy(text, "Instructions from Houston"); +#if _TEEN + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Dictionnary"); +#else + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Satellite report"); +#endif + if ( num == EVENT_SATCOM_LOADING ) strcpy(text, "Programs dispatched by Houston"); + if ( num == EVENT_SATCOM_OBJECT ) strcpy(text, "List of objects"); + if ( num == EVENT_SATCOM_PROG ) strcpy(text, "Programming help"); + if ( num == EVENT_SATCOM_SOLUCE ) strcpy(text, "Solution"); + + if ( num == EVENT_STUDIO_OK ) strcpy(text, "OK\\Close program editor and return to game"); + if ( num == EVENT_STUDIO_CANCEL ) strcpy(text, "Cancel\\Cancel all changes"); + if ( num == EVENT_STUDIO_NEW ) strcpy(text, "New"); + if ( num == EVENT_STUDIO_OPEN ) strcpy(text, "Open (Ctrl+o)"); + if ( num == EVENT_STUDIO_SAVE ) strcpy(text, "Save (Ctrl+s)"); + if ( num == EVENT_STUDIO_UNDO ) strcpy(text, "Undo (Ctrl+z)"); + if ( num == EVENT_STUDIO_CUT ) strcpy(text, "Cut (Ctrl+x)"); + if ( num == EVENT_STUDIO_COPY ) strcpy(text, "Copy (Ctrl+c)"); + if ( num == EVENT_STUDIO_PASTE ) strcpy(text, "Paste (Ctrl+v)"); + if ( num == EVENT_STUDIO_SIZE ) strcpy(text, "Font size"); + if ( num == EVENT_STUDIO_TOOL ) strcpy(text, "Instructions (\\key help;)"); + if ( num == EVENT_STUDIO_HELP ) strcpy(text, "Programming help (\\key prog;)"); + if ( num == EVENT_STUDIO_COMPILE ) strcpy(text, "Compile"); + if ( num == EVENT_STUDIO_RUN ) strcpy(text, "Execute/stop"); + if ( num == EVENT_STUDIO_REALTIME ) strcpy(text, "Pause/continue"); + if ( num == EVENT_STUDIO_STEP ) strcpy(text, "One step"); + } + + if ( type == RES_OBJECT ) + { + if ( num == OBJECT_PORTICO ) strcpy(text, "Gantry crane"); + if ( num == OBJECT_BASE ) strcpy(text, "Spaceship"); + if ( num == OBJECT_DERRICK ) strcpy(text, "Derrick"); + if ( num == OBJECT_FACTORY ) strcpy(text, "Bot factory"); + if ( num == OBJECT_REPAIR ) strcpy(text, "Repair center"); + if ( num == OBJECT_DESTROYER ) strcpy(text, "Destroyer"); + if ( num == OBJECT_STATION ) strcpy(text, "Power station"); + if ( num == OBJECT_CONVERT ) strcpy(text, "Converts ore to titanium"); + if ( num == OBJECT_TOWER ) strcpy(text, "Defense tower"); + if ( num == OBJECT_NEST ) strcpy(text, "Nest"); + if ( num == OBJECT_RESEARCH ) strcpy(text, "Research center"); + if ( num == OBJECT_RADAR ) strcpy(text, "Radar station"); + if ( num == OBJECT_INFO ) strcpy(text, "Information exchange post"); +#if _TEEN + if ( num == OBJECT_ENERGY ) strcpy(text, "Power cell factory"); +#else + if ( num == OBJECT_ENERGY ) strcpy(text, "Power cell factory"); +#endif + if ( num == OBJECT_LABO ) strcpy(text, "Autolab"); + if ( num == OBJECT_NUCLEAR ) strcpy(text, "Nuclear power station"); + if ( num == OBJECT_PARA ) strcpy(text, "Lightning conductor"); + if ( num == OBJECT_SAFE ) strcpy(text, "Vault"); + if ( num == OBJECT_HUSTON ) strcpy(text, "Houston Mission Control"); + if ( num == OBJECT_TARGET1 ) strcpy(text, "Target"); + if ( num == OBJECT_TARGET2 ) strcpy(text, "Target"); + if ( num == OBJECT_START ) strcpy(text, "Start"); + if ( num == OBJECT_END ) strcpy(text, "Finish"); + if ( num == OBJECT_STONE ) strcpy(text, "Titanium ore"); + if ( num == OBJECT_URANIUM ) strcpy(text, "Uranium ore"); + if ( num == OBJECT_BULLET ) strcpy(text, "Organic matter"); + if ( num == OBJECT_METAL ) strcpy(text, "Titanium"); + if ( num == OBJECT_POWER ) strcpy(text, "Power cell"); + if ( num == OBJECT_ATOMIC ) strcpy(text, "Nuclear power cell"); + if ( num == OBJECT_BBOX ) strcpy(text, "Black box"); + if ( num == OBJECT_KEYa ) strcpy(text, "Key A"); + if ( num == OBJECT_KEYb ) strcpy(text, "Key B"); + if ( num == OBJECT_KEYc ) strcpy(text, "Key C"); + if ( num == OBJECT_KEYd ) strcpy(text, "Key D"); + if ( num == OBJECT_TNT ) strcpy(text, "Explosive"); + if ( num == OBJECT_BOMB ) strcpy(text, "Fixed mine"); + if ( num == OBJECT_BAG ) strcpy(text, "Survival kit"); + if ( num == OBJECT_WAYPOINT ) strcpy(text, "Checkpoint"); + if ( num == OBJECT_FLAGb ) strcpy(text, "Blue flag"); + if ( num == OBJECT_FLAGr ) strcpy(text, "Red flag"); + if ( num == OBJECT_FLAGg ) strcpy(text, "Green flag"); + if ( num == OBJECT_FLAGy ) strcpy(text, "Yellow flag"); + if ( num == OBJECT_FLAGv ) strcpy(text, "Violet flag"); + if ( num == OBJECT_MARKPOWER ) strcpy(text, "Energy deposit (site for power station)"); + if ( num == OBJECT_MARKURANIUM ) strcpy(text, "Uranium deposit (site for derrick)"); + if ( num == OBJECT_MARKKEYa ) strcpy(text, "Found key A (site for derrick)"); + if ( num == OBJECT_MARKKEYb ) strcpy(text, "Found key B (site for derrick)"); + if ( num == OBJECT_MARKKEYc ) strcpy(text, "Found key C (site for derrick)"); + if ( num == OBJECT_MARKKEYd ) strcpy(text, "Found key D (site for derrick)"); + if ( num == OBJECT_MARKSTONE ) strcpy(text, "Titanium deposit (site for derrick)"); + if ( num == OBJECT_MOBILEft ) strcpy(text, "Practice bot"); + if ( num == OBJECT_MOBILEtt ) strcpy(text, "Practice bot"); + if ( num == OBJECT_MOBILEwt ) strcpy(text, "Practice bot"); + if ( num == OBJECT_MOBILEit ) strcpy(text, "Practice bot"); + if ( num == OBJECT_MOBILEfa ) strcpy(text, "Winged grabber"); + if ( num == OBJECT_MOBILEta ) strcpy(text, "Tracked grabber"); + if ( num == OBJECT_MOBILEwa ) strcpy(text, "Wheeled grabber"); + if ( num == OBJECT_MOBILEia ) strcpy(text, "Legged grabber"); + if ( num == OBJECT_MOBILEfc ) strcpy(text, "Winged shooter"); + if ( num == OBJECT_MOBILEtc ) strcpy(text, "Tracked shooter"); + if ( num == OBJECT_MOBILEwc ) strcpy(text, "Wheeled shooter"); + if ( num == OBJECT_MOBILEic ) strcpy(text, "Legged shooter"); + if ( num == OBJECT_MOBILEfi ) strcpy(text, "Winged orga shooter"); + if ( num == OBJECT_MOBILEti ) strcpy(text, "Tracked orga shooter"); + if ( num == OBJECT_MOBILEwi ) strcpy(text, "Wheeled orga shooter"); + if ( num == OBJECT_MOBILEii ) strcpy(text, "Legged orga shooter"); + if ( num == OBJECT_MOBILEfs ) strcpy(text, "Winged sniffer"); + if ( num == OBJECT_MOBILEts ) strcpy(text, "Tracked sniffer"); + if ( num == OBJECT_MOBILEws ) strcpy(text, "Wheeled sniffer"); + if ( num == OBJECT_MOBILEis ) strcpy(text, "Legged sniffer"); + if ( num == OBJECT_MOBILErt ) strcpy(text, "Thumper"); + if ( num == OBJECT_MOBILErc ) strcpy(text, "Phazer shooter"); + if ( num == OBJECT_MOBILErr ) strcpy(text, "Recycler"); + if ( num == OBJECT_MOBILErs ) strcpy(text, "Shielder"); + if ( num == OBJECT_MOBILEsa ) strcpy(text, "Subber"); + if ( num == OBJECT_MOBILEtg ) strcpy(text, "Target bot"); + if ( num == OBJECT_MOBILEdr ) strcpy(text, "Drawer bot"); + if ( num == OBJECT_HUMAN ) strcpy(text, g_gamerName); + if ( num == OBJECT_TECH ) strcpy(text, "Engineer"); + if ( num == OBJECT_TOTO ) strcpy(text, "Robbie"); + if ( num == OBJECT_MOTHER ) strcpy(text, "Alien Queen"); + if ( num == OBJECT_ANT ) strcpy(text, "Ant"); + if ( num == OBJECT_SPIDER ) strcpy(text, "Spider"); + if ( num == OBJECT_BEE ) strcpy(text, "Wasp"); + if ( num == OBJECT_WORM ) strcpy(text, "Worm"); + if ( num == OBJECT_EGG ) strcpy(text, "Egg"); + if ( num == OBJECT_RUINmobilew1 ) strcpy(text, "Wreckage"); + if ( num == OBJECT_RUINmobilew2 ) strcpy(text, "Wreckage"); + if ( num == OBJECT_RUINmobilet1 ) strcpy(text, "Wreckage"); + if ( num == OBJECT_RUINmobilet2 ) strcpy(text, "Wreckage"); + if ( num == OBJECT_RUINmobiler1 ) strcpy(text, "Wreckage"); + if ( num == OBJECT_RUINmobiler2 ) strcpy(text, "Wreckage"); + if ( num == OBJECT_RUINfactory ) strcpy(text, "Ruin"); + if ( num == OBJECT_RUINdoor ) strcpy(text, "Ruin"); + if ( num == OBJECT_RUINsupport ) strcpy(text, "Waste"); + if ( num == OBJECT_RUINradar ) strcpy(text, "Ruin"); + if ( num == OBJECT_RUINconvert ) strcpy(text, "Ruin"); + if ( num == OBJECT_RUINbase ) strcpy(text, "Spaceship ruin"); + if ( num == OBJECT_RUINhead ) strcpy(text, "Spaceship ruin"); + if ( num == OBJECT_APOLLO1 || + num == OBJECT_APOLLO3 || + num == OBJECT_APOLLO4 || + num == OBJECT_APOLLO5 ) strcpy(text, "Remains of Apollo mission"); + if ( num == OBJECT_APOLLO2 ) strcpy(text, "Lunar Roving Vehicle"); + } + + if ( type == RES_ERR ) + { + strcpy(text, "Error"); + if ( num == ERR_CMD ) strcpy(text, "Unknown command"); +#if _NEWLOOK + if ( num == ERR_INSTALL ) strcpy(text, "CeeBot not installed."); + if ( num == ERR_NOCD ) strcpy(text, "Please insert the CeeBot CD\nand re-run the game."); +#else + if ( num == ERR_INSTALL ) strcpy(text, "COLOBOT not installed."); + if ( num == ERR_NOCD ) strcpy(text, "Please insert the COLOBOT CD\nand re-run the game."); +#endif + if ( num == ERR_MANIP_VEH ) strcpy(text, "Inappropriate bot"); + if ( num == ERR_MANIP_FLY ) strcpy(text, "Impossible when flying"); + if ( num == ERR_MANIP_BUSY ) strcpy(text, "Already carrying something"); + if ( num == ERR_MANIP_NIL ) strcpy(text, "Nothing to grab"); + if ( num == ERR_MANIP_MOTOR ) strcpy(text, "Impossible when moving"); + if ( num == ERR_MANIP_OCC ) strcpy(text, "Place occupied"); + if ( num == ERR_MANIP_FRIEND ) strcpy(text, "No other robot"); + if ( num == ERR_MANIP_RADIO ) strcpy(text, "You can not carry a radioactive object"); + if ( num == ERR_MANIP_WATER ) strcpy(text, "You can not carry an object under water"); + if ( num == ERR_MANIP_EMPTY ) strcpy(text, "Nothing to drop"); + if ( num == ERR_BUILD_FLY ) strcpy(text, "Impossible when flying"); + if ( num == ERR_BUILD_WATER ) strcpy(text, "Impossible under water"); + if ( num == ERR_BUILD_ENERGY ) strcpy(text, "Not enough energy"); + if ( num == ERR_BUILD_METALAWAY ) strcpy(text, "Titanium too far away"); + if ( num == ERR_BUILD_METALNEAR ) strcpy(text, "Titanium too close"); + if ( num == ERR_BUILD_METALINEX ) strcpy(text, "No titanium around"); + if ( num == ERR_BUILD_FLAT ) strcpy(text, "Ground not flat enough"); + if ( num == ERR_BUILD_FLATLIT ) strcpy(text, "Flat ground not large enough"); + if ( num == ERR_BUILD_BUSY ) strcpy(text, "Place occupied"); + if ( num == ERR_BUILD_BASE ) strcpy(text, "Too close to space ship"); + if ( num == ERR_BUILD_NARROW ) strcpy(text, "Too close to a building"); + if ( num == ERR_BUILD_MOTOR ) strcpy(text, "Impossible when moving"); + if ( num == ERR_SEARCH_FLY ) strcpy(text, "Impossible when flying"); + if ( num == ERR_SEARCH_VEH ) strcpy(text, "Inappropriate bot"); + if ( num == ERR_SEARCH_MOTOR ) strcpy(text, "Impossible when moving"); + if ( num == ERR_TERRA_VEH ) strcpy(text, "Inappropriate bot"); + if ( num == ERR_TERRA_ENERGY ) strcpy(text, "Not enough energy"); + if ( num == ERR_TERRA_FLOOR ) strcpy(text, "Ground inappropriate"); + if ( num == ERR_TERRA_BUILDING ) strcpy(text, "Building too close"); + if ( num == ERR_TERRA_OBJECT ) strcpy(text, "Object too close"); + if ( num == ERR_RECOVER_VEH ) strcpy(text, "Inappropriate bot"); + if ( num == ERR_RECOVER_ENERGY ) strcpy(text, "Not enough energy"); + if ( num == ERR_RECOVER_NULL ) strcpy(text, "Nothing to recycle"); + if ( num == ERR_SHIELD_VEH ) strcpy(text, "Inappropriate bot"); + if ( num == ERR_SHIELD_ENERGY ) strcpy(text, "No more energy"); + if ( num == ERR_MOVE_IMPOSSIBLE ) strcpy(text, "Error in instruction move"); + if ( num == ERR_FIND_IMPOSSIBLE ) strcpy(text, "Object not found"); + if ( num == ERR_GOTO_IMPOSSIBLE ) strcpy(text, "Goto: inaccessible destination"); + if ( num == ERR_GOTO_ITER ) strcpy(text, "Goto: inaccessible destination"); + if ( num == ERR_GOTO_BUSY ) strcpy(text, "Goto: destination occupied"); + if ( num == ERR_FIRE_VEH ) strcpy(text, "Inappropriate bot"); + if ( num == ERR_FIRE_ENERGY ) strcpy(text, "Not enough energy"); + if ( num == ERR_FIRE_FLY ) strcpy(text, "Impossible when flying"); + if ( num == ERR_CONVERT_EMPTY ) strcpy(text, "No titanium ore to convert"); + if ( num == ERR_DERRICK_NULL ) strcpy(text, "No ore in the subsoil"); + if ( num == ERR_STATION_NULL ) strcpy(text, "No energy in the subsoil"); + if ( num == ERR_TOWER_POWER ) strcpy(text, "No power cell"); + if ( num == ERR_TOWER_ENERGY ) strcpy(text, "No more energy"); + if ( num == ERR_RESEARCH_POWER ) strcpy(text, "No power cell"); + if ( num == ERR_RESEARCH_ENERGY ) strcpy(text, "Not enough energy"); + if ( num == ERR_RESEARCH_TYPE ) strcpy(text, "Inappropriate cell type"); + if ( num == ERR_RESEARCH_ALREADY) strcpy(text, "Research program already performed"); + if ( num == ERR_ENERGY_NULL ) strcpy(text, "No energy in the subsoil"); + if ( num == ERR_ENERGY_LOW ) strcpy(text, "Not enough energy yet"); + if ( num == ERR_ENERGY_EMPTY ) strcpy(text, "No titanium to transform"); + if ( num == ERR_ENERGY_BAD ) strcpy(text, "Transforms only titanium"); + if ( num == ERR_BASE_DLOCK ) strcpy(text, "Doors blocked by a robot or another object "); + if ( num == ERR_BASE_DHUMAN ) strcpy(text, "You must get on the spaceship to take off "); + if ( num == ERR_LABO_NULL ) strcpy(text, "Nothing to analyze"); + if ( num == ERR_LABO_BAD ) strcpy(text, "Analyzes only organic matter"); + if ( num == ERR_LABO_ALREADY ) strcpy(text, "Analysis already performed"); + if ( num == ERR_NUCLEAR_NULL ) strcpy(text, "No energy in the subsoil"); + if ( num == ERR_NUCLEAR_LOW ) strcpy(text, "Not yet enough energy"); + if ( num == ERR_NUCLEAR_EMPTY ) strcpy(text, "No uranium to transform"); + if ( num == ERR_NUCLEAR_BAD ) strcpy(text, "Transforms only uranium"); + if ( num == ERR_FACTORY_NULL ) strcpy(text, "No titanium"); + if ( num == ERR_FACTORY_NEAR ) strcpy(text, "Object too close"); + if ( num == ERR_RESET_NEAR ) strcpy(text, "Place occupied"); + if ( num == ERR_INFO_NULL ) strcpy(text, "No information exchange post within range"); + if ( num == ERR_VEH_VIRUS ) strcpy(text, "Program infected by a virus"); + if ( num == ERR_BAT_VIRUS ) strcpy(text, "Infected by a virus, temporarily out of order"); + if ( num == ERR_VEH_POWER ) strcpy(text, "No power cell"); + if ( num == ERR_VEH_ENERGY ) strcpy(text, "No more energy"); + if ( num == ERR_FLAG_FLY ) strcpy(text, "Impossible when flying"); + if ( num == ERR_FLAG_WATER ) strcpy(text, "Impossible when swimming"); + if ( num == ERR_FLAG_MOTOR ) strcpy(text, "Impossible when moving"); + if ( num == ERR_FLAG_BUSY ) strcpy(text, "Impossible when carrying an object"); + if ( num == ERR_FLAG_CREATE ) strcpy(text, "Too many flags of this color (maximum 5)"); + if ( num == ERR_FLAG_PROXY ) strcpy(text, "Too close to an existing flag"); + if ( num == ERR_FLAG_DELETE ) strcpy(text, "No flag nearby"); + if ( num == ERR_MISSION_NOTERM ) strcpy(text, "The mission is not accomplished yet (press \\key help; for more details)"); + if ( num == ERR_DELETEMOBILE ) strcpy(text, "Bot destroyed"); + if ( num == ERR_DELETEBUILDING ) strcpy(text, "Building destroyed"); + if ( num == ERR_TOOMANY ) strcpy(text, "Can not create this, there are too many objects"); + if ( num == ERR_OBLIGATORYTOKEN ) strcpy(text, "\"%s\" missing in this exercise"); //** + if ( num == ERR_PROHIBITEDTOKEN ) strcpy(text, "Do not use in this exercise"); //** + + if ( num == INFO_BUILD ) strcpy(text, "Building completed"); + if ( num == INFO_CONVERT ) strcpy(text, "Titanium available"); + if ( num == INFO_RESEARCH ) strcpy(text, "Research program completed"); + if ( num == INFO_RESEARCHTANK ) strcpy(text, "Plans for tracked robots available "); + if ( num == INFO_RESEARCHFLY ) strcpy(text, "You can fly with the keys (\\key gup;) and (\\key gdown;)"); + if ( num == INFO_RESEARCHTHUMP ) strcpy(text, "Plans for thumper available"); + if ( num == INFO_RESEARCHCANON ) strcpy(text, "Plans for shooter available"); + if ( num == INFO_RESEARCHTOWER ) strcpy(text, "Plans for defense tower available"); + if ( num == INFO_RESEARCHPHAZER ) strcpy(text, "Plans for phazer shooter available"); + if ( num == INFO_RESEARCHSHIELD ) strcpy(text, "Plans for shielder available"); + if ( num == INFO_RESEARCHATOMIC ) strcpy(text, "Plans for nuclear power plant available"); + if ( num == INFO_FACTORY ) strcpy(text, "New bot available"); + if ( num == INFO_LABO ) strcpy(text, "Analysis performed"); + if ( num == INFO_ENERGY ) strcpy(text, "Power cell available"); + if ( num == INFO_NUCLEAR ) strcpy(text, "Nuclear power cell available"); + if ( num == INFO_FINDING ) strcpy(text, "You found a usable object"); + if ( num == INFO_MARKPOWER ) strcpy(text, "Found a site for power station"); + if ( num == INFO_MARKURANIUM ) strcpy(text, "Found a site for a derrick"); + if ( num == INFO_MARKSTONE ) strcpy(text, "Found a site for a derrick"); + if ( num == INFO_MARKKEYa ) strcpy(text, "Found a site for a derrick"); + if ( num == INFO_MARKKEYb ) strcpy(text, "Found a site for a derrick"); + if ( num == INFO_MARKKEYc ) strcpy(text, "Found a site for a derrick"); + if ( num == INFO_MARKKEYd ) strcpy(text, "Found a site for a derrick"); + if ( num == INFO_WIN ) strcpy(text, "<<< Well done, mission accomplished >>>"); + if ( num == INFO_LOST ) strcpy(text, "<<< Sorry, mission failed >>>"); + if ( num == INFO_LOSTq ) strcpy(text, "<<< Sorry, mission failed >>>"); + if ( num == INFO_WRITEOK ) strcpy(text, "Current mission saved"); + if ( num == INFO_DELETEPATH ) strcpy(text, "Checkpoint crossed"); + if ( num == INFO_DELETEMOTHER ) strcpy(text, "Alien Queen killed"); + if ( num == INFO_DELETEANT ) strcpy(text, "Ant fatally wounded"); + if ( num == INFO_DELETEBEE ) strcpy(text, "Wasp fatally wounded"); + if ( num == INFO_DELETEWORM ) strcpy(text, "Worm fatally wounded"); + if ( num == INFO_DELETESPIDER ) strcpy(text, "Spider fatally wounded"); + if ( num == INFO_BEGINSATCOM ) strcpy(text, "Press \\key help; to read instructions on your SatCom"); + } + + if ( type == RES_CBOT ) + { + strcpy(text, "Error"); + if ( num == TX_OPENPAR ) strcpy(text, "Opening bracket missing"); + if ( num == TX_CLOSEPAR ) strcpy(text, "Closing bracket missing "); + if ( num == TX_NOTBOOL ) strcpy(text, "The expression must return a boolean value"); + if ( num == TX_UNDEFVAR ) strcpy(text, "Variable not declared"); + if ( num == TX_BADLEFT ) strcpy(text, "Assignment impossible"); + if ( num == TX_ENDOF ) strcpy(text, "Semicolon terminator missing"); + if ( num == TX_OUTCASE ) strcpy(text, "Instruction ""case"" outside a block ""switch"""); + if ( num == TX_NOTERM ) strcpy(text, "Instructions after the final closing brace"); + if ( num == TX_CLOSEBLK ) strcpy(text, "End of block missing"); + if ( num == TX_ELSEWITHOUTIF ) strcpy(text, "Instruction ""else"" without corresponding ""if"" "); + if ( num == TX_OPENBLK ) strcpy(text, "Opening brace missing ");//début d'un bloc attendu? + if ( num == TX_BADTYPE ) strcpy(text, "Wrong type for the assignment"); + if ( num == TX_REDEFVAR ) strcpy(text, "A variable can not be declared twice"); + if ( num == TX_BAD2TYPE ) strcpy(text, "The types of the two operands are incompatible "); + if ( num == TX_UNDEFCALL ) strcpy(text, "Unknown function"); + if ( num == TX_MISDOTS ) strcpy(text, "Sign "" : "" missing"); + if ( num == TX_WHILE ) strcpy(text, "Keyword ""while"" missing"); + if ( num == TX_BREAK ) strcpy(text, "Instruction ""break"" outside a loop"); + if ( num == TX_LABEL ) strcpy(text, "A label must be followed by ""for"", ""while"", ""do"" or ""switch"""); + if ( num == TX_NOLABEL ) strcpy(text, "This label does not exist");// Cette étiquette n'existe pas + if ( num == TX_NOCASE ) strcpy(text, "Instruction ""case"" missing"); + if ( num == TX_BADNUM ) strcpy(text, "Number missing"); + if ( num == TX_VOID ) strcpy(text, "Void parameter"); + if ( num == TX_NOTYP ) strcpy(text, "Type declaration missing"); + if ( num == TX_NOVAR ) strcpy(text, "Variable name missing"); + if ( num == TX_NOFONC ) strcpy(text, "Function name missing"); + if ( num == TX_OVERPARAM ) strcpy(text, "Too many parameters"); + if ( num == TX_REDEF ) strcpy(text, "Function already exists"); + if ( num == TX_LOWPARAM ) strcpy(text, "Parameters missing "); + if ( num == TX_BADPARAM ) strcpy(text, "No function with this name accepts this kind of parameter"); + if ( num == TX_NUMPARAM ) strcpy(text, "No function with this name accepts this number of parameters"); + if ( num == TX_NOITEM ) strcpy(text, "This is not a member of this class"); + if ( num == TX_DOT ) strcpy(text, "This object is not a member of a class"); + if ( num == TX_NOCONST ) strcpy(text, "Appropriate constructor missing"); + if ( num == TX_REDEFCLASS ) strcpy(text, "This class already exists"); + if ( num == TX_CLBRK ) strcpy(text, """ ] "" missing"); + if ( num == TX_RESERVED ) strcpy(text, "Reserved keyword of CBOT language"); + if ( num == TX_BADNEW ) strcpy(text, "Bad argument for ""new"""); + if ( num == TX_OPBRK ) strcpy(text, """ [ "" expected"); + if ( num == TX_BADSTRING ) strcpy(text, "String missing"); + if ( num == TX_BADINDEX ) strcpy(text, "Incorrect index type"); + if ( num == TX_PRIVATE ) strcpy(text, "Private element"); + if ( num == TX_NOPUBLIC ) strcpy(text, "Public required"); + if ( num == TX_DIVZERO ) strcpy(text, "Dividing by zero"); + if ( num == TX_NOTINIT ) strcpy(text, "Variable not initialized"); + if ( num == TX_BADTHROW ) strcpy(text, "Negative value rejected by ""throw""");//C'est quoi, ça? + if ( num == TX_NORETVAL ) strcpy(text, "The function returned no value "); + if ( num == TX_NORUN ) strcpy(text, "No function running"); + if ( num == TX_NOCALL ) strcpy(text, "Calling an unknown function"); + if ( num == TX_NOCLASS ) strcpy(text, "This class does not exist"); + if ( num == TX_NULLPT ) strcpy(text, "Unknown Object"); + if ( num == TX_OPNAN ) strcpy(text, "Operation impossible with value ""nan"""); + if ( num == TX_OUTARRAY ) strcpy(text, "Access beyond array limit"); + if ( num == TX_STACKOVER ) strcpy(text, "Stack overflow"); + if ( num == TX_DELETEDPT ) strcpy(text, "Illegal object"); + if ( num == TX_FILEOPEN ) strcpy(text, "Can't open file"); + if ( num == TX_NOTOPEN ) strcpy(text, "File not open"); + if ( num == TX_ERRREAD ) strcpy(text, "Read error"); + if ( num == TX_ERRWRITE ) strcpy(text, "Write error"); + } + + if ( type == RES_KEY ) + { + if ( num == 0 ) strcpy(text, "< none >"); + if ( num == VK_LEFT ) strcpy(text, "Arrow left"); + if ( num == VK_RIGHT ) strcpy(text, "Arrow right"); + if ( num == VK_UP ) strcpy(text, "Arrow up"); + if ( num == VK_DOWN ) strcpy(text, "Arrow down"); + if ( num == VK_CANCEL ) strcpy(text, "Control-break"); + if ( num == VK_BACK ) strcpy(text, "<--"); + if ( num == VK_TAB ) strcpy(text, "Tab"); + if ( num == VK_CLEAR ) strcpy(text, "Clear"); + if ( num == VK_RETURN ) strcpy(text, "Enter"); + if ( num == VK_SHIFT ) strcpy(text, "Shift"); + if ( num == VK_CONTROL ) strcpy(text, "Ctrl"); + if ( num == VK_MENU ) strcpy(text, "Alt"); + if ( num == VK_PAUSE ) strcpy(text, "Pause"); + if ( num == VK_CAPITAL ) strcpy(text, "Caps Lock"); + if ( num == VK_ESCAPE ) strcpy(text, "Esc"); + if ( num == VK_SPACE ) strcpy(text, "Space"); + if ( num == VK_PRIOR ) strcpy(text, "Page Up"); + if ( num == VK_NEXT ) strcpy(text, "Page Down"); + if ( num == VK_END ) strcpy(text, "End"); + if ( num == VK_HOME ) strcpy(text, "Home"); + if ( num == VK_SELECT ) strcpy(text, "Select"); + if ( num == VK_EXECUTE ) strcpy(text, "Execute"); + if ( num == VK_SNAPSHOT ) strcpy(text, "Print Scrn"); + if ( num == VK_INSERT ) strcpy(text, "Insert"); + if ( num == VK_DELETE ) strcpy(text, "Delete"); + if ( num == VK_HELP ) strcpy(text, "Help"); + if ( num == VK_LWIN ) strcpy(text, "Left Windows"); + if ( num == VK_RWIN ) strcpy(text, "Right Windows"); + if ( num == VK_APPS ) strcpy(text, "Application key"); + if ( num == VK_NUMPAD0 ) strcpy(text, "NumPad 0"); + if ( num == VK_NUMPAD1 ) strcpy(text, "NumPad 1"); + if ( num == VK_NUMPAD2 ) strcpy(text, "NumPad 2"); + if ( num == VK_NUMPAD3 ) strcpy(text, "NumPad 3"); + if ( num == VK_NUMPAD4 ) strcpy(text, "NumPad 4"); + if ( num == VK_NUMPAD5 ) strcpy(text, "NumPad 5"); + if ( num == VK_NUMPAD6 ) strcpy(text, "NumPad 6"); + if ( num == VK_NUMPAD7 ) strcpy(text, "NumPad 7"); + if ( num == VK_NUMPAD8 ) strcpy(text, "NumPad 8"); + if ( num == VK_NUMPAD9 ) strcpy(text, "NumPad 9"); + if ( num == VK_MULTIPLY ) strcpy(text, "NumPad *"); + if ( num == VK_ADD ) strcpy(text, "NumPad +"); + if ( num == VK_SEPARATOR ) strcpy(text, "NumPad sep"); + if ( num == VK_SUBTRACT ) strcpy(text, "NumPad -"); + if ( num == VK_DECIMAL ) strcpy(text, "NumPad ."); + if ( num == VK_DIVIDE ) strcpy(text, "NumPad /"); + if ( num == VK_F1 ) strcpy(text, "F1"); + if ( num == VK_F2 ) strcpy(text, "F2"); + if ( num == VK_F3 ) strcpy(text, "F3"); + if ( num == VK_F4 ) strcpy(text, "F4"); + if ( num == VK_F5 ) strcpy(text, "F5"); + if ( num == VK_F6 ) strcpy(text, "F6"); + if ( num == VK_F7 ) strcpy(text, "F7"); + if ( num == VK_F8 ) strcpy(text, "F8"); + if ( num == VK_F9 ) strcpy(text, "F9"); + if ( num == VK_F10 ) strcpy(text, "F10"); + if ( num == VK_F11 ) strcpy(text, "F11"); + if ( num == VK_F12 ) strcpy(text, "F12"); + if ( num == VK_F13 ) strcpy(text, "F13"); + if ( num == VK_F14 ) strcpy(text, "F14"); + if ( num == VK_F15 ) strcpy(text, "F15"); + if ( num == VK_F16 ) strcpy(text, "F16"); + if ( num == VK_F17 ) strcpy(text, "F17"); + if ( num == VK_F18 ) strcpy(text, "F18"); + if ( num == VK_F19 ) strcpy(text, "F19"); + if ( num == VK_F20 ) strcpy(text, "F20"); + if ( num == VK_NUMLOCK ) strcpy(text, "Num Lock"); + if ( num == VK_SCROLL ) strcpy(text, "Scroll"); + if ( num == VK_ATTN ) strcpy(text, "Attn"); + if ( num == VK_CRSEL ) strcpy(text, "CrSel"); + if ( num == VK_EXSEL ) strcpy(text, "ExSel"); + if ( num == VK_EREOF ) strcpy(text, "Erase EOF"); + if ( num == VK_PLAY ) strcpy(text, "Play"); + if ( num == VK_ZOOM ) strcpy(text, "Zoom"); + if ( num == VK_PA1 ) strcpy(text, "PA1"); + if ( num == VK_OEM_CLEAR ) strcpy(text, "Clear"); + if ( num == VK_BUTTON1 ) strcpy(text, "Button 1"); + if ( num == VK_BUTTON2 ) strcpy(text, "Button 2"); + if ( num == VK_BUTTON3 ) strcpy(text, "Button 3"); + if ( num == VK_BUTTON4 ) strcpy(text, "Button 4"); + if ( num == VK_BUTTON5 ) strcpy(text, "Button 5"); + if ( num == VK_BUTTON6 ) strcpy(text, "Button 6"); + if ( num == VK_BUTTON7 ) strcpy(text, "Button 7"); + if ( num == VK_BUTTON8 ) strcpy(text, "Button 8"); + if ( num == VK_BUTTON9 ) strcpy(text, "Button 9"); + if ( num == VK_BUTTON10 ) strcpy(text, "Button 10"); + if ( num == VK_BUTTON11 ) strcpy(text, "Button 11"); + if ( num == VK_BUTTON12 ) strcpy(text, "Button 12"); + if ( num == VK_BUTTON13 ) strcpy(text, "Button 13"); + if ( num == VK_BUTTON14 ) strcpy(text, "Button 14"); + if ( num == VK_BUTTON15 ) strcpy(text, "Button 15"); + if ( num == VK_BUTTON16 ) strcpy(text, "Button 16"); + if ( num == VK_BUTTON17 ) strcpy(text, "Button 17"); + if ( num == VK_BUTTON18 ) strcpy(text, "Button 18"); + if ( num == VK_BUTTON19 ) strcpy(text, "Button 19"); + if ( num == VK_BUTTON20 ) strcpy(text, "Button 20"); + if ( num == VK_BUTTON21 ) strcpy(text, "Button 21"); + if ( num == VK_BUTTON22 ) strcpy(text, "Button 22"); + if ( num == VK_BUTTON23 ) strcpy(text, "Button 23"); + if ( num == VK_BUTTON24 ) strcpy(text, "Button 24"); + if ( num == VK_BUTTON25 ) strcpy(text, "Button 25"); + if ( num == VK_BUTTON26 ) strcpy(text, "Button 26"); + if ( num == VK_BUTTON27 ) strcpy(text, "Button 27"); + if ( num == VK_BUTTON28 ) strcpy(text, "Button 28"); + if ( num == VK_BUTTON29 ) strcpy(text, "Button 29"); + if ( num == VK_BUTTON30 ) strcpy(text, "Button 30"); + if ( num == VK_BUTTON31 ) strcpy(text, "Button 31"); + if ( num == VK_BUTTON32 ) strcpy(text, "Button 32"); + if ( num == VK_WHEELUP ) strcpy(text, "Wheel up"); + if ( num == VK_WHEELDOWN ) strcpy(text, "Wheel down"); + } +#endif + +#if _FRENCH + if ( type == RES_TEXT ) + { + #if _FULL + if ( num == RT_VERSION_ID ) strcpy(text, "1.18 /f"); + #endif + #if _NET + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A 1.18"); + #endif + #if _SCHOOL & _EDU + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen EDU 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A EDU 1.18"); + #endif + #endif + #if _SCHOOL & _PERSO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen PERSO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A PERSO 1.18"); + #endif + #endif + #if _SCHOOL & _CEEBOTDEMO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen DEMO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A DEMO 1.18"); + #endif + #endif + #if _DEMO + if ( num == RT_VERSION_ID ) strcpy(text, "Demo 1.18 /f"); + #endif + if ( num == RT_DISINFO_TITLE ) strcpy(text, "SatCom"); + if ( num == RT_WINDOW_MAXIMIZED ) strcpy(text, "Taille maximale"); + if ( num == RT_WINDOW_MINIMIZED ) strcpy(text, "Taille réduite"); + if ( num == RT_WINDOW_STANDARD ) strcpy(text, "Taille normale"); + if ( num == RT_WINDOW_CLOSE ) strcpy(text, "Fermer"); + + if ( num == RT_STUDIO_TITLE ) strcpy(text, "Edition du programme"); + if ( num == RT_SCRIPT_NEW ) strcpy(text, "Nouveau"); + if ( num == RT_NAME_DEFAULT ) strcpy(text, "Joueur"); + if ( num == RT_IO_NEW ) strcpy(text, "Nouveau ..."); + if ( num == RT_KEY_OR ) strcpy(text, " ou "); + +#if _NEWLOOK + if ( num == RT_TITLE_BASE ) strcpy(text, "CeeBot"); + if ( num == RT_TITLE_INIT ) strcpy(text, "CeeBot"); +#else + if ( num == RT_TITLE_BASE ) strcpy(text, "COLOBOT"); + if ( num == RT_TITLE_INIT ) strcpy(text, "COLOBOT"); +#endif + if ( num == RT_TITLE_TRAINER ) strcpy(text, "Programmation"); + if ( num == RT_TITLE_DEFI ) strcpy(text, "Défis"); + if ( num == RT_TITLE_MISSION ) strcpy(text, "Missions"); + if ( num == RT_TITLE_FREE ) strcpy(text, "Jeu libre"); + if ( num == RT_TITLE_TEEN ) strcpy(text, "Jeu libre"); + if ( num == RT_TITLE_USER ) strcpy(text, "Niveaux supplémentaires"); + if ( num == RT_TITLE_PROTO ) strcpy(text, "Prototypes"); + if ( num == RT_TITLE_SETUP ) strcpy(text, "Options"); + if ( num == RT_TITLE_NAME ) strcpy(text, "Nom du joueur"); + if ( num == RT_TITLE_PERSO ) strcpy(text, "Personnalisation de votre apparence"); + if ( num == RT_TITLE_WRITE ) strcpy(text, "Enregistrement de la mission en cours"); + if ( num == RT_TITLE_READ ) strcpy(text, "Chargement d'une mission enregistrée"); + + if ( num == RT_PLAY_CHAPt ) strcpy(text, " Liste des chapitres :"); + if ( num == RT_PLAY_CHAPd ) strcpy(text, " Liste des chapitres :"); + if ( num == RT_PLAY_CHAPm ) strcpy(text, " Liste des planètes :"); + if ( num == RT_PLAY_CHAPf ) strcpy(text, " Liste des planètes :"); + if ( num == RT_PLAY_CHAPu ) strcpy(text, " Niveaux supplémentaires :"); + if ( num == RT_PLAY_CHAPp ) strcpy(text, " Liste des planètes :"); + if ( num == RT_PLAY_CHAPte ) strcpy(text, " Liste des chapitres :"); + if ( num == RT_PLAY_LISTt ) strcpy(text, " Liste des exercices du chapitre :"); + if ( num == RT_PLAY_LISTd ) strcpy(text, " Liste des défis du chapitre :"); + if ( num == RT_PLAY_LISTm ) strcpy(text, " Liste des missions du chapitre :"); + if ( num == RT_PLAY_LISTf ) strcpy(text, " Liste des jeux libres du chapitre :"); + if ( num == RT_PLAY_LISTu ) strcpy(text, " Missions du niveau :"); + if ( num == RT_PLAY_LISTp ) strcpy(text, " Liste des prototypes du chapitre :"); + if ( num == RT_PLAY_LISTk ) strcpy(text, " Liste des jeux libres du chapitre :"); + if ( num == RT_PLAY_RESUME ) strcpy(text, " Résumé :"); + + if ( num == RT_SETUP_DEVICE ) strcpy(text, " Pilotes :"); + if ( num == RT_SETUP_MODE ) strcpy(text, " Résolutions :"); + if ( num == RT_SETUP_KEY1 ) strcpy(text, "1) Cliquez d'abord sur la touche à redéfinir."); + if ( num == RT_SETUP_KEY2 ) strcpy(text, "2) Appuyez ensuite sur la nouvelle touche souhaitée."); + + if ( num == RT_PERSO_FACE ) strcpy(text, "Type de visage :"); + if ( num == RT_PERSO_GLASSES ) strcpy(text, "Lunettes :"); + if ( num == RT_PERSO_HAIR ) strcpy(text, "Couleur des cheveux :"); + if ( num == RT_PERSO_COMBI ) strcpy(text, "Couleur de la combinaison :"); + if ( num == RT_PERSO_BAND ) strcpy(text, "Couleur des bandes :"); + +#if _NEWLOOK + if ( num == RT_DIALOG_TITLE ) strcpy(text, "CeeBot"); + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Voulez-vous quitter CeeBot ?"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Quitter\\Quitter CeeBot"); +#else + if ( num == RT_DIALOG_TITLE ) strcpy(text, "COLOBOT"); + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Voulez-vous quitter COLOBOT ?"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Quitter\\Quitter COLOBOT"); +#endif + if ( num == RT_DIALOG_ABORT ) strcpy(text, "Quitter la mission ?"); + if ( num == RT_DIALOG_YES ) strcpy(text, "Abandonner\\Abandonner la mission en cours"); + if ( num == RT_DIALOG_NO ) strcpy(text, "Continuer\\Continuer la mission en cours"); + if ( num == RT_DIALOG_NOQUIT ) strcpy(text, "Continuer\\Continuer de jouer"); + if ( num == RT_DIALOG_DELOBJ ) strcpy(text, "Voulez-vous vraiment détruire le bâtiment sélectionné ?"); + if ( num == RT_DIALOG_DELGAME ) strcpy(text, "Voulez-vous détruire les sauvegardes de %s ?"); + if ( num == RT_DIALOG_YESDEL ) strcpy(text, "Détruire"); + if ( num == RT_DIALOG_NODEL ) strcpy(text, "Annuler"); + if ( num == RT_DIALOG_LOADING ) strcpy(text, "CHARGEMENT"); + + if ( num == RT_STUDIO_LISTTT ) strcpy(text, "Aide sur le mot-clé (\\key cbot;)"); + if ( num == RT_STUDIO_COMPOK ) strcpy(text, "Compilation ok (0 erreur)"); + if ( num == RT_STUDIO_PROGSTOP ) strcpy(text, "Programme terminé"); + + if ( num == RT_SATCOM_LIST ) strcpy(text, "\\b;Listes des objets\n"); + if ( num == RT_SATCOM_BOT ) strcpy(text, "\\b;Listes des robots\n"); + if ( num == RT_SATCOM_BUILDING ) strcpy(text, "\\b;Listes des bâtiments\n"); + if ( num == RT_SATCOM_FRET ) strcpy(text, "\\b;Listes des objets transportables\n"); + if ( num == RT_SATCOM_ALIEN ) strcpy(text, "\\b;Listes des ennemis\n"); + if ( num == RT_SATCOM_NULL ) strcpy(text, "\\c; (aucun)\\n;\n"); + if ( num == RT_SATCOM_ERROR1 ) strcpy(text, "\\b;Erreur\n"); + if ( num == RT_SATCOM_ERROR2 ) strcpy(text, "Liste non disponible sans \\l;radar\\u object\\radar; !\n"); + + if ( num == RT_IO_OPEN ) strcpy(text, "Ouvrir"); + if ( num == RT_IO_SAVE ) strcpy(text, "Enregistrer"); + if ( num == RT_IO_LIST ) strcpy(text, "Dossier: %s"); + if ( num == RT_IO_NAME ) strcpy(text, "Nom:"); + if ( num == RT_IO_DIR ) strcpy(text, "Dans:"); + if ( num == RT_IO_PRIVATE ) strcpy(text, "Privé\\Dossier privé"); + if ( num == RT_IO_PUBLIC ) strcpy(text, "Public\\Dossier commun à tous les joueurs"); + + if ( num == RT_GENERIC_DEV1 ) strcpy(text, "Développé par :"); + if ( num == RT_GENERIC_DEV2 ) strcpy(text, "www.epsitec.com"); +#if _SCHOOL + if ( num == RT_GENERIC_EDIT1 ) strcpy(text, " "); + if ( num == RT_GENERIC_EDIT2 ) strcpy(text, " "); +#else + //?if ( num == RT_GENERIC_EDIT1 ) strcpy(text, "Version française éditée par :"); + //?if ( num == RT_GENERIC_EDIT2 ) strcpy(text, "www.alsyd.com"); + if ( num == RT_GENERIC_EDIT1 ) strcpy(text, " "); + if ( num == RT_GENERIC_EDIT2 ) strcpy(text, " "); +#endif + + if ( num == RT_INTERFACE_REC ) strcpy(text, "Enregistreur"); + } + + if ( type == RES_EVENT ) + { + if ( num == EVENT_BUTTON_OK ) strcpy(text, "D'accord"); + if ( num == EVENT_BUTTON_CANCEL ) strcpy(text, "Annuler"); + if ( num == EVENT_BUTTON_NEXT ) strcpy(text, "Suivant"); + if ( num == EVENT_BUTTON_PREV ) strcpy(text, "Précédent"); + if ( num == EVENT_BUTTON_QUIT ) strcpy(text, "Menu (\\key quit;)"); + + if ( num == EVENT_DIALOG_OK ) strcpy(text, "D'accord"); + if ( num == EVENT_DIALOG_CANCEL ) strcpy(text, "Annuler"); + + if ( num == EVENT_INTERFACE_TRAINER) strcpy(text, "Programmation\\Exercices de programmation"); + if ( num == EVENT_INTERFACE_DEFI ) strcpy(text, "Défis\\Défis de programmation"); + if ( num == EVENT_INTERFACE_MISSION) strcpy(text, "Missions\\La grande aventure"); + if ( num == EVENT_INTERFACE_FREE ) strcpy(text, "Jeu libre\\Jeu libre sans but précis"); + if ( num == EVENT_INTERFACE_TEEN ) strcpy(text, "Jeu libre\\Jeu libre sans but précis"); + if ( num == EVENT_INTERFACE_USER ) strcpy(text, "Suppl.\\Niveaux supplémentaires"); + if ( num == EVENT_INTERFACE_PROTO ) strcpy(text, "Proto\\Prototypes en cours d'élaboration"); + if ( num == EVENT_INTERFACE_NAME ) strcpy(text, "Autre joueur\\Choix du nom du joueur"); + if ( num == EVENT_INTERFACE_SETUP ) strcpy(text, "Options\\Réglages"); + if ( num == EVENT_INTERFACE_AGAIN ) strcpy(text, "Recommencer\\Recommencer la mission au début"); + if ( num == EVENT_INTERFACE_WRITE ) strcpy(text, "Enregistrer\\Enregistrer la mission en cours"); + if ( num == EVENT_INTERFACE_READ ) strcpy(text, "Charger\\Charger une mission enregistrée"); +#if _NEWLOOK + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Retourner dans CeeBot"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Quitter\\Quitter CeeBot"); +#else + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Retourner dans COLOBOT"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Quitter\\Quitter COLOBOT"); +#endif + if ( num == EVENT_INTERFACE_BACK ) strcpy(text, "<< Retour \\Retour au niveau précédent"); + if ( num == EVENT_INTERFACE_PLAY ) strcpy(text, "Jouer ...\\Démarrer l'action"); + if ( num == EVENT_INTERFACE_SETUPd ) strcpy(text, "Affichage\\Pilote et résolution d'affichage"); + if ( num == EVENT_INTERFACE_SETUPg ) strcpy(text, "Graphique\\Options graphiques"); + if ( num == EVENT_INTERFACE_SETUPp ) strcpy(text, "Jeu\\Options de jouabilité"); + if ( num == EVENT_INTERFACE_SETUPc ) strcpy(text, "Commandes\\Touches du clavier"); + if ( num == EVENT_INTERFACE_SETUPs ) strcpy(text, "Son\\Volumes bruitages & musiques"); + if ( num == EVENT_INTERFACE_DEVICE ) strcpy(text, "Unité"); + if ( num == EVENT_INTERFACE_RESOL ) strcpy(text, "Résolution"); + if ( num == EVENT_INTERFACE_FULL ) strcpy(text, "Plein écran\\Plein écran ou fenêtré"); + if ( num == EVENT_INTERFACE_APPLY ) strcpy(text, "Appliquer les changements\\Active les changements effectués"); + + if ( num == EVENT_INTERFACE_TOTO ) strcpy(text, "Robbie\\Votre assistant"); + if ( num == EVENT_INTERFACE_SHADOW ) strcpy(text, "Ombres\\Ombres projetées au sol"); + if ( num == EVENT_INTERFACE_GROUND ) strcpy(text, "Marques sur le sol\\Marques dessinées sur le sol"); + if ( num == EVENT_INTERFACE_DIRTY ) strcpy(text, "Salissures\\Salissures des robots et bâtiments"); + if ( num == EVENT_INTERFACE_FOG ) strcpy(text, "Brouillard\\Nappes de brouillard"); + if ( num == EVENT_INTERFACE_LENS ) strcpy(text, "Rayons du soleil\\Rayons selon l'orientation"); + if ( num == EVENT_INTERFACE_SKY ) strcpy(text, "Ciel\\Ciel et nuages"); + if ( num == EVENT_INTERFACE_PLANET ) strcpy(text, "Planètes et étoiles\\Motifs mobiles dans le ciel"); + if ( num == EVENT_INTERFACE_LIGHT ) strcpy(text, "Lumières dynamiques\\Eclairages mobiles"); + if ( num == EVENT_INTERFACE_PARTI ) strcpy(text, "Quantité de particules\\Explosions, poussières, reflets, etc."); + if ( num == EVENT_INTERFACE_CLIP ) strcpy(text, "Profondeur de champ\\Distance de vue maximale"); + if ( num == EVENT_INTERFACE_DETAIL ) strcpy(text, "Détails des objets\\Qualité des objets en 3D"); + if ( num == EVENT_INTERFACE_TEXTURE) strcpy(text, "Qualité des textures\\Qualité des images"); + if ( num == EVENT_INTERFACE_GADGET ) strcpy(text, "Nb d'objets décoratifs\\Qualité d'objets non indispensables"); + if ( num == EVENT_INTERFACE_RAIN ) strcpy(text, "Particules dans l'interface\\Pluie de particules"); + if ( num == EVENT_INTERFACE_GLINT ) strcpy(text, "Reflets sur les boutons\\Boutons brillants"); + if ( num == EVENT_INTERFACE_TOOLTIP) strcpy(text, "Bulles d'aide\\Bulles explicatives"); + if ( num == EVENT_INTERFACE_MOVIES ) strcpy(text, "Séquences cinématiques\\Films avant ou après une mission"); + if ( num == EVENT_INTERFACE_NICERST) strcpy(text, "Retour animé\\Retour animé dans les exercices"); + if ( num == EVENT_INTERFACE_HIMSELF) strcpy(text, "Dégâts à soi-même\\Vos tirs infligent des dommages à vos unités"); + if ( num == EVENT_INTERFACE_SCROLL ) strcpy(text, "Défilement dans les bords\\Défilement lorsque la souris touches les bords gauche ou droite"); + if ( num == EVENT_INTERFACE_INVERTX) strcpy(text, "Inversion souris X\\Inversion de la rotation lorsque la souris touche un bord"); + if ( num == EVENT_INTERFACE_INVERTY) strcpy(text, "Inversion souris Y\\Inversion de la rotation lorsque la souris touche un bord"); + if ( num == EVENT_INTERFACE_EFFECT ) strcpy(text, "Secousses lors d'explosions\\L'écran vibre lors d'une explosion"); + if ( num == EVENT_INTERFACE_MOUSE ) strcpy(text, "Souris ombrée\\Jolie souris avec une ombre"); + if ( num == EVENT_INTERFACE_EDITMODE) strcpy(text, "Indentation automatique\\Pendant l'édition d'un programme"); + if ( num == EVENT_INTERFACE_EDITVALUE)strcpy(text, "Grande indentation\\Indente avec 2 ou 4 espaces"); + if ( num == EVENT_INTERFACE_SOLUCE4) strcpy(text, "Accès aux solutions\\Programme \"4: Solution\" dans les exercices"); + + if ( num == EVENT_INTERFACE_KDEF ) strcpy(text, "Tout réinitialiser\\Remet toutes les touches standards"); + if ( num == EVENT_INTERFACE_KLEFT ) strcpy(text, "Tourner à gauche\\Moteur à gauche"); + if ( num == EVENT_INTERFACE_KRIGHT ) strcpy(text, "Tourner à droite\\Moteur à droite"); + if ( num == EVENT_INTERFACE_KUP ) strcpy(text, "Avancer\\Moteur en avant"); + if ( num == EVENT_INTERFACE_KDOWN ) strcpy(text, "Reculer\\Moteur en arrière"); + if ( num == EVENT_INTERFACE_KGUP ) strcpy(text, "Monter\\Augmenter la puissance du réacteur"); + if ( num == EVENT_INTERFACE_KGDOWN ) strcpy(text, "Descendre\\Diminuer la puissance du réacteur"); + if ( num == EVENT_INTERFACE_KCAMERA) strcpy(text, "Changement de caméra\\Autre de point de vue"); + if ( num == EVENT_INTERFACE_KDESEL ) strcpy(text, "Sélection précédente\\Sélectionne l'objet précédent"); + if ( num == EVENT_INTERFACE_KACTION) strcpy(text, "Action standard\\Action du bouton avec le cadre rouge"); + if ( num == EVENT_INTERFACE_KNEAR ) strcpy(text, "Caméra plus proche\\Avance la caméra"); + if ( num == EVENT_INTERFACE_KAWAY ) strcpy(text, "Caméra plus loin\\Recule la caméra"); + if ( num == EVENT_INTERFACE_KNEXT ) strcpy(text, "Sélectionner l'objet suivant\\Sélectionner l'objet suivant"); + if ( num == EVENT_INTERFACE_KHUMAN ) strcpy(text, "Sélectionner le cosmonaute\\Sélectionner le cosmonaute"); + if ( num == EVENT_INTERFACE_KQUIT ) strcpy(text, "Quitter la mission en cours\\Terminer un exercice ou une mssion"); + if ( num == EVENT_INTERFACE_KHELP ) strcpy(text, "Instructions mission\\Marche à suivre"); + if ( num == EVENT_INTERFACE_KPROG ) strcpy(text, "Instructions programmation\\Explication sur la programmation"); + if ( num == EVENT_INTERFACE_KCBOT ) strcpy(text, "Instructions mot-clé\\Explication sur le mot-clé"); + if ( num == EVENT_INTERFACE_KVISIT ) strcpy(text, "Montrer le lieu d'un message\\Montrer le lieu du dernier message"); + if ( num == EVENT_INTERFACE_KSPEED10) strcpy(text, "Vitesse 1.0x\\Vitesse normale"); + if ( num == EVENT_INTERFACE_KSPEED15) strcpy(text, "Vitesse 1.5x\\Une fois et demi plus rapide"); + if ( num == EVENT_INTERFACE_KSPEED20) strcpy(text, "Vitesse 2.0x\\Deux fois plus rapide"); + if ( num == EVENT_INTERFACE_KSPEED30) strcpy(text, "Vitesse 3.0x\\Trois fois plus rapide"); + + if ( num == EVENT_INTERFACE_VOLSOUND) strcpy(text, "Bruitages :\\Volume des moteurs, voix, etc."); + if ( num == EVENT_INTERFACE_VOLMUSIC) strcpy(text, "Fond sonore :\\Volume des pistes audio du CD"); + if ( num == EVENT_INTERFACE_SOUND3D) strcpy(text, "Bruitages 3D\\Positionnement sonore dans l'espace"); + + if ( num == EVENT_INTERFACE_MIN ) strcpy(text, "Mini\\Qualité minimale (+ rapide)"); + if ( num == EVENT_INTERFACE_NORM ) strcpy(text, "Normal\\Qualité standard"); + if ( num == EVENT_INTERFACE_MAX ) strcpy(text, "Maxi\\Haute qualité (+ lent)"); + + if ( num == EVENT_INTERFACE_SILENT ) strcpy(text, "Silencieux\\Totalement silencieux"); + if ( num == EVENT_INTERFACE_NOISY ) strcpy(text, "Normal\\Niveaux normaux"); + + if ( num == EVENT_INTERFACE_JOYSTICK) strcpy(text, "Utilise un joystick\\Joystick ou clavier"); + if ( num == EVENT_INTERFACE_SOLUCE ) strcpy(text, "Accès à la solution\\Donne la solution"); + + if ( num == EVENT_INTERFACE_NEDIT ) strcpy(text, "\\Nom du joueur à créer"); + if ( num == EVENT_INTERFACE_NOK ) strcpy(text, "D'accord\\Choisir le joueur"); + if ( num == EVENT_INTERFACE_NCANCEL) strcpy(text, "Annuler\\Conserver le joueur actuel"); + if ( num == EVENT_INTERFACE_NDELETE) strcpy(text, "Supprimer le joueur\\Supprimer le joueur de la liste"); + if ( num == EVENT_INTERFACE_NLABEL ) strcpy(text, "Nom du joueur"); + + if ( num == EVENT_INTERFACE_IOWRITE) strcpy(text, "Enregistrer\\Enregistrer la mission en cours"); + if ( num == EVENT_INTERFACE_IOREAD ) strcpy(text, "Charger\\Charger la mission sélectionnée"); + if ( num == EVENT_INTERFACE_IOLIST ) strcpy(text, "Liste des missions enregistrées"); + if ( num == EVENT_INTERFACE_IOLABEL) strcpy(text, "Nom du fichier :"); + if ( num == EVENT_INTERFACE_IONAME ) strcpy(text, "Nom de la mission"); + if ( num == EVENT_INTERFACE_IOIMAGE) strcpy(text, "Vue de la mission"); + if ( num == EVENT_INTERFACE_IODELETE) strcpy(text, "Supprimer\\Supprime l'enregistrement sélectionné"); + + if ( num == EVENT_INTERFACE_PERSO ) strcpy(text, "Aspect\\Choisir votre aspect"); + if ( num == EVENT_INTERFACE_POK ) strcpy(text, "D'accord"); + if ( num == EVENT_INTERFACE_PCANCEL) strcpy(text, "Annuler"); + if ( num == EVENT_INTERFACE_PDEF ) strcpy(text, "Standard\\Remet les couleurs standards"); + if ( num == EVENT_INTERFACE_PHEAD ) strcpy(text, "Tête\\Visage et cheveux"); + if ( num == EVENT_INTERFACE_PBODY ) strcpy(text, "Corps\\Combinaison"); + if ( num == EVENT_INTERFACE_PLROT ) strcpy(text, "\\Rotation à gauche"); + if ( num == EVENT_INTERFACE_PRROT ) strcpy(text, "\\Rotation à droite"); + if ( num == EVENT_INTERFACE_PCRa ) strcpy(text, "Rouge"); + if ( num == EVENT_INTERFACE_PCGa ) strcpy(text, "Vert"); + if ( num == EVENT_INTERFACE_PCBa ) strcpy(text, "Bleu"); + if ( num == EVENT_INTERFACE_PCRb ) strcpy(text, "Rouge"); + if ( num == EVENT_INTERFACE_PCGb ) strcpy(text, "Vert"); + if ( num == EVENT_INTERFACE_PCBb ) strcpy(text, "Bleu"); + if ( num == EVENT_INTERFACE_PFACE1 ) strcpy(text, "\\Visage 1"); + if ( num == EVENT_INTERFACE_PFACE2 ) strcpy(text, "\\Visage 4"); + if ( num == EVENT_INTERFACE_PFACE3 ) strcpy(text, "\\Visage 3"); + if ( num == EVENT_INTERFACE_PFACE4 ) strcpy(text, "\\Visage 2"); + if ( num == EVENT_INTERFACE_PGLASS0) strcpy(text, "\\Pas de lunettes"); + if ( num == EVENT_INTERFACE_PGLASS1) strcpy(text, "\\Lunettes 1"); + if ( num == EVENT_INTERFACE_PGLASS2) strcpy(text, "\\Lunettes 2"); + if ( num == EVENT_INTERFACE_PGLASS3) strcpy(text, "\\Lunettes 3"); + if ( num == EVENT_INTERFACE_PGLASS4) strcpy(text, "\\Lunettes 4"); + if ( num == EVENT_INTERFACE_PGLASS5) strcpy(text, "\\Lunettes 5"); + + if ( num == EVENT_OBJECT_DESELECT ) strcpy(text, "Sélection précédente (\\key desel;)"); + if ( num == EVENT_OBJECT_LEFT ) strcpy(text, "Tourne à gauche (\\key left;)"); + if ( num == EVENT_OBJECT_RIGHT ) strcpy(text, "Tourne à droite (\\key right;)"); + if ( num == EVENT_OBJECT_UP ) strcpy(text, "Avance (\\key up;)"); + if ( num == EVENT_OBJECT_DOWN ) strcpy(text, "Recule (\\key down;)"); + if ( num == EVENT_OBJECT_GASUP ) strcpy(text, "Monte (\\key gup;)"); + if ( num == EVENT_OBJECT_GASDOWN ) strcpy(text, "Descend (\\key gdown;)"); + if ( num == EVENT_OBJECT_HTAKE ) strcpy(text, "Prend ou dépose (\\key action;)"); + if ( num == EVENT_OBJECT_MTAKE ) strcpy(text, "Prend ou dépose (\\key action;)"); + if ( num == EVENT_OBJECT_MFRONT ) strcpy(text, "..devant"); + if ( num == EVENT_OBJECT_MBACK ) strcpy(text, "..derrière"); + if ( num == EVENT_OBJECT_MPOWER ) strcpy(text, "..pile"); + if ( num == EVENT_OBJECT_BHELP ) strcpy(text, "Instructions sur la mission (\\key help;)"); + if ( num == EVENT_OBJECT_BTAKEOFF ) strcpy(text, "Décolle pour terminer la mission"); + if ( num == EVENT_OBJECT_BDERRICK ) strcpy(text, "Construit un derrick"); + if ( num == EVENT_OBJECT_BSTATION ) strcpy(text, "Construit une station"); + if ( num == EVENT_OBJECT_BFACTORY ) strcpy(text, "Construit une fabrique de robots"); + if ( num == EVENT_OBJECT_BREPAIR ) strcpy(text, "Construit un centre de réparation"); + if ( num == EVENT_OBJECT_BCONVERT ) strcpy(text, "Construit un convertisseur"); + if ( num == EVENT_OBJECT_BTOWER ) strcpy(text, "Construit une tour"); + if ( num == EVENT_OBJECT_BRESEARCH ) strcpy(text, "Construit un centre de recherches"); + if ( num == EVENT_OBJECT_BRADAR ) strcpy(text, "Construit un radar"); + if ( num == EVENT_OBJECT_BENERGY ) strcpy(text, "Construit une fabrique de piles"); + if ( num == EVENT_OBJECT_BLABO ) strcpy(text, "Construit un laboratoire"); + if ( num == EVENT_OBJECT_BNUCLEAR ) strcpy(text, "Construit une centrale nucléaire"); + if ( num == EVENT_OBJECT_BPARA ) strcpy(text, "Construit un paratonnerre"); + if ( num == EVENT_OBJECT_BINFO ) strcpy(text, "Construit une borne d'information"); + if ( num == EVENT_OBJECT_GFLAT ) strcpy(text, "Montre si le sol est plat"); + if ( num == EVENT_OBJECT_FCREATE ) strcpy(text, "Pose un drapeau de couleur"); + if ( num == EVENT_OBJECT_FDELETE ) strcpy(text, "Enlève un drapeau"); + if ( num == EVENT_OBJECT_FCOLORb ) strcpy(text, "\\Drapeaux bleus"); + if ( num == EVENT_OBJECT_FCOLORr ) strcpy(text, "\\Drapeaux rouges"); + if ( num == EVENT_OBJECT_FCOLORg ) strcpy(text, "\\Drapeaux verts"); + if ( num == EVENT_OBJECT_FCOLORy ) strcpy(text, "\\Drapeaux jaunes"); + if ( num == EVENT_OBJECT_FCOLORv ) strcpy(text, "\\Drapeaux violets"); + if ( num == EVENT_OBJECT_FACTORYfa ) strcpy(text, "Fabrique un déménageur volant"); + if ( num == EVENT_OBJECT_FACTORYta ) strcpy(text, "Fabrique un déménageur à chenilles"); + if ( num == EVENT_OBJECT_FACTORYwa ) strcpy(text, "Fabrique un déménageur à roues"); + if ( num == EVENT_OBJECT_FACTORYia ) strcpy(text, "Fabrique un déménageur à pattes"); + if ( num == EVENT_OBJECT_FACTORYfc ) strcpy(text, "Fabrique un shooter volant"); + if ( num == EVENT_OBJECT_FACTORYtc ) strcpy(text, "Fabrique un shooter à chenilles"); + if ( num == EVENT_OBJECT_FACTORYwc ) strcpy(text, "Fabrique un shooter à roues"); + if ( num == EVENT_OBJECT_FACTORYic ) strcpy(text, "Fabrique un shooter à pattes"); + if ( num == EVENT_OBJECT_FACTORYfi ) strcpy(text, "Fabrique un orgaShooter volant"); + if ( num == EVENT_OBJECT_FACTORYti ) strcpy(text, "Fabrique un orgaShooter à chenilles"); + if ( num == EVENT_OBJECT_FACTORYwi ) strcpy(text, "Fabrique un orgaShooter à roues"); + if ( num == EVENT_OBJECT_FACTORYii ) strcpy(text, "Fabrique un orgaShooter à pattes"); + if ( num == EVENT_OBJECT_FACTORYfs ) strcpy(text, "Fabrique un renifleur volant"); + if ( num == EVENT_OBJECT_FACTORYts ) strcpy(text, "Fabrique un renifleur à chenilles"); + if ( num == EVENT_OBJECT_FACTORYws ) strcpy(text, "Fabrique un renifleur à roues"); + if ( num == EVENT_OBJECT_FACTORYis ) strcpy(text, "Fabrique un renifleur à pattes"); + if ( num == EVENT_OBJECT_FACTORYrt ) strcpy(text, "Fabrique un robot secoueur"); + if ( num == EVENT_OBJECT_FACTORYrc ) strcpy(text, "Fabrique un robot phazer"); + if ( num == EVENT_OBJECT_FACTORYrr ) strcpy(text, "Fabrique un robot recycleur"); + if ( num == EVENT_OBJECT_FACTORYrs ) strcpy(text, "Fabrique un robot bouclier"); + if ( num == EVENT_OBJECT_FACTORYsa ) strcpy(text, "Fabrique un robot sous-marin"); + if ( num == EVENT_OBJECT_RTANK ) strcpy(text, "Recherche les chenilles"); + if ( num == EVENT_OBJECT_RFLY ) strcpy(text, "Recherche les robots volants"); + if ( num == EVENT_OBJECT_RTHUMP ) strcpy(text, "Recherche le secoueur"); + if ( num == EVENT_OBJECT_RCANON ) strcpy(text, "Recherche le canon shooter"); + if ( num == EVENT_OBJECT_RTOWER ) strcpy(text, "Recherche la tour de défense"); + if ( num == EVENT_OBJECT_RPHAZER ) strcpy(text, "Recherche le canon phazer"); + if ( num == EVENT_OBJECT_RSHIELD ) strcpy(text, "Recherche le bouclier"); + if ( num == EVENT_OBJECT_RATOMIC ) strcpy(text, "Recherche le nucléaire"); + if ( num == EVENT_OBJECT_RiPAW ) strcpy(text, "Recherche les pattes"); + if ( num == EVENT_OBJECT_RiGUN ) strcpy(text, "Recherche le canon orgaShooter"); + if ( num == EVENT_OBJECT_RESET ) strcpy(text, "Remet au départ"); + if ( num == EVENT_OBJECT_SEARCH ) strcpy(text, "Cherche (\\key action;)"); + if ( num == EVENT_OBJECT_TERRAFORM ) strcpy(text, "Secoue (\\key action;)"); + if ( num == EVENT_OBJECT_FIRE ) strcpy(text, "Tir (\\key action;)"); + if ( num == EVENT_OBJECT_RECOVER ) strcpy(text, "Recycle (\\key action;)"); + if ( num == EVENT_OBJECT_BEGSHIELD ) strcpy(text, "Déploie le bouclier (\\key action;)"); + if ( num == EVENT_OBJECT_ENDSHIELD ) strcpy(text, "Stoppe le bouclier (\\key action;)"); + if ( num == EVENT_OBJECT_DIMSHIELD ) strcpy(text, "Rayon du bouclier"); + if ( num == EVENT_OBJECT_PROGRUN ) strcpy(text, "Exécute le programme sélectionné"); + if ( num == EVENT_OBJECT_PROGEDIT ) strcpy(text, "Edite le programme sélectionné"); + if ( num == EVENT_OBJECT_INFOOK ) strcpy(text, "\\Mettre le SatCom en veille"); + if ( num == EVENT_OBJECT_DELETE ) strcpy(text, "Démolit le bâtiment"); + if ( num == EVENT_OBJECT_GENERGY ) strcpy(text, "Niveau d'énergie"); + if ( num == EVENT_OBJECT_GSHIELD ) strcpy(text, "Niveau du bouclier"); + if ( num == EVENT_OBJECT_GRANGE ) strcpy(text, "Température du réacteur"); + if ( num == EVENT_OBJECT_GPROGRESS ) strcpy(text, "Travail en cours ..."); + if ( num == EVENT_OBJECT_GRADAR ) strcpy(text, "Nombre d'insectes détectés"); + if ( num == EVENT_OBJECT_GINFO ) strcpy(text, "Informations diffusées"); + if ( num == EVENT_OBJECT_COMPASS ) strcpy(text, "Boussole"); +//? if ( num == EVENT_OBJECT_MAP ) strcpy(text, "Mini-carte"); + if ( num == EVENT_OBJECT_MAPZOOM ) strcpy(text, "Zoom mini-carte"); + if ( num == EVENT_OBJECT_CAMERA ) strcpy(text, "Caméra (\\key camera;)"); + if ( num == EVENT_OBJECT_CAMERAleft) strcpy(text, "Caméra à gauche"); + if ( num == EVENT_OBJECT_CAMERAright) strcpy(text, "Caméra à droite"); + if ( num == EVENT_OBJECT_CAMERAnear) strcpy(text, "Caméra plus proche"); + if ( num == EVENT_OBJECT_CAMERAaway) strcpy(text, "Caméra plus loin"); + if ( num == EVENT_OBJECT_HELP ) strcpy(text, "Instructions sur la sélection"); + if ( num == EVENT_OBJECT_SOLUCE ) strcpy(text, "Donne la solution"); + if ( num == EVENT_OBJECT_SHORTCUT00) strcpy(text, "Permute robots <-> bâtiments"); + if ( num == EVENT_OBJECT_LIMIT ) strcpy(text, "Montre le rayon d'action"); + if ( num == EVENT_OBJECT_PEN0 ) strcpy(text, "\\Relève le crayon"); + if ( num == EVENT_OBJECT_PEN1 ) strcpy(text, "\\Abaisse le crayon noir"); + if ( num == EVENT_OBJECT_PEN2 ) strcpy(text, "\\Abaisse le crayon jaune"); + if ( num == EVENT_OBJECT_PEN3 ) strcpy(text, "\\Abaisse le crayon orange"); + if ( num == EVENT_OBJECT_PEN4 ) strcpy(text, "\\Abaisse le crayon rouge"); + if ( num == EVENT_OBJECT_PEN5 ) strcpy(text, "\\Abaisse le crayon violet"); + if ( num == EVENT_OBJECT_PEN6 ) strcpy(text, "\\Abaisse le crayon bleu"); + if ( num == EVENT_OBJECT_PEN7 ) strcpy(text, "\\Abaisse le crayon vert"); + if ( num == EVENT_OBJECT_PEN8 ) strcpy(text, "\\Abaisse le crayon brun"); + if ( num == EVENT_OBJECT_REC ) strcpy(text, "\\Démarre l'enregistrement"); + if ( num == EVENT_OBJECT_STOP ) strcpy(text, "\\Stoppe l'enregistrement"); + if ( num == EVENT_DT_VISIT0 || + num == EVENT_DT_VISIT1 || + num == EVENT_DT_VISIT2 || + num == EVENT_DT_VISIT3 || + num == EVENT_DT_VISIT4 ) strcpy(text, "Montre l'endroit"); + if ( num == EVENT_DT_END ) strcpy(text, "Continuer"); + if ( num == EVENT_CMD ) strcpy(text, "Console de commande"); + if ( num == EVENT_SPEED ) strcpy(text, "Vitesse du jeu"); + + if ( num == EVENT_HYPER_PREV ) strcpy(text, "Page précédente"); + if ( num == EVENT_HYPER_NEXT ) strcpy(text, "Page suivante"); + if ( num == EVENT_HYPER_HOME ) strcpy(text, "Page initiale"); + if ( num == EVENT_HYPER_COPY ) strcpy(text, "Copier"); + if ( num == EVENT_HYPER_SIZE1 ) strcpy(text, "Taille 1"); + if ( num == EVENT_HYPER_SIZE2 ) strcpy(text, "Taille 2"); + if ( num == EVENT_HYPER_SIZE3 ) strcpy(text, "Taille 3"); + if ( num == EVENT_HYPER_SIZE4 ) strcpy(text, "Taille 4"); + if ( num == EVENT_HYPER_SIZE5 ) strcpy(text, "Taille 5"); + if ( num == EVENT_SATCOM_HUSTON ) strcpy(text, "Instructions de Houston"); +#if _TEEN + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Dictionnaire anglais-français"); +#else + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Rapport du satellite"); +#endif + if ( num == EVENT_SATCOM_LOADING ) strcpy(text, "Programmes envoyés par Houston"); + if ( num == EVENT_SATCOM_OBJECT ) strcpy(text, "Liste des objets"); + if ( num == EVENT_SATCOM_PROG ) strcpy(text, "Aide à la programmation"); + if ( num == EVENT_SATCOM_SOLUCE ) strcpy(text, "Solution"); + + if ( num == EVENT_STUDIO_OK ) strcpy(text, "D'accord\\Compiler le programme"); + if ( num == EVENT_STUDIO_CANCEL ) strcpy(text, "Annuler\\Annuler toutes les modifications"); + if ( num == EVENT_STUDIO_NEW ) strcpy(text, "Nouveau"); + if ( num == EVENT_STUDIO_OPEN ) strcpy(text, "Ouvrir (Ctrl+o)"); + if ( num == EVENT_STUDIO_SAVE ) strcpy(text, "Enregistrer (Ctrl+s)"); + if ( num == EVENT_STUDIO_UNDO ) strcpy(text, "Annuler (Ctrl+z)"); + if ( num == EVENT_STUDIO_CUT ) strcpy(text, "Couper (Ctrl+x)"); + if ( num == EVENT_STUDIO_COPY ) strcpy(text, "Copier (Ctrl+c)"); + if ( num == EVENT_STUDIO_PASTE ) strcpy(text, "Coller (Ctrl+v)"); + if ( num == EVENT_STUDIO_SIZE ) strcpy(text, "Taille des caractères"); + if ( num == EVENT_STUDIO_TOOL ) strcpy(text, "Instructions (\\key help;)"); + if ( num == EVENT_STUDIO_HELP ) strcpy(text, "Aide à la programmation (\\key prog;)"); + if ( num == EVENT_STUDIO_COMPILE ) strcpy(text, "Compiler"); + if ( num == EVENT_STUDIO_RUN ) strcpy(text, "Démarrer/stopper"); + if ( num == EVENT_STUDIO_REALTIME ) strcpy(text, "Pause/continuer"); + if ( num == EVENT_STUDIO_STEP ) strcpy(text, "Un pas"); + } + + if ( type == RES_OBJECT ) + { + if ( num == OBJECT_PORTICO ) strcpy(text, "Portique"); + if ( num == OBJECT_BASE ) strcpy(text, "Vaisseau spatial"); + if ( num == OBJECT_DERRICK ) strcpy(text, "Derrick"); + if ( num == OBJECT_FACTORY ) strcpy(text, "Fabrique de robots"); + if ( num == OBJECT_REPAIR ) strcpy(text, "Centre de réparation"); + if ( num == OBJECT_DESTROYER ) strcpy(text, "Destructeur"); + if ( num == OBJECT_STATION ) strcpy(text, "Station de recharge"); + if ( num == OBJECT_CONVERT ) strcpy(text, "Conversion minerai en titanium"); + if ( num == OBJECT_TOWER ) strcpy(text, "Tour de défense"); + if ( num == OBJECT_NEST ) strcpy(text, "Nid"); + if ( num == OBJECT_RESEARCH ) strcpy(text, "Centre de recherches"); + if ( num == OBJECT_RADAR ) strcpy(text, "Radar"); + if ( num == OBJECT_INFO ) strcpy(text, "Borne d'information"); +#if _TEEN + if ( num == OBJECT_ENERGY ) strcpy(text, "Désintégrateur"); +#else + if ( num == OBJECT_ENERGY ) strcpy(text, "Fabrique de piles"); +#endif + if ( num == OBJECT_LABO ) strcpy(text, "Laboratoire de matières organiques"); + if ( num == OBJECT_NUCLEAR ) strcpy(text, "Centrale nucléaire"); + if ( num == OBJECT_PARA ) strcpy(text, "Paratonnerre"); + if ( num == OBJECT_SAFE ) strcpy(text, "Coffre-fort"); + if ( num == OBJECT_HUSTON ) strcpy(text, "Centre de contrôle"); + if ( num == OBJECT_TARGET1 ) strcpy(text, "Cible"); + if ( num == OBJECT_TARGET2 ) strcpy(text, "Cible"); + if ( num == OBJECT_START ) strcpy(text, "Départ"); + if ( num == OBJECT_END ) strcpy(text, "But"); + if ( num == OBJECT_STONE ) strcpy(text, "Minerai de titanium"); + if ( num == OBJECT_URANIUM ) strcpy(text, "Minerai d'uranium"); + if ( num == OBJECT_BULLET ) strcpy(text, "Matière organique"); + if ( num == OBJECT_METAL ) strcpy(text, "Titanium"); + if ( num == OBJECT_POWER ) strcpy(text, "Pile normale"); + if ( num == OBJECT_ATOMIC ) strcpy(text, "Pile nucléaire"); + if ( num == OBJECT_BBOX ) strcpy(text, "Boîte noire"); + if ( num == OBJECT_KEYa ) strcpy(text, "Clé A"); + if ( num == OBJECT_KEYb ) strcpy(text, "Clé B"); + if ( num == OBJECT_KEYc ) strcpy(text, "Clé C"); + if ( num == OBJECT_KEYd ) strcpy(text, "Clé D"); + if ( num == OBJECT_TNT ) strcpy(text, "Explosif"); + if ( num == OBJECT_BOMB ) strcpy(text, "Mine fixe"); + if ( num == OBJECT_BAG ) strcpy(text, "Sac de survie"); + if ( num == OBJECT_WAYPOINT ) strcpy(text, "Indicateur"); + if ( num == OBJECT_FLAGb ) strcpy(text, "Drapeau bleu"); + if ( num == OBJECT_FLAGr ) strcpy(text, "Drapeau rouge"); + if ( num == OBJECT_FLAGg ) strcpy(text, "Drapeau vert"); + if ( num == OBJECT_FLAGy ) strcpy(text, "Drapeau jaune"); + if ( num == OBJECT_FLAGv ) strcpy(text, "Drapeau violet"); + if ( num == OBJECT_MARKPOWER ) strcpy(text, "Emplacement pour station"); + if ( num == OBJECT_MARKURANIUM ) strcpy(text, "Emplacement pour derrick (uranium)"); + if ( num == OBJECT_MARKKEYa ) strcpy(text, "Emplacement pour derrick (clé A)"); + if ( num == OBJECT_MARKKEYb ) strcpy(text, "Emplacement pour derrick (clé B)"); + if ( num == OBJECT_MARKKEYc ) strcpy(text, "Emplacement pour derrick (clé C)"); + if ( num == OBJECT_MARKKEYd ) strcpy(text, "Emplacement pour derrick (clé D)"); + if ( num == OBJECT_MARKSTONE ) strcpy(text, "Emplacement pour derrick (titanium)"); + if ( num == OBJECT_MOBILEft ) strcpy(text, "Robot d'entraînement"); + if ( num == OBJECT_MOBILEtt ) strcpy(text, "Robot d'entraînement"); + if ( num == OBJECT_MOBILEwt ) strcpy(text, "Robot d'entraînement"); + if ( num == OBJECT_MOBILEit ) strcpy(text, "Robot d'entraînement"); + if ( num == OBJECT_MOBILEfa ) strcpy(text, "Robot déménageur"); + if ( num == OBJECT_MOBILEta ) strcpy(text, "Robot déménageur"); + if ( num == OBJECT_MOBILEwa ) strcpy(text, "Robot déménageur"); + if ( num == OBJECT_MOBILEia ) strcpy(text, "Robot déménageur"); + if ( num == OBJECT_MOBILEfc ) strcpy(text, "Robot shooter"); + if ( num == OBJECT_MOBILEtc ) strcpy(text, "Robot shooter"); + if ( num == OBJECT_MOBILEwc ) strcpy(text, "Robot shooter"); + if ( num == OBJECT_MOBILEic ) strcpy(text, "Robot shooter"); + if ( num == OBJECT_MOBILEfi ) strcpy(text, "Robot orgaShooter"); + if ( num == OBJECT_MOBILEti ) strcpy(text, "Robot orgaShooter"); + if ( num == OBJECT_MOBILEwi ) strcpy(text, "Robot orgaShooter"); + if ( num == OBJECT_MOBILEii ) strcpy(text, "Robot orgaShooter"); + if ( num == OBJECT_MOBILEfs ) strcpy(text, "Robot renifleur"); + if ( num == OBJECT_MOBILEts ) strcpy(text, "Robot renifleur"); + if ( num == OBJECT_MOBILEws ) strcpy(text, "Robot renifleur"); + if ( num == OBJECT_MOBILEis ) strcpy(text, "Robot renifleur"); + if ( num == OBJECT_MOBILErt ) strcpy(text, "Robot secoueur"); + if ( num == OBJECT_MOBILErc ) strcpy(text, "Robot phazer"); + if ( num == OBJECT_MOBILErr ) strcpy(text, "Robot recycleur"); + if ( num == OBJECT_MOBILErs ) strcpy(text, "Robot bouclier"); + if ( num == OBJECT_MOBILEsa ) strcpy(text, "Robot sous-marin"); + if ( num == OBJECT_MOBILEtg ) strcpy(text, "Cible d'entraînement"); + if ( num == OBJECT_MOBILEdr ) strcpy(text, "Robot dessinateur"); + if ( num == OBJECT_HUMAN ) strcpy(text, g_gamerName); + if ( num == OBJECT_TECH ) strcpy(text, "Technicien"); + if ( num == OBJECT_TOTO ) strcpy(text, "Robbie"); + if ( num == OBJECT_MOTHER ) strcpy(text, "Pondeuse"); + if ( num == OBJECT_ANT ) strcpy(text, "Fourmi"); + if ( num == OBJECT_SPIDER ) strcpy(text, "Araignée"); + if ( num == OBJECT_BEE ) strcpy(text, "Guêpe"); + if ( num == OBJECT_WORM ) strcpy(text, "Ver"); + if ( num == OBJECT_EGG ) strcpy(text, "Oeuf"); + if ( num == OBJECT_RUINmobilew1 ) strcpy(text, "Epave de robot"); + if ( num == OBJECT_RUINmobilew2 ) strcpy(text, "Epave de robot"); + if ( num == OBJECT_RUINmobilet1 ) strcpy(text, "Epave de robot"); + if ( num == OBJECT_RUINmobilet2 ) strcpy(text, "Epave de robot"); + if ( num == OBJECT_RUINmobiler1 ) strcpy(text, "Epave de robot"); + if ( num == OBJECT_RUINmobiler2 ) strcpy(text, "Epave de robot"); + if ( num == OBJECT_RUINfactory ) strcpy(text, "Bâtiment en ruine"); + if ( num == OBJECT_RUINdoor ) strcpy(text, "Bâtiment en ruine"); + if ( num == OBJECT_RUINsupport ) strcpy(text, "Déchet"); + if ( num == OBJECT_RUINradar ) strcpy(text, "Bâtiment en ruine"); + if ( num == OBJECT_RUINconvert ) strcpy(text, "Bâtiment en ruine"); + if ( num == OBJECT_RUINbase ) strcpy(text, "Epave de vaisseau spatial"); + if ( num == OBJECT_RUINhead ) strcpy(text, "Epave de vaisseau spatial"); + if ( num == OBJECT_APOLLO1 || + num == OBJECT_APOLLO3 || + num == OBJECT_APOLLO4 || + num == OBJECT_APOLLO5 ) strcpy(text, "Vestige d'une mission Apollo"); + if ( num == OBJECT_APOLLO2 ) strcpy(text, "Lunar Roving Vehicle"); + } + + if ( type == RES_ERR ) + { + strcpy(text, "Erreur"); + if ( num == ERR_CMD ) strcpy(text, "Commande inconnue"); +#if _NEWLOOK + if ( num == ERR_INSTALL ) strcpy(text, "CeeBot n'est pas installé."); + if ( num == ERR_NOCD ) strcpy(text, "Veuillez mettre le CD de CeeBot\net relancer le jeu."); +#else + if ( num == ERR_INSTALL ) strcpy(text, "COLOBOT n'est pas installé."); + if ( num == ERR_NOCD ) strcpy(text, "Veuillez mettre le CD de COLOBOT\net relancer le jeu."); +#endif + if ( num == ERR_MANIP_VEH ) strcpy(text, "Robot inadapté"); + if ( num == ERR_MANIP_FLY ) strcpy(text, "Impossible en vol"); + if ( num == ERR_MANIP_BUSY ) strcpy(text, "Porte déjà quelque chose"); + if ( num == ERR_MANIP_NIL ) strcpy(text, "Rien à prendre"); + if ( num == ERR_MANIP_MOTOR ) strcpy(text, "Impossible en mouvement"); + if ( num == ERR_MANIP_OCC ) strcpy(text, "Emplacement occupé"); + if ( num == ERR_MANIP_FRIEND ) strcpy(text, "Pas d'autre robot"); + if ( num == ERR_MANIP_RADIO ) strcpy(text, "Vous ne pouvez pas transporter un objet radioactif"); + if ( num == ERR_MANIP_WATER ) strcpy(text, "Vous ne pouvez pas transporter un objet sous l'eau"); + if ( num == ERR_MANIP_EMPTY ) strcpy(text, "Rien à déposer"); + if ( num == ERR_BUILD_FLY ) strcpy(text, "Impossible en vol"); + if ( num == ERR_BUILD_WATER ) strcpy(text, "Impossible sous l'eau"); + if ( num == ERR_BUILD_ENERGY ) strcpy(text, "Pas assez d'énergie"); + if ( num == ERR_BUILD_METALAWAY ) strcpy(text, "Titanium trop loin"); + if ( num == ERR_BUILD_METALNEAR ) strcpy(text, "Titanium trop proche"); + if ( num == ERR_BUILD_METALINEX ) strcpy(text, "Titanium inexistant"); + if ( num == ERR_BUILD_FLAT ) strcpy(text, "Sol pas assez plat"); + if ( num == ERR_BUILD_FLATLIT ) strcpy(text, "Sol plat pas assez grand"); + if ( num == ERR_BUILD_BUSY ) strcpy(text, "Emplacement occupé"); + if ( num == ERR_BUILD_BASE ) strcpy(text, "Trop proche du vaisseau spatial"); + if ( num == ERR_BUILD_NARROW ) strcpy(text, "Trop proche d'un bâtiment"); + if ( num == ERR_BUILD_MOTOR ) strcpy(text, "Impossible en mouvement"); + if ( num == ERR_SEARCH_FLY ) strcpy(text, "Impossible en vol"); + if ( num == ERR_SEARCH_VEH ) strcpy(text, "Robot inadapté"); + if ( num == ERR_SEARCH_MOTOR ) strcpy(text, "Impossible en mouvement"); + if ( num == ERR_TERRA_VEH ) strcpy(text, "Robot inadapté"); + if ( num == ERR_TERRA_ENERGY ) strcpy(text, "Pas assez d'énergie"); + if ( num == ERR_TERRA_FLOOR ) strcpy(text, "Terrain inadapté"); + if ( num == ERR_TERRA_BUILDING ) strcpy(text, "Bâtiment trop proche"); + if ( num == ERR_TERRA_OBJECT ) strcpy(text, "Objet trop proche"); + if ( num == ERR_RECOVER_VEH ) strcpy(text, "Robot inadapté"); + if ( num == ERR_RECOVER_ENERGY ) strcpy(text, "Pas assez d'énergie"); + if ( num == ERR_RECOVER_NULL ) strcpy(text, "Rien à recycler"); + if ( num == ERR_SHIELD_VEH ) strcpy(text, "Robot inadapté"); + if ( num == ERR_SHIELD_ENERGY ) strcpy(text, "Plus d'énergie"); + if ( num == ERR_MOVE_IMPOSSIBLE ) strcpy(text, "Déplacement impossible"); + if ( num == ERR_FIND_IMPOSSIBLE ) strcpy(text, "Objet n'existe pas"); + if ( num == ERR_GOTO_IMPOSSIBLE ) strcpy(text, "Chemin introuvable"); + if ( num == ERR_GOTO_ITER ) strcpy(text, "Position inaccessible"); + if ( num == ERR_GOTO_BUSY ) strcpy(text, "Destination occupée"); + if ( num == ERR_FIRE_VEH ) strcpy(text, "Robot inadapté"); + if ( num == ERR_FIRE_ENERGY ) strcpy(text, "Pas assez d'énergie"); + if ( num == ERR_FIRE_FLY ) strcpy(text, "Impossible en vol"); + if ( num == ERR_CONVERT_EMPTY ) strcpy(text, "Pas de minerai de titanium à convertir"); + if ( num == ERR_DERRICK_NULL ) strcpy(text, "Pas de minerai en sous-sol"); + if ( num == ERR_STATION_NULL ) strcpy(text, "Pas d'énergie en sous-sol"); + if ( num == ERR_TOWER_POWER ) strcpy(text, "Pas de pile"); + if ( num == ERR_TOWER_ENERGY ) strcpy(text, "Plus d'énergie"); + if ( num == ERR_RESEARCH_POWER ) strcpy(text, "Pas de pile"); + if ( num == ERR_RESEARCH_ENERGY ) strcpy(text, "Plus assez d'énergie"); + if ( num == ERR_RESEARCH_TYPE ) strcpy(text, "Pas le bon type de pile"); + if ( num == ERR_RESEARCH_ALREADY) strcpy(text, "Recherche déjà effectuée"); + if ( num == ERR_ENERGY_NULL ) strcpy(text, "Pas d'énergie en sous-sol"); + if ( num == ERR_ENERGY_LOW ) strcpy(text, "Pas encore assez d'énergie"); + if ( num == ERR_ENERGY_EMPTY ) strcpy(text, "Pas de titanium à transformer"); + if ( num == ERR_ENERGY_BAD ) strcpy(text, "Ne transforme que le titanium"); + if ( num == ERR_BASE_DLOCK ) strcpy(text, "Portes bloquées par un robot ou un objet"); + if ( num == ERR_BASE_DHUMAN ) strcpy(text, "Vous devez embarquer pour pouvoir décoller"); + if ( num == ERR_LABO_NULL ) strcpy(text, "Rien à analyser"); + if ( num == ERR_LABO_BAD ) strcpy(text, "N'analyse que la matière organique"); + if ( num == ERR_LABO_ALREADY ) strcpy(text, "Analyse déjà effectuée"); + if ( num == ERR_NUCLEAR_NULL ) strcpy(text, "Pas d'énergie en sous-sol"); + if ( num == ERR_NUCLEAR_LOW ) strcpy(text, "Pas encore assez d'énergie"); + if ( num == ERR_NUCLEAR_EMPTY ) strcpy(text, "Pas d'uranium à transformer"); + if ( num == ERR_NUCLEAR_BAD ) strcpy(text, "Ne transforme que l'uranium"); + if ( num == ERR_FACTORY_NULL ) strcpy(text, "Pas de titanium"); + if ( num == ERR_FACTORY_NEAR ) strcpy(text, "Quelque chose est trop proche"); + if ( num == ERR_RESET_NEAR ) strcpy(text, "Emplacement occupé"); + if ( num == ERR_INFO_NULL ) strcpy(text, "Pas trouvé de borne d'information"); + if ( num == ERR_VEH_VIRUS ) strcpy(text, "Un programme est infecté par un virus"); + if ( num == ERR_BAT_VIRUS ) strcpy(text, "Infecté par un virus, ne fonctionne plus temporairement"); + if ( num == ERR_VEH_POWER ) strcpy(text, "Pas de pile"); + if ( num == ERR_VEH_ENERGY ) strcpy(text, "Plus d'énergie"); + if ( num == ERR_FLAG_FLY ) strcpy(text, "Impossible en vol"); + if ( num == ERR_FLAG_WATER ) strcpy(text, "Impossible en nageant"); + if ( num == ERR_FLAG_MOTOR ) strcpy(text, "Impossible en mouvement"); + if ( num == ERR_FLAG_BUSY ) strcpy(text, "Impossible en portant un objet"); + if ( num == ERR_FLAG_CREATE ) strcpy(text, "Trop de drapeaux de cette couleur (maximum 5)"); + if ( num == ERR_FLAG_PROXY ) strcpy(text, "Trop proche d'un drapeau existant"); + if ( num == ERR_FLAG_DELETE ) strcpy(text, "Aucun drapeau à proximité"); + if ( num == ERR_MISSION_NOTERM ) strcpy(text, "La misssion n'est pas terminée (appuyez sur \\key help; pour plus de détails)"); + if ( num == ERR_DELETEMOBILE ) strcpy(text, "Robot détruit"); + if ( num == ERR_DELETEBUILDING ) strcpy(text, "Bâtiment détruit"); + if ( num == ERR_TOOMANY ) strcpy(text, "Création impossible, il y a trop d'objets"); + if ( num == ERR_OBLIGATORYTOKEN ) strcpy(text, "Il manque \"%s\" dans le programme"); + if ( num == ERR_PROHIBITEDTOKEN ) strcpy(text, "Interdit dans cet exercice"); + + if ( num == INFO_BUILD ) strcpy(text, "Bâtiment terminé"); + if ( num == INFO_CONVERT ) strcpy(text, "Titanium disponible"); + if ( num == INFO_RESEARCH ) strcpy(text, "Recherche terminée"); + if ( num == INFO_RESEARCHTANK ) strcpy(text, "Fabrication d'un robot à chenilles possible"); + if ( num == INFO_RESEARCHFLY ) strcpy(text, "Il est possible de voler avec les touches (\\key gup;) et (\\key gdown;)"); + if ( num == INFO_RESEARCHTHUMP ) strcpy(text, "Fabrication d'un robot secoueur possible"); + if ( num == INFO_RESEARCHCANON ) strcpy(text, "Fabrication de robots shooter possible"); + if ( num == INFO_RESEARCHTOWER ) strcpy(text, "Construction d'une tour de défense possible"); + if ( num == INFO_RESEARCHPHAZER ) strcpy(text, "Fabrication d'un robot phazer possible"); + if ( num == INFO_RESEARCHSHIELD ) strcpy(text, "Fabrication d'un robot bouclier possible"); + if ( num == INFO_RESEARCHATOMIC ) strcpy(text, "Construction d'une centrale nucléaire possible"); + if ( num == INFO_FACTORY ) strcpy(text, "Nouveau robot disponible"); + if ( num == INFO_LABO ) strcpy(text, "Analyse terminée"); + if ( num == INFO_ENERGY ) strcpy(text, "Pile disponible"); + if ( num == INFO_NUCLEAR ) strcpy(text, "Pile nucléaire disponible"); + if ( num == INFO_FINDING ) strcpy(text, "Vous avez trouvé un objet utilisable"); + if ( num == INFO_MARKPOWER ) strcpy(text, "Emplacement pour station trouvé"); + if ( num == INFO_MARKURANIUM ) strcpy(text, "Emplacement pour derrick trouvé"); + if ( num == INFO_MARKSTONE ) strcpy(text, "Emplacement pour derrick trouvé"); + if ( num == INFO_MARKKEYa ) strcpy(text, "Emplacement pour derrick trouvé"); + if ( num == INFO_MARKKEYb ) strcpy(text, "Emplacement pour derrick trouvé"); + if ( num == INFO_MARKKEYc ) strcpy(text, "Emplacement pour derrick trouvé"); + if ( num == INFO_MARKKEYd ) strcpy(text, "Emplacement pour derrick trouvé"); + if ( num == INFO_WIN ) strcpy(text, "<<< Bravo, mission terminée >>>"); + if ( num == INFO_LOST ) strcpy(text, "<<< Désolé, mission échouée >>>"); + if ( num == INFO_LOSTq ) strcpy(text, "<<< Désolé, mission échouée >>>"); + if ( num == INFO_WRITEOK ) strcpy(text, "Enregistrement effectué"); + if ( num == INFO_DELETEPATH ) strcpy(text, "Indicateur atteint"); + if ( num == INFO_DELETEMOTHER ) strcpy(text, "Pondeuse mortellement touchée"); + if ( num == INFO_DELETEANT ) strcpy(text, "Fourmi mortellement touchée"); + if ( num == INFO_DELETEBEE ) strcpy(text, "Guêpe mortellement touchée"); + if ( num == INFO_DELETEWORM ) strcpy(text, "Ver mortellement touché"); + if ( num == INFO_DELETESPIDER ) strcpy(text, "Araignée mortellement touchée"); + if ( num == INFO_BEGINSATCOM ) strcpy(text, "Consultez votre SatCom en appuyant sur \\key help;"); + } + + if ( type == RES_CBOT ) + { + strcpy(text, "Erreur"); + if ( num == TX_OPENPAR ) strcpy(text, "Il manque une parenthèse ouvrante"); + if ( num == TX_CLOSEPAR ) strcpy(text, "Il manque une parenthèse fermante"); + if ( num == TX_NOTBOOL ) strcpy(text, "L'expression doit être un boolean"); + if ( num == TX_UNDEFVAR ) strcpy(text, "Variable non déclarée"); + if ( num == TX_BADLEFT ) strcpy(text, "Assignation impossible"); + if ( num == TX_ENDOF ) strcpy(text, "Terminateur point-virgule non trouvé"); + if ( num == TX_OUTCASE ) strcpy(text, "Instruction ""case"" hors d'un bloc ""switch"""); + if ( num == TX_NOTERM ) strcpy(text, "Instructions après la fin"); + if ( num == TX_CLOSEBLK ) strcpy(text, "Il manque la fin du bloc"); + if ( num == TX_ELSEWITHOUTIF ) strcpy(text, "Instruction ""else"" sans ""if"" correspondant"); + if ( num == TX_OPENBLK ) strcpy(text, "Début d'un bloc attendu"); + if ( num == TX_BADTYPE ) strcpy(text, "Mauvais type de résultat pour l'assignation"); + if ( num == TX_REDEFVAR ) strcpy(text, "Redéfinition d'une variable"); + if ( num == TX_BAD2TYPE ) strcpy(text, "Les deux opérandes ne sont pas de types compatibles"); + if ( num == TX_UNDEFCALL ) strcpy(text, "Routine inconnue"); + if ( num == TX_MISDOTS ) strcpy(text, "Séparateur "" : "" attendu"); + if ( num == TX_WHILE ) strcpy(text, "Manque le mot ""while"""); + if ( num == TX_BREAK ) strcpy(text, "Instruction ""break"" en dehors d'une boucle"); + if ( num == TX_LABEL ) strcpy(text, "Un label ne peut se placer que devant un ""for"", un ""while"", un ""do"" ou un ""switch"""); + if ( num == TX_NOLABEL ) strcpy(text, "Cette étiquette n'existe pas"); + if ( num == TX_NOCASE ) strcpy(text, "Manque une instruction ""case"""); + if ( num == TX_BADNUM ) strcpy(text, "Un nombre est attendu"); + if ( num == TX_VOID ) strcpy(text, "Paramètre void"); + if ( num == TX_NOTYP ) strcpy(text, "Déclaration de type attendu"); + if ( num == TX_NOVAR ) strcpy(text, "Nom d'une variable attendu"); + if ( num == TX_NOFONC ) strcpy(text, "Nom de la fonction attendu"); + if ( num == TX_OVERPARAM ) strcpy(text, "Trop de paramètres"); + if ( num == TX_REDEF ) strcpy(text, "Cette fonction existe déjà"); + if ( num == TX_LOWPARAM ) strcpy(text, "Pas assez de paramètres"); + if ( num == TX_BADPARAM ) strcpy(text, "Aucune fonction de ce nom n'accepte ce(s) type(s) de paramètre(s)"); + if ( num == TX_NUMPARAM ) strcpy(text, "Aucune fonction de ce nom n'accepte ce nombre de paramètres"); + if ( num == TX_NOITEM ) strcpy(text, "Cet élément n'existe pas dans cette classe"); + if ( num == TX_DOT ) strcpy(text, "L'objet n'est pas une instance d'une classe"); + if ( num == TX_NOCONST ) strcpy(text, "Il n'y a pas de constructeur approprié"); + if ( num == TX_REDEFCLASS ) strcpy(text, "Cette classe existe déjà"); + if ( num == TX_CLBRK ) strcpy(text, """ ] "" attendu"); + if ( num == TX_RESERVED ) strcpy(text, "Ce mot est réservé"); + if ( num == TX_BADNEW ) strcpy(text, "Mauvais argument pour ""new"""); + if ( num == TX_OPBRK ) strcpy(text, """ [ "" attendu"); + if ( num == TX_BADSTRING ) strcpy(text, "Une chaîne de caractère est attendue"); + if ( num == TX_BADINDEX ) strcpy(text, "Mauvais type d'index"); + if ( num == TX_PRIVATE ) strcpy(text, "Elément protégé"); + if ( num == TX_NOPUBLIC ) strcpy(text, "Public requis"); + if ( num == TX_DIVZERO ) strcpy(text, "Division par zéro"); + if ( num == TX_NOTINIT ) strcpy(text, "Variable non initialisée"); + if ( num == TX_BADTHROW ) strcpy(text, "Valeur négative refusée pour ""throw"""); + if ( num == TX_NORETVAL ) strcpy(text, "La fonction n'a pas retourné de résultat"); + if ( num == TX_NORUN ) strcpy(text, "Pas de fonction en exécution"); + if ( num == TX_NOCALL ) strcpy(text, "Appel d'une fonction inexistante"); + if ( num == TX_NOCLASS ) strcpy(text, "Cette classe n'existe pas"); + if ( num == TX_NULLPT ) strcpy(text, "Objet n'existe pas"); + if ( num == TX_OPNAN ) strcpy(text, "Opération sur un ""nan"""); + if ( num == TX_OUTARRAY ) strcpy(text, "Accès hors du tableau"); + if ( num == TX_STACKOVER ) strcpy(text, "Débordement de la pile"); + if ( num == TX_DELETEDPT ) strcpy(text, "Objet inaccessible"); + if ( num == TX_FILEOPEN ) strcpy(text, "Ouverture du fichier impossible"); + if ( num == TX_NOTOPEN ) strcpy(text, "Le fichier n'est pas ouvert"); + if ( num == TX_ERRREAD ) strcpy(text, "Erreur à la lecture"); + if ( num == TX_ERRWRITE ) strcpy(text, "Erreur à l'écriture"); + } + + if ( type == RES_KEY ) + { + if ( num == 0 ) strcpy(text, "< aucune >"); + if ( num == VK_LEFT ) strcpy(text, "Flèche Gauche"); + if ( num == VK_RIGHT ) strcpy(text, "Flèche Droite"); + if ( num == VK_UP ) strcpy(text, "Flèche Haut"); + if ( num == VK_DOWN ) strcpy(text, "Flèche Bas"); + if ( num == VK_CANCEL ) strcpy(text, "Control-break"); + if ( num == VK_BACK ) strcpy(text, "<--"); + if ( num == VK_TAB ) strcpy(text, "Tab"); + if ( num == VK_CLEAR ) strcpy(text, "Clear"); + if ( num == VK_RETURN ) strcpy(text, "Entrée"); + if ( num == VK_SHIFT ) strcpy(text, "Shift"); + if ( num == VK_CONTROL ) strcpy(text, "Ctrl"); + if ( num == VK_MENU ) strcpy(text, "Alt"); + if ( num == VK_PAUSE ) strcpy(text, "Pause"); + if ( num == VK_CAPITAL ) strcpy(text, "Caps Lock"); + if ( num == VK_ESCAPE ) strcpy(text, "Esc"); + if ( num == VK_SPACE ) strcpy(text, "Espace"); + if ( num == VK_PRIOR ) strcpy(text, "Page Up"); + if ( num == VK_NEXT ) strcpy(text, "Page Down"); + if ( num == VK_END ) strcpy(text, "End"); + if ( num == VK_HOME ) strcpy(text, "Home"); + if ( num == VK_SELECT ) strcpy(text, "Select"); + if ( num == VK_EXECUTE ) strcpy(text, "Execute"); + if ( num == VK_SNAPSHOT ) strcpy(text, "Print Scrn"); + if ( num == VK_INSERT ) strcpy(text, "Insert"); + if ( num == VK_DELETE ) strcpy(text, "Delete"); + if ( num == VK_HELP ) strcpy(text, "Help"); + if ( num == VK_LWIN ) strcpy(text, "Left Windows"); + if ( num == VK_RWIN ) strcpy(text, "Right Windows"); + if ( num == VK_APPS ) strcpy(text, "Application key"); + if ( num == VK_NUMPAD0 ) strcpy(text, "NumPad 0"); + if ( num == VK_NUMPAD1 ) strcpy(text, "NumPad 1"); + if ( num == VK_NUMPAD2 ) strcpy(text, "NumPad 2"); + if ( num == VK_NUMPAD3 ) strcpy(text, "NumPad 3"); + if ( num == VK_NUMPAD4 ) strcpy(text, "NumPad 4"); + if ( num == VK_NUMPAD5 ) strcpy(text, "NumPad 5"); + if ( num == VK_NUMPAD6 ) strcpy(text, "NumPad 6"); + if ( num == VK_NUMPAD7 ) strcpy(text, "NumPad 7"); + if ( num == VK_NUMPAD8 ) strcpy(text, "NumPad 8"); + if ( num == VK_NUMPAD9 ) strcpy(text, "NumPad 9"); + if ( num == VK_MULTIPLY ) strcpy(text, "NumPad *"); + if ( num == VK_ADD ) strcpy(text, "NumPad +"); + if ( num == VK_SEPARATOR ) strcpy(text, "NumPad sep"); + if ( num == VK_SUBTRACT ) strcpy(text, "NumPad -"); + if ( num == VK_DECIMAL ) strcpy(text, "NumPad ."); + if ( num == VK_DIVIDE ) strcpy(text, "NumPad /"); + if ( num == VK_F1 ) strcpy(text, "F1"); + if ( num == VK_F2 ) strcpy(text, "F2"); + if ( num == VK_F3 ) strcpy(text, "F3"); + if ( num == VK_F4 ) strcpy(text, "F4"); + if ( num == VK_F5 ) strcpy(text, "F5"); + if ( num == VK_F6 ) strcpy(text, "F6"); + if ( num == VK_F7 ) strcpy(text, "F7"); + if ( num == VK_F8 ) strcpy(text, "F8"); + if ( num == VK_F9 ) strcpy(text, "F9"); + if ( num == VK_F10 ) strcpy(text, "F10"); + if ( num == VK_F11 ) strcpy(text, "F11"); + if ( num == VK_F12 ) strcpy(text, "F12"); + if ( num == VK_F13 ) strcpy(text, "F13"); + if ( num == VK_F14 ) strcpy(text, "F14"); + if ( num == VK_F15 ) strcpy(text, "F15"); + if ( num == VK_F16 ) strcpy(text, "F16"); + if ( num == VK_F17 ) strcpy(text, "F17"); + if ( num == VK_F18 ) strcpy(text, "F18"); + if ( num == VK_F19 ) strcpy(text, "F19"); + if ( num == VK_F20 ) strcpy(text, "F20"); + if ( num == VK_NUMLOCK ) strcpy(text, "Num Lock"); + if ( num == VK_SCROLL ) strcpy(text, "Scroll"); + if ( num == VK_ATTN ) strcpy(text, "Attn"); + if ( num == VK_CRSEL ) strcpy(text, "CrSel"); + if ( num == VK_EXSEL ) strcpy(text, "ExSel"); + if ( num == VK_EREOF ) strcpy(text, "Erase EOF"); + if ( num == VK_PLAY ) strcpy(text, "Play"); + if ( num == VK_ZOOM ) strcpy(text, "Zoom"); + if ( num == VK_PA1 ) strcpy(text, "PA1"); + if ( num == VK_OEM_CLEAR ) strcpy(text, "Clear"); + if ( num == VK_BUTTON1 ) strcpy(text, "Bouton 1"); + if ( num == VK_BUTTON2 ) strcpy(text, "Bouton 2"); + if ( num == VK_BUTTON3 ) strcpy(text, "Bouton 3"); + if ( num == VK_BUTTON4 ) strcpy(text, "Bouton 4"); + if ( num == VK_BUTTON5 ) strcpy(text, "Bouton 5"); + if ( num == VK_BUTTON6 ) strcpy(text, "Bouton 6"); + if ( num == VK_BUTTON7 ) strcpy(text, "Bouton 7"); + if ( num == VK_BUTTON8 ) strcpy(text, "Bouton 8"); + if ( num == VK_BUTTON9 ) strcpy(text, "Bouton 9"); + if ( num == VK_BUTTON10 ) strcpy(text, "Bouton 10"); + if ( num == VK_BUTTON11 ) strcpy(text, "Bouton 11"); + if ( num == VK_BUTTON12 ) strcpy(text, "Bouton 12"); + if ( num == VK_BUTTON13 ) strcpy(text, "Bouton 13"); + if ( num == VK_BUTTON14 ) strcpy(text, "Bouton 14"); + if ( num == VK_BUTTON15 ) strcpy(text, "Bouton 15"); + if ( num == VK_BUTTON16 ) strcpy(text, "Bouton 16"); + if ( num == VK_BUTTON17 ) strcpy(text, "Bouton 17"); + if ( num == VK_BUTTON18 ) strcpy(text, "Bouton 18"); + if ( num == VK_BUTTON19 ) strcpy(text, "Bouton 19"); + if ( num == VK_BUTTON20 ) strcpy(text, "Bouton 20"); + if ( num == VK_BUTTON21 ) strcpy(text, "Bouton 21"); + if ( num == VK_BUTTON22 ) strcpy(text, "Bouton 22"); + if ( num == VK_BUTTON23 ) strcpy(text, "Bouton 23"); + if ( num == VK_BUTTON24 ) strcpy(text, "Bouton 24"); + if ( num == VK_BUTTON25 ) strcpy(text, "Bouton 25"); + if ( num == VK_BUTTON26 ) strcpy(text, "Bouton 26"); + if ( num == VK_BUTTON27 ) strcpy(text, "Bouton 27"); + if ( num == VK_BUTTON28 ) strcpy(text, "Bouton 28"); + if ( num == VK_BUTTON29 ) strcpy(text, "Bouton 29"); + if ( num == VK_BUTTON30 ) strcpy(text, "Bouton 30"); + if ( num == VK_BUTTON31 ) strcpy(text, "Bouton 31"); + if ( num == VK_BUTTON32 ) strcpy(text, "Bouton 32"); + if ( num == VK_WHEELUP ) strcpy(text, "Molette haut"); + if ( num == VK_WHEELDOWN ) strcpy(text, "Molette bas"); + } +#endif + +#if _GERMAN | _WG + if ( type == RES_TEXT ) + { + #if _FULL + if ( num == RT_VERSION_ID ) strcpy(text, "1.18 /d"); + #endif + #if _NET + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A 1.18"); + #endif + #if _SCHOOL & _EDU + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen EDU 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A EDU 1.18"); + #endif + #endif + #if _SCHOOL & _PERSO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen PERSO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A PERSO 1.18"); + #endif + #endif + #if _SCHOOL & _CEEBOTDEMO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen DEMO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A DEMO 1.18"); + #endif + #endif + #if _DEMO + if ( num == RT_VERSION_ID ) strcpy(text, "Demo 1.18 /d"); + #endif + if ( num == RT_DISINFO_TITLE ) strcpy(text, "SatCom"); + if ( num == RT_WINDOW_MAXIMIZED ) strcpy(text, "Großes Fenster"); + if ( num == RT_WINDOW_MINIMIZED ) strcpy(text, "Reduzieren"); + if ( num == RT_WINDOW_STANDARD ) strcpy(text, "Normale Größe"); + if ( num == RT_WINDOW_CLOSE ) strcpy(text, "Schließen"); + + if ( num == RT_STUDIO_TITLE ) strcpy(text, "Programmeditor"); + if ( num == RT_SCRIPT_NEW ) strcpy(text, "Neu"); + if ( num == RT_NAME_DEFAULT ) strcpy(text, "Spieler"); + if ( num == RT_IO_NEW ) strcpy(text, "Neu ..."); + if ( num == RT_KEY_OR ) strcpy(text, " oder "); + +#if _NEWLOOK + if ( num == RT_TITLE_BASE ) strcpy(text, "CeeBot"); + if ( num == RT_TITLE_INIT ) strcpy(text, "CeeBot"); +#else + if ( num == RT_TITLE_BASE ) strcpy(text, "COLOBOT"); + if ( num == RT_TITLE_INIT ) strcpy(text, "COLOBOT"); +#endif +#if _SCHOOL + if ( num == RT_TITLE_TRAINER ) strcpy(text, "Übungen"); +#else + if ( num == RT_TITLE_TRAINER ) strcpy(text, "Programmieren"); +#endif + if ( num == RT_TITLE_DEFI ) strcpy(text, "Challenges"); + if ( num == RT_TITLE_MISSION ) strcpy(text, "Missionen"); + if ( num == RT_TITLE_FREE ) strcpy(text, "Freestyle"); + if ( num == RT_TITLE_TEEN ) strcpy(text, "Freestyle"); + if ( num == RT_TITLE_USER ) strcpy(text, "Userlevels"); + if ( num == RT_TITLE_PROTO ) strcpy(text, "Prototypen"); + if ( num == RT_TITLE_SETUP ) strcpy(text, "Einstellungen"); + if ( num == RT_TITLE_NAME ) strcpy(text, "Name "); + if ( num == RT_TITLE_PERSO ) strcpy(text, "Aussehen einstellen"); + if ( num == RT_TITLE_WRITE ) strcpy(text, "Aktuelle Mission speichern"); + if ( num == RT_TITLE_READ ) strcpy(text, "Gespeicherte Mission laden"); + + if ( num == RT_PLAY_CHAPt ) strcpy(text, " Liste der Kapitel:"); + if ( num == RT_PLAY_CHAPd ) strcpy(text, " Liste der Kapitel:"); + if ( num == RT_PLAY_CHAPm ) strcpy(text, " Liste der Planeten:"); + if ( num == RT_PLAY_CHAPf ) strcpy(text, " Liste der Planeten:"); + if ( num == RT_PLAY_CHAPu ) strcpy(text, " Userlevels:"); + if ( num == RT_PLAY_CHAPp ) strcpy(text, " Liste der Planeten:"); + if ( num == RT_PLAY_CHAPte ) strcpy(text, " Liste der Kapitel:"); + if ( num == RT_PLAY_LISTt ) strcpy(text, " Liste der Übungen des Kapitels:"); + if ( num == RT_PLAY_LISTd ) strcpy(text, " Liste der Challenges des Kapitels:"); + if ( num == RT_PLAY_LISTm ) strcpy(text, " Liste der Missionen des Planeten:"); + if ( num == RT_PLAY_LISTf ) strcpy(text, " Liste der freien Levels des Planeten:"); + if ( num == RT_PLAY_LISTu ) strcpy(text, " Missionen des Userlevels:"); + if ( num == RT_PLAY_LISTp ) strcpy(text, " Liste der Prototypen des Planeten:"); + if ( num == RT_PLAY_LISTk ) strcpy(text, " Liste der freien Levels des Kapitel:"); + if ( num == RT_PLAY_RESUME ) strcpy(text, " Zusammenfassung:"); + + if ( num == RT_SETUP_DEVICE ) strcpy(text, " Driver:"); + if ( num == RT_SETUP_MODE ) strcpy(text, " Auflösung:"); + if ( num == RT_SETUP_KEY1 ) strcpy(text, "1) Klicken Sie auf die neu zu definierende Taste."); + if ( num == RT_SETUP_KEY2 ) strcpy(text, "2) Drücken Sie auf die neue Taste."); + + if ( num == RT_PERSO_FACE ) strcpy(text, "Kopf:"); + if ( num == RT_PERSO_GLASSES ) strcpy(text, "Brille:"); + if ( num == RT_PERSO_HAIR ) strcpy(text, "Haarfarbe:"); + if ( num == RT_PERSO_COMBI ) strcpy(text, "Farbe des Anzugs:"); + if ( num == RT_PERSO_BAND ) strcpy(text, "Farbe der Streifen:"); + +#if _NEWLOOK + if ( num == RT_DIALOG_TITLE ) strcpy(text, "CeeBot"); + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Wollen Sie CeeBot schließen ?"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Schließen\\CeeBot schließen"); +#else + if ( num == RT_DIALOG_TITLE ) strcpy(text, "COLOBOT"); + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Wollen Sie COLOBOT schließen ?"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Schließen\\COLOBOT schließen"); +#endif + if ( num == RT_DIALOG_ABORT ) strcpy(text, "Mission abbrechen ?"); + if ( num == RT_DIALOG_YES ) strcpy(text, "Abbrechen\\Mission abbrechen"); + if ( num == RT_DIALOG_NO ) strcpy(text, "Weitermachen\\Mission weitermachen"); + if ( num == RT_DIALOG_NOQUIT ) strcpy(text, "Weitermachen\\Weitermachen"); + if ( num == RT_DIALOG_DELOBJ ) strcpy(text, "Wollen Sie das angewählte Gebäude wirklich zerstören ?"); + if ( num == RT_DIALOG_DELGAME ) strcpy(text, "Wollen Sie die gespeicherten Missionen von %s löschen ?"); + if ( num == RT_DIALOG_YESDEL ) strcpy(text, "Zerstören"); + if ( num == RT_DIALOG_NODEL ) strcpy(text, "Abbrechen"); + if ( num == RT_DIALOG_LOADING ) strcpy(text, "Laden"); + + if ( num == RT_STUDIO_LISTTT ) strcpy(text, "Hilfe über den Begriff (\\key cbot;)"); + if ( num == RT_STUDIO_COMPOK ) strcpy(text, "Kompilieren OK (0 Fehler)"); + if ( num == RT_STUDIO_PROGSTOP ) strcpy(text, "Programm beendet"); + + if ( num == RT_SATCOM_LIST ) strcpy(text, "\\b;Liste der Objekte\n"); + if ( num == RT_SATCOM_BOT ) strcpy(text, "\\b;Liste der Roboter\n"); + if ( num == RT_SATCOM_BUILDING ) strcpy(text, "\\b;Listes der Gebäude\n"); + if ( num == RT_SATCOM_FRET ) strcpy(text, "\\b;Listes der tragbaren Gegenstände\n"); + if ( num == RT_SATCOM_ALIEN ) strcpy(text, "\\b;Listes der Feinde\n"); + if ( num == RT_SATCOM_NULL ) strcpy(text, "\\c; (keine)\\n;\n"); + if ( num == RT_SATCOM_ERROR1 ) strcpy(text, "\\b;Fehler\n"); + if ( num == RT_SATCOM_ERROR2 ) strcpy(text, "Die Liste ist ohne \\l;Radar\\u object\\radar; nicht verfügbar !\n"); + + if ( num == RT_IO_OPEN ) strcpy(text, "Öffnen"); + if ( num == RT_IO_SAVE ) strcpy(text, "Speichern"); + if ( num == RT_IO_LIST ) strcpy(text, "Ordner: %s"); + if ( num == RT_IO_NAME ) strcpy(text, "Name:"); + if ( num == RT_IO_DIR ) strcpy(text, "In:"); + if ( num == RT_IO_PRIVATE ) strcpy(text, "Privat\\Privater Ordner"); + if ( num == RT_IO_PUBLIC ) strcpy(text, "Öffentlich\\Gemeinsamer Ordner für alle Spieler"); + + if ( num == RT_GENERIC_DEV1 ) strcpy(text, "Entwickelt von:"); + if ( num == RT_GENERIC_DEV2 ) strcpy(text, "www.epsitec.com"); +#if _WG + if ( num == RT_GENERIC_EDIT1 ) strcpy(text, "Herausgegeben von:"); + if ( num == RT_GENERIC_EDIT2 ) strcpy(text, "www.wg-verlag.ch"); +#else + if ( num == RT_GENERIC_EDIT1 ) strcpy(text, " "); + if ( num == RT_GENERIC_EDIT2 ) strcpy(text, " "); +#endif + + if ( num == RT_INTERFACE_REC ) strcpy(text, "Recorder"); + } + + if ( type == RES_EVENT ) + { + if ( num == EVENT_BUTTON_OK ) strcpy(text, "OK"); + if ( num == EVENT_BUTTON_CANCEL ) strcpy(text, "Abbrechen"); + if ( num == EVENT_BUTTON_NEXT ) strcpy(text, "Nächster"); + if ( num == EVENT_BUTTON_PREV ) strcpy(text, "Vorherg."); + if ( num == EVENT_BUTTON_QUIT ) strcpy(text, "Menü (\\key quit;)"); + + if ( num == EVENT_DIALOG_OK ) strcpy(text, "OK"); + if ( num == EVENT_DIALOG_CANCEL ) strcpy(text, "Abbrechen"); + +#if _SCHOOL + if ( num == EVENT_INTERFACE_TRAINER) strcpy(text, "Übungen\\Programmierübungen"); +#else + if ( num == EVENT_INTERFACE_TRAINER) strcpy(text, "Programmieren\\Programmierübungen"); +#endif + if ( num == EVENT_INTERFACE_DEFI ) strcpy(text, "Challenges\\Herausforderungen"); + if ( num == EVENT_INTERFACE_MISSION) strcpy(text, "Missionen\\Aufbruch ins Weltall"); + if ( num == EVENT_INTERFACE_FREE ) strcpy(text, "Freestyle\\Freies Spielen ohne vorgegebenes Ziel"); + if ( num == EVENT_INTERFACE_TEEN ) strcpy(text, "Freestyle\\Freies Spielen ohne vorgegebenes Ziel"); + if ( num == EVENT_INTERFACE_USER ) strcpy(text, "User\\Userlevels"); + if ( num == EVENT_INTERFACE_PROTO ) strcpy(text, "Proto\\In Entwicklung befindliche Prototypen"); + if ( num == EVENT_INTERFACE_NAME ) strcpy(text, "Anderer Spieler\\Spielername ändern"); + if ( num == EVENT_INTERFACE_SETUP ) strcpy(text, "Einstellungen\\Einstellungen"); + if ( num == EVENT_INTERFACE_AGAIN ) strcpy(text, "Neu anfangen\\Die Mission von vorne anfangen"); + if ( num == EVENT_INTERFACE_WRITE ) strcpy(text, "Speichern\\Aktuelle Mission speichern"); + if ( num == EVENT_INTERFACE_READ ) strcpy(text, "Laden\\Eine gespeicherte Mission öffnen"); +#if _NEWLOOK + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Zurück zu CeeBot"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Schließen\\CeeBot schließen"); +#else + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Zurück zu COLOBOT"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Schließen\\COLOBOT schließen"); +#endif + if ( num == EVENT_INTERFACE_BACK ) strcpy(text, "<< Zurück \\Zurück zum Hauptmenü"); + if ( num == EVENT_INTERFACE_PLAY ) strcpy(text, "Spielen ...\\Los geht's"); + if ( num == EVENT_INTERFACE_SETUPd ) strcpy(text, "Bildschirm\\Driver und Bildschirmauflösung"); + if ( num == EVENT_INTERFACE_SETUPg ) strcpy(text, "Grafik\\Grafische Einstellungen"); + if ( num == EVENT_INTERFACE_SETUPp ) strcpy(text, "Spiel\\Gameplay Einstellungen"); + if ( num == EVENT_INTERFACE_SETUPc ) strcpy(text, "Steuerung\\Auswahl der Tasten"); + if ( num == EVENT_INTERFACE_SETUPs ) strcpy(text, "Geräusche\\Lautstärke Geräusche und Musik"); + if ( num == EVENT_INTERFACE_DEVICE ) strcpy(text, "Einheit"); + if ( num == EVENT_INTERFACE_RESOL ) strcpy(text, "Auflösung"); + if ( num == EVENT_INTERFACE_FULL ) strcpy(text, "Vollbildschirm\\Vollbildschirm oder Fenster"); + if ( num == EVENT_INTERFACE_APPLY ) strcpy(text, "Änderungen ausführen\\Getätigte Einstellungen ausführen"); + + if ( num == EVENT_INTERFACE_TOTO ) strcpy(text, "Robby\\Ihr Assistent"); + if ( num == EVENT_INTERFACE_SHADOW ) strcpy(text, "Schatten\\Schlagschatten auf dem Boden"); + if ( num == EVENT_INTERFACE_GROUND ) strcpy(text, "Markierungen\\Markierungen auf dem Boden"); + if ( num == EVENT_INTERFACE_DIRTY ) strcpy(text, "Schmutz\\Schmutz auf Robotern und Bauten"); + if ( num == EVENT_INTERFACE_FOG ) strcpy(text, "Nebel\\Nebelschwaden"); + if ( num == EVENT_INTERFACE_LENS ) strcpy(text, "Sonnenstrahlen\\Sonnenstrahlen"); + if ( num == EVENT_INTERFACE_SKY ) strcpy(text, "Himmel\\Himmel und Wolken"); + if ( num == EVENT_INTERFACE_PLANET ) strcpy(text, "Planeten und Sterne\\Kreisende Planeten und Sterne"); + if ( num == EVENT_INTERFACE_LIGHT ) strcpy(text, "Dynamische Beleuchtung\\Dynamische Beleuchtung"); + if ( num == EVENT_INTERFACE_PARTI ) strcpy(text, "Anzahl Partikel\\Explosionen, Staub, usw."); + if ( num == EVENT_INTERFACE_CLIP ) strcpy(text, "Sichtweite\\Maximale Sichtweite"); + if ( num == EVENT_INTERFACE_DETAIL ) strcpy(text, "Details\\Detailliertheit der Objekte in 3D"); + if ( num == EVENT_INTERFACE_TEXTURE) strcpy(text, "Qualität der Texturen\\Qualität der Anzeige"); + if ( num == EVENT_INTERFACE_GADGET ) strcpy(text, "Anzahl Ziergegenstände\\Anzahl Gegenstände ohne Funktion"); + if ( num == EVENT_INTERFACE_RAIN ) strcpy(text, "Partikel in den Menüs\\Funken und Sterne in den Menüs"); + if ( num == EVENT_INTERFACE_GLINT ) strcpy(text, "Glänzende Tasten\\Glänzende Tasten in den Menüs"); + if ( num == EVENT_INTERFACE_TOOLTIP) strcpy(text, "Hilfsblasen\\Hilfsblasen"); + if ( num == EVENT_INTERFACE_MOVIES ) strcpy(text, "Filme\\Filme vor und nach den Missionen"); + if ( num == EVENT_INTERFACE_NICERST) strcpy(text, "Zurücksetzen \\Kleine Show beim Zurücksetzen in den Übungen"); + if ( num == EVENT_INTERFACE_HIMSELF) strcpy(text, "Eigenbeschuss\\Ihre Einheiten werden von Ihren Waffen beschädigt."); + if ( num == EVENT_INTERFACE_SCROLL ) strcpy(text, "Kameradrehung mit der Maus\\Die Kamera dreht wenn die Maus den Rand erreicht"); + if ( num == EVENT_INTERFACE_INVERTX) strcpy(text, "Umkehr X\\Umkehr der Kameradrehung X-Achse"); + if ( num == EVENT_INTERFACE_INVERTY) strcpy(text, "Umkehr Y\\Umkehr der Kameradrehung Y-Achse"); + if ( num == EVENT_INTERFACE_EFFECT ) strcpy(text, "Beben bei Explosionen\\Die Kamera bebt bei Explosionen"); + if ( num == EVENT_INTERFACE_MOUSE ) strcpy(text, "Schatten unter der Maus\\Ein Schatten erscheint unter der Maus"); + if ( num == EVENT_INTERFACE_EDITMODE) strcpy(text, "Automatisches Einrücken\\Beim Bearbeiten der Programme"); + if ( num == EVENT_INTERFACE_EDITVALUE)strcpy(text, "Einrücken mit 4 Leerstellen\\Einrücken mit 2 oder 4 Leerstellen"); + if ( num == EVENT_INTERFACE_SOLUCE4) strcpy(text, "Lösung zugänglich\\Die Lösung ist im Programmslot \"4: Lösung\" zugänglich"); + + if ( num == EVENT_INTERFACE_KDEF ) strcpy(text, "Alles zurücksetzen\\Standarddefinition aller Tasten"); + if ( num == EVENT_INTERFACE_KLEFT ) strcpy(text, "Drehung nach links\\Steuer links"); + if ( num == EVENT_INTERFACE_KRIGHT ) strcpy(text, "Drehung nach rechts\\Steuer rechts"); + if ( num == EVENT_INTERFACE_KUP ) strcpy(text, "Vorwärts\\Bewegung nach vorne"); + if ( num == EVENT_INTERFACE_KDOWN ) strcpy(text, "Rückwärts\\Bewegung nach hinten"); + if ( num == EVENT_INTERFACE_KGUP ) strcpy(text, "Steigen\\Leistung des Triebwerks steigern"); + if ( num == EVENT_INTERFACE_KGDOWN ) strcpy(text, "Sinken\\Leistung des Triebwerks drosseln"); + if ( num == EVENT_INTERFACE_KCAMERA) strcpy(text, "Andere Kamera\\Sichtpunkt einstellen"); + if ( num == EVENT_INTERFACE_KDESEL ) strcpy(text, "Vorherg. Auswahl\\Das vorhergehende Objekt auswählen"); + if ( num == EVENT_INTERFACE_KACTION) strcpy(text, "Standardhandlung\\Führt die Standardhandlung des Roboters aus."); + if ( num == EVENT_INTERFACE_KNEAR ) strcpy(text, "Kamera näher\\Bewegung der Kamera vorwärts"); + if ( num == EVENT_INTERFACE_KAWAY ) strcpy(text, "Kamera weiter\\Bewegung der Kamera rückwärts"); + if ( num == EVENT_INTERFACE_KNEXT ) strcpy(text, "Nächstes auswählen\\Nächstes Objekt auswählen"); + if ( num == EVENT_INTERFACE_KHUMAN ) strcpy(text, "Astronauten auswählen\\Astronauten auswählen"); + if ( num == EVENT_INTERFACE_KQUIT ) strcpy(text, "Mission verlassen\\Eine Mission oder Übung verlassen"); + if ( num == EVENT_INTERFACE_KHELP ) strcpy(text, "Anweisungen\\Anweisungen für die Mission oder Übung"); + if ( num == EVENT_INTERFACE_KPROG ) strcpy(text, "Hilfe CBOT-Sprache\\Hilfe über die Programmiersprache CBOT"); + if ( num == EVENT_INTERFACE_KCBOT ) strcpy(text, "Hilfe über Begriff\\Hilfe über einen Begriff"); + if ( num == EVENT_INTERFACE_KVISIT ) strcpy(text, "Ort der Meldung\\Zeigt den Ort, von dem die letzte Meldung stammt"); + if ( num == EVENT_INTERFACE_KSPEED10) strcpy(text, "Geschwindigkeit 1.0x\\Normale Spielgeschwindigkeit"); + if ( num == EVENT_INTERFACE_KSPEED15) strcpy(text, "Geschwindigkeit 1.5x\\Spielgeschwindigkeit anderthalb Mal schneller"); + if ( num == EVENT_INTERFACE_KSPEED20) strcpy(text, "Geschwindigkeit 2.0x\\Spielgeschwindigkeit doppelt so schnell"); + if ( num == EVENT_INTERFACE_KSPEED30) strcpy(text, "Geschwindigkeit 3.0x\\Spielgeschwindigkeit drei Mal schneller"); + + if ( num == EVENT_INTERFACE_VOLSOUND) strcpy(text, "Geräusche:\\Lautstärke Motoren, Stimmen, usw."); + if ( num == EVENT_INTERFACE_VOLMUSIC) strcpy(text, "Geräuschkulisse:\\Lautstärke der Soundtracks der CD"); + if ( num == EVENT_INTERFACE_SOUND3D) strcpy(text, "3D-Geräusche\\Orten der Geräusche im Raum"); + + if ( num == EVENT_INTERFACE_MIN ) strcpy(text, "Min.\\Minimale Qualität (großes Framerate)"); + if ( num == EVENT_INTERFACE_NORM ) strcpy(text, "Normal\\Standardqualität"); + if ( num == EVENT_INTERFACE_MAX ) strcpy(text, "Max.\\Beste Qualität (niedriges Framerate)"); + + if ( num == EVENT_INTERFACE_SILENT ) strcpy(text, "Kein Ton\\Keine Geräusche und Geräuschkulisse"); + if ( num == EVENT_INTERFACE_NOISY ) strcpy(text, "Normal\\Normale Lautstärke"); + + if ( num == EVENT_INTERFACE_JOYSTICK) strcpy(text, "Joystick\\Joystick oder Tastatur"); + if ( num == EVENT_INTERFACE_SOLUCE ) strcpy(text, "Zeigt die Lösung\\Zeigt nach 3mal Scheitern die Lösung"); + + if ( num == EVENT_INTERFACE_NEDIT ) strcpy(text, "\\Name des Spielers"); + if ( num == EVENT_INTERFACE_NOK ) strcpy(text, "OK\\Spieler auswählen"); + if ( num == EVENT_INTERFACE_NCANCEL) strcpy(text, "Abbrechen\\Behält den bisherigen Spieler bei"); + if ( num == EVENT_INTERFACE_NDELETE) strcpy(text, "Spieler löschen\\Löscht den Spieler aus der Liste"); + if ( num == EVENT_INTERFACE_NLABEL ) strcpy(text, "Name "); + + if ( num == EVENT_INTERFACE_IOWRITE) strcpy(text, "Speichern\\Speichert die Mission"); + if ( num == EVENT_INTERFACE_IOREAD ) strcpy(text, "Laden\\Öffnet eine gespeicherte Mission"); + if ( num == EVENT_INTERFACE_IOLIST ) strcpy(text, "Liste der gespeicherten Missionen"); + if ( num == EVENT_INTERFACE_IOLABEL) strcpy(text, "Dateiname:"); + if ( num == EVENT_INTERFACE_IONAME ) strcpy(text, "Name der Mission"); + if ( num == EVENT_INTERFACE_IOIMAGE) strcpy(text, "Ansicht der Mission"); + if ( num == EVENT_INTERFACE_IODELETE) strcpy(text, "Löschen\\Löscht die gespeicherte Mission"); + + if ( num == EVENT_INTERFACE_PERSO ) strcpy(text, "Aussehen\\Erscheinungsbild des Astronauten einstellen"); + if ( num == EVENT_INTERFACE_POK ) strcpy(text, "OK"); + if ( num == EVENT_INTERFACE_PCANCEL) strcpy(text, "Abbrechen"); + if ( num == EVENT_INTERFACE_PDEF ) strcpy(text, "Standard\\Standardfarben einsetzen"); + if ( num == EVENT_INTERFACE_PHEAD ) strcpy(text, "Kopf\\Gesicht und Haare"); + if ( num == EVENT_INTERFACE_PBODY ) strcpy(text, "Anzug\\Raumfahrtanzug"); + if ( num == EVENT_INTERFACE_PLROT ) strcpy(text, "\\Drehung links"); + if ( num == EVENT_INTERFACE_PRROT ) strcpy(text, "\\Drehung rechts"); + if ( num == EVENT_INTERFACE_PCRa ) strcpy(text, "Rot"); + if ( num == EVENT_INTERFACE_PCGa ) strcpy(text, "Grün"); + if ( num == EVENT_INTERFACE_PCBa ) strcpy(text, "Blau"); + if ( num == EVENT_INTERFACE_PCRb ) strcpy(text, "Rot"); + if ( num == EVENT_INTERFACE_PCGb ) strcpy(text, "Grün"); + if ( num == EVENT_INTERFACE_PCBb ) strcpy(text, "Blau"); + if ( num == EVENT_INTERFACE_PFACE1 ) strcpy(text, "\\Kopf 1"); + if ( num == EVENT_INTERFACE_PFACE2 ) strcpy(text, "\\Kopf 4"); + if ( num == EVENT_INTERFACE_PFACE3 ) strcpy(text, "\\Kopf 3"); + if ( num == EVENT_INTERFACE_PFACE4 ) strcpy(text, "\\Kopf 2"); + if ( num == EVENT_INTERFACE_PGLASS0) strcpy(text, "\\Keine Brille"); + if ( num == EVENT_INTERFACE_PGLASS1) strcpy(text, "\\Brille 1"); + if ( num == EVENT_INTERFACE_PGLASS2) strcpy(text, "\\Brille 2"); + if ( num == EVENT_INTERFACE_PGLASS3) strcpy(text, "\\Brille 3"); + if ( num == EVENT_INTERFACE_PGLASS4) strcpy(text, "\\Brille 4"); + if ( num == EVENT_INTERFACE_PGLASS5) strcpy(text, "\\Brille 5"); + + if ( num == EVENT_OBJECT_DESELECT ) strcpy(text, "Vorherg. Auwahl (\\key desel;)"); + if ( num == EVENT_OBJECT_LEFT ) strcpy(text, "Drehung links (\\key left;)"); + if ( num == EVENT_OBJECT_RIGHT ) strcpy(text, "Drehung rechts (\\key right;)"); + if ( num == EVENT_OBJECT_UP ) strcpy(text, "Vorwärts (\\key up;)"); + if ( num == EVENT_OBJECT_DOWN ) strcpy(text, "Rückwärts (\\key down;)"); + if ( num == EVENT_OBJECT_GASUP ) strcpy(text, "Steigt (\\key gup;)"); + if ( num == EVENT_OBJECT_GASDOWN ) strcpy(text, "Sinkt (\\key gdown;)"); + if ( num == EVENT_OBJECT_HTAKE ) strcpy(text, "Nehmen oder hinlegen (\\key action;)"); + if ( num == EVENT_OBJECT_MTAKE ) strcpy(text, "Nehmen oder hinlegen (\\key action;)"); + if ( num == EVENT_OBJECT_MFRONT ) strcpy(text, "..vorne"); + if ( num == EVENT_OBJECT_MBACK ) strcpy(text, "..hinten"); + if ( num == EVENT_OBJECT_MPOWER ) strcpy(text, "..Batterie"); + if ( num == EVENT_OBJECT_BHELP ) strcpy(text, "Anweisungen über die Mission(\\key help;)"); + if ( num == EVENT_OBJECT_BTAKEOFF ) strcpy(text, "Abheben nach vollbrachter Mission"); + if ( num == EVENT_OBJECT_BDERRICK ) strcpy(text, "Baut einen Bohrturm"); + if ( num == EVENT_OBJECT_BSTATION ) strcpy(text, "Baut ein Kraftwerk"); + if ( num == EVENT_OBJECT_BFACTORY ) strcpy(text, "Baut eine Roboterfabrik"); + if ( num == EVENT_OBJECT_BREPAIR ) strcpy(text, "Baut ein Reparaturzentrum"); + if ( num == EVENT_OBJECT_BCONVERT ) strcpy(text, "Baut einen Konverter"); + if ( num == EVENT_OBJECT_BTOWER ) strcpy(text, "Baut einen Geschützturm"); + if ( num == EVENT_OBJECT_BRESEARCH ) strcpy(text, "Baut ein Forschungszentrum"); + if ( num == EVENT_OBJECT_BRADAR ) strcpy(text, "Baut ein Radar"); + if ( num == EVENT_OBJECT_BENERGY ) strcpy(text, "Baut eine Batteriefabrik"); + if ( num == EVENT_OBJECT_BLABO ) strcpy(text, "Baut ein automatisches Labor"); + if ( num == EVENT_OBJECT_BNUCLEAR ) strcpy(text, "Baut eine Brennstoffzellenfabrik"); + if ( num == EVENT_OBJECT_BPARA ) strcpy(text, "Baut einen Blitzableiter"); + if ( num == EVENT_OBJECT_BINFO ) strcpy(text, "Baut einen Infoserver"); + if ( num == EVENT_OBJECT_GFLAT ) strcpy(text, "Zeigt ob der Boden eben ist"); + if ( num == EVENT_OBJECT_FCREATE ) strcpy(text, "Setzt eine Fahne"); + if ( num == EVENT_OBJECT_FDELETE ) strcpy(text, "Sammelt die Fahne ein"); + if ( num == EVENT_OBJECT_FCOLORb ) strcpy(text, "\\Blaue Fahne"); + if ( num == EVENT_OBJECT_FCOLORr ) strcpy(text, "\\Rote Fahne"); + if ( num == EVENT_OBJECT_FCOLORg ) strcpy(text, "\\Grüne Fahne"); + if ( num == EVENT_OBJECT_FCOLORy ) strcpy(text, "\\Gelbe Fahne"); + if ( num == EVENT_OBJECT_FCOLORv ) strcpy(text, "\\Violette Fahne"); + if ( num == EVENT_OBJECT_FACTORYfa ) strcpy(text, "Baut einen Jettransporter"); + if ( num == EVENT_OBJECT_FACTORYta ) strcpy(text, "Baut einen Kettentransporter"); + if ( num == EVENT_OBJECT_FACTORYwa ) strcpy(text, "Baut einen Radtransporter"); + if ( num == EVENT_OBJECT_FACTORYia ) strcpy(text, "Baut einen Krabbeltransporter"); + if ( num == EVENT_OBJECT_FACTORYfc ) strcpy(text, "Baut einen Jetshooter"); + if ( num == EVENT_OBJECT_FACTORYtc ) strcpy(text, "Baut einen Kettenshooter"); + if ( num == EVENT_OBJECT_FACTORYwc ) strcpy(text, "Baut einen Radshooter"); + if ( num == EVENT_OBJECT_FACTORYic ) strcpy(text, "Baut einen Krabbelshooter"); + if ( num == EVENT_OBJECT_FACTORYfi ) strcpy(text, "Baut einen Jetorgashooter"); + if ( num == EVENT_OBJECT_FACTORYti ) strcpy(text, "Baut einen Kettenorgashooter"); + if ( num == EVENT_OBJECT_FACTORYwi ) strcpy(text, "Baut einen Radorgashooter"); + if ( num == EVENT_OBJECT_FACTORYii ) strcpy(text, "Baut einen Krabbelorgashooter"); + if ( num == EVENT_OBJECT_FACTORYfs ) strcpy(text, "Baut einen Jetschnüffler"); + if ( num == EVENT_OBJECT_FACTORYts ) strcpy(text, "Baut einen Kettenschnüffler"); + if ( num == EVENT_OBJECT_FACTORYws ) strcpy(text, "Baut einen Radschnüffler"); + if ( num == EVENT_OBJECT_FACTORYis ) strcpy(text, "Baut einen Krabbelschnüffler"); + if ( num == EVENT_OBJECT_FACTORYrt ) strcpy(text, "Baut einen Stampfer"); + if ( num == EVENT_OBJECT_FACTORYrc ) strcpy(text, "Baut einen Phazershooter"); + if ( num == EVENT_OBJECT_FACTORYrr ) strcpy(text, "Baut einen Recycler"); + if ( num == EVENT_OBJECT_FACTORYrs ) strcpy(text, "Baut einen Schutzschild"); + if ( num == EVENT_OBJECT_FACTORYsa ) strcpy(text, "Baut einen Kettentaucher"); + if ( num == EVENT_OBJECT_RTANK ) strcpy(text, "Forschungsprogramm Kettenantrieb"); + if ( num == EVENT_OBJECT_RFLY ) strcpy(text, "Forschungsprogramm Jetantrieb"); + if ( num == EVENT_OBJECT_RTHUMP ) strcpy(text, "Forschungsprogramm Stampfer"); + if ( num == EVENT_OBJECT_RCANON ) strcpy(text, "Forschungsprogramm Shooterkanone"); + if ( num == EVENT_OBJECT_RTOWER ) strcpy(text, "Forschungsprogramm Geschützturm"); + if ( num == EVENT_OBJECT_RPHAZER ) strcpy(text, "Forschungsprogramm Phazerkanone"); + if ( num == EVENT_OBJECT_RSHIELD ) strcpy(text, "Forschungsprogramm Schutzschild"); + if ( num == EVENT_OBJECT_RATOMIC ) strcpy(text, "Forschungsprogramm Brennstoffzelle"); + if ( num == EVENT_OBJECT_RiPAW ) strcpy(text, "Forschungsprogramm Krabbelantrieb"); + if ( num == EVENT_OBJECT_RiGUN ) strcpy(text, "Forschungsprogramm Orgashooterkanone"); + if ( num == EVENT_OBJECT_RESET ) strcpy(text, "Alles zurücksetzen"); + if ( num == EVENT_OBJECT_SEARCH ) strcpy(text, "Schnüffeln (\\key action;)"); + if ( num == EVENT_OBJECT_TERRAFORM ) strcpy(text, "Stampfen (\\key action;)"); + if ( num == EVENT_OBJECT_FIRE ) strcpy(text, "Feuer (\\key action;)"); + if ( num == EVENT_OBJECT_RECOVER ) strcpy(text, "Recyceln (\\key action;)"); + if ( num == EVENT_OBJECT_BEGSHIELD ) strcpy(text, "Schutzschild ausfahren (\\key action;)"); + if ( num == EVENT_OBJECT_ENDSHIELD ) strcpy(text, "Schutzschild einholen (\\key action;)"); + if ( num == EVENT_OBJECT_DIMSHIELD ) strcpy(text, "Reichweite Schutzschild"); + if ( num == EVENT_OBJECT_PROGRUN ) strcpy(text, "Gewähltes Programm ausführen"); + if ( num == EVENT_OBJECT_PROGEDIT ) strcpy(text, "Gewähltes Programm bearbeiten"); + if ( num == EVENT_OBJECT_INFOOK ) strcpy(text, "\\SatCom in Standby"); + if ( num == EVENT_OBJECT_DELETE ) strcpy(text, "Gebäude sprengen"); + if ( num == EVENT_OBJECT_GENERGY ) strcpy(text, "Energievorrat"); + if ( num == EVENT_OBJECT_GSHIELD ) strcpy(text, "Schäden"); + if ( num == EVENT_OBJECT_GRANGE ) strcpy(text, "Triebwerktemperatur"); + if ( num == EVENT_OBJECT_GPROGRESS ) strcpy(text, "Prozess im Gang ..."); + if ( num == EVENT_OBJECT_GRADAR ) strcpy(text, "Anzahl erfasster Insekten"); + if ( num == EVENT_OBJECT_GINFO ) strcpy(text, "Gesendete Informationen"); + if ( num == EVENT_OBJECT_COMPASS ) strcpy(text, "Kompass"); +//? if ( num == EVENT_OBJECT_MAP ) strcpy(text, "Minikarte"); + if ( num == EVENT_OBJECT_MAPZOOM ) strcpy(text, "Zoom Minikarte"); + if ( num == EVENT_OBJECT_CAMERA ) strcpy(text, "Kamera (\\key camera;)"); + if ( num == EVENT_OBJECT_CAMERAleft) strcpy(text, "Kamera links"); + if ( num == EVENT_OBJECT_CAMERAright) strcpy(text, "Kamera rechts"); + if ( num == EVENT_OBJECT_CAMERAnear) strcpy(text, "Kamera näher"); + if ( num == EVENT_OBJECT_CAMERAaway) strcpy(text, "Kamera weiter weg"); + if ( num == EVENT_OBJECT_HELP ) strcpy(text, "Anweisungen über das ausgewählte Objekt"); + if ( num == EVENT_OBJECT_SOLUCE ) strcpy(text, "Zeigt die Lösung"); + if ( num == EVENT_OBJECT_SHORTCUT00) strcpy(text, "Anzeige Roboter <-> Bauten"); + if ( num == EVENT_OBJECT_LIMIT ) strcpy(text, "Zeigt die Reichweite"); + if ( num == EVENT_OBJECT_PEN0 ) strcpy(text, "\\Bleistift abheben"); + if ( num == EVENT_OBJECT_PEN1 ) strcpy(text, "\\Schwarzen Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_PEN2 ) strcpy(text, "\\Gelben Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_PEN3 ) strcpy(text, "\\Orangefarbenen Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_PEN4 ) strcpy(text, "\\Roten Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_PEN5 ) strcpy(text, "\\Violetten Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_PEN6 ) strcpy(text, "\\Blauen Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_PEN7 ) strcpy(text, "\\Grünen Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_PEN8 ) strcpy(text, "\\Braunen Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_REC ) strcpy(text, "\\Aufnahme starten"); + if ( num == EVENT_OBJECT_STOP ) strcpy(text, "\\Aufnahme stoppen"); + if ( num == EVENT_DT_VISIT0 || + num == EVENT_DT_VISIT1 || + num == EVENT_DT_VISIT2 || + num == EVENT_DT_VISIT3 || + num == EVENT_DT_VISIT4 ) strcpy(text, "Zeigt den Ort"); + if ( num == EVENT_DT_END ) strcpy(text, "Weitermachen"); + if ( num == EVENT_CMD ) strcpy(text, "Befehleingabe"); + if ( num == EVENT_SPEED ) strcpy(text, "Spielgeschwindigkeit"); + + if ( num == EVENT_HYPER_PREV ) strcpy(text, "Vorherg. Seite"); + if ( num == EVENT_HYPER_NEXT ) strcpy(text, "Nächste Seite"); + if ( num == EVENT_HYPER_HOME ) strcpy(text, "Home"); + if ( num == EVENT_HYPER_COPY ) strcpy(text, "Kopieren"); + if ( num == EVENT_HYPER_SIZE1 ) strcpy(text, "Größe 1"); + if ( num == EVENT_HYPER_SIZE2 ) strcpy(text, "Größe 2"); + if ( num == EVENT_HYPER_SIZE3 ) strcpy(text, "Größe 3"); + if ( num == EVENT_HYPER_SIZE4 ) strcpy(text, "Größe 4"); + if ( num == EVENT_HYPER_SIZE5 ) strcpy(text, "Größe 5"); + if ( num == EVENT_SATCOM_HUSTON ) strcpy(text, "Anweisungen von Houston"); +#if _TEEN + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Wörterbuch Englisch-Deutsch"); +#else + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Satellitenbericht"); +#endif + if ( num == EVENT_SATCOM_LOADING ) strcpy(text, "Von Houston übermittelte Programme"); + if ( num == EVENT_SATCOM_OBJECT ) strcpy(text, "Liste der Objekte"); + if ( num == EVENT_SATCOM_PROG ) strcpy(text, "Hilfe über Programmieren"); + if ( num == EVENT_SATCOM_SOLUCE ) strcpy(text, "Lösung"); + + if ( num == EVENT_STUDIO_OK ) strcpy(text, "OK\\Programm kompilieren"); + if ( num == EVENT_STUDIO_CANCEL ) strcpy(text, "Abbrechen\\Editor schließen"); + if ( num == EVENT_STUDIO_NEW ) strcpy(text, "Neu"); + if ( num == EVENT_STUDIO_OPEN ) strcpy(text, "Öffnen (Ctrl+o)"); + if ( num == EVENT_STUDIO_SAVE ) strcpy(text, "Speichern (Ctrl+s)"); + if ( num == EVENT_STUDIO_UNDO ) strcpy(text, "Widerrufen (Ctrl+z)"); + if ( num == EVENT_STUDIO_CUT ) strcpy(text, "Ausschneiden (Ctrl+x)"); + if ( num == EVENT_STUDIO_COPY ) strcpy(text, "Kopieren (Ctrl+c)"); + if ( num == EVENT_STUDIO_PASTE ) strcpy(text, "Einfügen (Ctrl+v)"); + if ( num == EVENT_STUDIO_SIZE ) strcpy(text, "Zeichengröße"); + if ( num == EVENT_STUDIO_TOOL ) strcpy(text, "Anweisungen (\\key help;)"); + if ( num == EVENT_STUDIO_HELP ) strcpy(text, "Hilfe über Programmieren (\\key prog;)"); + if ( num == EVENT_STUDIO_COMPILE ) strcpy(text, "Kompilieren"); + if ( num == EVENT_STUDIO_RUN ) strcpy(text, "Start/Stop"); + if ( num == EVENT_STUDIO_REALTIME ) strcpy(text, "Pause/Weitermachen"); + if ( num == EVENT_STUDIO_STEP ) strcpy(text, "Ein Schritt"); + } + + if ( type == RES_OBJECT ) + { + if ( num == OBJECT_PORTICO ) strcpy(text, "Träger"); + if ( num == OBJECT_BASE ) strcpy(text, "Raumschiff"); + if ( num == OBJECT_DERRICK ) strcpy(text, "Bohrturm"); + if ( num == OBJECT_FACTORY ) strcpy(text, "Roboterfabrik"); + if ( num == OBJECT_REPAIR ) strcpy(text, "Reparaturzentrum"); + if ( num == OBJECT_DESTROYER ) strcpy(text, "Einstampfer"); + if ( num == OBJECT_STATION ) strcpy(text, "Kraftwerk"); + if ( num == OBJECT_CONVERT ) strcpy(text, "Konverter Erz-Titan"); + if ( num == OBJECT_TOWER ) strcpy(text, "Geschützturm"); + if ( num == OBJECT_NEST ) strcpy(text, "Orgastoffquelle"); + if ( num == OBJECT_RESEARCH ) strcpy(text, "Forschungszentrum"); + if ( num == OBJECT_RADAR ) strcpy(text, "Radar"); + if ( num == OBJECT_INFO ) strcpy(text, "Infoserver"); +#if _TEEN + if ( num == OBJECT_ENERGY ) strcpy(text, "Auflöser"); +#else + if ( num == OBJECT_ENERGY ) strcpy(text, "Batteriefabrik"); +#endif + if ( num == OBJECT_LABO ) strcpy(text, "Automatisches Labor"); + if ( num == OBJECT_NUCLEAR ) strcpy(text, "Brennstoffzellenfabrik"); + if ( num == OBJECT_PARA ) strcpy(text, "Blitzableiter"); + if ( num == OBJECT_SAFE ) strcpy(text, "Bunker"); + if ( num == OBJECT_HUSTON ) strcpy(text, "Kontrollzentrum"); + if ( num == OBJECT_TARGET1 ) strcpy(text, "Zielscheibe"); + if ( num == OBJECT_TARGET2 ) strcpy(text, "Zielscheibe"); + if ( num == OBJECT_START ) strcpy(text, "Startfläche"); + if ( num == OBJECT_END ) strcpy(text, "Zielfläche"); + if ( num == OBJECT_STONE ) strcpy(text, "Titanerz"); + if ( num == OBJECT_URANIUM ) strcpy(text, "Platinerz"); + if ( num == OBJECT_BULLET ) strcpy(text, "Orgastoff"); + if ( num == OBJECT_METAL ) strcpy(text, "Titan"); + if ( num == OBJECT_POWER ) strcpy(text, "Elektrolytische Batterie"); + if ( num == OBJECT_ATOMIC ) strcpy(text, "Brennstoffzelle"); + if ( num == OBJECT_BBOX ) strcpy(text, "Flugschreiber"); + if ( num == OBJECT_KEYa ) strcpy(text, "Schlüssel A"); + if ( num == OBJECT_KEYb ) strcpy(text, "Schlüssel B"); + if ( num == OBJECT_KEYc ) strcpy(text, "Schlüssel C"); + if ( num == OBJECT_KEYd ) strcpy(text, "Schlüssel D"); + if ( num == OBJECT_TNT ) strcpy(text, "Sprengstoff"); + if ( num == OBJECT_BOMB ) strcpy(text, "Landmine"); + if ( num == OBJECT_BAG ) strcpy(text, "Überlebenskit"); + if ( num == OBJECT_WAYPOINT ) strcpy(text, "Checkpoint"); + if ( num == OBJECT_FLAGb ) strcpy(text, "Blaue Fahne"); + if ( num == OBJECT_FLAGr ) strcpy(text, "Rote Fahne"); + if ( num == OBJECT_FLAGg ) strcpy(text, "Grüne Fahne"); + if ( num == OBJECT_FLAGy ) strcpy(text, "Gelbe Fahne"); + if ( num == OBJECT_FLAGv ) strcpy(text, "Violette Fahne"); + if ( num == OBJECT_MARKPOWER ) strcpy(text, "Markierung für unterirdische Energiequelle"); + if ( num == OBJECT_MARKURANIUM ) strcpy(text, "Markierung für unterirdisches Platinvorkommen"); + if ( num == OBJECT_MARKKEYa ) strcpy(text, "Markierung für vergrabenen Schlüssel A"); + if ( num == OBJECT_MARKKEYb ) strcpy(text, "Markierung für vergrabenen Schlüssel B"); + if ( num == OBJECT_MARKKEYc ) strcpy(text, "Markierung für vergrabenen Schlüssel C"); + if ( num == OBJECT_MARKKEYd ) strcpy(text, "Markierung für vergrabenen Schlüssel D"); + if ( num == OBJECT_MARKSTONE ) strcpy(text, "Markierung für unterirdisches Titanvorkommen"); + if ( num == OBJECT_MOBILEft ) strcpy(text, "Übungsroboter"); + if ( num == OBJECT_MOBILEtt ) strcpy(text, "Übungsroboter"); + if ( num == OBJECT_MOBILEwt ) strcpy(text, "Übungsroboter"); + if ( num == OBJECT_MOBILEit ) strcpy(text, "Übungsroboter"); + if ( num == OBJECT_MOBILEfa ) strcpy(text, "Transporter"); + if ( num == OBJECT_MOBILEta ) strcpy(text, "Transporter"); + if ( num == OBJECT_MOBILEwa ) strcpy(text, "Transporter"); + if ( num == OBJECT_MOBILEia ) strcpy(text, "Transporter"); + if ( num == OBJECT_MOBILEfc ) strcpy(text, "Shooter"); + if ( num == OBJECT_MOBILEtc ) strcpy(text, "Shooter"); + if ( num == OBJECT_MOBILEwc ) strcpy(text, "Shooter"); + if ( num == OBJECT_MOBILEic ) strcpy(text, "Shooter"); + if ( num == OBJECT_MOBILEfi ) strcpy(text, "OrgaShooter"); + if ( num == OBJECT_MOBILEti ) strcpy(text, "OrgaShooter"); + if ( num == OBJECT_MOBILEwi ) strcpy(text, "OrgaShooter"); + if ( num == OBJECT_MOBILEii ) strcpy(text, "OrgaShooter"); + if ( num == OBJECT_MOBILEfs ) strcpy(text, "Schnüffler"); + if ( num == OBJECT_MOBILEts ) strcpy(text, "Schnüffler"); + if ( num == OBJECT_MOBILEws ) strcpy(text, "Schnüffler"); + if ( num == OBJECT_MOBILEis ) strcpy(text, "Schnüffler"); + if ( num == OBJECT_MOBILErt ) strcpy(text, "Stampfer"); + if ( num == OBJECT_MOBILErc ) strcpy(text, "Phazershooter"); + if ( num == OBJECT_MOBILErr ) strcpy(text, "Recycler"); + if ( num == OBJECT_MOBILErs ) strcpy(text, "Schutzschild"); + if ( num == OBJECT_MOBILEsa ) strcpy(text, "Kettentaucher"); + if ( num == OBJECT_MOBILEtg ) strcpy(text, "Mobile Zielscheibe"); + if ( num == OBJECT_MOBILEdr ) strcpy(text, "Zeichner"); + if ( num == OBJECT_HUMAN ) strcpy(text, g_gamerName); + if ( num == OBJECT_TECH ) strcpy(text, "Techniker"); + if ( num == OBJECT_TOTO ) strcpy(text, "Robby"); + if ( num == OBJECT_MOTHER ) strcpy(text, "Insektenkönigin"); + if ( num == OBJECT_ANT ) strcpy(text, "Ameise"); + if ( num == OBJECT_SPIDER ) strcpy(text, "Spinne"); + if ( num == OBJECT_BEE ) strcpy(text, "Wespe"); + if ( num == OBJECT_WORM ) strcpy(text, "Wurm"); + if ( num == OBJECT_EGG ) strcpy(text, "Ei"); + if ( num == OBJECT_RUINmobilew1 ) strcpy(text, "Roboterwrack"); + if ( num == OBJECT_RUINmobilew2 ) strcpy(text, "Roboterwrack"); + if ( num == OBJECT_RUINmobilet1 ) strcpy(text, "Roboterwrack"); + if ( num == OBJECT_RUINmobilet2 ) strcpy(text, "Roboterwrack"); + if ( num == OBJECT_RUINmobiler1 ) strcpy(text, "Roboterwrack"); + if ( num == OBJECT_RUINmobiler2 ) strcpy(text, "Roboterwrack"); + if ( num == OBJECT_RUINfactory ) strcpy(text, "Gebäuderuine"); + if ( num == OBJECT_RUINdoor ) strcpy(text, "Gebäuderuine"); + if ( num == OBJECT_RUINsupport ) strcpy(text, "Abfall"); + if ( num == OBJECT_RUINradar ) strcpy(text, "Gebäuderuine"); + if ( num == OBJECT_RUINconvert ) strcpy(text, "Gebäuderuine"); + if ( num == OBJECT_RUINbase ) strcpy(text, "Raumschiffruine"); + if ( num == OBJECT_RUINhead ) strcpy(text, "Raumschiffruine"); + if ( num == OBJECT_APOLLO1 || + num == OBJECT_APOLLO3 || + num == OBJECT_APOLLO4 || + num == OBJECT_APOLLO5 ) strcpy(text, "Überreste einer Apollo-Mission"); + if ( num == OBJECT_APOLLO2 ) strcpy(text, "Lunar Roving Vehicle"); + } + + if ( type == RES_ERR ) + { + strcpy(text, "Fehler"); + if ( num == ERR_CMD ) strcpy(text, "Befehl unbekannt"); +#if _NEWLOOK + if ( num == ERR_INSTALL ) strcpy(text, "CeeBot wurde nicht installiert."); + if ( num == ERR_NOCD ) strcpy(text, "Legen Sie die CeeBot-CD ein\nund starten Sie das Spiel neu."); +#else + if ( num == ERR_INSTALL ) strcpy(text, "COLOBOT wurde nicht installiert."); + if ( num == ERR_NOCD ) strcpy(text, "Legen Sie die COLOBOT-CD ein\nund starten Sie das Spiel neu."); +#endif + if ( num == ERR_MANIP_VEH ) strcpy(text, "Roboter ungeeignet"); + if ( num == ERR_MANIP_FLY ) strcpy(text, "Im Flug unmöglich"); + if ( num == ERR_MANIP_BUSY ) strcpy(text, "Trägt schon etwas"); + if ( num == ERR_MANIP_NIL ) strcpy(text, "Nichts zu ergreifen"); + if ( num == ERR_MANIP_MOTOR ) strcpy(text, "In Fahrt unmöglich"); + if ( num == ERR_MANIP_OCC ) strcpy(text, "Stelle schon besetzt"); + if ( num == ERR_MANIP_FRIEND ) strcpy(text, "Kein anderer Roboter"); + if ( num == ERR_MANIP_RADIO ) strcpy(text, "Sie können keinen radioaktiven Gegenstand tragen"); + if ( num == ERR_MANIP_WATER ) strcpy(text, "Sie können unter Wasser nichts tragen"); + if ( num == ERR_MANIP_EMPTY ) strcpy(text, "Nichts abzulegen"); + if ( num == ERR_BUILD_FLY ) strcpy(text, "Im Flug unmöglich"); + if ( num == ERR_BUILD_WATER ) strcpy(text, "Unter Wasser unmöglich"); + if ( num == ERR_BUILD_ENERGY ) strcpy(text, "Nicht genug Energie"); + if ( num == ERR_BUILD_METALAWAY ) strcpy(text, "Titan zu weit weg"); + if ( num == ERR_BUILD_METALNEAR ) strcpy(text, "Titan zu nahe"); + if ( num == ERR_BUILD_METALINEX ) strcpy(text, "Kein Titan vorhanden"); + if ( num == ERR_BUILD_FLAT ) strcpy(text, "Boden nicht eben genug"); + if ( num == ERR_BUILD_FLATLIT ) strcpy(text, "Ebener Boden nicht groß genug"); + if ( num == ERR_BUILD_BUSY ) strcpy(text, "Stelle schon besetzt"); + if ( num == ERR_BUILD_BASE ) strcpy(text, "Zu nahe am Raumschiff"); + if ( num == ERR_BUILD_NARROW ) strcpy(text, "Zu nahe an einem Gebäude"); + if ( num == ERR_BUILD_MOTOR ) strcpy(text, "In Fahrt unmöglich"); + if ( num == ERR_SEARCH_FLY ) strcpy(text, "Im Flug unmöglich"); + if ( num == ERR_SEARCH_VEH ) strcpy(text, "Roboter ungeeignet"); + if ( num == ERR_SEARCH_MOTOR ) strcpy(text, "In Fahrt unmöglich"); + if ( num == ERR_TERRA_VEH ) strcpy(text, "Roboter ungeeignet"); + if ( num == ERR_TERRA_ENERGY ) strcpy(text, "Nicht genug Energie"); + if ( num == ERR_TERRA_FLOOR ) strcpy(text, "Boden ungeeignet"); + if ( num == ERR_TERRA_BUILDING ) strcpy(text, "Gebäude zu nahe"); + if ( num == ERR_TERRA_OBJECT ) strcpy(text, "Gegenstand zu nahe"); + if ( num == ERR_RECOVER_VEH ) strcpy(text, "Roboter ungeeignet"); + if ( num == ERR_RECOVER_ENERGY ) strcpy(text, "Nicht genug Energie"); + if ( num == ERR_RECOVER_NULL ) strcpy(text, "Nichts zu recyceln"); + if ( num == ERR_SHIELD_VEH ) strcpy(text, "Roboter ungeeignet"); + if ( num == ERR_SHIELD_ENERGY ) strcpy(text, "Keine Energie mehr"); +//? if ( num == ERR_COM ) strcpy(text, "Kommunikationsproblem mit dem Roboter"); + if ( num == ERR_MOVE_IMPOSSIBLE ) strcpy(text, "Ziel kann nicht erreicht werden"); + if ( num == ERR_FIND_IMPOSSIBLE ) strcpy(text, "Das Objekt existiert nicht"); + if ( num == ERR_GOTO_IMPOSSIBLE ) strcpy(text, "Ziel kann nicht erreicht werden"); + if ( num == ERR_GOTO_ITER ) strcpy(text, "Ziel kann nicht erreicht werden"); + if ( num == ERR_GOTO_BUSY ) strcpy(text, "Ziel ist schon besetzt"); + if ( num == ERR_FIRE_VEH ) strcpy(text, "Roboter ungeeignet"); + if ( num == ERR_FIRE_ENERGY ) strcpy(text, "Nicht genug Energie"); + if ( num == ERR_FIRE_FLY ) strcpy(text, "Im Flug unmöglich"); + if ( num == ERR_CONVERT_EMPTY ) strcpy(text, "Kein konvertierbares Titanerz vorhanden"); + if ( num == ERR_DERRICK_NULL ) strcpy(text, "Keine unterirdische Erzlagerstätte"); + if ( num == ERR_STATION_NULL ) strcpy(text, "Kein unterirdisches Energievorkommen"); + if ( num == ERR_TOWER_POWER ) strcpy(text, "Keine Batterie"); + if ( num == ERR_TOWER_ENERGY ) strcpy(text, "Keine Energie mehr"); + if ( num == ERR_RESEARCH_POWER ) strcpy(text, "Keine Batterie"); + if ( num == ERR_RESEARCH_ENERGY ) strcpy(text, "Nicht mehr genug Energie"); + if ( num == ERR_RESEARCH_TYPE ) strcpy(text, "Falscher Batterietyp"); + if ( num == ERR_RESEARCH_ALREADY) strcpy(text, "Forschungsprogramm schon ausgeführt"); + if ( num == ERR_ENERGY_NULL ) strcpy(text, "Kein unterirdisches Energievorkommen"); + if ( num == ERR_ENERGY_LOW ) strcpy(text, "Noch nicht genug Energie"); + if ( num == ERR_ENERGY_EMPTY ) strcpy(text, "Kein konvertierbares Titanerz vorhanden"); + if ( num == ERR_ENERGY_BAD ) strcpy(text, "Wandelt nur Titanerz um"); + if ( num == ERR_BASE_DLOCK ) strcpy(text, "Die Türen werden von einem Gegenstand blockiert"); + if ( num == ERR_BASE_DHUMAN ) strcpy(text, "Gehen Sie an Bord, bevor Sie abheben"); + if ( num == ERR_LABO_NULL ) strcpy(text, "Nichts zu analysieren"); + if ( num == ERR_LABO_BAD ) strcpy(text, "Analysiert nur Orgastoff"); + if ( num == ERR_LABO_ALREADY ) strcpy(text, "Analyse schon durchgeführt"); + if ( num == ERR_NUCLEAR_NULL ) strcpy(text, "Kein unterirdisches Energievorkommen"); + if ( num == ERR_NUCLEAR_LOW ) strcpy(text, "Noch nicht genug Energie"); + if ( num == ERR_NUCLEAR_EMPTY ) strcpy(text, "Kein konvertierbares Platin"); + if ( num == ERR_NUCLEAR_BAD ) strcpy(text, "Wandelt nur Platin um"); + if ( num == ERR_FACTORY_NULL ) strcpy(text, "Kein Titan vorhanden"); + if ( num == ERR_FACTORY_NEAR ) strcpy(text, "Ein Gegenstand ist zu nahe"); + if ( num == ERR_RESET_NEAR ) strcpy(text, "Stelle schon besetzt"); + if ( num == ERR_INFO_NULL ) strcpy(text, "Kein Infoserver in Reichweite"); + if ( num == ERR_VEH_VIRUS ) strcpy(text, "Ein Programm wurde von einem Virus infiziert"); + if ( num == ERR_BAT_VIRUS ) strcpy(text, "Von Virus infiziert, zeitweise außer Betrieb"); + if ( num == ERR_VEH_POWER ) strcpy(text, "Keine Batterie"); + if ( num == ERR_VEH_ENERGY ) strcpy(text, "Keine Energie mehr"); + if ( num == ERR_FLAG_FLY ) strcpy(text, "Im Flug unmöglich"); + if ( num == ERR_FLAG_WATER ) strcpy(text, "Im Wasser unmöglich"); + if ( num == ERR_FLAG_MOTOR ) strcpy(text, "Beim Gehen unmöglich"); + if ( num == ERR_FLAG_BUSY ) strcpy(text, "Unmöglich wenn Sie etwas tragen"); + if ( num == ERR_FLAG_CREATE ) strcpy(text, "Zu viele Fahnen dieser Farbe (Maximum 5)"); + if ( num == ERR_FLAG_PROXY ) strcpy(text, "Zu nahe an einer anderen Fahne"); + if ( num == ERR_FLAG_DELETE ) strcpy(text, "Keine Fahne in Reichweite"); + if ( num == ERR_MISSION_NOTERM ) strcpy(text, "Mission noch nicht beendet (Drücken Sie auf \\key help; für weitere Informationen)"); + if ( num == ERR_DELETEMOBILE ) strcpy(text, "Roboter zerstört"); + if ( num == ERR_DELETEBUILDING ) strcpy(text, "Gebäude zerstört"); + if ( num == ERR_TOOMANY ) strcpy(text, "Kein neues Objekt kann erstellt werden (zu viele vorhanden)"); + if ( num == ERR_OBLIGATORYTOKEN ) strcpy(text, "Es fehlt \"%s\" in Ihrem Programm"); + if ( num == ERR_PROHIBITEDTOKEN ) strcpy(text, "In dieser Übung verboten"); + + if ( num == INFO_BUILD ) strcpy(text, "Gebäude fertiggestellt"); + if ( num == INFO_CONVERT ) strcpy(text, "Titan verfügbar"); + if ( num == INFO_RESEARCH ) strcpy(text, "Forschungsprogramm abgeschlossen"); + if ( num == INFO_RESEARCHTANK ) strcpy(text, "Herstellung eines Roboters mit Kettenantrieb möglich"); + if ( num == INFO_RESEARCHFLY ) strcpy(text, "Sie können jetzt mit den Tasten \\key gup; und \\key gdown; fliegen"); + if ( num == INFO_RESEARCHTHUMP ) strcpy(text, "Herstellung eines Stampfers möglich"); + if ( num == INFO_RESEARCHCANON ) strcpy(text, "Herstellung eines Shooters möglich"); + if ( num == INFO_RESEARCHTOWER ) strcpy(text, "Errichtung eines Geschützturms möglich"); + if ( num == INFO_RESEARCHPHAZER ) strcpy(text, "Herstellung eines Phazershooters möglich"); + if ( num == INFO_RESEARCHSHIELD ) strcpy(text, "Herstellung eines Schutzschildes möglich"); + if ( num == INFO_RESEARCHATOMIC ) strcpy(text, "Errichtung einer Brennstoffzellenfabrik möglich"); + if ( num == INFO_FACTORY ) strcpy(text, "Neuer Roboter verfügbar"); + if ( num == INFO_LABO ) strcpy(text, "Analyse vollendet"); + if ( num == INFO_ENERGY ) strcpy(text, "Batterie verfügbar"); + if ( num == INFO_NUCLEAR ) strcpy(text, "Brennstoffzelle verfügbar"); + if ( num == INFO_FINDING ) strcpy(text, "Sie haben ein brauchbares Objekt gefunden"); + if ( num == INFO_MARKPOWER ) strcpy(text, "Geeignete Stelle für Kraftwerk gefunden"); + if ( num == INFO_MARKURANIUM ) strcpy(text, "Geeignete Stelle für Bohrturm gefunden"); + if ( num == INFO_MARKSTONE ) strcpy(text, "Geeignete Stelle für Bohrturm gefunden"); + if ( num == INFO_MARKKEYa ) strcpy(text, "Geeignete Stelle für Bohrturm gefunden"); + if ( num == INFO_MARKKEYb ) strcpy(text, "Geeignete Stelle für Bohrturm gefunden"); + if ( num == INFO_MARKKEYc ) strcpy(text, "Geeignete Stelle für Bohrturm gefunden"); + if ( num == INFO_MARKKEYd ) strcpy(text, "Geeignete Stelle für Bohrturm gefunden"); + if ( num == INFO_WIN ) strcpy(text, "<<< Bravo, Mission vollendet >>>"); + if ( num == INFO_LOST ) strcpy(text, "<<< Mission gescheitert >>>"); + if ( num == INFO_LOSTq ) strcpy(text, "<<< Mission gescheitert >>>"); + if ( num == INFO_WRITEOK ) strcpy(text, "Mission gespeichert"); + if ( num == INFO_DELETEPATH ) strcpy(text, "Checkpoint erreicht"); + if ( num == INFO_DELETEMOTHER ) strcpy(text, "Insektenkönigin tödlich verwundet"); + if ( num == INFO_DELETEANT ) strcpy(text, "Ameise tödlich verwundet"); + if ( num == INFO_DELETEBEE ) strcpy(text, "Wespe tödlich verwundet"); + if ( num == INFO_DELETEWORM ) strcpy(text, "Wurm tödlich verwundet"); + if ( num == INFO_DELETESPIDER ) strcpy(text, "Spinne tödlich verwundet"); + if ( num == INFO_BEGINSATCOM ) strcpy(text, "Beziehen Sie sich auf Ihren SatCom, indem Sie auf \\key help; drücken"); + } + + if ( type == RES_CBOT ) + { + strcpy(text, "Fehler"); + if ( num == TX_OPENPAR ) strcpy(text, "Es fehlt eine offene Klammer ""("""); + if ( num == TX_CLOSEPAR ) strcpy(text, "Es fehlt eine geschlossene Klammer "")"""); + if ( num == TX_NOTBOOL ) strcpy(text, "Der Ausdruck muss einen boolschen Wert ergeben"); + if ( num == TX_UNDEFVAR ) strcpy(text, "Variable nicht deklariert"); + if ( num == TX_BADLEFT ) strcpy(text, "Zuweisung unmöglich"); + if ( num == TX_ENDOF ) strcpy(text, "Es fehlt ein Strichpunkt "";"" am Ende der Anweisung"); + if ( num == TX_OUTCASE ) strcpy(text, "Anweisung ""case"" ohne vorhergehende Anweisung ""switch"""); + if ( num == TX_NOTERM ) strcpy(text, "Hier ist eine Anweisung nach dem Ende des Programms"); + if ( num == TX_CLOSEBLK ) strcpy(text, "Es fehlt eine geschlossene geschweifte Klammer ""}"" (Ende des Blocks)"); + if ( num == TX_ELSEWITHOUTIF ) strcpy(text, "Anweisung ""else"" ohne vorhergehende Anweisung ""if"""); + if ( num == TX_OPENBLK ) strcpy(text, "Es fehlt eine offene geschweifte Klammer""{"""); + if ( num == TX_BADTYPE ) strcpy(text, "Der Ausdruck ergibt einen falschen Typ für die Zuweisung"); + if ( num == TX_REDEFVAR ) strcpy(text, "Eine Variable wird zum zweiten Mal deklariert"); + if ( num == TX_BAD2TYPE ) strcpy(text, "Die zwei Operanden sind nicht kompatibel"); + if ( num == TX_UNDEFCALL ) strcpy(text, "Unbekannte Funktion"); + if ( num == TX_MISDOTS ) strcpy(text, "Es fehlt ein Doppelpunkt "" : """); + if ( num == TX_WHILE ) strcpy(text, "Es fehlt das Wort ""while"""); + if ( num == TX_BREAK ) strcpy(text, "Anweisung ""break"" außerhalb einer Schleife"); + if ( num == TX_LABEL ) strcpy(text, "Ein Label kann nur vor den Anweisungen ""for"", ""while"", ""do"" oder ""switch"" vorkommen"); + if ( num == TX_NOLABEL ) strcpy(text, "Dieses Label existiert nicht"); + if ( num == TX_NOCASE ) strcpy(text, "Es fehlt eine Anweisung ""case"""); + if ( num == TX_BADNUM ) strcpy(text, "Es fehlt eine Zahl"); + if ( num == TX_VOID ) strcpy(text, "Parameter void"); + if ( num == TX_NOTYP ) strcpy(text, "Hier muss ein Variablentyp stehen"); + if ( num == TX_NOVAR ) strcpy(text, "Es fehlt der Name einer Variable"); + if ( num == TX_NOFONC ) strcpy(text, "Hier muss der Name der Funktion stehen"); + if ( num == TX_OVERPARAM ) strcpy(text, "Zu viele Parameter"); + if ( num == TX_REDEF ) strcpy(text, "Diese Funktion gibt es schon"); + if ( num == TX_LOWPARAM ) strcpy(text, "Nicht genug Parameter"); + if ( num == TX_BADPARAM ) strcpy(text, "Keine Funktion mit diesem Namen verträgt Parameter diesen Typs"); + if ( num == TX_NUMPARAM ) strcpy(text, "Keine Funktion mit diesem Namen verträgt diese Anzahl Parameter"); + if ( num == TX_NOITEM ) strcpy(text, "Dieses Element gibt es nicht in dieser Klasse"); + if ( num == TX_DOT ) strcpy(text, "Das Objekt ist nicht eine Instanz einer Klasse"); + if ( num == TX_NOCONST ) strcpy(text, "Es gibt keinen geeigneten Konstruktor"); + if ( num == TX_REDEFCLASS ) strcpy(text, "Diese Klasse gibt es schon"); + if ( num == TX_CLBRK ) strcpy(text, "Es fehlt eine geschlossene eckige Klammer "" ] """); + if ( num == TX_RESERVED ) strcpy(text, "Dieses Wort ist reserviert"); + if ( num == TX_BADNEW ) strcpy(text, "Falsche Argumente für ""new"""); + if ( num == TX_OPBRK ) strcpy(text, "Es fehlt eine offene eckige Klammer "" [ """); + if ( num == TX_BADSTRING ) strcpy(text, "Hier wird eine Zeichenkette erwartet"); + if ( num == TX_BADINDEX ) strcpy(text, "Falscher Typ für einen Index"); + if ( num == TX_PRIVATE ) strcpy(text, "Geschütztes Element (private)"); + if ( num == TX_NOPUBLIC ) strcpy(text, "Hier muss das Wort ""public"" stehen"); + if ( num == TX_DIVZERO ) strcpy(text, "Teilung durch Null"); + if ( num == TX_NOTINIT ) strcpy(text, "Der Wert dieser Variable wurde nicht definiert"); + if ( num == TX_BADTHROW ) strcpy(text, "Negativer Wert ungeeignet für Anweisung ""throw"""); + if ( num == TX_NORETVAL ) strcpy(text, "Die Funktion hat kein Ergebnis zurückgegeben"); + if ( num == TX_NORUN ) strcpy(text, "Keine Funktion wird ausgeführt"); + if ( num == TX_NOCALL ) strcpy(text, "Die aufgerufene Funktion existiert nicht"); + if ( num == TX_NOCLASS ) strcpy(text, "Diese Klasse existiert nicht"); + if ( num == TX_NULLPT ) strcpy(text, "Das Objekt existiert nicht"); + if ( num == TX_OPNAN ) strcpy(text, "Operation mit dem Wert ""nan"""); + if ( num == TX_OUTARRAY ) strcpy(text, "Zugriff im Array außerhalb der Grenzen"); + if ( num == TX_STACKOVER ) strcpy(text, "Stack overflow"); + if ( num == TX_DELETEDPT ) strcpy(text, "Objekt nicht verfügbar"); + if ( num == TX_FILEOPEN ) strcpy(text, "Die Datei kann nicht geöffnet werden"); + if ( num == TX_NOTOPEN ) strcpy(text, "Die Datei wurde nicht geöffnet"); + if ( num == TX_ERRREAD ) strcpy(text, "Fehler beim Lesezugriff"); + if ( num == TX_ERRWRITE ) strcpy(text, "Fehler beim Schreibzugriff"); + } + + if ( type == RES_KEY ) + { + if ( num == 0 ) strcpy(text, "< keine >"); + if ( num == VK_LEFT ) strcpy(text, "Pfeiltaste links"); + if ( num == VK_RIGHT ) strcpy(text, "Pfeiltaste rechts"); + if ( num == VK_UP ) strcpy(text, "Pfeil nach oben"); + if ( num == VK_DOWN ) strcpy(text, "Pfeil nach unten"); + if ( num == VK_CANCEL ) strcpy(text, "Ctrl-Break"); + if ( num == VK_BACK ) strcpy(text, "<--"); + if ( num == VK_TAB ) strcpy(text, "Tab"); + if ( num == VK_CLEAR ) strcpy(text, "Clear"); + if ( num == VK_RETURN ) strcpy(text, "Eingabe"); + if ( num == VK_SHIFT ) strcpy(text, "Shift"); + if ( num == VK_CONTROL ) strcpy(text, "Ctrl"); + if ( num == VK_MENU ) strcpy(text, "Alt"); + if ( num == VK_PAUSE ) strcpy(text, "Pause"); + if ( num == VK_CAPITAL ) strcpy(text, "Caps Lock"); + if ( num == VK_ESCAPE ) strcpy(text, "Esc"); + if ( num == VK_SPACE ) strcpy(text, "Leertaste"); + if ( num == VK_PRIOR ) strcpy(text, "Page Up"); + if ( num == VK_NEXT ) strcpy(text, "Page Down"); + if ( num == VK_END ) strcpy(text, "End"); + if ( num == VK_HOME ) strcpy(text, "Home"); + if ( num == VK_SELECT ) strcpy(text, "Select"); + if ( num == VK_EXECUTE ) strcpy(text, "Execute"); + if ( num == VK_SNAPSHOT ) strcpy(text, "Print Scrn"); + if ( num == VK_INSERT ) strcpy(text, "Insert"); + if ( num == VK_DELETE ) strcpy(text, "Delete"); + if ( num == VK_HELP ) strcpy(text, "Help"); + if ( num == VK_LWIN ) strcpy(text, "Left Windows"); + if ( num == VK_RWIN ) strcpy(text, "Right Windows"); + if ( num == VK_APPS ) strcpy(text, "Application key"); + if ( num == VK_NUMPAD0 ) strcpy(text, "NumPad 0"); + if ( num == VK_NUMPAD1 ) strcpy(text, "NumPad 1"); + if ( num == VK_NUMPAD2 ) strcpy(text, "NumPad 2"); + if ( num == VK_NUMPAD3 ) strcpy(text, "NumPad 3"); + if ( num == VK_NUMPAD4 ) strcpy(text, "NumPad 4"); + if ( num == VK_NUMPAD5 ) strcpy(text, "NumPad 5"); + if ( num == VK_NUMPAD6 ) strcpy(text, "NumPad 6"); + if ( num == VK_NUMPAD7 ) strcpy(text, "NumPad 7"); + if ( num == VK_NUMPAD8 ) strcpy(text, "NumPad 8"); + if ( num == VK_NUMPAD9 ) strcpy(text, "NumPad 9"); + if ( num == VK_MULTIPLY ) strcpy(text, "NumPad *"); + if ( num == VK_ADD ) strcpy(text, "NumPad +"); + if ( num == VK_SEPARATOR ) strcpy(text, "NumPad sep"); + if ( num == VK_SUBTRACT ) strcpy(text, "NumPad -"); + if ( num == VK_DECIMAL ) strcpy(text, "NumPad ."); + if ( num == VK_DIVIDE ) strcpy(text, "NumPad /"); + if ( num == VK_F1 ) strcpy(text, "F1"); + if ( num == VK_F2 ) strcpy(text, "F2"); + if ( num == VK_F3 ) strcpy(text, "F3"); + if ( num == VK_F4 ) strcpy(text, "F4"); + if ( num == VK_F5 ) strcpy(text, "F5"); + if ( num == VK_F6 ) strcpy(text, "F6"); + if ( num == VK_F7 ) strcpy(text, "F7"); + if ( num == VK_F8 ) strcpy(text, "F8"); + if ( num == VK_F9 ) strcpy(text, "F9"); + if ( num == VK_F10 ) strcpy(text, "F10"); + if ( num == VK_F11 ) strcpy(text, "F11"); + if ( num == VK_F12 ) strcpy(text, "F12"); + if ( num == VK_F13 ) strcpy(text, "F13"); + if ( num == VK_F14 ) strcpy(text, "F14"); + if ( num == VK_F15 ) strcpy(text, "F15"); + if ( num == VK_F16 ) strcpy(text, "F16"); + if ( num == VK_F17 ) strcpy(text, "F17"); + if ( num == VK_F18 ) strcpy(text, "F18"); + if ( num == VK_F19 ) strcpy(text, "F19"); + if ( num == VK_F20 ) strcpy(text, "F20"); + if ( num == VK_NUMLOCK ) strcpy(text, "Num Lock"); + if ( num == VK_SCROLL ) strcpy(text, "Scroll"); + if ( num == VK_ATTN ) strcpy(text, "Attn"); + if ( num == VK_CRSEL ) strcpy(text, "CrSel"); + if ( num == VK_EXSEL ) strcpy(text, "ExSel"); + if ( num == VK_EREOF ) strcpy(text, "Erase EOF"); + if ( num == VK_PLAY ) strcpy(text, "Play"); + if ( num == VK_ZOOM ) strcpy(text, "Zoom"); + if ( num == VK_PA1 ) strcpy(text, "PA1"); + if ( num == VK_OEM_CLEAR ) strcpy(text, "Clear"); + if ( num == VK_BUTTON1 ) strcpy(text, "Knopf 1"); + if ( num == VK_BUTTON2 ) strcpy(text, "Knopf 2"); + if ( num == VK_BUTTON3 ) strcpy(text, "Knopf 3"); + if ( num == VK_BUTTON4 ) strcpy(text, "Knopf 4"); + if ( num == VK_BUTTON5 ) strcpy(text, "Knopf 5"); + if ( num == VK_BUTTON6 ) strcpy(text, "Knopf 6"); + if ( num == VK_BUTTON7 ) strcpy(text, "Knopf 7"); + if ( num == VK_BUTTON8 ) strcpy(text, "Knopf 8"); + if ( num == VK_BUTTON9 ) strcpy(text, "Knopf 9"); + if ( num == VK_BUTTON10 ) strcpy(text, "Knopf 10"); + if ( num == VK_BUTTON11 ) strcpy(text, "Knopf 11"); + if ( num == VK_BUTTON12 ) strcpy(text, "Knopf 12"); + if ( num == VK_BUTTON13 ) strcpy(text, "Knopf 13"); + if ( num == VK_BUTTON14 ) strcpy(text, "Knopf 14"); + if ( num == VK_BUTTON15 ) strcpy(text, "Knopf 15"); + if ( num == VK_BUTTON16 ) strcpy(text, "Knopf 16"); + if ( num == VK_BUTTON17 ) strcpy(text, "Knopf 17"); + if ( num == VK_BUTTON18 ) strcpy(text, "Knopf 18"); + if ( num == VK_BUTTON19 ) strcpy(text, "Knopf 19"); + if ( num == VK_BUTTON20 ) strcpy(text, "Knopf 20"); + if ( num == VK_BUTTON21 ) strcpy(text, "Knopf 21"); + if ( num == VK_BUTTON22 ) strcpy(text, "Knopf 22"); + if ( num == VK_BUTTON23 ) strcpy(text, "Knopf 23"); + if ( num == VK_BUTTON24 ) strcpy(text, "Knopf 24"); + if ( num == VK_BUTTON25 ) strcpy(text, "Knopf 25"); + if ( num == VK_BUTTON26 ) strcpy(text, "Knopf 26"); + if ( num == VK_BUTTON27 ) strcpy(text, "Knopf 27"); + if ( num == VK_BUTTON28 ) strcpy(text, "Knopf 28"); + if ( num == VK_BUTTON29 ) strcpy(text, "Knopf 29"); + if ( num == VK_BUTTON30 ) strcpy(text, "Knopf 30"); + if ( num == VK_BUTTON31 ) strcpy(text, "Knopf 31"); + if ( num == VK_BUTTON32 ) strcpy(text, "Knopf 32"); + if ( num == VK_WHEELUP ) strcpy(text, "Mausrad nach vorne"); + if ( num == VK_WHEELDOWN ) strcpy(text, "Mausrad zurück"); + } +#endif + +#if _POLISH + if ( type == RES_TEXT ) + { + #if _FULL + if ( num == RT_VERSION_ID ) strcpy(text, "Wersja 1.18 /pl"); + #endif + #if _NET + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A 1.18"); + #endif + #if _SCHOOL & _EDU + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen EDU 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A EDU 1.18"); + #endif + #endif + #if _SCHOOL & _PERSO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen PERSO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A PERSO 1.18"); + #endif + #endif + #if _SCHOOL & _CEEBOTDEMO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen DEMO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A DEMO 1.18"); + #endif + #endif + #if _DEMO + if ( num == RT_VERSION_ID ) strcpy(text, "Demo 1.18 /pl"); + #endif + if ( num == RT_DISINFO_TITLE ) strcpy(text, "SatCom"); + if ( num == RT_WINDOW_MAXIMIZED ) strcpy(text, "Powiêksz"); + if ( num == RT_WINDOW_MINIMIZED ) strcpy(text, "Pomniejsz"); + if ( num == RT_WINDOW_STANDARD ) strcpy(text, "Normalna wielkoœæ"); + if ( num == RT_WINDOW_CLOSE ) strcpy(text, "Zamknij"); + + if ( num == RT_STUDIO_TITLE ) strcpy(text, "Edytor programu"); + if ( num == RT_SCRIPT_NEW ) strcpy(text, "Nowy"); + if ( num == RT_NAME_DEFAULT ) strcpy(text, "Gracz"); + if ( num == RT_IO_NEW ) strcpy(text, "Nowy ..."); + if ( num == RT_KEY_OR ) strcpy(text, " lub "); + +#if _NEWLOOK + if ( num == RT_TITLE_BASE ) strcpy(text, "CeeBot"); + if ( num == RT_TITLE_INIT ) strcpy(text, "CeeBot"); +#else + if ( num == RT_TITLE_BASE ) strcpy(text, "COLOBOT"); + if ( num == RT_TITLE_INIT ) strcpy(text, "COLOBOT"); +#endif + if ( num == RT_TITLE_TRAINER ) strcpy(text, "Æwiczenia programistyczne"); + if ( num == RT_TITLE_DEFI ) strcpy(text, "Wyzwania"); + if ( num == RT_TITLE_MISSION ) strcpy(text, "Misje"); + if ( num == RT_TITLE_FREE ) strcpy(text, "Swobodna gra"); + if ( num == RT_TITLE_TEEN ) strcpy(text, "Swobodna gra"); + if ( num == RT_TITLE_USER ) strcpy(text, "Poziomy u¿ytkownika"); + if ( num == RT_TITLE_PROTO ) strcpy(text, "Prototypy"); + if ( num == RT_TITLE_SETUP ) strcpy(text, "Opcje"); + if ( num == RT_TITLE_NAME ) strcpy(text, "Imiê gracza"); + if ( num == RT_TITLE_PERSO ) strcpy(text, "Dostosuj wygl¹d"); + if ( num == RT_TITLE_WRITE ) strcpy(text, "Zapisz bie¿¹c¹ misjê"); + if ( num == RT_TITLE_READ ) strcpy(text, "Wczytaj zapisan¹ misjê"); + + if ( num == RT_PLAY_CHAPt ) strcpy(text, " Rozdzia³y:"); + if ( num == RT_PLAY_CHAPd ) strcpy(text, " Rozdzia³y:"); + if ( num == RT_PLAY_CHAPm ) strcpy(text, " Planety:"); + if ( num == RT_PLAY_CHAPf ) strcpy(text, " Planety:"); + if ( num == RT_PLAY_CHAPu ) strcpy(text, " Poziomy u¿ytkownika:"); + if ( num == RT_PLAY_CHAPp ) strcpy(text, " Planety:"); + if ( num == RT_PLAY_CHAPte ) strcpy(text, " Planety:"); + if ( num == RT_PLAY_LISTt ) strcpy(text, " Æwiczenia w tym rozdziale:"); + if ( num == RT_PLAY_LISTd ) strcpy(text, " Wyzwania w tym rozdziale:"); + if ( num == RT_PLAY_LISTm ) strcpy(text, " Misje na tej planecie:"); + if ( num == RT_PLAY_LISTf ) strcpy(text, " Swobodna gra na tej planecie:"); + if ( num == RT_PLAY_LISTu ) strcpy(text, " Misje na tym poziomie:"); + if ( num == RT_PLAY_LISTp ) strcpy(text, " Prototypy na tej planecie:"); + if ( num == RT_PLAY_LISTk ) strcpy(text, " Prototypy na tej planecie:"); + if ( num == RT_PLAY_RESUME ) strcpy(text, " Streszczenie:"); + + if ( num == RT_SETUP_DEVICE ) strcpy(text, " Sterowniki:"); + if ( num == RT_SETUP_MODE ) strcpy(text, " Rozdzielczoœæ:"); + if ( num == RT_SETUP_KEY1 ) strcpy(text, "1) Najpierw kliknij klawisz, który chcesz przedefiniowaæ."); + if ( num == RT_SETUP_KEY2 ) strcpy(text, "2) Nastêpnie naciœnij klawisz, którego chcesz u¿ywaæ."); + + if ( num == RT_PERSO_FACE ) strcpy(text, "Rodzaj twarzy:"); + if ( num == RT_PERSO_GLASSES ) strcpy(text, "Okulary:"); + if ( num == RT_PERSO_HAIR ) strcpy(text, "Kolor w³osów:"); + if ( num == RT_PERSO_COMBI ) strcpy(text, "Kolor skafandra:"); + if ( num == RT_PERSO_BAND ) strcpy(text, "Kolor pasków:"); + +#if _NEWLOOK + if ( num == RT_DIALOG_TITLE ) strcpy(text, "CeeBot"); + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Czy na pewno chcesz opuœciæ grê CeeBot?"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Zakoñcz\\Koñczy grê CeeBot"); +#else + if ( num == RT_DIALOG_TITLE ) strcpy(text, "COLOBOT"); + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Czy na pewno chcesz opuœciæ grê COLOBOT?"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Zakoñcz\\Koñczy grê COLOBOT"); +#endif + if ( num == RT_DIALOG_ABORT ) strcpy(text, "Opuœciæ misjê?"); + if ( num == RT_DIALOG_YES ) strcpy(text, "Przerwij\\Przerywa bie¿¹c¹ misjê"); + if ( num == RT_DIALOG_NO ) strcpy(text, "Kontynuuj\\Kontynuuje bie¿¹c¹ misjê"); + if ( num == RT_DIALOG_NOQUIT ) strcpy(text, "Kontynuuj\\Kontynuuje grê"); + if ( num == RT_DIALOG_DELOBJ ) strcpy(text, "Czy na pewno chcesz zniszczyæ zaznaczony budynek?"); + if ( num == RT_DIALOG_DELGAME ) strcpy(text, "Czy na pewno chcesz skasowaæ zapisane gry gracza %s? "); + if ( num == RT_DIALOG_YESDEL ) strcpy(text, "Usuñ"); + if ( num == RT_DIALOG_NODEL ) strcpy(text, "Anuluj"); + if ( num == RT_DIALOG_LOADING ) strcpy(text, "WCZYTYWANIE"); + + if ( num == RT_STUDIO_LISTTT ) strcpy(text, "Skróty klawiszowe (\\key cbot;)"); + if ( num == RT_STUDIO_COMPOK ) strcpy(text, "Program skompilowany (0 b³êdów)"); + if ( num == RT_STUDIO_PROGSTOP ) strcpy(text, "Program zakoñczony"); + + if ( num == RT_SATCOM_LIST ) strcpy(text, "\\b;Lista obiektów\n"); + if ( num == RT_SATCOM_BOT ) strcpy(text, "\\b;Roboty\n"); + if ( num == RT_SATCOM_BUILDING ) strcpy(text, "\\b;Budynki\n"); + if ( num == RT_SATCOM_FRET ) strcpy(text, "\\b;Obiekty ruchome\n"); + if ( num == RT_SATCOM_ALIEN ) strcpy(text, "\\b;Obcy\n"); + if ( num == RT_SATCOM_NULL ) strcpy(text, "\\c; (brak)\\n;\n"); + if ( num == RT_SATCOM_ERROR1 ) strcpy(text, "\\b;B³¹d\n"); + if ( num == RT_SATCOM_ERROR2 ) strcpy(text, "Lista jest dostêpna jedynie gdy dzia³a \\l;stacja radarowa\\u object\\radar;.\n"); + + if ( num == RT_IO_OPEN ) strcpy(text, "Otwórz"); + if ( num == RT_IO_SAVE ) strcpy(text, "Zapisz"); + if ( num == RT_IO_LIST ) strcpy(text, "Folder: %s"); + if ( num == RT_IO_NAME ) strcpy(text, "Nazwa:"); + if ( num == RT_IO_DIR ) strcpy(text, "Folder:"); + if ( num == RT_IO_PRIVATE ) strcpy(text, "Prywatny\\Folder prywatny"); + if ( num == RT_IO_PUBLIC ) strcpy(text, "Publiczny\\Folder ogólnodostêpny"); + + if ( num == RT_GENERIC_DEV1 ) strcpy(text, "Twórcy:"); + if ( num == RT_GENERIC_DEV2 ) strcpy(text, "www.epsitec.com"); + if ( num == RT_GENERIC_EDIT1 ) strcpy(text, "Wersja polska wydana przez:"); + if ( num == RT_GENERIC_EDIT2 ) strcpy(text, "www.manta.com.pl"); + if ( num == RT_GENERIC_EDIT1 ) strcpy(text, " "); + if ( num == RT_GENERIC_EDIT2 ) strcpy(text, " "); + + if ( num == RT_INTERFACE_REC ) strcpy(text, "Recorder"); + } + + if ( type == RES_EVENT ) + { + if ( num == EVENT_BUTTON_OK ) strcpy(text, "OK"); + if ( num == EVENT_BUTTON_CANCEL ) strcpy(text, "Anuluj"); + if ( num == EVENT_BUTTON_NEXT ) strcpy(text, "Nastêpny"); + if ( num == EVENT_BUTTON_PREV ) strcpy(text, "Poprzedni"); + if ( num == EVENT_BUTTON_QUIT ) strcpy(text, "Menu (\\key quit;)"); + + if ( num == EVENT_DIALOG_OK ) strcpy(text, "OK"); + if ( num == EVENT_DIALOG_CANCEL ) strcpy(text, "Anuluj"); + + if ( num == EVENT_INTERFACE_TRAINER) strcpy(text, "Æwiczenia\\Æwiczenia programistyczne"); + if ( num == EVENT_INTERFACE_DEFI ) strcpy(text, "Wyzwania\\Wyzwania programistyczne"); + if ( num == EVENT_INTERFACE_MISSION) strcpy(text, "Misje\\Wybierz misjê"); + if ( num == EVENT_INTERFACE_FREE ) strcpy(text, "Swobodna gra\\Swobodna gra bez konkretnych celów"); + if ( num == EVENT_INTERFACE_TEEN ) strcpy(text, "Swobodna gra\\Swobodna gra bez konkretnych celów"); + if ( num == EVENT_INTERFACE_USER ) strcpy(text, "Poziomy\\Poziomy u¿ytkownika"); + if ( num == EVENT_INTERFACE_PROTO ) strcpy(text, "Prototypy\\Prototypy w trakcie rozwijania"); + if ( num == EVENT_INTERFACE_NAME ) strcpy(text, "Nowy gracz\\Wybierz imiê gracza"); + if ( num == EVENT_INTERFACE_SETUP ) strcpy(text, "Opcje\\Preferencje"); + if ( num == EVENT_INTERFACE_AGAIN ) strcpy(text, "Uruchom ponownie\\Uruchamia ponownie misjê od pocz¹tku"); + if ( num == EVENT_INTERFACE_WRITE ) strcpy(text, "Zapisz\\Zapisuje bie¿¹c¹ misjê"); + if ( num == EVENT_INTERFACE_READ ) strcpy(text, "Wczytaj\\Wczytuje zapisan¹ misjê"); +#if _NEWLOOK + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Powróæ do gry CeeBot"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Zakoñcz\\Koñczy grê CeeBot"); +#else + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Powróæ do gry COLOBOT"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Zakoñcz\\Koñczy grê COLOBOT"); +#endif + if ( num == EVENT_INTERFACE_BACK ) strcpy(text, "<< Wstecz \\Wraca do poprzedniego ekranu"); + if ( num == EVENT_INTERFACE_PLAY ) strcpy(text, "Graj\\Rozpoczyna misjê!"); + if ( num == EVENT_INTERFACE_SETUPd ) strcpy(text, "Urz¹dzenie\\Ustawienia sterownika i rozdzielczoœci"); + if ( num == EVENT_INTERFACE_SETUPg ) strcpy(text, "Grafika\\Ustawienia grafiki"); + if ( num == EVENT_INTERFACE_SETUPp ) strcpy(text, "Gra\\Ustawienia gry"); + if ( num == EVENT_INTERFACE_SETUPc ) strcpy(text, "Sterowanie\\Ustawienia klawiatury, joysticka i myszy"); + if ( num == EVENT_INTERFACE_SETUPs ) strcpy(text, "DŸwiêk\\G³oœnoœæ muzyki i dŸwiêków gry"); + if ( num == EVENT_INTERFACE_DEVICE ) strcpy(text, "Jednostka"); + if ( num == EVENT_INTERFACE_RESOL ) strcpy(text, "Rozdzielczoœæ"); + if ( num == EVENT_INTERFACE_FULL ) strcpy(text, "Pe³ny ekran\\Pe³ny ekran lub tryb okna"); + if ( num == EVENT_INTERFACE_APPLY ) strcpy(text, "Zastosuj zmiany\\Aktywuje zmienione ustawienia"); + + if ( num == EVENT_INTERFACE_TOTO ) strcpy(text, "Robbie\\Twój asystent"); + if ( num == EVENT_INTERFACE_SHADOW ) strcpy(text, "Cienie\\Cienie na ziemi"); + if ( num == EVENT_INTERFACE_GROUND ) strcpy(text, "Znaki na ziemi\\Znaki na ziemi"); + if ( num == EVENT_INTERFACE_DIRTY ) strcpy(text, "Kurz\\Kurz i bród na robotach i budynkach"); + if ( num == EVENT_INTERFACE_FOG ) strcpy(text, "Mg³a\\Mg³a"); + if ( num == EVENT_INTERFACE_LENS ) strcpy(text, "Promienie s³oneczne\\Promienie s³oneczne na niebie"); + if ( num == EVENT_INTERFACE_SKY ) strcpy(text, "Niebo\\Chmury i mg³awice"); + if ( num == EVENT_INTERFACE_PLANET ) strcpy(text, "Planety i gwiazdy\\Obiekty astronomiczne na niebie"); + if ( num == EVENT_INTERFACE_LIGHT ) strcpy(text, "Dynamiczne oœwietlenie\\Ruchome Ÿród³a œwiat³a"); + if ( num == EVENT_INTERFACE_PARTI ) strcpy(text, "Liczba cz¹stek\\Wybuchy, kurz, odbicia, itp."); + if ( num == EVENT_INTERFACE_CLIP ) strcpy(text, "G³êbokoœæ pola\\Maksymalna widocznoœæ"); + if ( num == EVENT_INTERFACE_DETAIL ) strcpy(text, "Szczegó³y\\Jakoœæ wizualna obiektów 3D"); + if ( num == EVENT_INTERFACE_TEXTURE) strcpy(text, "Tekstury\\Jakoœæ tekstur "); + if ( num == EVENT_INTERFACE_GADGET ) strcpy(text, "Iloœæ elementów dekoracyjnych \\Iloœæ elementów czysto dekoracyjnych"); + if ( num == EVENT_INTERFACE_RAIN ) strcpy(text, "Cz¹stki w interfejsie\\Para i iskry z silników w interfejsie"); + if ( num == EVENT_INTERFACE_GLINT ) strcpy(text, "Odbicia na przyciskach \\Œwiec¹ce przyciski"); + if ( num == EVENT_INTERFACE_TOOLTIP) strcpy(text, "Dymki pomocy\\Wyjaœnia funkcje przycisków"); + if ( num == EVENT_INTERFACE_MOVIES ) strcpy(text, "Sekwencje filmowe\\Filmy przed rozpoczêciem i na zakoñczenie misji"); + if ( num == EVENT_INTERFACE_NICERST) strcpy(text, "Koñcowy film\\Film na zakoñczenie æwiczeñ"); + if ( num == EVENT_INTERFACE_HIMSELF) strcpy(text, "Przyjacielski ogieñ\\W³asne strza³y uszkadzaj¹ Twoje obiekty"); + if ( num == EVENT_INTERFACE_SCROLL ) strcpy(text, "Przewijanie\\Ekran jest przewijany gdy mysz dotknie prawej lub lewej jego krawêdzi"); + if ( num == EVENT_INTERFACE_INVERTX) strcpy(text, "Odwrócenie myszy X\\Odwrócenie kierunków przewijania w poziomie"); + if ( num == EVENT_INTERFACE_INVERTY) strcpy(text, "Odwrócenie myszy Y\\Odwrócenie kierunków przewijania w pionie"); + if ( num == EVENT_INTERFACE_EFFECT ) strcpy(text, "Wstrz¹sy przy wybuchach\\Ekran trzêsie siê podczas wybuchów"); + if ( num == EVENT_INTERFACE_MOUSE ) strcpy(text, "Cieñ kursora myszy\\Dodaje cieñ kursorowi myszy"); + if ( num == EVENT_INTERFACE_EDITMODE) strcpy(text, "Automatyczne wciêcia\\Automatyczne wciêcia podczas edycji programu"); + if ( num == EVENT_INTERFACE_EDITVALUE)strcpy(text, "Du¿e wciêcie\\2 lub 4 spacje wciêcia na ka¿dy poziom zdefiniowany przez klamry"); + if ( num == EVENT_INTERFACE_SOLUCE4) strcpy(text, "Accès aux solutions\\Programme \"4: Solution\" dans les exercices"); + + if ( num == EVENT_INTERFACE_KDEF ) strcpy(text, "Standardowa kontrola\\Standardowe klawisze funkcyjne"); + if ( num == EVENT_INTERFACE_KLEFT ) strcpy(text, "Skrêæ w lewo\\Obraca robota w lewo"); + if ( num == EVENT_INTERFACE_KRIGHT ) strcpy(text, "Obróæ w prawo\\Obraca robota w prawo"); + if ( num == EVENT_INTERFACE_KUP ) strcpy(text, "Naprzód\\Porusza do przodu"); + if ( num == EVENT_INTERFACE_KDOWN ) strcpy(text, "Wstecz\\Porusza do ty³u"); + if ( num == EVENT_INTERFACE_KGUP ) strcpy(text, "W górê\\Zwiêksza moc silnika"); + if ( num == EVENT_INTERFACE_KGDOWN ) strcpy(text, "W dó³\\Zmniejsza moc silnika"); + if ( num == EVENT_INTERFACE_KCAMERA) strcpy(text, "Zmieñ kamerê\\Prze³¹cza pomiêdzy kamer¹ pok³adow¹ i œledz¹c¹"); + if ( num == EVENT_INTERFACE_KDESEL ) strcpy(text, "Poprzedni obiekt\\Zaznacz poprzedni obiekt"); + if ( num == EVENT_INTERFACE_KACTION) strcpy(text, "Standardowa akcja\\Standardowa akcja robota (podnieœ/upuœæ, strzelaj, szukaj, itp.)"); + if ( num == EVENT_INTERFACE_KNEAR ) strcpy(text, "Kamera bli¿ej\\Przybli¿a kamerê"); + if ( num == EVENT_INTERFACE_KAWAY ) strcpy(text, "Kamera dalej\\Oddala kamerê"); + if ( num == EVENT_INTERFACE_KNEXT ) strcpy(text, "Nastêpny obiekt\\Zaznacza nastêpny obiekt"); + if ( num == EVENT_INTERFACE_KHUMAN ) strcpy(text, "Zaznacz astronautê\\Zaznacza astronautê"); + if ( num == EVENT_INTERFACE_KQUIT ) strcpy(text, "Zakoñcz\\Koñczy bie¿¹c¹ misjê lub æwiczenie"); + if ( num == EVENT_INTERFACE_KHELP ) strcpy(text, "Rozkazy\\Pokazuje rozkazy dotycz¹ce bie¿¹cej misji"); + if ( num == EVENT_INTERFACE_KPROG ) strcpy(text, "Podrêcznik programowania\\Dostarcza szczegó³ow¹ pomoc w programowaniu"); + if ( num == EVENT_INTERFACE_KCBOT ) strcpy(text, "Pomoc dot. s³ów kluczowych\\Dok³adniejsza pomoc na temat s³ów kluczowych"); + if ( num == EVENT_INTERFACE_KVISIT ) strcpy(text, "Miejsce nadania wiadomoœci\\Pokazuje sk¹d zosta³a wys³ana ostatnia wiadomoœæ"); + if ( num == EVENT_INTERFACE_KSPEED10) strcpy(text, "Prêdkoœæ 1,0x\\Prêdkoœæ normalna"); + if ( num == EVENT_INTERFACE_KSPEED15) strcpy(text, "Prêdkoœæ 1,5x\\1,5 raza szybciej"); + if ( num == EVENT_INTERFACE_KSPEED20) strcpy(text, "Prêdkoœæ 2,0x\\Dwa razy szybciej"); + if ( num == EVENT_INTERFACE_KSPEED30) strcpy(text, "Prêdkoœæ 3,0x\\Trzy razy szybciej"); + + if ( num == EVENT_INTERFACE_VOLSOUND) strcpy(text, "Efekty dŸwiêkowe:\\G³oœnoœæ silników, g³osów, strza³ów, itp."); + if ( num == EVENT_INTERFACE_VOLMUSIC) strcpy(text, "Muzyka w tle :\\G³oœnoœæ œcie¿ek dŸwiêkowych z p³yty CD"); + if ( num == EVENT_INTERFACE_SOUND3D) strcpy(text, "DŸwiêk 3D\\Przestrzenne pozycjonowanie dŸwiêków"); + + if ( num == EVENT_INTERFACE_MIN ) strcpy(text, "Najni¿sza\\Minimalna jakoœæ grafiki (najwy¿sza czêstotliwoœæ odœwie¿ania)"); + if ( num == EVENT_INTERFACE_NORM ) strcpy(text, "Normalna\\Normalna jakoœæ grafiki"); + if ( num == EVENT_INTERFACE_MAX ) strcpy(text, "Najwy¿sza\\Maksymalna jakoœæ grafiki (najni¿sza czêstotliwoœæ odœwie¿ania)"); + + if ( num == EVENT_INTERFACE_SILENT ) strcpy(text, "Cisza\\Brak dŸwiêków"); + if ( num == EVENT_INTERFACE_NOISY ) strcpy(text, "Normalne\\Normalna g³oœnoœæ dŸwiêków"); + + if ( num == EVENT_INTERFACE_JOYSTICK) strcpy(text, "U¿ywaj joysticka\\Joystick lub klawiatura"); + if ( num == EVENT_INTERFACE_SOLUCE ) strcpy(text, "Dostêp do rozwi¹zania\\Pokazuje rozwi¹zanie (szczegó³owe instrukcje dotycz¹ce misji)"); + + if ( num == EVENT_INTERFACE_NEDIT ) strcpy(text, "\\Nowe imiê gracza"); + if ( num == EVENT_INTERFACE_NOK ) strcpy(text, "OK\\Wybiera zaznaczonego gracza"); + if ( num == EVENT_INTERFACE_NCANCEL) strcpy(text, "Anuluj\\Zachowuje bie¿¹ce imiê gracza"); + if ( num == EVENT_INTERFACE_NDELETE) strcpy(text, "Usuñ gracza\\Usuwa gracza z listy"); + if ( num == EVENT_INTERFACE_NLABEL ) strcpy(text, "Imiê gracza"); + + if ( num == EVENT_INTERFACE_IOWRITE) strcpy(text, "Zapisz\\Zapisuje bie¿¹c¹ misjê"); + if ( num == EVENT_INTERFACE_IOREAD ) strcpy(text, "Wczytaj\\Wczytuje zaznaczon¹ misjê"); + if ( num == EVENT_INTERFACE_IOLIST ) strcpy(text, "Lista zapisanych misji"); + if ( num == EVENT_INTERFACE_IOLABEL) strcpy(text, "Nazwa pliku:"); + if ( num == EVENT_INTERFACE_IONAME ) strcpy(text, "Nazwa misji"); + if ( num == EVENT_INTERFACE_IOIMAGE) strcpy(text, "Fotografia"); + if ( num == EVENT_INTERFACE_IODELETE) strcpy(text, "Usuñ\\Usuwa zaznaczony plik"); + + if ( num == EVENT_INTERFACE_PERSO ) strcpy(text, "Wygl¹d\\Wybierz swoj¹ postaæ"); + if ( num == EVENT_INTERFACE_POK ) strcpy(text, "OK"); + if ( num == EVENT_INTERFACE_PCANCEL) strcpy(text, "Anuluj"); + if ( num == EVENT_INTERFACE_PDEF ) strcpy(text, "Standardowe\\Standardowe ustawienia wygl¹du"); + if ( num == EVENT_INTERFACE_PHEAD ) strcpy(text, "G³owa\\Twarz i w³osy"); + if ( num == EVENT_INTERFACE_PBODY ) strcpy(text, "Skafander\\Skafander astronauty"); + if ( num == EVENT_INTERFACE_PLROT ) strcpy(text, "\\Obróæ w lewo"); + if ( num == EVENT_INTERFACE_PRROT ) strcpy(text, "\\Obróæ w prawo"); + if ( num == EVENT_INTERFACE_PCRa ) strcpy(text, "Czerwony"); + if ( num == EVENT_INTERFACE_PCGa ) strcpy(text, "Zielony"); + if ( num == EVENT_INTERFACE_PCBa ) strcpy(text, "Niebieski"); + if ( num == EVENT_INTERFACE_PCRb ) strcpy(text, "Czerwony"); + if ( num == EVENT_INTERFACE_PCGb ) strcpy(text, "Zielony"); + if ( num == EVENT_INTERFACE_PCBb ) strcpy(text, "Niebieski"); + if ( num == EVENT_INTERFACE_PFACE1 ) strcpy(text, "\\Twarz 1"); + if ( num == EVENT_INTERFACE_PFACE2 ) strcpy(text, "\\Twarz 4"); + if ( num == EVENT_INTERFACE_PFACE3 ) strcpy(text, "\\Twarz 3"); + if ( num == EVENT_INTERFACE_PFACE4 ) strcpy(text, "\\Twarz 2"); + if ( num == EVENT_INTERFACE_PGLASS0) strcpy(text, "\\Bez okularów"); + if ( num == EVENT_INTERFACE_PGLASS1) strcpy(text, "\\Okulary 1"); + if ( num == EVENT_INTERFACE_PGLASS2) strcpy(text, "\\Okulary 2"); + if ( num == EVENT_INTERFACE_PGLASS3) strcpy(text, "\\Okulary 3"); + if ( num == EVENT_INTERFACE_PGLASS4) strcpy(text, "\\Okulary 4"); + if ( num == EVENT_INTERFACE_PGLASS5) strcpy(text, "\\Okulary 5"); + + if ( num == EVENT_OBJECT_DESELECT ) strcpy(text, "Poprzednie zaznaczenie (\\key desel;)"); + if ( num == EVENT_OBJECT_LEFT ) strcpy(text, "Skrêæ w lewo (\\key left;)"); + if ( num == EVENT_OBJECT_RIGHT ) strcpy(text, "Skrêæ w prawo (\\key right;)"); + if ( num == EVENT_OBJECT_UP ) strcpy(text, "Naprzód (\\key up;)"); + if ( num == EVENT_OBJECT_DOWN ) strcpy(text, "Cofnij (\\key down;)"); + if ( num == EVENT_OBJECT_GASUP ) strcpy(text, "Góra (\\key gup;)"); + if ( num == EVENT_OBJECT_GASDOWN ) strcpy(text, "Dó³ (\\key gdown;)"); + if ( num == EVENT_OBJECT_HTAKE ) strcpy(text, "Podnieœ lub upuœæ (\\key action;)"); + if ( num == EVENT_OBJECT_MTAKE ) strcpy(text, "Podnieœ lub upuœæ (\\key action;)"); + if ( num == EVENT_OBJECT_MFRONT ) strcpy(text, "..przed"); + if ( num == EVENT_OBJECT_MBACK ) strcpy(text, "..za"); + if ( num == EVENT_OBJECT_MPOWER ) strcpy(text, "..ogniwo elektryczne"); + if ( num == EVENT_OBJECT_BHELP ) strcpy(text, "Rozkazy dotycz¹ce misji (\\key help;)"); + if ( num == EVENT_OBJECT_BTAKEOFF ) strcpy(text, "Odleæ, aby zakoñczyæ misjê"); + if ( num == EVENT_OBJECT_BDERRICK ) strcpy(text, "Zbuduj kopalniê"); + if ( num == EVENT_OBJECT_BSTATION ) strcpy(text, "Zbuduj elektrowniê"); + if ( num == EVENT_OBJECT_BFACTORY ) strcpy(text, "Zbuduj fabrykê robotów"); + if ( num == EVENT_OBJECT_BREPAIR ) strcpy(text, "Zbuduj warsztat"); + if ( num == EVENT_OBJECT_BCONVERT ) strcpy(text, "Zbuduj hutê"); + if ( num == EVENT_OBJECT_BTOWER ) strcpy(text, "Zbuduj wie¿ê obronn¹"); + if ( num == EVENT_OBJECT_BRESEARCH ) strcpy(text, "Zbuduj centrum badawcze"); + if ( num == EVENT_OBJECT_BRADAR ) strcpy(text, "Zbuduj stacjê radarow¹"); + if ( num == EVENT_OBJECT_BENERGY ) strcpy(text, "Zbuduj fabrykê ogniw elektrycznych"); + if ( num == EVENT_OBJECT_BLABO ) strcpy(text, "Zbuduj laboratorium"); + if ( num == EVENT_OBJECT_BNUCLEAR ) strcpy(text, "Zbuduj elektrowniê atomow¹"); + if ( num == EVENT_OBJECT_BPARA ) strcpy(text, "Zbuduj odgromnik"); + if ( num == EVENT_OBJECT_BINFO ) strcpy(text, "Zbuduj stacjê przekaŸnikow¹"); + if ( num == EVENT_OBJECT_GFLAT ) strcpy(text, "Poka¿ czy teren jest p³aski"); + if ( num == EVENT_OBJECT_FCREATE ) strcpy(text, "Postaw flagê"); + if ( num == EVENT_OBJECT_FDELETE ) strcpy(text, "Usuñ flagê"); + if ( num == EVENT_OBJECT_FCOLORb ) strcpy(text, "\\Niebieskie flagi"); + if ( num == EVENT_OBJECT_FCOLORr ) strcpy(text, "\\Czerwone flagi"); + if ( num == EVENT_OBJECT_FCOLORg ) strcpy(text, "\\Zielone flagi"); + if ( num == EVENT_OBJECT_FCOLORy ) strcpy(text, "\\¯ó³te flagi"); + if ( num == EVENT_OBJECT_FCOLORv ) strcpy(text, "\\Fioletowe flagi"); + if ( num == EVENT_OBJECT_FACTORYfa ) strcpy(text, "Zbuduj transporter lataj¹cy"); + if ( num == EVENT_OBJECT_FACTORYta ) strcpy(text, "Zbuduj transporter na g¹sienicach"); + if ( num == EVENT_OBJECT_FACTORYwa ) strcpy(text, "Zbuduj transporter na ko³ach"); + if ( num == EVENT_OBJECT_FACTORYia ) strcpy(text, "Zbuduj transporter na nogach"); + if ( num == EVENT_OBJECT_FACTORYfc ) strcpy(text, "Zbuduj dzia³o lataj¹ce"); + if ( num == EVENT_OBJECT_FACTORYtc ) strcpy(text, "Zbuduj dzia³o na g¹sienicach"); + if ( num == EVENT_OBJECT_FACTORYwc ) strcpy(text, "Zbuduj dzia³o na ko³ach"); + if ( num == EVENT_OBJECT_FACTORYic ) strcpy(text, "Zbuduj dzia³o na nogach"); + if ( num == EVENT_OBJECT_FACTORYfi ) strcpy(text, "Zbuduj lataj¹ce dzia³o organiczne"); + if ( num == EVENT_OBJECT_FACTORYti ) strcpy(text, "Zbuduj dzia³o organiczne na g¹sienicach"); + if ( num == EVENT_OBJECT_FACTORYwi ) strcpy(text, "Zbuduj dzia³o organiczne na ko³ach"); + if ( num == EVENT_OBJECT_FACTORYii ) strcpy(text, "Zbuduj dzia³o organiczne na nogach"); + if ( num == EVENT_OBJECT_FACTORYfs ) strcpy(text, "Zbuduj szperacz lataj¹cy"); + if ( num == EVENT_OBJECT_FACTORYts ) strcpy(text, "Zbuduj szperacz na g¹sienicach"); + if ( num == EVENT_OBJECT_FACTORYws ) strcpy(text, "Zbuduj szperacz na ko³ach"); + if ( num == EVENT_OBJECT_FACTORYis ) strcpy(text, "Zbuduj szperacz na nogach"); + if ( num == EVENT_OBJECT_FACTORYrt ) strcpy(text, "Zbuduj robota uderzacza"); + if ( num == EVENT_OBJECT_FACTORYrc ) strcpy(text, "Zbuduj dzia³o fazowe"); + if ( num == EVENT_OBJECT_FACTORYrr ) strcpy(text, "Zbuduj robota recyklera"); + if ( num == EVENT_OBJECT_FACTORYrs ) strcpy(text, "Zbuduj robota os³aniajacza"); + if ( num == EVENT_OBJECT_FACTORYsa ) strcpy(text, "Zbuduj robota nurka"); + if ( num == EVENT_OBJECT_RTANK ) strcpy(text, "Rozpocznij prace badawcze nad transporterem na g¹sienicach"); + if ( num == EVENT_OBJECT_RFLY ) strcpy(text, "Rozpocznij prace badawcze nad transporterem lataj¹cym"); + if ( num == EVENT_OBJECT_RTHUMP ) strcpy(text, "Rozpocznij prace badawcze nad robotem uderzaczem"); + if ( num == EVENT_OBJECT_RCANON ) strcpy(text, "Rozpocznij prace badawcze nad dzia³em"); + if ( num == EVENT_OBJECT_RTOWER ) strcpy(text, "Rozpocznij prace badawcze nad wie¿¹ obronn¹"); + if ( num == EVENT_OBJECT_RPHAZER ) strcpy(text, "Rozpocznij prace badawcze nad dzia³em fazowym"); + if ( num == EVENT_OBJECT_RSHIELD ) strcpy(text, "Rozpocznij prace badawcze nad robotem os³aniaczem"); + if ( num == EVENT_OBJECT_RATOMIC ) strcpy(text, "Rozpocznij prace badawcze nad energi¹ atomow¹"); + if ( num == EVENT_OBJECT_RiPAW ) strcpy(text, "Rozpocznij prace badawcze nad transporterem na nogach"); + if ( num == EVENT_OBJECT_RiGUN ) strcpy(text, "Rozpocznij prace badawcze nad dzia³em organicznym"); + if ( num == EVENT_OBJECT_RESET ) strcpy(text, "Powrót do pocz¹tku"); + if ( num == EVENT_OBJECT_SEARCH ) strcpy(text, "Szukaj (\\key action;)"); + if ( num == EVENT_OBJECT_TERRAFORM ) strcpy(text, "Uderz (\\key action;)"); + if ( num == EVENT_OBJECT_FIRE ) strcpy(text, "Strzelaj (\\key action;)"); + if ( num == EVENT_OBJECT_RECOVER ) strcpy(text, "Odzyskaj (\\key action;)"); + if ( num == EVENT_OBJECT_BEGSHIELD ) strcpy(text, "Rozszerz os³onê (\\key action;)"); + if ( num == EVENT_OBJECT_ENDSHIELD ) strcpy(text, "Wy³¹cz os³onê (\\key action;)"); + if ( num == EVENT_OBJECT_DIMSHIELD ) strcpy(text, "Zasiêg os³ony"); + if ( num == EVENT_OBJECT_PROGRUN ) strcpy(text, "Wykonaj zaznaczony program"); + if ( num == EVENT_OBJECT_PROGEDIT ) strcpy(text, "Edytuj zaznaczony program"); + if ( num == EVENT_OBJECT_INFOOK ) strcpy(text, "\\Prze³¹cz przekaŸnik SatCom w stan gotowoœci"); + if ( num == EVENT_OBJECT_DELETE ) strcpy(text, "Zniszcz budynek"); + if ( num == EVENT_OBJECT_GENERGY ) strcpy(text, "Poziom energii"); + if ( num == EVENT_OBJECT_GSHIELD ) strcpy(text, "Poziom os³ony"); + if ( num == EVENT_OBJECT_GRANGE ) strcpy(text, "Temperatura silnika"); + if ( num == EVENT_OBJECT_GPROGRESS ) strcpy(text, "Wci¹¿ pracuje..."); + if ( num == EVENT_OBJECT_GRADAR ) strcpy(text, "Liczba wykrytych insektów"); + if ( num == EVENT_OBJECT_GINFO ) strcpy(text, "Przes³ane informacje"); + if ( num == EVENT_OBJECT_COMPASS ) strcpy(text, "Kompas"); +//? if ( num == EVENT_OBJECT_MAP ) strcpy(text, "Mapka"); + if ( num == EVENT_OBJECT_MAPZOOM ) strcpy(text, "Powiêkszenie mapki"); + if ( num == EVENT_OBJECT_CAMERA ) strcpy(text, "Kamera (\\key camera;)"); + if ( num == EVENT_OBJECT_CAMERAleft) strcpy(text, "Camera to left"); + if ( num == EVENT_OBJECT_CAMERAright) strcpy(text, "Camera to right"); + if ( num == EVENT_OBJECT_CAMERAnear) strcpy(text, "Camera nearest"); + if ( num == EVENT_OBJECT_CAMERAaway) strcpy(text, "Camera awayest"); + if ( num == EVENT_OBJECT_HELP ) strcpy(text, "Pomoc na temat zaznaczonego obiektu"); + if ( num == EVENT_OBJECT_SOLUCE ) strcpy(text, "Poka¿ rozwi¹zanie"); + if ( num == EVENT_OBJECT_SHORTCUT00) strcpy(text, "Prze³¹cz roboty <-> budynki"); + if ( num == EVENT_OBJECT_LIMIT ) strcpy(text, "Poka¿ zasiêg"); + if ( num == EVENT_OBJECT_PEN0 ) strcpy(text, "\\Relève le crayon"); + if ( num == EVENT_OBJECT_PEN1 ) strcpy(text, "\\Abaisse le crayon noir"); + if ( num == EVENT_OBJECT_PEN2 ) strcpy(text, "\\Abaisse le crayon jaune"); + if ( num == EVENT_OBJECT_PEN3 ) strcpy(text, "\\Abaisse le crayon orange"); + if ( num == EVENT_OBJECT_PEN4 ) strcpy(text, "\\Abaisse le crayon rouge"); + if ( num == EVENT_OBJECT_PEN5 ) strcpy(text, "\\Abaisse le crayon violet"); + if ( num == EVENT_OBJECT_PEN6 ) strcpy(text, "\\Abaisse le crayon bleu"); + if ( num == EVENT_OBJECT_PEN7 ) strcpy(text, "\\Abaisse le crayon vert"); + if ( num == EVENT_OBJECT_PEN8 ) strcpy(text, "\\Abaisse le crayon brun"); + if ( num == EVENT_OBJECT_REC ) strcpy(text, "\\Démarre l'enregistrement"); + if ( num == EVENT_OBJECT_STOP ) strcpy(text, "\\Stoppe l'enregistrement"); + if ( num == EVENT_DT_VISIT0 || + num == EVENT_DT_VISIT1 || + num == EVENT_DT_VISIT2 || + num == EVENT_DT_VISIT3 || + num == EVENT_DT_VISIT4 ) strcpy(text, "Poka¿ miejsce"); + if ( num == EVENT_DT_END ) strcpy(text, "Kontynuuj"); + if ( num == EVENT_CMD ) strcpy(text, "Linia polecenia"); + if ( num == EVENT_SPEED ) strcpy(text, "Prêdkoœæ gry"); + + if ( num == EVENT_HYPER_PREV ) strcpy(text, "Wstecz"); + if ( num == EVENT_HYPER_NEXT ) strcpy(text, "Naprzód"); + if ( num == EVENT_HYPER_HOME ) strcpy(text, "Pocz¹tek"); + if ( num == EVENT_HYPER_COPY ) strcpy(text, "Kopiuj"); + if ( num == EVENT_HYPER_SIZE1 ) strcpy(text, "Wielkoœæ 1"); + if ( num == EVENT_HYPER_SIZE2 ) strcpy(text, "Wielkoœæ 2"); + if ( num == EVENT_HYPER_SIZE3 ) strcpy(text, "Wielkoœæ 3"); + if ( num == EVENT_HYPER_SIZE4 ) strcpy(text, "Wielkoœæ 4"); + if ( num == EVENT_HYPER_SIZE5 ) strcpy(text, "Wielkoœæ 5"); + if ( num == EVENT_SATCOM_HUSTON ) strcpy(text, "Rozkazy z Houston"); +#if _TEEN + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Raport z satelity"); +#else + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Raport z satelity"); +#endif + if ( num == EVENT_SATCOM_LOADING ) strcpy(text, "Program dostarczony z Houston"); + if ( num == EVENT_SATCOM_OBJECT ) strcpy(text, "Lista obiektów"); + if ( num == EVENT_SATCOM_PROG ) strcpy(text, "Podrêcznik programowania"); + if ( num == EVENT_SATCOM_SOLUCE ) strcpy(text, "Rozwi¹zanie"); + + if ( num == EVENT_STUDIO_OK ) strcpy(text, "OK\\Zamyka edytor programu i powraca do gry"); + if ( num == EVENT_STUDIO_CANCEL ) strcpy(text, "Anuluj\\Pomija wszystkie zmiany"); + if ( num == EVENT_STUDIO_NEW ) strcpy(text, "Nowy"); + if ( num == EVENT_STUDIO_OPEN ) strcpy(text, "Otwórz (Ctrl+O)"); + if ( num == EVENT_STUDIO_SAVE ) strcpy(text, "Zapisz (Ctrl+S)"); + if ( num == EVENT_STUDIO_UNDO ) strcpy(text, "Cofnij (Ctrl+Z)"); + if ( num == EVENT_STUDIO_CUT ) strcpy(text, "Wytnij (Ctrl+X)"); + if ( num == EVENT_STUDIO_COPY ) strcpy(text, "Kopiuj (Ctrl+C)"); + if ( num == EVENT_STUDIO_PASTE ) strcpy(text, "Wklej (Ctrl+V)"); + if ( num == EVENT_STUDIO_SIZE ) strcpy(text, "Wielkoœæ czcionki"); + if ( num == EVENT_STUDIO_TOOL ) strcpy(text, "Rozkazy (\\key help;)"); + if ( num == EVENT_STUDIO_HELP ) strcpy(text, "Podrêcznik programowania (\\key prog;)"); + if ( num == EVENT_STUDIO_COMPILE ) strcpy(text, "Kompiluj"); + if ( num == EVENT_STUDIO_RUN ) strcpy(text, "Wykonaj/Zatrzymaj"); + if ( num == EVENT_STUDIO_REALTIME ) strcpy(text, "Pauza/Kontynuuj"); + if ( num == EVENT_STUDIO_STEP ) strcpy(text, "Jeden krok"); + } + + if ( type == RES_OBJECT ) + { + if ( num == OBJECT_PORTICO ) strcpy(text, "¯uraw przesuwalny"); + if ( num == OBJECT_BASE ) strcpy(text, "Statek kosmiczny"); + if ( num == OBJECT_DERRICK ) strcpy(text, "Kopalnia"); + if ( num == OBJECT_FACTORY ) strcpy(text, "Fabryka robotów"); + if ( num == OBJECT_REPAIR ) strcpy(text, "Warsztat"); + if ( num == OBJECT_DESTROYER ) strcpy(text, "Destroyer"); + if ( num == OBJECT_STATION ) strcpy(text, "Stacja energetyczna"); + if ( num == OBJECT_CONVERT ) strcpy(text, "Przetop rudê na tytan"); + if ( num == OBJECT_TOWER ) strcpy(text, "Wie¿a obronna"); + if ( num == OBJECT_NEST ) strcpy(text, "Gniazdo"); + if ( num == OBJECT_RESEARCH ) strcpy(text, "Centrum badawcze"); + if ( num == OBJECT_RADAR ) strcpy(text, "Stacja radarowa"); + if ( num == OBJECT_INFO ) strcpy(text, "Stacja przekaŸnikowa informacji"); +#if _TEEN + if ( num == OBJECT_ENERGY ) strcpy(text, "Fabryka ogniw elektrycznych"); +#else + if ( num == OBJECT_ENERGY ) strcpy(text, "Fabryka ogniw elektrycznych"); +#endif + if ( num == OBJECT_LABO ) strcpy(text, "Laboratorium"); + if ( num == OBJECT_NUCLEAR ) strcpy(text, "Elektrownia atomowa"); + if ( num == OBJECT_PARA ) strcpy(text, "Odgromnik"); + if ( num == OBJECT_SAFE ) strcpy(text, "Skrytka"); + if ( num == OBJECT_HUSTON ) strcpy(text, "Centrum Kontroli Misji w Houston"); + if ( num == OBJECT_TARGET1 ) strcpy(text, "Cel"); + if ( num == OBJECT_TARGET2 ) strcpy(text, "Cel"); + if ( num == OBJECT_START ) strcpy(text, "Pocz¹tek"); + if ( num == OBJECT_END ) strcpy(text, "Koniec"); + if ( num == OBJECT_STONE ) strcpy(text, "Ruda tytanu"); + if ( num == OBJECT_URANIUM ) strcpy(text, "Ruda uranu"); + if ( num == OBJECT_BULLET ) strcpy(text, "Materia organiczna"); + if ( num == OBJECT_METAL ) strcpy(text, "Tytan"); + if ( num == OBJECT_POWER ) strcpy(text, "Ogniwo elektryczne"); + if ( num == OBJECT_ATOMIC ) strcpy(text, "Atomowe ogniwa elektryczne"); + if ( num == OBJECT_BBOX ) strcpy(text, "Czarna skrzynka"); + if ( num == OBJECT_KEYa ) strcpy(text, "Klucz A"); + if ( num == OBJECT_KEYb ) strcpy(text, "Klucz B"); + if ( num == OBJECT_KEYc ) strcpy(text, "Klucz C"); + if ( num == OBJECT_KEYd ) strcpy(text, "Klucz D"); + if ( num == OBJECT_TNT ) strcpy(text, "Materia³y wybuchowe"); + if ( num == OBJECT_BOMB ) strcpy(text, "Mina"); + if ( num == OBJECT_BAG ) strcpy(text, "Zestaw przetrwania"); + if ( num == OBJECT_WAYPOINT ) strcpy(text, "Punkt kontrolny"); + if ( num == OBJECT_FLAGb ) strcpy(text, "Niebieska flaga"); + if ( num == OBJECT_FLAGr ) strcpy(text, "Czerwona flaga"); + if ( num == OBJECT_FLAGg ) strcpy(text, "Zielona flaga"); + if ( num == OBJECT_FLAGy ) strcpy(text, "¯ó³ta flaga"); + if ( num == OBJECT_FLAGv ) strcpy(text, "Fioletowa flaga"); + if ( num == OBJECT_MARKPOWER ) strcpy(text, "ród³o energii (miejsce na elektrowniê)"); + if ( num == OBJECT_MARKURANIUM ) strcpy(text, "Z³o¿e uranu (miejsce na kopalniê)"); + if ( num == OBJECT_MARKKEYa ) strcpy(text, "Znaleziono klucz A (miejsce na kopalniê)"); + if ( num == OBJECT_MARKKEYb ) strcpy(text, "Znaleziono klucz B (miejsce na kopalniê)"); + if ( num == OBJECT_MARKKEYc ) strcpy(text, "Znaleziono klucz C (miejsce na kopalniê)"); + if ( num == OBJECT_MARKKEYd ) strcpy(text, "Znaleziono klucz D (miejsce na kopalniê)"); + if ( num == OBJECT_MARKSTONE ) strcpy(text, "Z³o¿e tytanu (miejsce na kopalniê)"); + if ( num == OBJECT_MOBILEft ) strcpy(text, "Robot treningowy"); + if ( num == OBJECT_MOBILEtt ) strcpy(text, "Robot treningowy"); + if ( num == OBJECT_MOBILEwt ) strcpy(text, "Robot treningowy"); + if ( num == OBJECT_MOBILEit ) strcpy(text, "Robot treningowy"); + if ( num == OBJECT_MOBILEfa ) strcpy(text, "Transporter lataj¹cy"); + if ( num == OBJECT_MOBILEta ) strcpy(text, "Transporter na g¹sienicach"); + if ( num == OBJECT_MOBILEwa ) strcpy(text, "Transporter na ko³ach"); + if ( num == OBJECT_MOBILEia ) strcpy(text, "Transporter na nogach"); + if ( num == OBJECT_MOBILEfc ) strcpy(text, "Dzia³o lataj¹ce"); + if ( num == OBJECT_MOBILEtc ) strcpy(text, "Dzia³o na g¹sienicach"); + if ( num == OBJECT_MOBILEwc ) strcpy(text, "Dzia³o na ko³ach"); + if ( num == OBJECT_MOBILEic ) strcpy(text, "Dzia³o na nogach"); + if ( num == OBJECT_MOBILEfi ) strcpy(text, "Lataj¹ce dzia³o organiczne"); + if ( num == OBJECT_MOBILEti ) strcpy(text, "Dzia³o organiczne na g¹sienicach"); + if ( num == OBJECT_MOBILEwi ) strcpy(text, "Dzia³o organiczne na ko³ach"); + if ( num == OBJECT_MOBILEii ) strcpy(text, "Dzia³o organiczne na nogach"); + if ( num == OBJECT_MOBILEfs ) strcpy(text, "Szperacz lataj¹cy"); + if ( num == OBJECT_MOBILEts ) strcpy(text, "Szperacz na g¹sienicach"); + if ( num == OBJECT_MOBILEws ) strcpy(text, "Szperacz na ko³ach"); + if ( num == OBJECT_MOBILEis ) strcpy(text, "Szperacz na nogach"); + if ( num == OBJECT_MOBILErt ) strcpy(text, "Uderzacz"); + if ( num == OBJECT_MOBILErc ) strcpy(text, "Dzia³o fazowe"); + if ( num == OBJECT_MOBILErr ) strcpy(text, "Recykler"); + if ( num == OBJECT_MOBILErs ) strcpy(text, "Os³aniacz"); + if ( num == OBJECT_MOBILEsa ) strcpy(text, "Robot nurek"); + if ( num == OBJECT_MOBILEtg ) strcpy(text, "Robot cel"); + if ( num == OBJECT_MOBILEdr ) strcpy(text, "Drawer bot"); + if ( num == OBJECT_HUMAN ) strcpy(text, g_gamerName); + if ( num == OBJECT_TECH ) strcpy(text, "In¿ynier"); + if ( num == OBJECT_TOTO ) strcpy(text, "Robbie"); + if ( num == OBJECT_MOTHER ) strcpy(text, "Królowa Obcych"); + if ( num == OBJECT_ANT ) strcpy(text, "Mrówka"); + if ( num == OBJECT_SPIDER ) strcpy(text, "Paj¹k"); + if ( num == OBJECT_BEE ) strcpy(text, "Osa"); + if ( num == OBJECT_WORM ) strcpy(text, "Robal"); + if ( num == OBJECT_EGG ) strcpy(text, "Jajo"); + if ( num == OBJECT_RUINmobilew1 ) strcpy(text, "Wrak"); + if ( num == OBJECT_RUINmobilew2 ) strcpy(text, "Wrak"); + if ( num == OBJECT_RUINmobilet1 ) strcpy(text, "Wrak"); + if ( num == OBJECT_RUINmobilet2 ) strcpy(text, "Wrak"); + if ( num == OBJECT_RUINmobiler1 ) strcpy(text, "Wrak"); + if ( num == OBJECT_RUINmobiler2 ) strcpy(text, "Wrak"); + if ( num == OBJECT_RUINfactory ) strcpy(text, "Ruiny"); + if ( num == OBJECT_RUINdoor ) strcpy(text, "Ruiny"); + if ( num == OBJECT_RUINsupport ) strcpy(text, "Odpady"); + if ( num == OBJECT_RUINradar ) strcpy(text, "Ruiny"); + if ( num == OBJECT_RUINconvert ) strcpy(text, "Ruiny"); + if ( num == OBJECT_RUINbase ) strcpy(text, "Ruiny statku kosmicznego"); + if ( num == OBJECT_RUINhead ) strcpy(text, "Ruiny statku kosmicznego"); + if ( num == OBJECT_APOLLO1 || + num == OBJECT_APOLLO3 || + num == OBJECT_APOLLO4 || + num == OBJECT_APOLLO5 ) strcpy(text, "Pozosta³oœci z misji Apollo"); + if ( num == OBJECT_APOLLO2 ) strcpy(text, "Pojazd Ksiê¿ycowy"); + } + + if ( type == RES_ERR ) + { + strcpy(text, "B³¹d"); + if ( num == ERR_CMD ) strcpy(text, "Nieznane polecenie"); +#if _NEWLOOK + if ( num == ERR_INSTALL ) strcpy(text, "Gra CeeBot nie jest zainstalowana."); + if ( num == ERR_NOCD ) strcpy(text, "W³ó¿ dysk CD z gr¹ CeeBot\ni uruchom grê jeszcze raz."); +#else + if ( num == ERR_INSTALL ) strcpy(text, "Gra COLOBOT nie jest zainstalowana."); + if ( num == ERR_NOCD ) strcpy(text, "W³ó¿ dysk CD z gr¹ COLOBOT\ni uruchom grê jeszcze raz."); +#endif + if ( num == ERR_MANIP_VEH ) strcpy(text, "Nieodpowiedni robot"); + if ( num == ERR_MANIP_FLY ) strcpy(text, "Niemo¿liwe podczas lotu"); + if ( num == ERR_MANIP_BUSY ) strcpy(text, "Nie mo¿na nieœæ wiêcej przedmiotów"); + if ( num == ERR_MANIP_NIL ) strcpy(text, "Nie ma nic do podniesienia"); + if ( num == ERR_MANIP_MOTOR ) strcpy(text, "Niemo¿liwe podczas ruchu"); + if ( num == ERR_MANIP_OCC ) strcpy(text, "Miejsce zajête"); + if ( num == ERR_MANIP_FRIEND ) strcpy(text, "Brak innego robota"); + if ( num == ERR_MANIP_RADIO ) strcpy(text, "Nie mo¿esz przenosiæ przedmiotów radioaktywnych"); + if ( num == ERR_MANIP_WATER ) strcpy(text, "Nie mo¿esz przenosiæ przedmiotów pod wod¹"); + if ( num == ERR_MANIP_EMPTY ) strcpy(text, "Nie ma nic do upuszczenia"); + if ( num == ERR_BUILD_FLY ) strcpy(text, "Niemo¿liwe podczas lotu"); + if ( num == ERR_BUILD_WATER ) strcpy(text, "Niemo¿liwe pod wod¹"); + if ( num == ERR_BUILD_ENERGY ) strcpy(text, "Za ma³o energii"); + if ( num == ERR_BUILD_METALAWAY ) strcpy(text, "Tytan za daleko"); + if ( num == ERR_BUILD_METALNEAR ) strcpy(text, "Tytan za blisko"); + if ( num == ERR_BUILD_METALINEX ) strcpy(text, "Brak tytanu w pobli¿u"); + if ( num == ERR_BUILD_FLAT ) strcpy(text, "Powierzchnia nie jest wystarczaj¹co p³aska"); + if ( num == ERR_BUILD_FLATLIT ) strcpy(text, "Za ma³o p³askiego terenu"); + if ( num == ERR_BUILD_BUSY ) strcpy(text, "Miejsce zajête"); + if ( num == ERR_BUILD_BASE ) strcpy(text, "Za blisko statku kosmicznego"); + if ( num == ERR_BUILD_NARROW ) strcpy(text, "Za blisko budynku"); + if ( num == ERR_BUILD_MOTOR ) strcpy(text, "Niemo¿liwe podczas ruchu"); + if ( num == ERR_SEARCH_FLY ) strcpy(text, "Niemo¿liwe podczas lotu"); + if ( num == ERR_SEARCH_VEH ) strcpy(text, "Nieodpowiedni robot"); + if ( num == ERR_SEARCH_MOTOR ) strcpy(text, "Niemo¿liwe podczas ruchu"); + if ( num == ERR_TERRA_VEH ) strcpy(text, "Nieodpowiedni robot"); + if ( num == ERR_TERRA_ENERGY ) strcpy(text, "Za ma³o energii"); + if ( num == ERR_TERRA_FLOOR ) strcpy(text, "Nieodpowiedni teren"); + if ( num == ERR_TERRA_BUILDING ) strcpy(text, "Budynek za blisko"); + if ( num == ERR_TERRA_OBJECT ) strcpy(text, "Obiekt za blisko"); + if ( num == ERR_RECOVER_VEH ) strcpy(text, "Nieodpowiedni robot"); + if ( num == ERR_RECOVER_ENERGY ) strcpy(text, "Za ma³o energii"); + if ( num == ERR_RECOVER_NULL ) strcpy(text, "Nie ma niczego do odzysku"); + if ( num == ERR_SHIELD_VEH ) strcpy(text, "Nieodpowiedni robot"); + if ( num == ERR_SHIELD_ENERGY ) strcpy(text, "Nie ma wiêcej energii"); + if ( num == ERR_MOVE_IMPOSSIBLE ) strcpy(text, "B³¹d w poleceniu ruchu"); + if ( num == ERR_FIND_IMPOSSIBLE ) strcpy(text, "Obiekt nieznany"); + if ( num == ERR_GOTO_IMPOSSIBLE ) strcpy(text, "Goto: miejsce docelowe niedostêpne"); + if ( num == ERR_GOTO_ITER ) strcpy(text, "Goto: miejsce docelowe niedostêpne"); + if ( num == ERR_GOTO_BUSY ) strcpy(text, "Goto: miejsce docelowe zajête"); + if ( num == ERR_FIRE_VEH ) strcpy(text, "Nieodpowiedni robot"); + if ( num == ERR_FIRE_ENERGY ) strcpy(text, "Za ma³o energii"); + if ( num == ERR_FIRE_FLY ) strcpy(text, "Niemo¿liwe podczas lotu"); + if ( num == ERR_CONVERT_EMPTY ) strcpy(text, "Brak rudy tytanu do przetopienia"); + if ( num == ERR_DERRICK_NULL ) strcpy(text, "W ziemi nie ma ¿adnej rudy"); + if ( num == ERR_STATION_NULL ) strcpy(text, "Brak energii w ziemi"); + if ( num == ERR_TOWER_POWER ) strcpy(text, "Brak ogniwa elektrycznego"); + if ( num == ERR_TOWER_ENERGY ) strcpy(text, "Nie ma wiêcej energii"); + if ( num == ERR_RESEARCH_POWER ) strcpy(text, "Brak ogniwa elektrycznego"); + if ( num == ERR_RESEARCH_ENERGY ) strcpy(text, "Za ma³o energii"); + if ( num == ERR_RESEARCH_TYPE ) strcpy(text, "Nieodpowiedni rodzaj ogniw"); + if ( num == ERR_RESEARCH_ALREADY) strcpy(text, "Program badawczy zosta³ ju¿ wykonany"); + if ( num == ERR_ENERGY_NULL ) strcpy(text, "Brak energii w ziemi"); + if ( num == ERR_ENERGY_LOW ) strcpy(text, "Wci¹¿ za ma³o energii"); + if ( num == ERR_ENERGY_EMPTY ) strcpy(text, "Brak tytanu do przetworzenia"); + if ( num == ERR_ENERGY_BAD ) strcpy(text, "Przetwarza jedynie tytan"); + if ( num == ERR_BASE_DLOCK ) strcpy(text, "Drzwi zablokowane przez robota lub inny obiekt "); + if ( num == ERR_BASE_DHUMAN ) strcpy(text, "Musisz byæ na statku kosmicznym aby nim odlecieæ"); + if ( num == ERR_LABO_NULL ) strcpy(text, "Nie ma niczego do zanalizowania"); + if ( num == ERR_LABO_BAD ) strcpy(text, "Analizuje jedynie materiê organiczn¹"); + if ( num == ERR_LABO_ALREADY ) strcpy(text, "Analiza zosta³a ju¿ wykonana"); + if ( num == ERR_NUCLEAR_NULL ) strcpy(text, "Brak energii w ziemi"); + if ( num == ERR_NUCLEAR_LOW ) strcpy(text, "Wci¹¿ za ma³o energii"); + if ( num == ERR_NUCLEAR_EMPTY ) strcpy(text, "Brak uranu do przetworzenia"); + if ( num == ERR_NUCLEAR_BAD ) strcpy(text, "Przetwarza jedynie uran"); + if ( num == ERR_FACTORY_NULL ) strcpy(text, "Brak tytanu"); + if ( num == ERR_FACTORY_NEAR ) strcpy(text, "Obiekt za blisko"); + if ( num == ERR_RESET_NEAR ) strcpy(text, "Miejsce zajête"); + if ( num == ERR_INFO_NULL ) strcpy(text, "Nie ma ¿adnej stacji przekaŸnikowej w zasiêgu"); + if ( num == ERR_VEH_VIRUS ) strcpy(text, "Program zawirusowany"); + if ( num == ERR_BAT_VIRUS ) strcpy(text, "Zainfekowane wirusem, chwilowo niesprawne"); + if ( num == ERR_VEH_POWER ) strcpy(text, "Brak ogniwa elektrycznego"); + if ( num == ERR_VEH_ENERGY ) strcpy(text, "Nie ma wiêcej energii"); + if ( num == ERR_FLAG_FLY ) strcpy(text, "Niemo¿liwe podczas lotu"); + if ( num == ERR_FLAG_WATER ) strcpy(text, "Niemo¿liwe podczas p³ywania"); + if ( num == ERR_FLAG_MOTOR ) strcpy(text, "Niemo¿liwe podczas ruchu"); + if ( num == ERR_FLAG_BUSY ) strcpy(text, "Niemo¿liwe podczas przenoszenia przedmiotu"); + if ( num == ERR_FLAG_CREATE ) strcpy(text, "Za du¿o flag w tym kolorze (maksymalnie 5)"); + if ( num == ERR_FLAG_PROXY ) strcpy(text, "Za blisko istniej¹cej flagi"); + if ( num == ERR_FLAG_DELETE ) strcpy(text, "Nie ma flagi w pobli¿u"); + if ( num == ERR_MISSION_NOTERM ) strcpy(text, "Misja nie jest wype³niona (naciœnij \\key help; aby uzyskaæ szczegó³y)"); + if ( num == ERR_DELETEMOBILE ) strcpy(text, "Robot zniszczony"); + if ( num == ERR_DELETEBUILDING ) strcpy(text, "Budynek zniszczony"); + if ( num == ERR_TOOMANY ) strcpy(text, "Nie mo¿na tego utworzyæ, za du¿o obiektów"); + if ( num == ERR_OBLIGATORYTOKEN ) strcpy(text, "It misses \"%s\" in this exercise"); + if ( num == ERR_PROHIBITEDTOKEN ) strcpy(text, "Do not use in this exercise"); + + if ( num == INFO_BUILD ) strcpy(text, "Budowa zakoñczona"); + if ( num == INFO_CONVERT ) strcpy(text, "Tytan dostêpny"); + if ( num == INFO_RESEARCH ) strcpy(text, "Program badawczy zakoñczony"); + if ( num == INFO_RESEARCHTANK ) strcpy(text, "Dostêpne plany tranporterów na g¹sienicach"); + if ( num == INFO_RESEARCHFLY ) strcpy(text, "Mo¿esz lataæ u¿ywaj¹c klawiszy (\\key gup;) oraz (\\key gdown;)"); + if ( num == INFO_RESEARCHTHUMP ) strcpy(text, "Dostêpne plany robota uderzacza"); + if ( num == INFO_RESEARCHCANON ) strcpy(text, "Dostêpne plany dzia³a"); + if ( num == INFO_RESEARCHTOWER ) strcpy(text, "Dostêpne plany wie¿y obronnej"); + if ( num == INFO_RESEARCHPHAZER ) strcpy(text, "Dostêpne plany dzia³a fazowego"); + if ( num == INFO_RESEARCHSHIELD ) strcpy(text, "Dostêpne plany robota os³aniacza"); + if ( num == INFO_RESEARCHATOMIC ) strcpy(text, "Dostêpne plany elektrowni atomowej"); + if ( num == INFO_FACTORY ) strcpy(text, "Dostêpny nowy robot"); + if ( num == INFO_LABO ) strcpy(text, "Analiza wykonana"); + if ( num == INFO_ENERGY ) strcpy(text, "Wytworzono ogniwo elektryczne"); + if ( num == INFO_NUCLEAR ) strcpy(text, "Wytworzono atomowe ogniwo elektryczne"); + if ( num == INFO_FINDING ) strcpy(text, "Znaleziono u¿yteczny przedmiot"); + if ( num == INFO_MARKPOWER ) strcpy(text, "Znaleziono miejsce na elektrowniê"); + if ( num == INFO_MARKURANIUM ) strcpy(text, "Znaleziono miejsce na kopalniê"); + if ( num == INFO_MARKSTONE ) strcpy(text, "Znaleziono miejsce na kopalniê"); + if ( num == INFO_MARKKEYa ) strcpy(text, "Znaleziono miejsce na kopalniê"); + if ( num == INFO_MARKKEYb ) strcpy(text, "Znaleziono miejsce na kopalniê"); + if ( num == INFO_MARKKEYc ) strcpy(text, "Znaleziono miejsce na kopalniê"); + if ( num == INFO_MARKKEYd ) strcpy(text, "Znaleziono miejsce na kopalniê"); + if ( num == INFO_WIN ) strcpy(text, "<<< Dobra robota, misja wype³niona >>>"); + if ( num == INFO_LOST ) strcpy(text, "<<< Niestety, misja nie powiod³a siê >>>"); + if ( num == INFO_LOSTq ) strcpy(text, "<<< Niestety, misja nie powiod³a siê >>>"); + if ( num == INFO_WRITEOK ) strcpy(text, "Bie¿¹ca misja zapisana"); + if ( num == INFO_DELETEPATH ) strcpy(text, "Przekroczono punkt kontrolny"); + if ( num == INFO_DELETEMOTHER ) strcpy(text, "Królowa Obcych zosta³a zabita"); + if ( num == INFO_DELETEANT ) strcpy(text, "Mrówka œmiertelnie raniona"); + if ( num == INFO_DELETEBEE ) strcpy(text, "Osa œmiertelnie raniona"); + if ( num == INFO_DELETEWORM ) strcpy(text, "Robal œmiertelnie raniony"); + if ( num == INFO_DELETESPIDER ) strcpy(text, "Paj¹k œmiertelnie raniony"); + if ( num == INFO_BEGINSATCOM ) strcpy(text, "Naciœnij klawisz \\key help; aby wyœwietliæ rozkazy na przekaŸniku SatCom"); + } + + if ( type == RES_CBOT ) + { + strcpy(text, "B³¹d"); + if ( num == TX_OPENPAR ) strcpy(text, "Brak nawiasu otwieraj¹cego"); + if ( num == TX_CLOSEPAR ) strcpy(text, "Brak nawiasu zamykaj¹cego"); + if ( num == TX_NOTBOOL ) strcpy(text, "Wyra¿enie musi zwróciæ wartoœæ logiczn¹"); + if ( num == TX_UNDEFVAR ) strcpy(text, "Zmienna nie zosta³a zadeklarowana"); + if ( num == TX_BADLEFT ) strcpy(text, "Przypisanie niemo¿liwe"); + if ( num == TX_ENDOF ) strcpy(text, "Brak œrednika na koñcu wiersza"); + if ( num == TX_OUTCASE ) strcpy(text, "Polecenie ""case"" na zewn¹trz bloku ""switch"""); + if ( num == TX_NOTERM ) strcpy(text, "Polecenie po koñcowej klamrze zamykaj¹cej"); + if ( num == TX_CLOSEBLK ) strcpy(text, "Brak koñca bloku"); + if ( num == TX_ELSEWITHOUTIF ) strcpy(text, "Polecenie ""else"" bez wyst¹pienia ""if"" "); + if ( num == TX_OPENBLK ) strcpy(text, "Brak klamry otwieraj¹cej");//début d'un bloc attendu? + if ( num == TX_BADTYPE ) strcpy(text, "Z³y typ dla przypisania"); + if ( num == TX_REDEFVAR ) strcpy(text, "Zmienna nie mo¿e byæ zadeklarowana dwukrotnie"); + if ( num == TX_BAD2TYPE ) strcpy(text, "Niezgodne typy operatorów"); + if ( num == TX_UNDEFCALL ) strcpy(text, "Funkcja nieznana"); + if ( num == TX_MISDOTS ) strcpy(text, "Brak znaku "" : "); + if ( num == TX_WHILE ) strcpy(text, "Brak kluczowego s³owa ""while"); + if ( num == TX_BREAK ) strcpy(text, "Polecenie ""break"" na zewn¹trz pêtli"); + if ( num == TX_LABEL ) strcpy(text, "Po etykiecie musi wyst¹piæ ""for"", ""while"", ""do"" lub ""switch"""); + if ( num == TX_NOLABEL ) strcpy(text, "Taka etykieta nie istnieje");// Cette étiquette n'existe pas + if ( num == TX_NOCASE ) strcpy(text, "Brak polecenia ""case"); + if ( num == TX_BADNUM ) strcpy(text, "Brak liczby"); + if ( num == TX_VOID ) strcpy(text, "Pusty parametr"); + if ( num == TX_NOTYP ) strcpy(text, "Brak deklaracji typu"); + if ( num == TX_NOVAR ) strcpy(text, "Brak nazwy zmiennej"); + if ( num == TX_NOFONC ) strcpy(text, "Brakuj¹ca nazwa funkcji"); + if ( num == TX_OVERPARAM ) strcpy(text, "Za du¿o parametrów"); + if ( num == TX_REDEF ) strcpy(text, "Funkcja ju¿ istnieje"); + if ( num == TX_LOWPARAM ) strcpy(text, "Brak wymaganego parametru"); + if ( num == TX_BADPARAM ) strcpy(text, "Funkcja o tej nazwie nie akceptuje parametrów tego typu"); + if ( num == TX_NUMPARAM ) strcpy(text, "Funkcja o tej nazwie nie akceptuje takiej liczby parametrów"); + if ( num == TX_NOITEM ) strcpy(text, "To nie jest obiekt tej klasy"); + if ( num == TX_DOT ) strcpy(text, "Ten obiekt nie jest cz³onkiem klasy"); + if ( num == TX_NOCONST ) strcpy(text, "Brak odpowiedniego konstruktora"); + if ( num == TX_REDEFCLASS ) strcpy(text, "Taka klasa ju¿ istnieje"); + if ( num == TX_CLBRK ) strcpy(text, "Brak "" ] """); + if ( num == TX_RESERVED ) strcpy(text, "S³owo zarezerwowane jêzyka CBOT"); + if ( num == TX_BADNEW ) strcpy(text, "Z³y argument dla funkcji ""new"""); + if ( num == TX_OPBRK ) strcpy(text, "Oczekiwane "" [ """); + if ( num == TX_BADSTRING ) strcpy(text, "Brak ³añcucha"); + if ( num == TX_BADINDEX ) strcpy(text, "Nieprawid³owy typ indeksu"); + if ( num == TX_PRIVATE ) strcpy(text, "Element prywatny"); + if ( num == TX_NOPUBLIC ) strcpy(text, "Wymagany publiczny"); + if ( num == TX_DIVZERO ) strcpy(text, "Dzielenie przez zero"); + if ( num == TX_NOTINIT ) strcpy(text, "Zmienna nie zosta³a zainicjalizowana"); + if ( num == TX_BADTHROW ) strcpy(text, "Wartoœæ ujemna odrzucona przez ""throw""");//C'est quoi, ça? + if ( num == TX_NORETVAL ) strcpy(text, "Funkcja nie zwróci³a ¿adnej wartoœci "); + if ( num == TX_NORUN ) strcpy(text, "¯adna funkcja nie dzia³a"); + if ( num == TX_NOCALL ) strcpy(text, "Odwo³anie do nieznanej funkcji"); + if ( num == TX_NOCLASS ) strcpy(text, "Taka klasa nie istnieje"); + if ( num == TX_NULLPT ) strcpy(text, "Obiekt nieznany"); + if ( num == TX_OPNAN ) strcpy(text, "Dzia³anie niemo¿liwe z wartoœci¹ ""nan"""); + if ( num == TX_OUTARRAY ) strcpy(text, "Dostêp poza tablicê"); + if ( num == TX_STACKOVER ) strcpy(text, "Przepe³nienie stosu"); + if ( num == TX_DELETEDPT ) strcpy(text, "Nieprawid³owy obiekt"); + if ( num == TX_FILEOPEN ) strcpy(text, "Nie mo¿na otworzyæ pliku"); + if ( num == TX_NOTOPEN ) strcpy(text, "Plik nie jest otwarty"); + if ( num == TX_ERRREAD ) strcpy(text, "B³¹d odczytu"); + if ( num == TX_ERRWRITE ) strcpy(text, "B³¹d zapisu"); + } + + if ( type == RES_KEY ) + { + if ( num == 0 ) strcpy(text, "< brak >"); + if ( num == VK_LEFT ) strcpy(text, "Strza³ka w lewo"); + if ( num == VK_RIGHT ) strcpy(text, "Strza³ka w prawo"); + if ( num == VK_UP ) strcpy(text, "Strza³ka w górê"); + if ( num == VK_DOWN ) strcpy(text, "Strza³ka w dó³"); + if ( num == VK_CANCEL ) strcpy(text, "Ctrl-break"); + if ( num == VK_BACK ) strcpy(text, "<--"); + if ( num == VK_TAB ) strcpy(text, "Tab"); + if ( num == VK_CLEAR ) strcpy(text, "Delete"); + if ( num == VK_RETURN ) strcpy(text, "Enter"); + if ( num == VK_SHIFT ) strcpy(text, "Shift"); + if ( num == VK_CONTROL ) strcpy(text, "Ctrl"); + if ( num == VK_MENU ) strcpy(text, "Alt"); + if ( num == VK_PAUSE ) strcpy(text, "Pause"); + if ( num == VK_CAPITAL ) strcpy(text, "Caps Lock"); + if ( num == VK_ESCAPE ) strcpy(text, "Esc"); + if ( num == VK_SPACE ) strcpy(text, "Spacja"); + if ( num == VK_PRIOR ) strcpy(text, "Page Up"); + if ( num == VK_NEXT ) strcpy(text, "Page Down"); + if ( num == VK_END ) strcpy(text, "End"); + if ( num == VK_HOME ) strcpy(text, "Home"); + if ( num == VK_SELECT ) strcpy(text, "Zaznacz"); + if ( num == VK_EXECUTE ) strcpy(text, "Wykonaj"); + if ( num == VK_SNAPSHOT ) strcpy(text, "Print Scrn"); + if ( num == VK_INSERT ) strcpy(text, "Insert"); + if ( num == VK_DELETE ) strcpy(text, "Delete"); + if ( num == VK_HELP ) strcpy(text, "Pomoc"); + if ( num == VK_LWIN ) strcpy(text, "Lewy klawisz Windows"); + if ( num == VK_RWIN ) strcpy(text, "Prawy klawisz Windows"); + if ( num == VK_APPS ) strcpy(text, "Klawisz menu kontekstowego"); + if ( num == VK_NUMPAD0 ) strcpy(text, "Klaw. Num. 0"); + if ( num == VK_NUMPAD1 ) strcpy(text, "Klaw. Num. 1"); + if ( num == VK_NUMPAD2 ) strcpy(text, "Klaw. Num. 2"); + if ( num == VK_NUMPAD3 ) strcpy(text, "Klaw. Num. 3"); + if ( num == VK_NUMPAD4 ) strcpy(text, "Klaw. Num. 4"); + if ( num == VK_NUMPAD5 ) strcpy(text, "Klaw. Num. 5"); + if ( num == VK_NUMPAD6 ) strcpy(text, "Klaw. Num. 6"); + if ( num == VK_NUMPAD7 ) strcpy(text, "Klaw. Num. 7"); + if ( num == VK_NUMPAD8 ) strcpy(text, "Klaw. Num. 8"); + if ( num == VK_NUMPAD9 ) strcpy(text, "Klaw. Num. 9"); + if ( num == VK_MULTIPLY ) strcpy(text, "Klaw. Num. *"); + if ( num == VK_ADD ) strcpy(text, "Klaw. Num. +"); + if ( num == VK_SEPARATOR ) strcpy(text, "Klaw. Num. separator"); + if ( num == VK_SUBTRACT ) strcpy(text, "Klaw. Num. -"); + if ( num == VK_DECIMAL ) strcpy(text, "Klaw. Num. ."); + if ( num == VK_DIVIDE ) strcpy(text, "Klaw. Num. /"); + if ( num == VK_F1 ) strcpy(text, "F1"); + if ( num == VK_F2 ) strcpy(text, "F2"); + if ( num == VK_F3 ) strcpy(text, "F3"); + if ( num == VK_F4 ) strcpy(text, "F4"); + if ( num == VK_F5 ) strcpy(text, "F5"); + if ( num == VK_F6 ) strcpy(text, "F6"); + if ( num == VK_F7 ) strcpy(text, "F7"); + if ( num == VK_F8 ) strcpy(text, "F8"); + if ( num == VK_F9 ) strcpy(text, "F9"); + if ( num == VK_F10 ) strcpy(text, "F10"); + if ( num == VK_F11 ) strcpy(text, "F11"); + if ( num == VK_F12 ) strcpy(text, "F12"); + if ( num == VK_F13 ) strcpy(text, "F13"); + if ( num == VK_F14 ) strcpy(text, "F14"); + if ( num == VK_F15 ) strcpy(text, "F15"); + if ( num == VK_F16 ) strcpy(text, "F16"); + if ( num == VK_F17 ) strcpy(text, "F17"); + if ( num == VK_F18 ) strcpy(text, "F18"); + if ( num == VK_F19 ) strcpy(text, "F19"); + if ( num == VK_F20 ) strcpy(text, "F20"); + if ( num == VK_NUMLOCK ) strcpy(text, "Num Lock"); + if ( num == VK_SCROLL ) strcpy(text, "Scroll Lock"); + if ( num == VK_ATTN ) strcpy(text, "Attn"); + if ( num == VK_CRSEL ) strcpy(text, "CrSel"); + if ( num == VK_EXSEL ) strcpy(text, "ExSel"); + if ( num == VK_EREOF ) strcpy(text, "Erase EOF"); + if ( num == VK_PLAY ) strcpy(text, "Graj"); + if ( num == VK_ZOOM ) strcpy(text, "Powiêkszenie"); + if ( num == VK_PA1 ) strcpy(text, "PA1"); + if ( num == VK_OEM_CLEAR ) strcpy(text, "Wyczyœæ"); + if ( num == VK_BUTTON1 ) strcpy(text, "Przycisk 1"); + if ( num == VK_BUTTON2 ) strcpy(text, "Przycisk 2"); + if ( num == VK_BUTTON3 ) strcpy(text, "Przycisk 3"); + if ( num == VK_BUTTON4 ) strcpy(text, "Przycisk 4"); + if ( num == VK_BUTTON5 ) strcpy(text, "Przycisk 5"); + if ( num == VK_BUTTON6 ) strcpy(text, "Przycisk 6"); + if ( num == VK_BUTTON7 ) strcpy(text, "Przycisk 7"); + if ( num == VK_BUTTON8 ) strcpy(text, "Przycisk 8"); + if ( num == VK_BUTTON9 ) strcpy(text, "Przycisk 9"); + if ( num == VK_BUTTON10 ) strcpy(text, "Przycisk 10"); + if ( num == VK_BUTTON11 ) strcpy(text, "Przycisk 11"); + if ( num == VK_BUTTON12 ) strcpy(text, "Przycisk 12"); + if ( num == VK_BUTTON13 ) strcpy(text, "Przycisk 13"); + if ( num == VK_BUTTON14 ) strcpy(text, "Przycisk 14"); + if ( num == VK_BUTTON15 ) strcpy(text, "Przycisk 15"); + if ( num == VK_BUTTON16 ) strcpy(text, "Przycisk 16"); + if ( num == VK_BUTTON17 ) strcpy(text, "Przycisk 17"); + if ( num == VK_BUTTON18 ) strcpy(text, "Przycisk 18"); + if ( num == VK_BUTTON19 ) strcpy(text, "Przycisk 19"); + if ( num == VK_BUTTON20 ) strcpy(text, "Przycisk 20"); + if ( num == VK_BUTTON21 ) strcpy(text, "Przycisk 21"); + if ( num == VK_BUTTON22 ) strcpy(text, "Przycisk 22"); + if ( num == VK_BUTTON23 ) strcpy(text, "Przycisk 23"); + if ( num == VK_BUTTON24 ) strcpy(text, "Przycisk 24"); + if ( num == VK_BUTTON25 ) strcpy(text, "Przycisk 25"); + if ( num == VK_BUTTON26 ) strcpy(text, "Przycisk 26"); + if ( num == VK_BUTTON27 ) strcpy(text, "Przycisk 27"); + if ( num == VK_BUTTON28 ) strcpy(text, "Przycisk 28"); + if ( num == VK_BUTTON29 ) strcpy(text, "Przycisk 29"); + if ( num == VK_BUTTON30 ) strcpy(text, "Przycisk 30"); + if ( num == VK_BUTTON31 ) strcpy(text, "Przycisk 31"); + if ( num == VK_BUTTON32 ) strcpy(text, "Przycisk 32"); + if ( num == VK_WHEELUP ) strcpy(text, "Kó³ko w górê"); + if ( num == VK_WHEELDOWN ) strcpy(text, "Kó³ko w dó³"); + } +#endif + + return ( text[0] != 0 ); +} + + diff --git a/src/common/restext.h b/src/common/restext.h new file mode 100644 index 0000000..2fe53fe --- /dev/null +++ b/src/common/restext.h @@ -0,0 +1,159 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// restext.h + +#ifndef _RESTEXT_H_ +#define _RESTEXT_H_ + + +#define STRICT +#define D3D_OVERLOADS + + +#include "d3dengine.h" +#include "event.h" + + + + +// Possible types of the text resources. + +enum ResType +{ + RES_TEXT = 0, // RT_* + RES_EVENT = 1, // EVENT_* (EventMsg) + RES_OBJECT = 2, // OBJECT_* (ObjectType) + RES_ERR = 3, // ERR_* (Error) + RES_KEY = 4, // VK_* (keys) + RES_CBOT = 5, // TX_* (cbot.dll) +}; + + +// Resources of type RES_TEXT. + +#define RT_VERSION_ID 1 +#define RT_DISINFO_TITLE 2 +#define RT_WINDOW_MAXIMIZED 3 +#define RT_WINDOW_MINIMIZED 4 +#define RT_WINDOW_STANDARD 5 +#define RT_WINDOW_CLOSE 6 + +#define RT_STUDIO_TITLE 10 +#define RT_SCRIPT_NEW 20 +#define RT_NAME_DEFAULT 21 +#define RT_IO_NEW 22 +#define RT_KEY_OR 23 + +#define RT_TITLE_BASE 40 +#define RT_TITLE_INIT 41 +#define RT_TITLE_TRAINER 42 +#define RT_TITLE_DEFI 43 +#define RT_TITLE_MISSION 44 +#define RT_TITLE_FREE 45 +#define RT_TITLE_PROTO 46 +#define RT_TITLE_SETUP 47 +#define RT_TITLE_NAME 48 +#define RT_TITLE_PERSO 49 +#define RT_TITLE_WRITE 50 +#define RT_TITLE_READ 51 +#define RT_TITLE_USER 52 +#define RT_TITLE_TEEN 53 + +#define RT_PLAY_CHAPt 60 +#define RT_PLAY_CHAPd 61 +#define RT_PLAY_CHAPm 62 +#define RT_PLAY_CHAPf 63 +#define RT_PLAY_CHAPp 64 +#define RT_PLAY_LISTt 65 +#define RT_PLAY_LISTd 66 +#define RT_PLAY_LISTm 67 +#define RT_PLAY_LISTf 68 +#define RT_PLAY_LISTp 69 +#define RT_PLAY_RESUME 70 +#define RT_PLAY_CHAPu 71 +#define RT_PLAY_LISTu 72 +#define RT_PLAY_CHAPte 73 +#define RT_PLAY_LISTk 74 + +#define RT_SETUP_DEVICE 80 +#define RT_SETUP_MODE 81 +#define RT_SETUP_KEY1 82 +#define RT_SETUP_KEY2 83 + +#define RT_PERSO_FACE 90 +#define RT_PERSO_GLASSES 91 +#define RT_PERSO_HAIR 92 +#define RT_PERSO_COMBI 93 +#define RT_PERSO_BAND 94 + +#define RT_DIALOG_TITLE 100 +#define RT_DIALOG_ABORT 101 +#define RT_DIALOG_QUIT 102 +#define RT_DIALOG_YES 103 +#define RT_DIALOG_NO 104 +#define RT_DIALOG_DELOBJ 105 +#define RT_DIALOG_DELGAME 106 +#define RT_DIALOG_YESDEL 107 +#define RT_DIALOG_NODEL 108 +#define RT_DIALOG_LOADING 109 +#define RT_DIALOG_YESQUIT 110 +#define RT_DIALOG_NOQUIT 111 + +#define RT_STUDIO_LISTTT 120 +#define RT_STUDIO_COMPOK 121 +#define RT_STUDIO_PROGSTOP 122 + +#define RT_SATCOM_LIST 140 +#define RT_SATCOM_BOT 141 +#define RT_SATCOM_BUILDING 142 +#define RT_SATCOM_FRET 143 +#define RT_SATCOM_ALIEN 144 +#define RT_SATCOM_NULL 145 +#define RT_SATCOM_ERROR1 146 +#define RT_SATCOM_ERROR2 147 + +#define RT_IO_OPEN 150 +#define RT_IO_SAVE 151 +#define RT_IO_LIST 152 +#define RT_IO_NAME 153 +#define RT_IO_DIR 154 +#define RT_IO_PRIVATE 155 +#define RT_IO_PUBLIC 156 + +#define RT_GENERIC_DEV1 170 +#define RT_GENERIC_DEV2 171 +#define RT_GENERIC_EDIT1 172 +#define RT_GENERIC_EDIT2 173 + +#define RT_INTERFACE_REC 180 + +#define RT_MESSAGE_WIN 200 +#define RT_MESSAGE_LOST 201 + + +static CD3DEngine* g_engine = 0; +static char g_gamerName[100]; + +extern void SetEngine(CD3DEngine *engine); +extern void SetGlobalGamerName(char *name); +extern BOOL SearchKey(char *cmd, KeyRank &key); +extern void PutKeyName(char* dst, char* src); +extern BOOL GetResource(ResType type, int num, char* text); +extern BOOL GetResourceBase(ResType type, int num, char* text); + + +#endif //_RESTEXT_H_ diff --git a/src/common/struct.h b/src/common/struct.h new file mode 100644 index 0000000..8b90288 --- /dev/null +++ b/src/common/struct.h @@ -0,0 +1,73 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// struct.h + +#ifndef _STRUCT_H_ +#define _STRUCT_H_ + +#include + + +#define NAN 999999 + +#define D3DFVF_VERTEX2 (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX2) + +struct D3DVERTEX2 +{ + float x,y,z; + float nx,ny,nz; + float tu, tv; + float tu2, tv2; + + D3DVERTEX2() { } + D3DVERTEX2(const D3DVECTOR& _v, const D3DVECTOR& _n, float _tu=0.0f, float _tv=0.0f, float _tu2=0.0f, float _tv2=0.0f) + { + x = _v.x; + y = _v.y; + z = _v.z; + nx = _n.x; + ny = _n.y; + nz = _n.z; + tu = _tu; + tv = _tv; + tu2 = _tu2; + tv2 = _tv2; + } +}; + + +struct FPOINT +{ + float x; + float y; + + FPOINT() { } + FPOINT(float _x, float _y) + { + x = _x; + y = _y; + } +}; + + +struct ColorHSV +{ + float h,s,v; +}; + + +#endif //_STRUCT_H_ diff --git a/src/compass.cpp b/src/compass.cpp deleted file mode 100644 index 92804c2..0000000 --- a/src/compass.cpp +++ /dev/null @@ -1,176 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "compass.h" - - - - -// Object's constructor. - -CCompass::CCompass(CInstanceManager* iMan) : CControl(iMan) -{ - m_dir = 0.0f; -} - -// Object's destructor. - -CCompass::~CCompass() -{ -} - - -// Creates a new button. - -BOOL CCompass::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - CControl::Create(pos, dim, icon, eventMsg); - return TRUE; -} - - -// Management of an event. - -BOOL CCompass::EventProcess(const Event &event) -{ - CControl::EventProcess(event); - - if ( event.event == EVENT_LBUTTONDOWN ) - { - if ( CControl::Detect(event.pos) ) - { - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - return FALSE; - } - } - - return TRUE; -} - - -// Draw button. - -void CCompass::Draw() -{ - LPDIRECT3DDEVICE7 device; - D3DVERTEX2 vertex[4]; // 2 triangles - FPOINT p1, p2, p3, c, uv1, uv2; - D3DVECTOR n; - float dp; - - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - device = m_engine->RetD3DDevice(); - - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - - p1.x = m_pos.x; - p1.y = m_pos.y; - p2.x = m_pos.x + m_dim.x; - p2.y = m_pos.y + m_dim.y; - - c.x = (p1.x+p2.x)/2.0f; - c.y = (p1.y+p2.y)/2.0f; // center - - uv1.x = 64.0f/256.0f; - uv1.y = 32.0f/256.0f; - uv2.x = 96.0f/256.0f; - uv2.y = 64.0f/256.0f; - - dp = 0.5f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal - - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x,uv1.y); - vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y); - vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv2.x,uv1.y); - - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); - - if ( m_state & STATE_ENABLE ) - { - p1.x = c.x; - p1.y = c.y+m_dim.x*0.40f; - p1 = RotatePoint(c, m_dir, p1); - p1.x = c.x+(p1.x-c.x)*(m_dim.x/m_dim.y); - - p2.x = c.x+m_dim.x*0.20f; - p2.y = c.y-m_dim.x*0.40f; - p2 = RotatePoint(c, m_dir, p2); - p2.x = c.x+(p2.x-c.x)*(m_dim.x/m_dim.y); - - p3.x = c.x-m_dim.x*0.20f; - p3.y = c.y-m_dim.x*0.40f; - p3 = RotatePoint(c, m_dir, p3); - p3.x = c.x+(p3.x-c.x)*(m_dim.x/m_dim.y); - - uv1.x = 96.0f/256.0f; - uv1.y = 32.0f/256.0f; - uv2.x = 104.0f/256.0f; - uv2.y = 64.0f/256.0f; - - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv1.y); - vertex[1] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv1.x,uv2.y); - vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv2.x,uv2.y); - - device->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_VERTEX2, vertex, 3, NULL); - m_engine->AddStatisticTriangle(1); - } -} - - -// Management directions of the compass. - -void CCompass::SetDirection(float dir) -{ - m_dir = dir; -} - -float CCompass::RetDirection() -{ - return m_dir; -} - - diff --git a/src/compass.h b/src/compass.h deleted file mode 100644 index 1eed3d6..0000000 --- a/src/compass.h +++ /dev/null @@ -1,52 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// compass.h - -#ifndef _COMPASS_H_ -#define _COMPASS_H_ - - -#include "control.h" - - -class CD3DEngine; - - - -class CCompass : public CControl -{ -public: - CCompass(CInstanceManager* iMan); - virtual ~CCompass(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - - BOOL EventProcess(const Event &event); - - void Draw(); - - void SetDirection(float dir); - float RetDirection(); - -protected: - -protected: - float m_dir; -}; - - -#endif //_COMPASS_H_ diff --git a/src/control.cpp b/src/control.cpp deleted file mode 100644 index 6ba5cef..0000000 --- a/src/control.cpp +++ /dev/null @@ -1,876 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "language.h" -#include "restext.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "robotmain.h" -#include "particule.h" -#include "misc.h" -#include "iman.h" -#include "text.h" -#include "sound.h" -#include "control.h" - - - - -// Object's constructor. - -CControl::CControl(CInstanceManager* iMan) -{ - m_iMan = iMan; - - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - m_eventMsg = EVENT_NULL; - m_state = STATE_ENABLE|STATE_VISIBLE|STATE_GLINT; - m_fontSize = SMALLFONT; - m_fontStretch = NORMSTRETCH; - m_fontType = FONT_COLOBOT; - m_justif = 0; - m_name[0] = 0; - m_tooltip[0] = 0; - m_bFocus = FALSE; - m_bCapture = FALSE; - - m_bGlint = FALSE; - m_glintCorner1 = FPOINT(0.0f, 0.0f); - m_glintCorner2 = FPOINT(0.0f, 0.0f); - m_glintProgress = 999.0f; - m_glintMouse = FPOINT(0.0f, 0.0f); -} - -// Object's destructor. - -CControl::~CControl() -{ -} - - -// Creates a new button. -// pos: [0..1] - -BOOL CControl::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - char text[100]; - char* p; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - m_pos = pos; - m_dim = dim; - m_icon = icon; - m_eventMsg = eventMsg; - - pos.x = m_pos.x; - pos.y = m_pos.y+m_dim.y; - GlintCreate(pos); - - GetResource(RES_EVENT, m_eventMsg, text); - p = strchr(text, '\\'); - if ( p == 0 ) - { - if ( icon != -1 ) - { - strcpy(m_tooltip, text); - } - } - else - { - strcpy(m_tooltip, p+1); // text after "\\" - } - - return TRUE; -} - - -void CControl::SetPos(FPOINT pos) -{ - m_pos = pos; - - pos.x = m_pos.x; - pos.y = m_pos.y+m_dim.y; - GlintCreate(pos); -} - -FPOINT CControl::RetPos() -{ - return m_pos; -} - -void CControl::SetDim(FPOINT dim) -{ - FPOINT pos; - - m_dim = dim; - - pos.x = m_pos.x; - pos.y = m_pos.y+m_dim.y; - GlintCreate(pos); -} - -FPOINT CControl::RetDim() -{ - return m_dim; -} - - -// Modify an attribute of state. - -BOOL CControl::SetState(int state, BOOL bState) -{ - if ( bState ) m_state |= state; - else m_state &= ~state; - return TRUE; -} - -// Sets an attribute of state. - -BOOL CControl::SetState(int state) -{ - m_state |= state; - return TRUE; -} - -// Removes an attribute of state. - -BOOL CControl::ClearState(int state) -{ - m_state &= ~state; - return TRUE; -} - -// Tests an attribute of state. - -BOOL CControl::TestState(int state) -{ - return (m_state & state) ? TRUE:FALSE; -} - -// Returns all attributes of state. - -int CControl::RetState() -{ - return m_state; -} - - -// Management icon. - -void CControl::SetIcon(int icon) -{ - m_icon = icon; -} - -int CControl::RetIcon() -{ - return m_icon; -} - - -// Management of the button name. - -void CControl::SetName(char* name, BOOL bTooltip) -{ - char* p; - - if ( bTooltip ) - { - p = strchr(name, '\\'); - if ( p == 0 ) - { - strncpy(m_name, name, 100); - m_name[100-1] = 0; - } - else - { - char buffer[100]; - - strncpy(m_tooltip, p+1, 100); // text after "\\" - m_tooltip[100-1] = 0; - - strncpy(buffer, name, 100); - buffer[100-1] = 0; - p = strchr(buffer, '\\'); - if ( p != 0 ) *p = 0; - strncpy(m_name, buffer, 100); - m_name[100-1] = 0; - } - } - else - { - strncpy(m_name, name, 100); - m_name[100-1] = 0; - } -} - -char* CControl::RetName() -{ - return m_name; -} - - -// Management of the mode of justification (-1,0,1). - -void CControl::SetJustif(int mode) -{ - m_justif = mode; -} - -int CControl::RetJustif() -{ - return m_justif; -} - - -// Management of the size of the font. - -void CControl::SetFontSize(float size) -{ - m_fontSize = size; -} - -float CControl::RetFontSize() -{ - return m_fontSize; -} - - -// Management of the stretch of font. - -void CControl::SetFontStretch(float stretch) -{ - m_fontStretch = stretch; -} - -float CControl::RetFontStretch() -{ - return m_fontStretch; -} - - -// Choice of the font. - -void CControl::SetFontType(FontType font) -{ - m_fontType = font; -} - -FontType CControl::RetFontType() -{ - return m_fontType; -} - - -// Specifies the tooltip. - -BOOL CControl::SetTooltip(char* name) -{ - strcpy(m_tooltip, name); - return TRUE; -} - -BOOL CControl::GetTooltip(FPOINT pos, char* name) -{ - if ( m_tooltip[0] == 0 ) return FALSE; - if ( (m_state & STATE_VISIBLE) == 0 ) return FALSE; - if ( (m_state & STATE_ENABLE) == 0 ) return FALSE; - if ( m_state & STATE_DEAD ) return FALSE; - if ( !Detect(pos) ) return FALSE; - - strcpy(name, m_tooltip); - return TRUE; -} - - -// Management of the focus. - -void CControl::SetFocus(BOOL bFocus) -{ - m_bFocus = bFocus; -} - -BOOL CControl::RetFocus() -{ - return m_bFocus; -} - - -// Returns the event associated with the control. - -EventMsg CControl::RetEventMsg() -{ - return m_eventMsg; -} - - -// Management of an event. - -BOOL CControl::EventProcess(const Event &event) -{ - if ( m_state & STATE_DEAD ) return TRUE; - - if ( event.event == EVENT_FRAME && m_bGlint ) - { - GlintFrame(event); - } - - if ( event.event == EVENT_MOUSEMOVE ) - { - m_glintMouse = event.pos; - - if ( Detect(event.pos) ) - { - if ( (m_state & STATE_VISIBLE) && - (m_state & STATE_ENABLE ) ) - { - m_engine->SetMouseType(D3DMOUSEHAND); - } - SetState(STATE_HILIGHT); - } - else - { - ClearState(STATE_HILIGHT); - } - } - - if ( event.event == EVENT_LBUTTONDOWN ) - { - if ( Detect(event.pos) ) - { - m_bCapture = TRUE; - SetState(STATE_PRESS); - } - } - - if ( event.event == EVENT_MOUSEMOVE && m_bCapture ) - { - if ( Detect(event.pos) ) - { - SetState(STATE_PRESS); - } - else - { - ClearState(STATE_PRESS); - } - } - - if ( event.event == EVENT_LBUTTONUP && m_bCapture ) - { - m_bCapture = FALSE; - ClearState(STATE_PRESS); - } - - return TRUE; -} - - -// Removes the reflection. - -void CControl::GlintDelete() -{ - m_bGlint = FALSE; -} - -// Creates a reflection for that button. - -void CControl::GlintCreate(FPOINT ref, BOOL bLeft, BOOL bUp) -{ - float offset; - - offset = 8.0f/640.0f; - if ( offset > m_dim.x/4.0f) offset = m_dim.x/4.0f; - - if ( bLeft ) - { - m_glintCorner1.x = ref.x; - m_glintCorner2.x = ref.x+offset; - } - else - { - m_glintCorner1.x = ref.x-offset; - m_glintCorner2.x = ref.x; - } - - offset = 8.0f/480.0f; - if ( offset > m_dim.y/4.0f) offset = m_dim.y/4.0f; - - if ( bUp ) - { - m_glintCorner1.y = ref.y-offset; - m_glintCorner2.y = ref.y; - } - else - { - m_glintCorner1.y = ref.y; - m_glintCorner2.y = ref.y+offset; - } - - m_bGlint = TRUE; -} - -// Management of reflection. - -void CControl::GlintFrame(const Event &event) -{ - D3DVECTOR pos, speed; - FPOINT dim; - - if ( (m_state & STATE_GLINT ) == 0 || - (m_state & STATE_ENABLE ) == 0 || - (m_state & STATE_VISIBLE) == 0 ) return; - - if ( !m_main->RetGlint() ) return; - - m_glintProgress += event.rTime; - - if ( m_glintProgress >= 2.0f && Detect(m_glintMouse) ) - { - pos.x = m_glintCorner1.x + (m_glintCorner2.x-m_glintCorner1.x)*Rand(); - pos.y = m_glintCorner1.y + (m_glintCorner2.y-m_glintCorner1.y)*Rand(); - pos.z = 0.0f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = ((15.0f+Rand()*15.0f)/640.0f); - dim.y = dim.x/0.75f; - m_particule->CreateParticule(pos, speed, dim, PARTICONTROL, - 1.0f, 0.0f, 0.0f, SH_INTERFACE); - - m_glintProgress = 0.0f; - } -} - - -// Draw button. - -void CControl::Draw() -{ - FPOINT pos; - float zoomExt, zoomInt; - int icon; - - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATENORMAL); - - zoomExt = 1.00f; - zoomInt = 0.95f; - - if ( m_icon >= 128 ) - { - zoomInt = 0.80f; - } - - icon = 2; - if ( m_state & STATE_CARD ) - { - icon = 26; - } - if ( m_state & STATE_DEFAULT ) - { - DrawPart(23, 1.3f, 0.0f); - - zoomExt *= 1.15f; - zoomInt *= 1.15f; - } - if ( m_state & STATE_HILIGHT ) - { - icon = 1; - } - if ( m_state & STATE_CHECK ) - { - if ( m_state & STATE_CARD ) - { - icon = 27; - } - else - { - icon = 0; - } - } - if ( m_state & STATE_PRESS ) - { - icon = 3; - zoomInt *= 0.9f; - } - if ( (m_state & STATE_ENABLE) == 0 ) - { - icon = 7; - } - if ( m_state & STATE_DEAD ) - { - icon = 17; - } - - if ( m_state & STATE_OKAY ) - { - m_engine->SetTexture("button3.tga"); - icon = 3; // yellow with green point pressed - } - - if ( m_name[0] == 0 ) // button without name? - { -//? DrawPart(icon, zoomExt, 0.0f); - DrawPart(icon, zoomExt, 8.0f/256.0f); - - if ( m_state & STATE_DEAD ) return; - - icon = m_icon; - if ( icon >= 192 ) - { - icon -= 192; -#if _POLISH - m_engine->SetTexture("textp.tga"); -#else - m_engine->SetTexture("text.tga"); -#endif - m_engine->SetState(D3DSTATETTw); - } - else if ( icon >= 128 ) - { - icon -= 128; - m_engine->SetTexture("button3.tga"); - m_engine->SetState(D3DSTATETTw); - } - else if ( icon >= 64 ) - { - icon -= 64; - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTw); - } - else - { - m_engine->SetState(D3DSTATETTw); - } - if ( icon != -1 ) - { - DrawPart(icon, zoomInt, 0.0f); - } - } - else // button with the name? - { - DrawPart(icon, 1.0f, 8.0f/256.0f); - - if ( m_state & STATE_DEAD ) return; - - if ( m_justif < 0 ) - { - pos.x = m_pos.x+m_dim.x-m_dim.y*0.5f; - pos.y = m_pos.y+m_dim.y*0.5f; - pos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2; - m_engine->RetText()->DrawText(m_name, pos, m_dim.x, m_justif, m_fontSize, m_fontStretch, m_fontType, 0); - } - else if ( m_justif > 0 ) - { - pos.x = m_pos.x+m_dim.y*0.5f; - pos.y = m_pos.y+m_dim.y*0.5f; - pos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; - m_engine->RetText()->DrawText(m_name, pos, m_dim.x, m_justif, m_fontSize, m_fontStretch, m_fontType, 0); - } - else - { - pos.x = m_pos.x+m_dim.x*0.5f; - pos.y = m_pos.y+m_dim.y*0.5f; - pos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; - m_engine->RetText()->DrawText(m_name, pos, m_dim.x, m_justif, m_fontSize, m_fontStretch, m_fontType, 0); - } - } -} - -// Draw the vertex array. - -void CControl::DrawPart(int icon, float zoom, float ex) -{ - FPOINT p1, p2, c, uv1, uv2; - float dp; - - p1.x = m_pos.x; - p1.y = m_pos.y; - p2.x = m_pos.x + m_dim.x; - p2.y = m_pos.y + m_dim.y; - - if ( (m_state & STATE_CARD ) && - (m_state & STATE_CHECK) ) - { - p2.y += (2.0f/480.0f); // a bit above - } - - c.x = (p1.x+p2.x)/2.0f; - c.y = (p1.y+p2.y)/2.0f; // center - - p1.x = (p1.x-c.x)*zoom + c.x; - p1.y = (p1.y-c.y)*zoom + c.y; - p2.x = (p2.x-c.x)*zoom + c.x; - p2.y = (p2.y-c.y)*zoom + c.y; - - p2.x -= p1.x; - p2.y -= p1.y; - - uv1.x = (32.0f/256.0f)*(icon%8); - uv1.y = (32.0f/256.0f)*(icon/8); // uv texture - uv2.x = (32.0f/256.0f)+uv1.x; - uv2.y = (32.0f/256.0f)+uv1.y; - - dp = 0.5f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - DrawIcon(p1, p2, uv1, uv2, ex); -} - -// Draws an icon made up of a rectangular (if x = 0) -// or 3 pieces. - -void CControl::DrawIcon(FPOINT pos, FPOINT dim, FPOINT uv1, FPOINT uv2, - float ex) -{ - LPDIRECT3DDEVICE7 device; - D3DVERTEX2 vertex[8]; // 6 triangles - FPOINT p1, p2, p3, p4; - D3DVECTOR n; - - device = m_engine->RetD3DDevice(); - - p1.x = pos.x; - p1.y = pos.y; - p2.x = pos.x + dim.x; - p2.y = pos.y + dim.y; - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal - - if ( ex == 0.0f ) // one piece? - { - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x,uv1.y); - vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y); - vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv2.x,uv1.y); - - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); - } - else // 3 pieces? - { - if ( dim.x >= dim.y ) - { - p3.x = p1.x + ex*dim.y/(uv2.y-uv1.y); - p4.x = p2.x - ex*dim.y/(uv2.y-uv1.y); - - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x, uv2.y); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x, uv1.y); - vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p1.y, 0.0f), n, uv1.x+ex,uv2.y); - vertex[3] = D3DVERTEX2(D3DVECTOR(p3.x, p2.y, 0.0f), n, uv1.x+ex,uv1.y); - vertex[4] = D3DVERTEX2(D3DVECTOR(p4.x, p1.y, 0.0f), n, uv2.x-ex,uv2.y); - vertex[5] = D3DVERTEX2(D3DVECTOR(p4.x, p2.y, 0.0f), n, uv2.x-ex,uv1.y); - vertex[6] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x, uv2.y); - vertex[7] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv2.x, uv1.y); - - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL); - m_engine->AddStatisticTriangle(6); - } - else - { - p3.y = p1.y + ex*dim.x/(uv2.x-uv1.x); - p4.y = p2.y - ex*dim.x/(uv2.x-uv1.x); - - vertex[0] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y ); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y ); - vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p3.y, 0.0f), n, uv2.x,uv2.y-ex); - vertex[3] = D3DVERTEX2(D3DVECTOR(p1.x, p3.y, 0.0f), n, uv1.x,uv2.y-ex); - vertex[4] = D3DVERTEX2(D3DVECTOR(p2.x, p4.y, 0.0f), n, uv2.x,uv1.y+ex); - vertex[5] = D3DVERTEX2(D3DVECTOR(p1.x, p4.y, 0.0f), n, uv1.x,uv1.y+ex); - vertex[6] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv2.x,uv1.y ); - vertex[7] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x,uv1.y ); - - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL); - m_engine->AddStatisticTriangle(6); - } - } -} - -// Draws a rectangular icon made up of 9 pieces. - -void CControl::DrawIcon(FPOINT pos, FPOINT dim, FPOINT uv1, FPOINT uv2, - FPOINT corner, float ex) -{ - LPDIRECT3DDEVICE7 device; - D3DVERTEX2 vertex[8]; // 6 triangles - FPOINT p1, p2, p3, p4; - D3DVECTOR n; - - device = m_engine->RetD3DDevice(); - - p1.x = pos.x; - p1.y = pos.y; - p2.x = pos.x + dim.x; - p2.y = pos.y + dim.y; - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal - - if ( corner.x > dim.x/2.0f ) corner.x = dim.x/2.0f; - if ( corner.y > dim.y/2.0f ) corner.y = dim.y/2.0f; - - p1.x = pos.x; - p1.y = pos.y; - p2.x = pos.x + dim.x; - p2.y = pos.y + dim.y; - p3.x = p1.x + corner.x; - p3.y = p1.y + corner.y; - p4.x = p2.x - corner.x; - p4.y = p2.y - corner.y; - - // Bottom horizontal band. - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x, uv2.y ); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p3.y, 0.0f), n, uv1.x, uv2.y-ex); - vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p1.y, 0.0f), n, uv1.x+ex,uv2.y ); - vertex[3] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv1.x+ex,uv2.y-ex); - vertex[4] = D3DVERTEX2(D3DVECTOR(p4.x, p1.y, 0.0f), n, uv2.x-ex,uv2.y ); - vertex[5] = D3DVERTEX2(D3DVECTOR(p4.x, p3.y, 0.0f), n, uv2.x-ex,uv2.y-ex); - vertex[6] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x, uv2.y ); - vertex[7] = D3DVERTEX2(D3DVECTOR(p2.x, p3.y, 0.0f), n, uv2.x, uv2.y-ex); - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL); - m_engine->AddStatisticTriangle(6); - - // Central horizontal band. - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p3.y, 0.0f), n, uv1.x, uv2.y-ex); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p4.y, 0.0f), n, uv1.x, uv1.y+ex); - vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv1.x+ex,uv2.y-ex); - vertex[3] = D3DVERTEX2(D3DVECTOR(p3.x, p4.y, 0.0f), n, uv1.x+ex,uv1.y+ex); - vertex[4] = D3DVERTEX2(D3DVECTOR(p4.x, p3.y, 0.0f), n, uv2.x-ex,uv2.y-ex); - vertex[5] = D3DVERTEX2(D3DVECTOR(p4.x, p4.y, 0.0f), n, uv2.x-ex,uv1.y+ex); - vertex[6] = D3DVERTEX2(D3DVECTOR(p2.x, p3.y, 0.0f), n, uv2.x, uv2.y-ex); - vertex[7] = D3DVERTEX2(D3DVECTOR(p2.x, p4.y, 0.0f), n, uv2.x, uv1.y+ex); - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL); - m_engine->AddStatisticTriangle(6); - - // Top horizontal band. - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p4.y, 0.0f), n, uv1.x, uv1.y+ex); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x, uv1.y ); - vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p4.y, 0.0f), n, uv1.x+ex,uv1.y+ex); - vertex[3] = D3DVERTEX2(D3DVECTOR(p3.x, p2.y, 0.0f), n, uv1.x+ex,uv1.y ); - vertex[4] = D3DVERTEX2(D3DVECTOR(p4.x, p4.y, 0.0f), n, uv2.x-ex,uv1.y+ex); - vertex[5] = D3DVERTEX2(D3DVECTOR(p4.x, p2.y, 0.0f), n, uv2.x-ex,uv1.y ); - vertex[6] = D3DVERTEX2(D3DVECTOR(p2.x, p4.y, 0.0f), n, uv2.x, uv1.y+ex); - vertex[7] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv2.x, uv1.y ); - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL); - m_engine->AddStatisticTriangle(6); -} - -// Draw round the hatch of a button. - -void CControl::DrawWarning(FPOINT pos, FPOINT dim) -{ - FPOINT uv1, uv2; - float dp; - - dp = 0.5f/256.0f; - - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - - uv1.x = 64.0f/256.0f; - uv1.y = 208.0f/256.0f; - uv2.x = 160.0f/256.0f; - uv2.y = 224.0f/256.0f; - - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - if ( dim.x < dim.y*4.0f ) - { - dim.y /= 2.0f; - DrawIcon(pos, dim, uv1, uv2); - pos.y += dim.y; - DrawIcon(pos, dim, uv1, uv2); - } - else - { - dim.x /= 2.0f; - dim.y /= 2.0f; - DrawIcon(pos, dim, uv1, uv2); - pos.x += dim.x; - DrawIcon(pos, dim, uv1, uv2); - pos.x -= dim.x; - pos.y += dim.y; - DrawIcon(pos, dim, uv1, uv2); - pos.x += dim.x; - DrawIcon(pos, dim, uv1, uv2); - } -} - -// Draw the shade under a button. - -void CControl::DrawShadow(FPOINT pos, FPOINT dim, float deep) -{ - FPOINT uv1, uv2, corner; - float dp; - - dp = 0.5f/256.0f; - - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTw); - - pos.x += deep*0.010f*0.75f; - pos.y -= deep*0.015f; - dim.x += deep*0.005f*0.75f; - dim.y += deep*0.005f; - - uv1.x = 192.0f/256.0f; - uv1.y = 32.0f/256.0f; - uv2.x = 224.0f/256.0f; - uv2.y = 64.0f/256.0f; - - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - corner.x = 10.0f/640.0f; - corner.y = 10.0f/480.0f; - - DrawIcon(pos, dim, uv1, uv2, corner, 6.0f/256.0f); -} - - -// Detects whether a position is in the button. - -BOOL CControl::Detect(FPOINT pos) -{ - return ( pos.x >= m_pos.x && - pos.x <= m_pos.x+m_dim.x && - pos.y >= m_pos.y && - pos.y <= m_pos.y+m_dim.y ); -} - - diff --git a/src/control.h b/src/control.h deleted file mode 100644 index 619cef2..0000000 --- a/src/control.h +++ /dev/null @@ -1,137 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// control.h - -#ifndef _CONTROL_H_ -#define _CONTROL_H_ - - -#include "text.h" -#include "struct.h" -#include "event.h" - - -class CInstanceManager; -class CEvent; -class CD3DEngine; -class CRobotMain; -class CParticule; -class CSound; - - -#define STATE_ENABLE (1<<0) // active -#define STATE_CHECK (1<<1) // pressed -#define STATE_HILIGHT (1<<2) // overflown by mouse -#define STATE_PRESS (1<<3) // pressed by mouse -#define STATE_VISIBLE (1<<4) // visible -#define STATE_DEAD (1<<5) // inaccessible (x) -#define STATE_DEFAULT (1<<6) // actuated by RETURN -#define STATE_OKAY (1<<7) // green point at the bottom right -#define STATE_SHADOW (1<<8) // shadow -#define STATE_GLINT (1<<9) // dynamic reflection -#define STATE_CARD (1<<10) // tab -#define STATE_EXTEND (1<<11) // extended mode -#define STATE_SIMPLY (1<<12) // undecorated -#define STATE_FRAME (1<<13) // framework highlighting -#define STATE_WARNING (1<<14) // framework hatched yellow / black -#define STATE_VALUE (1<<15) // displays the value -#define STATE_RUN (1<<16) // running program - - - -class CControl -{ -public: - CControl(CInstanceManager* iMan); - virtual ~CControl(); - - virtual BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - - virtual BOOL EventProcess(const Event &event); - - virtual void SetPos(FPOINT pos); - virtual FPOINT RetPos(); - virtual void SetDim(FPOINT dim); - virtual FPOINT RetDim(); - virtual BOOL SetState(int state, BOOL bState); - virtual BOOL SetState(int state); - virtual BOOL ClearState(int state); - virtual BOOL TestState(int state); - virtual int RetState(); - virtual void SetIcon(int icon); - virtual int RetIcon(); - virtual void SetName(char* name, BOOL bTooltip=TRUE); - virtual char* RetName(); - virtual void SetJustif(int mode); - virtual int RetJustif(); - virtual void SetFontSize(float size); - virtual float RetFontSize(); - virtual void SetFontStretch(float stretch); - virtual float RetFontStretch(); - virtual void SetFontType(FontType font); - virtual FontType RetFontType(); - virtual BOOL SetTooltip(char* name); - virtual BOOL GetTooltip(FPOINT pos, char* name); - virtual void SetFocus(BOOL bFocus); - virtual BOOL RetFocus(); - - virtual EventMsg RetEventMsg(); - - virtual void Draw(); - -protected: - void GlintDelete(); - void GlintCreate(FPOINT ref, BOOL bLeft=TRUE, BOOL bUp=TRUE); - void GlintFrame(const Event &event); - void DrawPart(int icon, float zoom, float ex); - void DrawIcon(FPOINT pos, FPOINT dim, FPOINT uv1, FPOINT uv2, float ex=0.0f); - void DrawIcon(FPOINT pos, FPOINT dim, FPOINT uv1, FPOINT uv2, FPOINT corner, float ex); - void DrawWarning(FPOINT pos, FPOINT dim); - void DrawShadow(FPOINT pos, FPOINT dim, float deep=1.0f); - virtual BOOL Detect(FPOINT pos); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CEvent* m_event; - CRobotMain* m_main; - CParticule* m_particule; - CSound* m_sound; - - FPOINT m_pos; // corner upper / left - FPOINT m_dim; // dimensions - int m_icon; - EventMsg m_eventMsg; // message to send when clicking - int m_state; // states (STATE_ *) - float m_fontSize; // size of the button name - float m_fontStretch; // stretch of the font - FontType m_fontType; // type of font - int m_justif; // type of justification (-1,0,1) - char m_name[100]; // name of the button - char m_tooltip[100]; // name of tooltip - BOOL m_bFocus; - BOOL m_bCapture; - - BOOL m_bGlint; - FPOINT m_glintCorner1; - FPOINT m_glintCorner2; - float m_glintProgress; - FPOINT m_glintMouse; -}; - - -#endif //_CONTROL_H_ diff --git a/src/cur00001.cur b/src/cur00001.cur deleted file mode 100644 index e19873e..0000000 Binary files a/src/cur00001.cur and /dev/null differ diff --git a/src/cur00002.cur b/src/cur00002.cur deleted file mode 100644 index 2376e8e..0000000 Binary files a/src/cur00002.cur and /dev/null differ diff --git a/src/cur00003.cur b/src/cur00003.cur deleted file mode 100644 index 8a4745a..0000000 Binary files a/src/cur00003.cur and /dev/null differ diff --git a/src/cursor1.cur b/src/cursor1.cur deleted file mode 100644 index 1f51251..0000000 Binary files a/src/cursor1.cur and /dev/null differ diff --git a/src/cursorha.cur b/src/cursorha.cur deleted file mode 100644 index 7b80435..0000000 Binary files a/src/cursorha.cur and /dev/null differ diff --git a/src/cursorsc.cur b/src/cursorsc.cur deleted file mode 100644 index 52004ac..0000000 Binary files a/src/cursorsc.cur and /dev/null differ diff --git a/src/d3dapp.cpp b/src/d3dapp.cpp deleted file mode 100644 index a1d5c6a..0000000 --- a/src/d3dapp.cpp +++ /dev/null @@ -1,2452 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "struct.h" -#include "d3dtextr.h" -#include "d3dengine.h" -#include "language.h" -#include "event.h" -#include "profile.h" -#include "iman.h" -#include "restext.h" -#include "math3d.h" -#include "joystick.h" -#include "robotmain.h" -#include "sound.h" -#include "d3dapp.h" - -// fix for "MSH_MOUSEWHEEL undefined" error -#ifdef UNICODE -#define MSH_MOUSEWHEEL L"MSWHEEL_ROLLMSG" -#else -#define MSH_MOUSEWHEEL "MSWHEEL_ROLLMSG" -#endif - - -#define AUDIO_TRACK 13 // total number of audio tracks on the CD -#define MAX_STEP 0.2f // maximum time for a step - -#define WINDOW_DX (640+6) // dimensions in windowed mode -#define WINDOW_DY (480+25) - -#define USE_THREAD FALSE // TRUE does not work! -#define TIME_THREAD 0.02f - - - - -// Limit the use of the controls keyboard & joystick. - -float AxeLimit(float value) -{ - if ( value < -1.0f ) value = -1.0f; - if ( value > 1.0f ) value = 1.0f; - return value; -} - - -// Entry point to the program. Initializes everything, and goes into a -// message-processing loop. Idle time is used to render the scene. - -INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) -{ - Error err; - char string[100]; - - CD3DApplication d3dApp; // single instance of the application - - err = d3dApp.CheckMistery(strCmdLine); - if ( err != ERR_OK ) - { - GetResource(RES_ERR, err, string); -#if _NEWLOOK - MessageBox( NULL, string, _T("CeeBot"), MB_ICONERROR|MB_OK ); -#else - MessageBox( NULL, string, _T("COLOBOT"), MB_ICONERROR|MB_OK ); -#endif - return 0; - } - - if ( FAILED(d3dApp.Create(hInst, strCmdLine)) ) - { - return 0; - } - - return d3dApp.Run(); // execution of all -} - - -// Internal variables and function prototypes. - -enum APPMSGTYPE { MSG_NONE, MSGERR_APPMUSTEXIT, MSGWARN_SWITCHEDTOSOFTWARE }; - -static INT CALLBACK AboutProc( HWND, UINT, WPARAM, LPARAM ); -static LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ); - -static CD3DApplication* g_pD3DApp; - - - -// Constructor. - -CD3DApplication::CD3DApplication() -{ - int i; - - m_iMan = new(CInstanceManager); - m_event = new CEvent(m_iMan); - - m_pD3DEngine = 0; - m_pRobotMain = 0; - m_pSound = 0; - m_pFramework = 0; - m_instance = 0; - m_hWnd = 0; - m_pDD = 0; - m_pD3D = 0; - m_pD3DDevice = 0; - - m_CDpath[0] = 0; - - m_pddsRenderTarget = 0; - m_pddsDepthBuffer = 0; - - m_keyState = 0; - m_axeKey = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_axeJoy = D3DVECTOR(0.0f, 0.0f, 0.0f); - - m_vidMemTotal = 0; - m_bActive = FALSE; - m_bActivateApp = FALSE; - m_bReady = FALSE; - m_bJoystick = FALSE; - m_aTime = 0.0f; - - for ( i=0 ; i<32 ; i++ ) - { - m_bJoyButton[i] = FALSE; - } - -#if _NEWLOOK - m_strWindowTitle = _T("CeeBot"); -#else - m_strWindowTitle = _T("COLOBOT"); -#endif - m_bAppUseZBuffer = TRUE; - m_bAppUseStereo = TRUE; - m_bShowStats = FALSE; - m_bDebugMode = FALSE; - m_bAudioState = TRUE; - m_bAudioTrack = TRUE; - m_bNiceMouse = FALSE; - m_bSetupMode = TRUE; - m_fnConfirmDevice = 0; - - ResetKey(); - - g_pD3DApp = this; - - // Request event sent by Logitech. - m_mshMouseWheel = RegisterWindowMessage(MSH_MOUSEWHEEL); - - _mkdir("files\\"); -} - - -// Destructor. - -CD3DApplication::~CD3DApplication() -{ - delete m_iMan; -} - - - -// Returns the path of the CD. - -char* CD3DApplication::RetCDpath() -{ - return m_CDpath; -} - -// Reads the information in the registry. - -Error CD3DApplication::RegQuery() -{ - FILE* file = NULL; - HKEY key; - LONG i; - DWORD type, len; - char filename[100]; - -#if _NEWLOOK - #if _TEEN - i = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Epsitec\\CeeBot-Teen\\Setup", - #else - i = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Epsitec\\CeeBot-A\\Setup", - #endif -#else - i = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Epsitec\\Colobot\\Setup", -#endif - 0, KEY_READ, &key); - if ( i != ERROR_SUCCESS ) return ERR_INSTALL; - - type = REG_SZ; - len = sizeof(m_CDpath); - i = RegQueryValueEx(key, "CDpath", NULL, &type, (LPBYTE)m_CDpath, &len); - if ( i != ERROR_SUCCESS || type != REG_SZ ) return ERR_INSTALL; - - filename[0] = m_CDpath[0]; - filename[1] = ':'; - filename[2] = '\\'; - filename[3] = 0; - i = GetDriveType(filename); - if ( i != DRIVE_CDROM ) return ERR_NOCD; - - strcat(filename, "install.ini"); - file = fopen(filename, "rb"); // install.ini file exist? - if ( file == NULL ) return ERR_NOCD; - fclose(file); - - return ERR_OK; -} - -// Checks for audio tracks on the CD. - -Error CD3DApplication::AudioQuery() -{ - MCI_OPEN_PARMS mciOpenParms; - MCI_STATUS_PARMS mciStatusParms; - DWORD dwReturn; - UINT deviceID; - char device[10]; - - // Open the device by specifying the device and filename. - // MCI will attempt to choose the MIDI mapper as the output port. - memset(&mciOpenParms, 0, sizeof(MCI_OPEN_PARMS)); - mciOpenParms.lpstrDeviceType = (LPCTSTR)MCI_DEVTYPE_CD_AUDIO; - if ( m_CDpath[0] == 0 ) - { - dwReturn = mciSendCommand(NULL, - MCI_OPEN, - MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID, - (DWORD)(LPVOID)&mciOpenParms); - } - else - { - device[0] = m_CDpath[0]; - device[1] = ':'; - device[2] = 0; - mciOpenParms.lpstrElementName = device; - dwReturn = mciSendCommand(NULL, - MCI_OPEN, - MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_OPEN_ELEMENT, - (DWORD)(LPVOID)&mciOpenParms); - } - if ( dwReturn != 0 ) - { - return ERR_NOCD; - } - - // The device opened successfully; get the device ID. - deviceID = mciOpenParms.wDeviceID; - - memset(&mciStatusParms, 0, sizeof(MCI_STATUS_PARMS)); - mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; - dwReturn = mciSendCommand(deviceID, - MCI_STATUS, - MCI_WAIT|MCI_STATUS_ITEM, - (DWORD)&mciStatusParms); - if ( dwReturn != 0 ) - { - mciSendCommand(deviceID, MCI_CLOSE, 0, NULL); - return ERR_NOCD; - } - - if ( mciStatusParms.dwReturn != AUDIO_TRACK ) - { - mciSendCommand(deviceID, MCI_CLOSE, 0, NULL); - return ERR_NOCD; - } - - mciSendCommand(deviceID, MCI_CLOSE, 0, NULL); - return ERR_OK; -} - -// Checks for the key. - -Error CD3DApplication::CheckMistery(char *strCmdLine) -{ - if ( strstr(strCmdLine, "-debug") != 0 ) - { - m_bShowStats = TRUE; - SetDebugMode(TRUE); - } - - if ( strstr(strCmdLine, "-audiostate") != 0 ) - { - m_bAudioState = FALSE; - } - - if ( strstr(strCmdLine, "-audiotrack") != 0 ) - { - m_bAudioTrack = FALSE; - } - - m_CDpath[0] = 0; -#if _FULL - if ( strstr(strCmdLine, "-nocd") == 0 && !m_bDebugMode ) - { - Error err; - - err = RegQuery(); - if ( err != ERR_OK ) return err; - - //?err = AudioQuery(); - //?if ( err != ERR_OK ) return err; - } -#endif -#if _SCHOOL & _EDU - if ( strstr(strCmdLine, "-nosetup") != 0 ) - { - m_bSetupMode = FALSE; - } - m_bAudioTrack = FALSE; -#endif -#if _SCHOOL & _PERSO - Error err = RegQuery(); - if ( err != ERR_OK ) return err; - m_bAudioTrack = FALSE; -#endif -#if _SCHOOL & _CEEBOTDEMO - m_bAudioTrack = FALSE; -#endif -#if _NET - m_bAudioTrack = FALSE; -#endif -#if _DEMO - m_bAudioTrack = FALSE; -#endif - - return ERR_OK; -} - - -// Returns the total amount of video memory for textures. - -int CD3DApplication::GetVidMemTotal() -{ - return m_vidMemTotal; -} - -BOOL CD3DApplication::IsVideo8MB() -{ - if ( m_vidMemTotal == 0 ) return FALSE; - return (m_vidMemTotal <= 8388608L); // 8 Mb or less (2 ^ 23)? -} - -BOOL CD3DApplication::IsVideo32MB() -{ - if ( m_vidMemTotal == 0 ) return FALSE; - return (m_vidMemTotal > 16777216L); // more than 16 Mb (2 ^ 24)? -} - - -void CD3DApplication::SetShowStat(BOOL bShow) -{ - m_bShowStats = bShow; -} - -BOOL CD3DApplication::RetShowStat() -{ - return m_bShowStats; -} - - -void CD3DApplication::SetDebugMode(BOOL bMode) -{ - m_bDebugMode = bMode; - D3DTextr_SetDebugMode(m_bDebugMode); -} - -BOOL CD3DApplication::RetDebugMode() -{ - return m_bDebugMode; -} - -BOOL CD3DApplication::RetSetupMode() -{ - return m_bSetupMode; -} - - - - -// Son process of time management. - -DWORD WINAPI ThreadRoutine(LPVOID) -{ - Event event; - float time; - int ms, start, end, delay; - - ms = (int)(TIME_THREAD*1000.0f); - time = 0.0f; - while ( TRUE ) - { - start = timeGetTime(); - - g_pD3DApp->m_pD3DEngine->FrameMove(TIME_THREAD); - - ZeroMemory(&event, sizeof(Event)); - event.event = EVENT_FRAME; - event.rTime = TIME_THREAD; - event.axeX = AxeLimit(g_pD3DApp->m_axeKey.x + g_pD3DApp->m_axeJoy.x); - event.axeY = AxeLimit(g_pD3DApp->m_axeKey.y + g_pD3DApp->m_axeJoy.y); - event.axeZ = AxeLimit(g_pD3DApp->m_axeKey.z + g_pD3DApp->m_axeJoy.z); - event.keyState = g_pD3DApp->m_keyState; - - if ( g_pD3DApp->m_pRobotMain != 0 ) - { - g_pD3DApp->m_pRobotMain->EventProcess(event); - } - - end = timeGetTime(); - - delay = ms-(end-start); - if ( delay > 0 ) - { - Sleep(delay); // waiting 20ms-used - } - time += TIME_THREAD; - } - return 0; -} - - -// Called during device intialization, this code checks the device -// for some minimum set of capabilities. - -HRESULT CD3DApplication::ConfirmDevice( DDCAPS* pddDriverCaps, - D3DDEVICEDESC7* pd3dDeviceDesc ) -{ -//? if( pd3dDeviceDesc->wMaxVertexBlendMatrices < 2 ) -//? return E_FAIL; - - return S_OK; -} - -// Create the application. - -HRESULT CD3DApplication::Create( HINSTANCE hInst, TCHAR* strCmdLine ) -{ - HRESULT hr; - char deviceName[100]; - char modeName[100]; - int iValue; - DWORD style; - BOOL bFull, b3D; - - m_instance = hInst; - - InitCurrentDirectory(); - - // Enumerate available D3D devices. The callback is used so the app can - // confirm/reject each enumerated device depending on its capabilities. - if( FAILED( hr = D3DEnum_EnumerateDevices( m_fnConfirmDevice ) ) ) - { - DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); - return hr; - } - - if( FAILED( hr = D3DEnum_SelectDefaultDevice( &m_pDeviceInfo ) ) ) - { - DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); - return hr; - } - - if ( !m_bDebugMode ) - { - m_pDeviceInfo->bWindowed = FALSE; // full screen - } - if ( GetProfileInt("Device", "FullScreen", bFull) ) - { - m_pDeviceInfo->bWindowed = !bFull; - } - - // Create the 3D engine. - if( (m_pD3DEngine = new CD3DEngine(m_iMan, this)) == NULL ) - { - DisplayFrameworkError( D3DENUMERR_ENGINE, MSGERR_APPMUSTEXIT ); - return E_OUTOFMEMORY; - } - SetEngine(m_pD3DEngine); - - // Initialize the app's custom scene stuff - if( FAILED( hr = m_pD3DEngine->OneTimeSceneInit() ) ) - { - DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); - return hr; - } - - // Create a new CD3DFramework class. This class does all of our D3D - // initialization and manages the common D3D objects. - if( (m_pFramework = new CD3DFramework7()) == NULL ) - { - DisplayFrameworkError( E_OUTOFMEMORY, MSGERR_APPMUSTEXIT ); - return E_OUTOFMEMORY; - } - - // Create the sound instance. - if( (m_pSound = new CSound(m_iMan)) == NULL ) - { - DisplayFrameworkError( D3DENUMERR_SOUND, MSGERR_APPMUSTEXIT ); - return E_OUTOFMEMORY; - } - - // Create the robot application. - if( (m_pRobotMain = new CRobotMain(m_iMan)) == NULL ) - { - DisplayFrameworkError( D3DENUMERR_ROBOT, MSGERR_APPMUSTEXIT ); - return E_OUTOFMEMORY; - } - - // Register the window class - WNDCLASS wndClass = { 0, WndProc, 0, 0, hInst, - LoadIcon( hInst, MAKEINTRESOURCE(IDI_MAIN_ICON) ), - LoadCursor( NULL, IDC_ARROW ), - (HBRUSH)GetStockObject(WHITE_BRUSH), - NULL, _T("D3D Window") }; - RegisterClass( &wndClass ); - - // Create the render window - style = WS_CAPTION|WS_VISIBLE; - if ( m_bDebugMode ) style |= WS_SYSMENU; // close box - m_hWnd = CreateWindow( _T("D3D Window"), m_strWindowTitle, -//? WS_OVERLAPPEDWINDOW|WS_VISIBLE, - style, CW_USEDEFAULT, CW_USEDEFAULT, - WINDOW_DX, WINDOW_DY, 0L, -//? LoadMenu( hInst, MAKEINTRESOURCE(IDR_MENU) ), - NULL, - hInst, 0L ); - UpdateWindow( m_hWnd ); - - if ( !GetProfileInt("Setup", "Sound3D", b3D) ) - { - b3D = TRUE; - } - m_pSound->SetDebugMode(m_bDebugMode); - m_pSound->Create(m_hWnd, b3D); - m_pSound->CacheAll(); - m_pSound->SetState(m_bAudioState); - m_pSound->SetAudioTrack(m_bAudioTrack); - m_pSound->SetCDpath(m_CDpath); - - // Initialize the 3D environment for the app - if( FAILED( hr = Initialize3DEnvironment() ) ) - { - DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); - Cleanup3DEnvironment(); - return E_FAIL; - } - - // Change the display device driver. - GetProfileString("Device", "Name", deviceName, 100); - GetProfileString("Device", "Mode", modeName, 100); - GetProfileInt("Device", "FullScreen", bFull); - if ( deviceName[0] != 0 && modeName[0] != 0 && bFull ) - { - ChangeDevice(deviceName, modeName, bFull); - } - - // First execution? - if ( !GetProfileInt("Setup", "ObjectDirty", iValue) ) - { - m_pD3DEngine->FirstExecuteAdapt(TRUE); - } - - // Creates the file colobot.ini at the first execution. - m_pRobotMain->CreateIni(); - -#if _DEMO - m_pRobotMain->ChangePhase(PHASE_NAME); -#else -#if _NET | _SCHOOL - m_pRobotMain->ChangePhase(PHASE_WELCOME2); -#else -#if _FRENCH - m_pRobotMain->ChangePhase(PHASE_WELCOME2); -#endif -#if _ENGLISH - m_pRobotMain->ChangePhase(PHASE_WELCOME2); -#endif -#if _GERMAN - m_pRobotMain->ChangePhase(PHASE_WELCOME2); -#endif -#if _WG - m_pRobotMain->ChangePhase(PHASE_WELCOME1); -#endif -#if _POLISH - m_pRobotMain->ChangePhase(PHASE_WELCOME1); -#endif -#endif -#endif - m_pD3DEngine->TimeInit(); - -#if USE_THREAD - m_thread = CreateThread(NULL, 0, ThreadRoutine, this, 0, &m_threadId); - SetThreadPriority(m_thread, THREAD_PRIORITY_ABOVE_NORMAL); -#endif - - // The app is ready to go - m_bReady = TRUE; - - return S_OK; -} - - -// Message-processing loop. Idle time is used to render the scene. - -INT CD3DApplication::Run() -{ - // Load keyboard accelerators - HACCEL hAccel = LoadAccelerators( NULL, MAKEINTRESOURCE(IDR_MAIN_ACCEL) ); - - // Now we're ready to recieve and process Windows messages. - BOOL bGotMsg; - MSG msg; - PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE ); - - while( WM_QUIT != msg.message ) - { - // Use PeekMessage() if the app is active, so we can use idle time to - // render the scene. Else, use GetMessage() to avoid eating CPU time. - if( m_bActive ) - bGotMsg = PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ); - else - bGotMsg = GetMessage( &msg, NULL, 0U, 0U ); - - if( bGotMsg ) - { - // Translate and dispatch the message - if( TranslateAccelerator( m_hWnd, hAccel, &msg ) == 0 ) - { - TranslateMessage( &msg ); - DispatchMessage( &msg ); - } - } - else - { - // Render a frame during idle time (no messages are waiting) - if( m_bActive && m_bReady ) - { - Event event; - - while ( m_event->GetEvent(event) ) - { - if ( event.event == EVENT_QUIT ) - { -//? SendMessage( m_hWnd, WM_CLOSE, 0, 0 ); - m_pSound->StopMusic(); - Cleanup3DEnvironment(); - PostQuitMessage(0); - return msg.wParam; - } - m_pRobotMain->EventProcess(event); - } - - if ( !RetNiceMouse() ) - { - SetMouseType(m_pD3DEngine->RetMouseType()); - } - - if( FAILED( Render3DEnvironment() ) ) - DestroyWindow( m_hWnd ); - } - } - } - - return msg.wParam; -} - - - -// Conversion of the position of the mouse. -// x: 0=left, 1=right -// y: 0=down, 1=up - -FPOINT CD3DApplication::ConvPosToInterface(HWND hWnd, LPARAM lParam) -{ - POINT cpos; - FPOINT pos; - float px, py, w, h; - - cpos.x = (short)LOWORD(lParam); - cpos.y = (short)HIWORD(lParam); - - if ( !m_pDeviceInfo->bWindowed ) - { - ClientToScreen(hWnd, &cpos); - } - - px = (float)cpos.x; - py = (float)cpos.y; - w = (float)m_ddsdRenderTarget.dwWidth; - h = (float)m_ddsdRenderTarget.dwHeight; - - pos.x = px/w; - pos.y = 1.0f-py/h; - - return pos; -} - -// Physically moves the mouse. - -void CD3DApplication::SetMousePos(FPOINT pos) -{ - POINT p; - - pos.y = 1.0f-pos.y; - - pos.x *= m_ddsdRenderTarget.dwWidth; - pos.y *= m_ddsdRenderTarget.dwHeight; - - p.x = (int)pos.x; - p.y = (int)pos.y; - ClientToScreen(m_hWnd, &p); - - SetCursorPos(p.x, p.y); -} - -// Choosing the type of cursor for the mouse. - -void CD3DApplication::SetMouseType(D3DMouse type) -{ - HCURSOR hc; - - if ( type == D3DMOUSEHAND ) - { - hc = LoadCursor(m_instance, MAKEINTRESOURCE(IDC_CURSORHAND)); - } - else if ( type == D3DMOUSECROSS ) - { - hc = LoadCursor(NULL, IDC_CROSS); - } - else if ( type == D3DMOUSEEDIT ) - { - hc = LoadCursor(NULL, IDC_IBEAM); - } - else if ( type == D3DMOUSENO ) - { - hc = LoadCursor(NULL, IDC_NO); - } - else if ( type == D3DMOUSEMOVE ) - { - hc = LoadCursor(NULL, IDC_SIZEALL); - } - else if ( type == D3DMOUSEMOVEH ) - { - hc = LoadCursor(NULL, IDC_SIZEWE); - } - else if ( type == D3DMOUSEMOVEV ) - { - hc = LoadCursor(NULL, IDC_SIZENS); - } - else if ( type == D3DMOUSEMOVED ) - { - hc = LoadCursor(NULL, IDC_SIZENESW); - } - else if ( type == D3DMOUSEMOVEI ) - { - hc = LoadCursor(NULL, IDC_SIZENWSE); - } - else if ( type == D3DMOUSEWAIT ) - { - hc = LoadCursor(NULL, IDC_WAIT); - } - else if ( type == D3DMOUSESCROLLL ) - { - hc = LoadCursor(m_instance, MAKEINTRESOURCE(IDC_CURSORSCROLLL)); - } - else if ( type == D3DMOUSESCROLLR ) - { - hc = LoadCursor(m_instance, MAKEINTRESOURCE(IDC_CURSORSCROLLR)); - } - else if ( type == D3DMOUSESCROLLU ) - { - hc = LoadCursor(m_instance, MAKEINTRESOURCE(IDC_CURSORSCROLLU)); - } - else if ( type == D3DMOUSESCROLLD ) - { - hc = LoadCursor(m_instance, MAKEINTRESOURCE(IDC_CURSORSCROLLD)); - } - else if ( type == D3DMOUSETARGET ) - { - hc = LoadCursor(m_instance, MAKEINTRESOURCE(IDC_CURSORTARGET)); - } - else - { - hc = LoadCursor(NULL, IDC_ARROW); - } - - if ( hc != NULL ) - { - SetCursor(hc); - } -} - -// Choice of mode for the mouse. - -void CD3DApplication::SetNiceMouse(BOOL bNice) -{ - if ( bNice == m_bNiceMouse ) return; - m_bNiceMouse = bNice; - - if ( m_bNiceMouse ) - { - ShowCursor(FALSE); // hides the ugly windows mouse - SetCursor(NULL); - } - else - { - ShowCursor(TRUE); // shows the ugly windows mouse - SetCursor(LoadCursor(NULL, IDC_ARROW)); - } -} - -// Whether to use the mouse pretty shaded. - -BOOL CD3DApplication::RetNiceMouse() -{ - if ( m_pDeviceInfo->bWindowed ) return FALSE; - if ( !m_pDeviceInfo->bHardware ) return FALSE; - - return m_bNiceMouse; -} - -// Indicates whether it is possible to use the mouse pretty shaded. - -BOOL CD3DApplication::RetNiceMouseCap() -{ - if ( m_pDeviceInfo->bWindowed ) return FALSE; - if ( !m_pDeviceInfo->bHardware ) return FALSE; - - return TRUE; -} - - -// Static msg handler which passes messages to the application class. - -LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) -{ - if ( g_pD3DApp != 0 ) - { - Event event; - short move; - - ZeroMemory(&event, sizeof(Event)); - -#if 0 - if ( uMsg == WM_KEYDOWN || - uMsg == WM_CHAR || - uMsg == WM_XBUTTONDOWN || - uMsg == WM_XBUTTONUP ) - { - char s[100]; - sprintf(s, "event: %d %d %d\n", uMsg, wParam, lParam); - OutputDebugString(s); - } -#endif - - if ( uMsg == WM_LBUTTONDOWN ) event.event = EVENT_LBUTTONDOWN; - if ( uMsg == WM_RBUTTONDOWN ) event.event = EVENT_RBUTTONDOWN; - if ( uMsg == WM_LBUTTONUP ) event.event = EVENT_LBUTTONUP; - if ( uMsg == WM_RBUTTONUP ) event.event = EVENT_RBUTTONUP; - if ( uMsg == WM_MOUSEMOVE ) event.event = EVENT_MOUSEMOVE; - if ( uMsg == WM_KEYDOWN ) event.event = EVENT_KEYDOWN; - if ( uMsg == WM_KEYUP ) event.event = EVENT_KEYUP; - if ( uMsg == WM_CHAR ) event.event = EVENT_CHAR; - - if ( uMsg == WM_XBUTTONUP ) - { - if ( (wParam>>16) == XBUTTON1 ) event.event = EVENT_HYPER_PREV; - if ( (wParam>>16) == XBUTTON2 ) event.event = EVENT_HYPER_NEXT; - } - - event.param = wParam; - event.axeX = AxeLimit(g_pD3DApp->m_axeKey.x + g_pD3DApp->m_axeJoy.x); - event.axeY = AxeLimit(g_pD3DApp->m_axeKey.y + g_pD3DApp->m_axeJoy.y); - event.axeZ = AxeLimit(g_pD3DApp->m_axeKey.z + g_pD3DApp->m_axeJoy.z); - event.keyState = g_pD3DApp->m_keyState; - - if ( uMsg == WM_LBUTTONDOWN || - uMsg == WM_RBUTTONDOWN || - uMsg == WM_LBUTTONUP || - uMsg == WM_RBUTTONUP || - uMsg == WM_MOUSEMOVE ) // mouse event? - { - event.pos = g_pD3DApp->ConvPosToInterface(hWnd, lParam); - g_pD3DApp->m_mousePos = event.pos; - g_pD3DApp->m_pD3DEngine->SetMousePos(event.pos); - } - - if ( uMsg == WM_MOUSEWHEEL ) // mouse wheel? - { - event.event = EVENT_KEYDOWN; - event.pos = g_pD3DApp->m_mousePos; - move = HIWORD(wParam); - if ( move/WHEEL_DELTA > 0 ) event.param = VK_WHEELUP; - if ( move/WHEEL_DELTA < 0 ) event.param = VK_WHEELDOWN; - } - if ( g_pD3DApp->m_mshMouseWheel != 0 && - uMsg == g_pD3DApp->m_mshMouseWheel ) // Logitech mouse wheel? - { - event.event = EVENT_KEYDOWN; - event.pos = g_pD3DApp->m_mousePos; - move = LOWORD(wParam); - if ( move/WHEEL_DELTA > 0 ) event.param = VK_WHEELUP; - if ( move/WHEEL_DELTA < 0 ) event.param = VK_WHEELDOWN; - } - - if ( event.event == EVENT_KEYDOWN || - event.event == EVENT_KEYUP || - event.event == EVENT_CHAR ) - { - if ( event.param == 0 ) - { - event.event = EVENT_NULL; - } - } - - if ( g_pD3DApp->m_pRobotMain != 0 && event.event != 0 ) - { - g_pD3DApp->m_pRobotMain->EventProcess(event); -//? if ( !g_pD3DApp->RetNiceMouse() ) -//? { -//? g_pD3DApp->SetMouseType(g_pD3DApp->m_pD3DEngine->RetMouseType()); -//? } - } - if ( g_pD3DApp->m_pD3DEngine != 0 ) - { - g_pD3DApp->m_pD3DEngine->MsgProc( hWnd, uMsg, wParam, lParam ); - } - return g_pD3DApp->MsgProc( hWnd, uMsg, wParam, lParam ); - } - - return DefWindowProc( hWnd, uMsg, wParam, lParam ); -} - - -// Minimal message proc function for the about box. - -BOOL CALLBACK AboutProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM ) -{ - if( WM_COMMAND == uMsg ) - if( IDOK == LOWORD(wParam) || IDCANCEL == LOWORD(wParam) ) - EndDialog( hWnd, TRUE ); - - return WM_INITDIALOG == uMsg ? TRUE : FALSE; -} - - - -// Ignore keypresses. - -void CD3DApplication::FlushPressKey() -{ - m_keyState = 0; - m_axeKey = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_axeJoy = D3DVECTOR(0.0f, 0.0f, 0.0f); -} - -// Resets the default keys. - -void CD3DApplication::ResetKey() -{ - int i; - - for ( i=0 ; i<50 ; i++ ) - { - m_key[i][0] = 0; - m_key[i][1] = 0; - } - m_key[KEYRANK_LEFT ][0] = VK_LEFT; - m_key[KEYRANK_RIGHT ][0] = VK_RIGHT; - m_key[KEYRANK_UP ][0] = VK_UP; - m_key[KEYRANK_DOWN ][0] = VK_DOWN; - m_key[KEYRANK_GUP ][0] = VK_SHIFT; - m_key[KEYRANK_GDOWN ][0] = VK_CONTROL; - m_key[KEYRANK_CAMERA ][0] = VK_SPACE; - m_key[KEYRANK_CAMERA ][1] = VK_BUTTON2; - m_key[KEYRANK_DESEL ][0] = VK_NUMPAD0; - m_key[KEYRANK_DESEL ][1] = VK_BUTTON6; - m_key[KEYRANK_ACTION ][0] = VK_RETURN; - m_key[KEYRANK_ACTION ][1] = VK_BUTTON1; - m_key[KEYRANK_NEAR ][0] = VK_ADD; - m_key[KEYRANK_NEAR ][1] = VK_BUTTON5; - m_key[KEYRANK_AWAY ][0] = VK_SUBTRACT; - m_key[KEYRANK_AWAY ][1] = VK_BUTTON4; - m_key[KEYRANK_NEXT ][0] = VK_TAB; - m_key[KEYRANK_NEXT ][1] = VK_BUTTON3; - m_key[KEYRANK_HUMAN ][0] = VK_HOME; - m_key[KEYRANK_HUMAN ][1] = VK_BUTTON7; - m_key[KEYRANK_QUIT ][0] = VK_ESCAPE; - m_key[KEYRANK_HELP ][0] = VK_F1; - m_key[KEYRANK_PROG ][0] = VK_F2; - m_key[KEYRANK_CBOT ][0] = VK_F3; - m_key[KEYRANK_VISIT ][0] = VK_DECIMAL; - m_key[KEYRANK_SPEED10][0] = VK_F4; - m_key[KEYRANK_SPEED15][0] = VK_F5; - m_key[KEYRANK_SPEED20][0] = VK_F6; -// m_key[KEYRANK_SPEED30][0] = VK_F7; -} - -// Modifies a button. - -void CD3DApplication::SetKey(int keyRank, int option, int key) -{ - if ( keyRank < 0 || - keyRank >= 50 ) return; - - if ( option < 0 || - option >= 2 ) return; - - m_key[keyRank][option] = key; -} - -// Gives a hint. - -int CD3DApplication::RetKey(int keyRank, int option) -{ - if ( keyRank < 0 || - keyRank >= 50 ) return 0; - - if ( option < 0 || - option >= 2 ) return 0; - - return m_key[keyRank][option]; -} - - - -// Use the joystick or keyboard. - -void CD3DApplication::SetJoystick(BOOL bEnable) -{ - m_bJoystick = bEnable; - - if ( m_bJoystick ) // joystick ? - { - if ( !InitDirectInput(m_instance, m_hWnd) ) // initialise joystick - { - m_bJoystick = FALSE; - } - else - { - SetAcquire(TRUE); - SetTimer(m_hWnd, 0, 1000/30, NULL); - } - } - else // keyboard? - { - KillTimer(m_hWnd, 0); - SetAcquire(FALSE); - FreeDirectInput(); - } -} - -BOOL CD3DApplication::RetJoystick() -{ - return m_bJoystick; -} - - -// Message handling function. - -LRESULT CD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, - LPARAM lParam ) -{ - HRESULT hr; - DIJOYSTATE js; - int i; - - // The F10 key sends another message to activate - // menu in standard Windows applications! - if ( uMsg == WM_SYSKEYDOWN && wParam == VK_F10 ) - { - uMsg = WM_KEYDOWN; - } - if ( uMsg == WM_SYSKEYUP && wParam == VK_F10 ) - { - uMsg = WM_KEYUP; - } - - // Mange event "menu" sent by Alt or F10. - if ( uMsg == WM_SYSCOMMAND && wParam == SC_KEYMENU ) - { - return 0; - } - - if ( uMsg == WM_KEYDOWN || uMsg == WM_KEYUP ) - { - if ( GetKeyState(VK_SHIFT) & 0x8000 ) - { - m_keyState |= KS_SHIFT; - } - else - { - m_keyState &= ~KS_SHIFT; - } - - if ( GetKeyState(VK_CONTROL) & 0x8000 ) - { - m_keyState |= KS_CONTROL; - } - else - { - m_keyState &= ~KS_CONTROL; - } - } - - switch( uMsg ) - { - case WM_KEYDOWN: - if ( wParam == m_key[KEYRANK_UP ][0] ) m_axeKey.y = 1.0f; - if ( wParam == m_key[KEYRANK_UP ][1] ) m_axeKey.y = 1.0f; - if ( wParam == m_key[KEYRANK_DOWN ][0] ) m_axeKey.y = -1.0f; - if ( wParam == m_key[KEYRANK_DOWN ][1] ) m_axeKey.y = -1.0f; - if ( wParam == m_key[KEYRANK_LEFT ][0] ) m_axeKey.x = -1.0f; - if ( wParam == m_key[KEYRANK_LEFT ][1] ) m_axeKey.x = -1.0f; - if ( wParam == m_key[KEYRANK_RIGHT][0] ) m_axeKey.x = 1.0f; - if ( wParam == m_key[KEYRANK_RIGHT][1] ) m_axeKey.x = 1.0f; - if ( wParam == m_key[KEYRANK_GUP ][0] ) m_axeKey.z = 1.0f; - if ( wParam == m_key[KEYRANK_GUP ][1] ) m_axeKey.z = 1.0f; - if ( wParam == m_key[KEYRANK_GDOWN][0] ) m_axeKey.z = -1.0f; - if ( wParam == m_key[KEYRANK_GDOWN][1] ) m_axeKey.z = -1.0f; - if ( wParam == m_key[KEYRANK_NEAR ][0] ) m_keyState |= KS_NUMPLUS; - if ( wParam == m_key[KEYRANK_NEAR ][1] ) m_keyState |= KS_NUMPLUS; - if ( wParam == m_key[KEYRANK_AWAY ][0] ) m_keyState |= KS_NUMMINUS; - if ( wParam == m_key[KEYRANK_AWAY ][1] ) m_keyState |= KS_NUMMINUS; - if ( wParam == VK_PRIOR ) m_keyState |= KS_PAGEUP; - if ( wParam == VK_NEXT ) m_keyState |= KS_PAGEDOWN; -//? if ( wParam == VK_SHIFT ) m_keyState |= KS_SHIFT; -//? if ( wParam == VK_CONTROL ) m_keyState |= KS_CONTROL; - if ( wParam == VK_NUMPAD8 ) m_keyState |= KS_NUMUP; - if ( wParam == VK_NUMPAD2 ) m_keyState |= KS_NUMDOWN; - if ( wParam == VK_NUMPAD4 ) m_keyState |= KS_NUMLEFT; - if ( wParam == VK_NUMPAD6 ) m_keyState |= KS_NUMRIGHT; - break; - - case WM_KEYUP: - if ( wParam == m_key[KEYRANK_UP ][0] ) m_axeKey.y = 0.0f; - if ( wParam == m_key[KEYRANK_UP ][1] ) m_axeKey.y = 0.0f; - if ( wParam == m_key[KEYRANK_DOWN ][0] ) m_axeKey.y = 0.0f; - if ( wParam == m_key[KEYRANK_DOWN ][1] ) m_axeKey.y = 0.0f; - if ( wParam == m_key[KEYRANK_LEFT ][0] ) m_axeKey.x = 0.0f; - if ( wParam == m_key[KEYRANK_LEFT ][1] ) m_axeKey.x = 0.0f; - if ( wParam == m_key[KEYRANK_RIGHT][0] ) m_axeKey.x = 0.0f; - if ( wParam == m_key[KEYRANK_RIGHT][1] ) m_axeKey.x = 0.0f; - if ( wParam == m_key[KEYRANK_GUP ][0] ) m_axeKey.z = 0.0f; - if ( wParam == m_key[KEYRANK_GUP ][1] ) m_axeKey.z = 0.0f; - if ( wParam == m_key[KEYRANK_GDOWN][0] ) m_axeKey.z = 0.0f; - if ( wParam == m_key[KEYRANK_GDOWN][1] ) m_axeKey.z = 0.0f; - if ( wParam == m_key[KEYRANK_NEAR ][0] ) m_keyState &= ~KS_NUMPLUS; - if ( wParam == m_key[KEYRANK_NEAR ][1] ) m_keyState &= ~KS_NUMPLUS; - if ( wParam == m_key[KEYRANK_AWAY ][0] ) m_keyState &= ~KS_NUMMINUS; - if ( wParam == m_key[KEYRANK_AWAY ][1] ) m_keyState &= ~KS_NUMMINUS; - if ( wParam == VK_PRIOR ) m_keyState &= ~KS_PAGEUP; - if ( wParam == VK_NEXT ) m_keyState &= ~KS_PAGEDOWN; -//? if ( wParam == VK_SHIFT ) m_keyState &= ~KS_SHIFT; -//? if ( wParam == VK_CONTROL ) m_keyState &= ~KS_CONTROL; - if ( wParam == VK_NUMPAD8 ) m_keyState &= ~KS_NUMUP; - if ( wParam == VK_NUMPAD2 ) m_keyState &= ~KS_NUMDOWN; - if ( wParam == VK_NUMPAD4 ) m_keyState &= ~KS_NUMLEFT; - if ( wParam == VK_NUMPAD6 ) m_keyState &= ~KS_NUMRIGHT; - break; - - case WM_LBUTTONDOWN: - m_keyState |= KS_MLEFT; - break; - - case WM_RBUTTONDOWN: - m_keyState |= KS_MRIGHT; - break; - - case WM_LBUTTONUP: - m_keyState &= ~KS_MLEFT; - break; - - case WM_RBUTTONUP: - m_keyState &= ~KS_MRIGHT; - break; - - case WM_PAINT: - // Handle paint messages when the app is not ready - if( m_pFramework && !m_bReady ) - { - if( m_pDeviceInfo->bWindowed ) - m_pFramework->ShowFrame(); - else - m_pFramework->FlipToGDISurface( TRUE ); - } - break; - - case WM_MOVE: - // If in windowed mode, move the Framework's window - if( m_pFramework && m_bActive && m_bReady && m_pDeviceInfo->bWindowed ) - m_pFramework->Move( (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam) ); - break; - - case WM_SIZE: - // Check to see if we are losing our window... - if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam ) - { - m_bActive = FALSE; - } - else - { - m_bActive = TRUE; - } -//? char s[100]; -//? sprintf(s, "WM_SIZE %d %d %d\n", m_bActive, m_bReady, m_pDeviceInfo->bWindowed); -//? OutputDebugString(s); - - // A new window size will require a new backbuffer - // size, so the 3D structures must be changed accordingly. - if( m_bActive && m_bReady && m_pDeviceInfo->bWindowed ) - { - m_bReady = FALSE; - -//? OutputDebugString("WM_SIZE Change3DEnvironment\n"); - if( FAILED( hr = Change3DEnvironment() ) ) - return 0; - - m_bReady = TRUE; - } - break; - - case WM_TIMER: - if ( m_bActivateApp && m_bJoystick ) - { - if ( UpdateInputState(js) ) - { - m_axeJoy.x = js.lX/1000.0f+js.lRz/1000.0f; // tourner - m_axeJoy.y = -js.lY/1000.0f; // avancer - m_axeJoy.z = -js.rglSlider[0]/1000.0f; // monter - - m_axeJoy.x = Neutral(m_axeJoy.x, 0.2f); - m_axeJoy.y = Neutral(m_axeJoy.y, 0.2f); - m_axeJoy.z = Neutral(m_axeJoy.z, 0.2f); - -//? char s[100]; -//? sprintf(s, "x=%d y=%d z=% x=%d y=%d z=%d\n", js.lX,js.lY,js.lZ,js.lRx,js.lRy,js.lRz); -//? OutputDebugString(s); - - for ( i=0 ; i<32 ; i++ ) - { - if ( js.rgbButtons[i] != 0 && !m_bJoyButton[i] ) - { - m_bJoyButton[i] = TRUE; - PostMessage(m_hWnd, WM_KEYDOWN, VK_BUTTON1+i, 0); - } - if ( js.rgbButtons[i] == 0 && m_bJoyButton[i] ) - { - m_bJoyButton[i] = FALSE; - PostMessage(m_hWnd, WM_KEYUP, VK_BUTTON1+i, 0); - } - } - } - else - { - OutputDebugString("UpdateInputState error\n"); - } - } - break; - - case WM_ACTIVATE: - if( LOWORD(wParam) == WA_INACTIVE ) - { - m_bActivateApp = FALSE; - } - else - { - m_bActivateApp = TRUE; - } - - if ( m_bActivateApp && m_bJoystick ) - { - SetAcquire(TRUE); // re-enables the joystick - } - break; - - case MM_MCINOTIFY: - if ( wParam == MCI_NOTIFY_SUCCESSFUL ) - { - OutputDebugString("Event MM_MCINOTIFY\n"); - m_pSound->SuspendMusic(); - m_pSound->RestartMusic(); - } - break; - - case WM_SETCURSOR: - // Prevent a cursor in fullscreen mode - if( m_bActive && m_bReady && !m_pDeviceInfo->bWindowed ) - { -//? SetCursor(NULL); - return 1; - } - break; - - case WM_ENTERMENULOOP: - // Pause the app when menus are displayed - Pause(TRUE); - break; - case WM_EXITMENULOOP: - Pause(FALSE); - break; - - case WM_ENTERSIZEMOVE: - // Halt frame movement while the app is sizing or moving - m_pD3DEngine->TimeEnterGel(); - break; - case WM_EXITSIZEMOVE: - m_pD3DEngine->TimeExitGel(); - break; - - case WM_NCHITTEST: - // Prevent the user from selecting the menu in fullscreen mode - if( !m_pDeviceInfo->bWindowed ) - return HTCLIENT; - - break; - - case WM_POWERBROADCAST: - switch( wParam ) - { - case PBT_APMQUERYSUSPEND: - // At this point, the app should save any data for open - // network connections, files, etc.., and prepare to go into - // a suspended mode. - return OnQuerySuspend( (DWORD)lParam ); - - case PBT_APMRESUMESUSPEND: - // At this point, the app should recover any data, network - // connections, files, etc.., and resume running from when - // the app was suspended. - return OnResumeSuspend( (DWORD)lParam ); - } - break; - - case WM_SYSCOMMAND: - // Prevent moving/sizing and power loss in fullscreen mode - switch( wParam ) - { - case SC_MOVE: - case SC_SIZE: - case SC_MAXIMIZE: - case SC_MONITORPOWER: - if( FALSE == m_pDeviceInfo->bWindowed ) - return 1; - break; - } - break; - - case WM_COMMAND: - switch( LOWORD(wParam) ) - { - case IDM_CHANGEDEVICE: - // Display the device-selection dialog box. - if( m_bActive && m_bReady ) - { - Pause(TRUE); - - if( SUCCEEDED( D3DEnum_UserChangeDevice( &m_pDeviceInfo ) ) ) - { - if( FAILED( hr = Change3DEnvironment() ) ) - return 0; - } - Pause(FALSE); - } - return 0; - - case IDM_ABOUT: - // Display the About box - Pause(TRUE); - DialogBox( (HINSTANCE)GetWindowLong( hWnd, GWL_HINSTANCE ), - MAKEINTRESOURCE(IDD_ABOUT), hWnd, AboutProc ); - Pause(FALSE); - return 0; - - case IDM_EXIT: - // Recieved key/menu command to exit app - SendMessage( hWnd, WM_CLOSE, 0, 0 ); - return 0; - } - break; - - case WM_GETMINMAXINFO: - ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100; - ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100; - break; - - case WM_CLOSE: - DestroyWindow( hWnd ); - return 0; - - case WM_DESTROY: - Cleanup3DEnvironment(); - PostQuitMessage(0); - return 0; - } - - return DefWindowProc( hWnd, uMsg, wParam, lParam ); -} - - -// Enumeration function to report valid pixel formats for z-buffers. - -HRESULT WINAPI EnumZBufferFormatsCallback(DDPIXELFORMAT* pddpf, - VOID* pContext) -{ - DDPIXELFORMAT* pddpfOut = (DDPIXELFORMAT*)pContext; - - char s[100]; - sprintf(s, "EnumZBufferFormatsCallback %d\n", pddpf->dwRGBBitCount); - OutputDebugString(s); - - if( pddpfOut->dwRGBBitCount == pddpf->dwRGBBitCount ) - { - (*pddpfOut) = (*pddpf); - return D3DENUMRET_CANCEL; - } - - return D3DENUMRET_OK; -} - -// Internal function called by Create() to make and attach a zbuffer -// to the renderer. - -HRESULT CD3DApplication::CreateZBuffer(GUID* pDeviceGUID) -{ - HRESULT hr; - - // Check if the device supports z-bufferless hidden surface removal. If so, - // we don't really need a z-buffer - D3DDEVICEDESC7 ddDesc; - m_pD3DDevice->GetCaps( &ddDesc ); - if( ddDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR ) - return S_OK; - - // Get z-buffer dimensions from the render target - DDSURFACEDESC2 ddsd; - ddsd.dwSize = sizeof(ddsd); - m_pddsRenderTarget->GetSurfaceDesc( &ddsd ); - - // Setup the surface desc for the z-buffer. - ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT; - ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY; - ddsd.ddpfPixelFormat.dwSize = 0; // Tag the pixel format as unitialized - - // Get an appropiate pixel format from enumeration of the formats. On the - // first pass, we look for a zbuffer dpeth which is equal to the frame - // buffer depth (as some cards unfornately require this). - m_pD3D->EnumZBufferFormats( *pDeviceGUID, EnumZBufferFormatsCallback, - (VOID*)&ddsd.ddpfPixelFormat ); - if( 0 == ddsd.ddpfPixelFormat.dwSize ) - { - // Try again, just accepting any 16-bit zbuffer - ddsd.ddpfPixelFormat.dwRGBBitCount = 16; - m_pD3D->EnumZBufferFormats( *pDeviceGUID, EnumZBufferFormatsCallback, - (VOID*)&ddsd.ddpfPixelFormat ); - - if( 0 == ddsd.ddpfPixelFormat.dwSize ) - { - DEBUG_MSG( _T("Device doesn't support requested zbuffer format") ); - return D3DFWERR_NOZBUFFER; - } - } - - // Create and attach a z-buffer - if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsDepthBuffer, NULL ) ) ) - { - DEBUG_MSG( _T("Error: Couldn't create a ZBuffer surface") ); - if( hr != DDERR_OUTOFVIDEOMEMORY ) - return D3DFWERR_NOZBUFFER; - DEBUG_MSG( _T("Error: Out of video memory") ); - return DDERR_OUTOFVIDEOMEMORY; - } - - if( FAILED( m_pddsRenderTarget->AddAttachedSurface( m_pddsDepthBuffer ) ) ) - { - DEBUG_MSG( _T("Error: Couldn't attach zbuffer to render surface") ); - return D3DFWERR_NOZBUFFER; - } - - // Finally, this call rebuilds internal structures - if( FAILED( m_pD3DDevice->SetRenderTarget( m_pddsRenderTarget, 0L ) ) ) - { - DEBUG_MSG( _T("Error: SetRenderTarget() failed after attaching zbuffer!") ); - return D3DFWERR_NOZBUFFER; - } - - return S_OK; -} - -// Initializes the sample framework, then calls the app-specific function -// to initialize device specific objects. This code is structured to -// handled any errors that may occur duing initialization. - -HRESULT CD3DApplication::Initialize3DEnvironment() -{ - HRESULT hr; - DDSCAPS2 ddsCaps2; - DWORD dwFrameworkFlags = 0L; - DWORD dwTotal; - DWORD dwFree; - - dwFrameworkFlags |= ( !m_pDeviceInfo->bWindowed ? D3DFW_FULLSCREEN : 0L ); - dwFrameworkFlags |= ( m_pDeviceInfo->bStereo ? D3DFW_STEREO : 0L ); - dwFrameworkFlags |= ( m_bAppUseZBuffer ? D3DFW_ZBUFFER : 0L ); - - // Initialize the D3D framework - if( SUCCEEDED( hr = m_pFramework->Initialize( m_hWnd, - m_pDeviceInfo->pDriverGUID, m_pDeviceInfo->pDeviceGUID, - &m_pDeviceInfo->ddsdFullscreenMode, dwFrameworkFlags ) ) ) - { - m_pDD = m_pFramework->GetDirectDraw(); - m_pD3D = m_pFramework->GetDirect3D(); - m_pD3DDevice = m_pFramework->GetD3DDevice(); - - m_pD3DEngine->SetD3DDevice(m_pD3DDevice); - - m_pddsRenderTarget = m_pFramework->GetRenderSurface(); - - m_ddsdRenderTarget.dwSize = sizeof(m_ddsdRenderTarget); - m_pddsRenderTarget->GetSurfaceDesc( &m_ddsdRenderTarget ); - - // Request the amount of video memory. - ZeroMemory(&ddsCaps2, sizeof(ddsCaps2)); - ddsCaps2.dwCaps = DDSCAPS_TEXTURE; - dwTotal = 0; - hr = m_pDD->GetAvailableVidMem(&ddsCaps2, &dwTotal, &dwFree); - m_vidMemTotal = dwTotal; - - // Let the app run its startup code which creates the 3d scene. - if( SUCCEEDED( hr = m_pD3DEngine->InitDeviceObjects() ) ) - { -//? CreateZBuffer(m_pDeviceInfo->pDeviceGUID); - return S_OK; - } - else - { - DeleteDeviceObjects(); - m_pFramework->DestroyObjects(); - } - } - - // If we get here, the first initialization passed failed. If that was with a - // hardware device, try again using a software rasterizer instead. - if( m_pDeviceInfo->bHardware ) - { - // Try again with a software rasterizer - DisplayFrameworkError( hr, MSGWARN_SWITCHEDTOSOFTWARE ); - D3DEnum_SelectDefaultDevice( &m_pDeviceInfo, D3DENUM_SOFTWAREONLY ); - return Initialize3DEnvironment(); - } - - return hr; -} - - -// Handles driver, device, and/or mode changes for the app. - -HRESULT CD3DApplication::Change3DEnvironment() -{ -#if 0 - HRESULT hr; - static BOOL bOldWindowedState = TRUE; - static DWORD dwSavedStyle; - static RECT rcSaved; - - // Release all scene objects that will be re-created for the new device - DeleteDeviceObjects(); - - // Release framework objects, so a new device can be created - if( FAILED( hr = m_pFramework->DestroyObjects() ) ) - { - DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); - SendMessage( m_hWnd, WM_CLOSE, 0, 0 ); - return hr; - } - - // Check if going from fullscreen to windowed mode, or vice versa. - if( bOldWindowedState != m_pDeviceInfo->bWindowed ) - { - if( m_pDeviceInfo->bWindowed ) - { - // Coming from fullscreen mode, so restore window properties - SetWindowLong( m_hWnd, GWL_STYLE, dwSavedStyle ); - SetWindowPos( m_hWnd, HWND_NOTOPMOST, rcSaved.left, rcSaved.top, - ( rcSaved.right - rcSaved.left ), - ( rcSaved.bottom - rcSaved.top ), SWP_SHOWWINDOW ); - } - else - { - // Going to fullscreen mode, save/set window properties as needed - dwSavedStyle = GetWindowLong( m_hWnd, GWL_STYLE ); - GetWindowRect( m_hWnd, &rcSaved ); - SetWindowLong( m_hWnd, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE ); - } - - bOldWindowedState = m_pDeviceInfo->bWindowed; - } - - // Inform the framework class of the driver change. It will internally - // re-create valid surfaces, a d3ddevice, etc. - if( FAILED( hr = Initialize3DEnvironment() ) ) - { - DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); - SendMessage( m_hWnd, WM_CLOSE, 0, 0 ); - return hr; - } - - return S_OK; -#else - HRESULT hr; - - // Release all scene objects that will be re-created for the new device - DeleteDeviceObjects(); - - // Release framework objects, so a new device can be created - if( FAILED( hr = m_pFramework->DestroyObjects() ) ) - { - DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); - SendMessage( m_hWnd, WM_CLOSE, 0, 0 ); - return hr; - } - - if( m_pDeviceInfo->bWindowed ) - { - SetWindowPos(m_hWnd, HWND_NOTOPMOST, 10, 10, WINDOW_DX, WINDOW_DY, SWP_SHOWWINDOW); - } - - // Inform the framework class of the driver change. It will internally - // re-create valid surfaces, a d3ddevice, etc. - if( FAILED( hr = Initialize3DEnvironment() ) ) - { - DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT ); - SendMessage( m_hWnd, WM_CLOSE, 0, 0 ); - return hr; - } - - m_pD3DEngine->ChangeLOD(); - - if( m_pDeviceInfo->bWindowed ) - { - SetNiceMouse(FALSE); // hides the ugly windows mouse - } - - return S_OK; -#endif -} - - - -// Evolved throughout the game - -void CD3DApplication::StepSimul(float rTime) -{ - Event event; - - if ( m_pRobotMain == 0 ) return; - - ZeroMemory(&event, sizeof(Event)); - event.event = EVENT_FRAME; // funny bug release "Maximize speed"! - event.rTime = rTime; - event.axeX = AxeLimit(m_axeKey.x + m_axeJoy.x); - event.axeY = AxeLimit(m_axeKey.y + m_axeJoy.y); - event.axeZ = AxeLimit(m_axeKey.z + m_axeJoy.z); - event.keyState = m_keyState; - -//?char s[100]; -//?sprintf(s, "StepSimul %.3f\n", event.rTime); -//?OutputDebugString(s); - m_pRobotMain->EventProcess(event); -} - - -// Draws the scene. - -HRESULT CD3DApplication::Render3DEnvironment() -{ - HRESULT hr; - float rTime; - - // Check the cooperative level before rendering - if( FAILED( hr = m_pDD->TestCooperativeLevel() ) ) - { - switch( hr ) - { - case DDERR_EXCLUSIVEMODEALREADYSET: - case DDERR_NOEXCLUSIVEMODE: - OutputDebugString("DDERR_EXCLUSIVEMODEALREADYSET\n"); - // Do nothing because some other app has exclusive mode - return S_OK; - - case DDERR_WRONGMODE: - OutputDebugString("DDERR_WRONGMODE\n"); - // The display mode changed on us. Resize accordingly - if( m_pDeviceInfo->bWindowed ) - return Change3DEnvironment(); - break; - } - return hr; - } - - // Get the relative time, in seconds - rTime = m_pD3DEngine->TimeGet(); - if ( rTime > MAX_STEP ) rTime = MAX_STEP; // never more than 0.5s! - m_aTime += rTime; - -#if !USE_THREAD - if( FAILED( hr = m_pD3DEngine->FrameMove(rTime) ) ) - return hr; - - // FrameMove (animate) the scene - StepSimul(rTime); -#endif - - // Render the scene. - if( FAILED( hr = m_pD3DEngine->Render() ) ) - return hr; - - DrawSuppl(); - - // Show the frame rate, etc. - if( m_bShowStats ) - ShowStats(); - - // Show the frame on the primary surface. - if( FAILED( hr = m_pFramework->ShowFrame() ) ) - { - if( DDERR_SURFACELOST != hr ) - return hr; - - m_pFramework->RestoreSurfaces(); - m_pD3DEngine->RestoreSurfaces(); - } - - return S_OK; -} - - -// Cleanup scene objects - -VOID CD3DApplication::Cleanup3DEnvironment() -{ - m_bActive = FALSE; - m_bReady = FALSE; - - if( m_pFramework ) - { - DeleteDeviceObjects(); - SAFE_DELETE( m_pFramework ); - - m_pD3DEngine->FinalCleanup(); - } - - D3DEnum_FreeResources(); -//? FreeDirectInput(); -} - -// Called when the app is exitting, or the device is being changed, -// this function deletes any device dependant objects. - -VOID CD3DApplication::DeleteDeviceObjects() -{ - if( m_pFramework ) - { - m_pD3DEngine->DeleteDeviceObjects(); - SAFE_RELEASE( m_pddsDepthBuffer ); - } -} - - - -// Called in to toggle the pause state of the app. This function -// brings the GDI surface to the front of the display, so drawing -// output like message boxes and menus may be displayed. - -VOID CD3DApplication::Pause( BOOL bPause ) -{ - static DWORD dwAppPausedCount = 0L; - - dwAppPausedCount += ( bPause ? +1 : -1 ); - m_bReady = ( dwAppPausedCount ? FALSE : TRUE ); - - // Handle the first pause request (of many, nestable pause requests) - if( bPause && ( 1 == dwAppPausedCount ) ) - { - // Get a surface for the GDI - if( m_pFramework ) - m_pFramework->FlipToGDISurface( TRUE ); - - // Stop the scene from animating - m_pD3DEngine->TimeEnterGel(); - } - - if( 0 == dwAppPausedCount ) - { - // Restart the scene - m_pD3DEngine->TimeExitGel(); - } -} - - -// Called when the app receives a PBT_APMQUERYSUSPEND message, meaning -// the computer is about to be suspended. At this point, the app should -// save any data for open network connections, files, etc.., and prepare -// to go into a suspended mode. - -LRESULT CD3DApplication::OnQuerySuspend( DWORD dwFlags ) -{ - OutputDebugString("OnQuerySuspend\n"); - Pause(TRUE); - return TRUE; -} - - -// Called when the app receives a PBT_APMRESUMESUSPEND message, meaning -// the computer has just resumed from a suspended state. At this point, -// the app should recover any data, network connections, files, etc.., -// and resume running from when the app was suspended. - -LRESULT CD3DApplication::OnResumeSuspend( DWORD dwData ) -{ - OutputDebugString("OnResumeSuspend\n"); - Pause(FALSE); - return TRUE; -} - - -// Draw all the additional graphic elements. - -void CD3DApplication::DrawSuppl() -{ - HDC hDC; - FPOINT p1, p2; - POINT list[3]; - RECT rect; - HPEN hPen; - HGDIOBJ old; - FPOINT pos; - float d; - int nbOut; - - if ( FAILED(m_pddsRenderTarget->GetDC(&hDC)) ) return; - - // Displays the selection rectangle. - if ( m_pD3DEngine->GetHilite(p1, p2) ) - { - nbOut = 0; - if ( p1.x < 0.0f || p1.x > 1.0f ) nbOut ++; - if ( p1.y < 0.0f || p1.y > 1.0f ) nbOut ++; - if ( p2.x < 0.0f || p2.x > 1.0f ) nbOut ++; - if ( p2.y < 0.0f || p2.y > 1.0f ) nbOut ++; - if ( nbOut <= 2 ) - { -#if 0 - time = Mod(m_aTime, 0.5f); - if ( time < 0.25f ) d = time*4.0f; - else d = (2.0f-time*4.0f); -#endif -#if 0 - time = Mod(m_aTime, 0.5f); - if ( time < 0.4f ) d = time/0.4f; - else d = 1.0f-(time-0.4f)/0.1f; -#endif -#if 1 - d = 0.5f+sinf(m_aTime*6.0f)*0.5f; -#endif - d *= (p2.x-p1.x)*0.1f; - p1.x += d; - p1.y += d; - p2.x -= d; - p2.y -= d; - - hPen = CreatePen(PS_SOLID, 1, RGB(255,255,0)); // yellow - old = SelectObject(hDC, hPen); - - rect.left = (int)(p1.x*m_ddsdRenderTarget.dwWidth); - rect.right = (int)(p2.x*m_ddsdRenderTarget.dwWidth); - rect.top = (int)((1.0f-p2.y)*m_ddsdRenderTarget.dwHeight); - rect.bottom = (int)((1.0f-p1.y)*m_ddsdRenderTarget.dwHeight); - - list[0].x = rect.left; - list[0].y = rect.top+(rect.bottom-rect.top)/5; - list[1].x = rect.left; - list[1].y = rect.top; - list[2].x = rect.left+(rect.right-rect.left)/5; - list[2].y = rect.top; - Polyline(hDC, list, 3); - - list[0].x = rect.right; - list[0].y = rect.top+(rect.bottom-rect.top)/5; - list[1].x = rect.right; - list[1].y = rect.top; - list[2].x = rect.right+(rect.left-rect.right)/5; - list[2].y = rect.top; - Polyline(hDC, list, 3); - - list[0].x = rect.left; - list[0].y = rect.bottom+(rect.top-rect.bottom)/5; - list[1].x = rect.left; - list[1].y = rect.bottom; - list[2].x = rect.left+(rect.right-rect.left)/5; - list[2].y = rect.bottom; - Polyline(hDC, list, 3); - - list[0].x = rect.right; - list[0].y = rect.bottom+(rect.top-rect.bottom)/5; - list[1].x = rect.right; - list[1].y = rect.bottom; - list[2].x = rect.right+(rect.left-rect.right)/5; - list[2].y = rect.bottom; - Polyline(hDC, list, 3); - - if ( old != 0 ) SelectObject(hDC, old); - DeleteObject(hPen); - } - } - - m_pddsRenderTarget->ReleaseDC(hDC); -} - -// Shows frame rate and dimensions of the rendering device. - -VOID CD3DApplication::ShowStats() -{ - static FLOAT fFPS = 0.0f; - static FLOAT fLastTime = 0.0f; - static DWORD dwFrames = 0L; - - // Keep track of the time lapse and frame count - FLOAT fTime = timeGetTime() * 0.001f; // Get current time in seconds - ++dwFrames; - - // Update the frame rate once per second - if( fTime - fLastTime > 1.0f ) - { - fFPS = dwFrames / (fTime - fLastTime); - fLastTime = fTime; - dwFrames = 0L; - } - - int t = m_pD3DEngine->RetStatisticTriangle(); - - // Setup the text buffer to write out dimensions - TCHAR buffer[100]; - sprintf( buffer, _T("%7.02f fps T=%d (%dx%dx%d)"), fFPS, t, - m_ddsdRenderTarget.dwWidth, m_ddsdRenderTarget.dwHeight, - m_ddsdRenderTarget.ddpfPixelFormat.dwRGBBitCount ); - OutputText( 400, 2, buffer ); - - int x, y, i; - if ( m_pD3DEngine->GetSpriteCoord(x, y) ) - { - OutputText( x, y, "+" ); - } - - for ( i=0 ; i<10 ; i++ ) - { - char* info = m_pD3DEngine->RetInfoText(i); - x = 50; - y = m_ddsdRenderTarget.dwHeight-20-i*20; - OutputText( x, y, info ); - } -} - - -// Draws text on the window. - -VOID CD3DApplication::OutputText( DWORD x, DWORD y, TCHAR* str ) -{ - HDC hDC; - - // Get a DC for the surface. Then, write out the buffer - if( m_pddsRenderTarget ) - { - if( SUCCEEDED( m_pddsRenderTarget->GetDC(&hDC) ) ) - { - SetTextColor( hDC, RGB(255,255,0) ); - SetBkMode( hDC, TRANSPARENT ); - ExtTextOut( hDC, x, y, 0, NULL, str, lstrlen(str), NULL ); - m_pddsRenderTarget->ReleaseDC(hDC); - } - } -} - - - - -// Defines a function that allocates memory for and initializes -// members within a BITMAPINFOHEADER structure - -PBITMAPINFO CD3DApplication::CreateBitmapInfoStruct(HBITMAP hBmp) -{ - BITMAP bmp; - PBITMAPINFO pbmi; - WORD cClrBits; - - // Retrieve the bitmap's color format, width, and height. - if ( !GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp) ) - return 0; - - // Convert the color format to a count of bits. - cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); - - if ( cClrBits == 1 ) cClrBits = 1; - else if ( cClrBits <= 4 ) cClrBits = 4; - else if ( cClrBits <= 8 ) cClrBits = 8; - else if ( cClrBits <= 16 ) cClrBits = 16; - else if ( cClrBits <= 24 ) cClrBits = 24; - else cClrBits = 32; - - // Allocate memory for the BITMAPINFO structure. (This structure - // contains a BITMAPINFOHEADER structure and an array of RGBQUAD data - // structures.) - if ( cClrBits != 24 ) - { - pbmi = (PBITMAPINFO)LocalAlloc(LPTR, - sizeof(BITMAPINFOHEADER) + - sizeof(RGBQUAD) * (2^cClrBits)); - } - // There is no RGBQUAD array for the 24-bit-per-pixel format. - else - { - pbmi = (PBITMAPINFO)LocalAlloc(LPTR, - sizeof(BITMAPINFOHEADER)); - } - - // Initialize the fields in the BITMAPINFO structure. - pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - pbmi->bmiHeader.biWidth = bmp.bmWidth; - pbmi->bmiHeader.biHeight = bmp.bmHeight; - pbmi->bmiHeader.biPlanes = bmp.bmPlanes; - pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel; - if ( cClrBits < 24 ) - pbmi->bmiHeader.biClrUsed = 2^cClrBits; - - // If the bitmap is not compressed, set the BI_RGB flag. - pbmi->bmiHeader.biCompression = BI_RGB; - - // Compute the number of bytes in the array of color - // indices and store the result in biSizeImage. - pbmi->bmiHeader.biSizeImage = (pbmi->bmiHeader.biWidth + 7) /8 - * pbmi->bmiHeader.biHeight - * cClrBits; - - // Set biClrImportant to 0, indicating that all of the - // device colors are important. - pbmi->bmiHeader.biClrImportant = 0; - - return pbmi; -} - -// Defines a function that initializes the remaining structures, -// retrieves the array of palette indices, opens the file, copies -// the data, and closes the file. - -BOOL CD3DApplication::CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC) -{ - FILE* file; // file handle - BITMAPFILEHEADER hdr; // bitmap file-header - PBITMAPINFOHEADER pbih; // bitmap info-header - LPBYTE lpBits; // memory pointer - DWORD dwTotal; // total count of bytes - - pbih = (PBITMAPINFOHEADER)pbi; - lpBits = (LPBYTE)GlobalAlloc(GMEM_FIXED, pbih->biSizeImage); - if ( !lpBits ) return FALSE; - - // Retrieve the color table (RGBQUAD array) and the bits - // (array of palette indices) from the DIB. - if ( !GetDIBits(hDC, hBMP, 0, (WORD)pbih->biHeight, - lpBits, pbi, DIB_RGB_COLORS) ) - return FALSE; - - // Create the .BMP file. - file = fopen(pszFile, "wb"); - if ( file == NULL ) return FALSE; - - hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" - - // Compute the size of the entire file. - hdr.bfSize = (DWORD)(sizeof(BITMAPFILEHEADER) + - pbih->biSize + pbih->biClrUsed - * sizeof(RGBQUAD) + pbih->biSizeImage); - - hdr.bfReserved1 = 0; - hdr.bfReserved2 = 0; - - // Compute the offset to the array of color indices. - hdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + - pbih->biSize + pbih->biClrUsed - * sizeof (RGBQUAD); - - // Copy the BITMAPFILEHEADER into the .BMP file. - fwrite(&hdr, sizeof(BITMAPFILEHEADER), 1, file); - - // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. - fwrite(pbih, sizeof(BITMAPINFOHEADER)+pbih->biClrUsed*sizeof(RGBQUAD), 1, file); - - // Copy the array of color indices into the .BMP file. - dwTotal = pbih->biSizeImage; - fwrite(lpBits, dwTotal, 1, file); - - // Close the .BMP file. - fclose(file); - - // Free memory. - GlobalFree((HGLOBAL)lpBits); - return TRUE; -} - -// Write a file. BMP screenshot. - -BOOL CD3DApplication::WriteScreenShot(char *filename, int width, int height) -{ - D3DVIEWPORT7 vp; - HDC hDC; - HDC hDCImage; - HBITMAP hb; - PBITMAPINFO info; - int dx, dy; - - m_pD3DDevice->GetViewport(&vp); - dx = vp.dwWidth; - dy = vp.dwHeight; - - if ( FAILED(m_pddsRenderTarget->GetDC(&hDC)) ) return FALSE; - - hDCImage = CreateCompatibleDC(hDC); - if ( hDCImage == 0 ) - { - m_pddsRenderTarget->ReleaseDC(hDC); - return FALSE; - } - - hb = CreateCompatibleBitmap(hDC, width, height); - if ( hb == 0 ) - { - DeleteDC(hDCImage); - m_pddsRenderTarget->ReleaseDC(hDC); - return FALSE; - } - - SelectObject(hDCImage, hb); - StretchBlt(hDCImage, 0, 0, width, height, hDC, 0, 0, dx, dy, SRCCOPY); - - info = CreateBitmapInfoStruct(hb); - if ( info == 0 ) - { - DeleteObject(hb); - DeleteDC(hDCImage); - m_pddsRenderTarget->ReleaseDC(hDC); - return FALSE; - } - - CreateBMPFile(filename, info, hb, hDCImage); - - DeleteObject(hb); - DeleteDC(hDCImage); - m_pddsRenderTarget->ReleaseDC(hDC); - return TRUE; -} - - -// Initializes an hDC on the rendering surface. - -BOOL CD3DApplication::GetRenderDC(HDC &hDC) -{ - if ( FAILED(m_pddsRenderTarget->GetDC(&hDC)) ) return FALSE; - return TRUE; -} - -// Frees the hDC of the rendering surface. - -BOOL CD3DApplication::ReleaseRenderDC(HDC &hDC) -{ - m_pddsRenderTarget->ReleaseDC(hDC); - return TRUE; -} - - - - -// Perform the list of all graphics devices available. -// For the device selected, lists the full screen modes -// possible. -// buf* --> nom1<0> nom2<0> <0> - -BOOL CD3DApplication::EnumDevices(char *bufDevices, int lenDevices, - char *bufModes, int lenModes, - int &totalDevices, int &selectDevices, - int &totalModes, int &selectModes) -{ - D3DEnum_DeviceInfo* pDeviceList; - D3DEnum_DeviceInfo* pDevice; - DDSURFACEDESC2* pddsdMode; - DWORD numDevices, device, mode; - int len; - char text[100]; - - D3DEnum_GetDevices(&pDeviceList, &numDevices); - - selectDevices = -1; - selectModes = -1; - totalModes = 0; - for( device=0 ; devicestrDesc)+1; - if ( len >= lenDevices ) break; // bufDevices full! - strcpy(bufDevices, pDevice->strDesc); - bufDevices += len; - lenDevices -= len; - - if ( pDevice == m_pDeviceInfo ) // select device ? - { - selectDevices = device; - - for( mode=0 ; modedwNumModes ; mode++ ) - { - pddsdMode = &pDevice->pddsdModes[mode]; - - sprintf(text, "%ld x %ld x %ld", - pddsdMode->dwWidth, - pddsdMode->dwHeight, - pddsdMode->ddpfPixelFormat.dwRGBBitCount); - - len = strlen(text)+1; - if ( len >= lenModes ) break; // bufModes full ! - strcpy(bufModes, text); - bufModes += len; - lenModes -= len; - - if ( mode == m_pDeviceInfo->dwCurrentMode ) // select mode ? - { - selectModes = mode; - } - } - bufModes[0] = 0; - totalModes = pDevice->dwNumModes; - } - } - bufDevices[0] = 0; - totalDevices = numDevices; - - return TRUE; -} - -// Indicates whether it is in full screen mode. - -BOOL CD3DApplication::RetFullScreen() -{ - return !m_pDeviceInfo->bWindowed; -} - -// Change the graphics mode. - -BOOL CD3DApplication::ChangeDevice(char *deviceName, char *modeName, - BOOL bFull) -{ - D3DEnum_DeviceInfo* pDeviceList; - D3DEnum_DeviceInfo* pDevice; - DDSURFACEDESC2* pddsdMode; - DWORD numDevices, device, mode; - HRESULT hr; - char text[100]; - - D3DEnum_GetDevices(&pDeviceList, &numDevices); - - for( device=0 ; devicestrDesc, deviceName) == 0 ) // device found ? - { - for( mode=0 ; modedwNumModes ; mode++ ) - { - pddsdMode = &pDevice->pddsdModes[mode]; - - sprintf(text, "%ld x %ld x %ld", - pddsdMode->dwWidth, - pddsdMode->dwHeight, - pddsdMode->ddpfPixelFormat.dwRGBBitCount); - - if ( strcmp(text, modeName) == 0 ) // mode found ? - { - m_pDeviceInfo = pDevice; - pDevice->bWindowed = !bFull; - pDevice->dwCurrentMode = mode; - pDevice->ddsdFullscreenMode = pDevice->pddsdModes[mode]; - - m_bReady = FALSE; - - if ( FAILED( hr = Change3DEnvironment() ) ) - { - return FALSE; - } - - SetProfileString("Device", "Name", deviceName); - SetProfileString("Device", "Mode", modeName); - SetProfileInt("Device", "FullScreen", bFull); - m_bReady = TRUE; - return TRUE; - } - } - } - } - - return FALSE; -} - - - -// Displays error messages in a message box. - -VOID CD3DApplication::DisplayFrameworkError( HRESULT hr, DWORD dwType ) -{ - TCHAR strMsg[512]; - - switch( hr ) - { - case D3DENUMERR_ENGINE: - lstrcpy( strMsg, _T("Could not create 3D Engine application!") ); - break; - case D3DENUMERR_ROBOT: - lstrcpy( strMsg, _T("Could not create Robot application!") ); - break; - case D3DENUMERR_NODIRECTDRAW: - lstrcpy( strMsg, _T("Could not create DirectDraw!") ); - break; - case D3DENUMERR_NOCOMPATIBLEDEVICES: - lstrcpy( strMsg, _T("Could not find any compatible Direct3D\n" - "devices.") ); - break; - case D3DENUMERR_SUGGESTREFRAST: - lstrcpy( strMsg, _T("Could not find any compatible devices.\n\n" - "Try enabling the reference rasterizer using\n" - "EnableRefRast.reg.") ); - break; - case D3DENUMERR_ENUMERATIONFAILED: - lstrcpy( strMsg, _T("Enumeration failed. Your system may be in an\n" - "unstable state and need to be rebooted") ); - break; - case D3DFWERR_INITIALIZATIONFAILED: - lstrcpy( strMsg, _T("Generic initialization error.\n\nEnable " - "debug output for detailed information.") ); - break; - case D3DFWERR_NODIRECTDRAW: - lstrcpy( strMsg, _T("No DirectDraw") ); - break; - case D3DFWERR_NODIRECT3D: - lstrcpy( strMsg, _T("No Direct3D") ); - break; - case D3DFWERR_INVALIDMODE: - lstrcpy( strMsg, _T("COLOBOT requires a 16-bit (or higher) " - "display mode\nto run in a window.\n\nPlease " - "switch your desktop settings accordingly.") ); - break; - case D3DFWERR_COULDNTSETCOOPLEVEL: - lstrcpy( strMsg, _T("Could not set Cooperative Level") ); - break; - case D3DFWERR_NO3DDEVICE: - lstrcpy( strMsg, _T("Could not create the Direct3DDevice object.") ); - - if( MSGWARN_SWITCHEDTOSOFTWARE == dwType ) - lstrcat( strMsg, _T("\nThe 3D hardware chipset may not support" - "\nrendering in the current display mode.") ); - break; - case D3DFWERR_NOZBUFFER: - lstrcpy( strMsg, _T("No ZBuffer") ); - break; - case D3DFWERR_INVALIDZBUFFERDEPTH: - lstrcpy( strMsg, _T("Invalid Z-buffer depth. Try switching modes\n" - "from 16- to 32-bit (or vice versa)") ); - break; - case D3DFWERR_NOVIEWPORT: - lstrcpy( strMsg, _T("No Viewport") ); - break; - case D3DFWERR_NOPRIMARY: - lstrcpy( strMsg, _T("No primary") ); - break; - case D3DFWERR_NOCLIPPER: - lstrcpy( strMsg, _T("No Clipper") ); - break; - case D3DFWERR_BADDISPLAYMODE: - lstrcpy( strMsg, _T("Bad display mode") ); - break; - case D3DFWERR_NOBACKBUFFER: - lstrcpy( strMsg, _T("No backbuffer") ); - break; - case D3DFWERR_NONZEROREFCOUNT: - lstrcpy( strMsg, _T("A DDraw object has a non-zero reference\n" - "count (meaning it was not properly cleaned up)." ) ); - break; - case D3DFWERR_NORENDERTARGET: - lstrcpy( strMsg, _T("No render target") ); - break; - case E_OUTOFMEMORY: - lstrcpy( strMsg, _T("Not enough memory!") ); - break; - case DDERR_OUTOFVIDEOMEMORY: - lstrcpy( strMsg, _T("There was insufficient video memory " - "to use the\nhardware device.") ); - break; - default: - lstrcpy( strMsg, _T("Generic application error.\n\nEnable " - "debug output for detailed information.") ); - } - - if( MSGERR_APPMUSTEXIT == dwType ) - { - lstrcat( strMsg, _T("\n\nCOLOBOT will now exit.") ); - MessageBox( NULL, strMsg, m_strWindowTitle, MB_ICONERROR|MB_OK ); - } - else - { - if( MSGWARN_SWITCHEDTOSOFTWARE == dwType ) - lstrcat( strMsg, _T("\n\nSwitching to software rasterizer.") ); - MessageBox( NULL, strMsg, m_strWindowTitle, MB_ICONWARNING|MB_OK ); - } -} - - diff --git a/src/d3dapp.h b/src/d3dapp.h deleted file mode 100644 index 6f28cda..0000000 --- a/src/d3dapp.h +++ /dev/null @@ -1,168 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// d3dapp.h - - -#ifndef _D3DAPP_H -#define _D3DAPP_H - -#define D3D_OVERLOADS - -#include - -#include "d3dengine.h" -#include "d3dframe.h" -#include "d3denum.h" -#include "d3dutil.h" -#include "d3dres.h" -#include "misc.h" -#include "struct.h" - - -class CInstanceManager; -class CEvent; -class CRobotMain; -class CSound; - - - -class CD3DApplication -{ -public: - CD3DApplication(); - ~CD3DApplication(); - -protected: - LRESULT OnQuerySuspend( DWORD dwFlags ); - LRESULT OnResumeSuspend( DWORD dwData ); - -public: - Error RegQuery(); - Error AudioQuery(); - Error CheckMistery(char *strCmdLine); - int GetVidMemTotal(); - BOOL IsVideo8MB(); - BOOL IsVideo32MB(); - HRESULT Create( HINSTANCE, TCHAR* ); - INT Run(); - LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); - VOID Pause( BOOL bPause ); - FPOINT ConvPosToInterface(HWND hWnd, LPARAM lParam); - void SetMousePos(FPOINT pos); - void StepSimul(float rTime); - char* RetCDpath(); - - void SetShowStat(BOOL bShow); - BOOL RetShowStat(); - void SetDebugMode(BOOL bMode); - BOOL RetDebugMode(); - BOOL RetSetupMode(); - - BOOL EnumDevices(char *bufDevices, int lenDevices, char *bufModes, int lenModes, int &totalDevices, int &selectDevices, int &totalModes, int &selectModes); - BOOL RetFullScreen(); - BOOL ChangeDevice(char *device, char *mode, BOOL bFull); - - void FlushPressKey(); - void ResetKey(); - void SetKey(int keyRank, int option, int key); - int RetKey(int keyRank, int option); - - void SetJoystick(BOOL bEnable); - BOOL RetJoystick(); - - void SetMouseType(D3DMouse type); - void SetNiceMouse(BOOL bNice); - BOOL RetNiceMouse(); - BOOL RetNiceMouseCap(); - - BOOL WriteScreenShot(char *filename, int width, int height); - - BOOL GetRenderDC(HDC &hDC); - BOOL ReleaseRenderDC(HDC &hDC); - PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp); - BOOL CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC); - -protected: - HRESULT ConfirmDevice( DDCAPS* pddDriverCaps, D3DDEVICEDESC7* pd3dDeviceDesc ); - HRESULT Initialize3DEnvironment(); - HRESULT Change3DEnvironment(); - HRESULT CreateZBuffer(GUID* pDeviceGUID); - HRESULT Render3DEnvironment(); - VOID Cleanup3DEnvironment(); - VOID DeleteDeviceObjects(); - VOID DisplayFrameworkError( HRESULT, DWORD ); - - void InitText(); - void DrawSuppl(); - VOID ShowStats(); - VOID OutputText( DWORD x, DWORD y, TCHAR* str ); - -protected: - CInstanceManager* m_iMan; - CEvent* m_event; - - HINSTANCE m_instance; - HWND m_hWnd; - D3DEnum_DeviceInfo* m_pDeviceInfo; - LPDIRECTDRAW7 m_pDD; - LPDIRECT3D7 m_pD3D; - LPDIRECT3DDEVICE7 m_pD3DDevice; - LPDIRECTDRAWSURFACE7 m_pddsRenderTarget; - DDSURFACEDESC2 m_ddsdRenderTarget; - LPDIRECTDRAWSURFACE7 m_pddsDepthBuffer; - - HANDLE m_thread; - DWORD m_threadId; - - char m_CDpath[100]; - - CD3DFramework7* m_pFramework; - BOOL m_bActive; - BOOL m_bActivateApp; - BOOL m_bReady; - BOOL m_bJoystick; - - DWORD m_vidMemTotal; - TCHAR* m_strWindowTitle; - BOOL m_bAppUseZBuffer; - BOOL m_bAppUseStereo; - BOOL m_bShowStats; - BOOL m_bDebugMode; - BOOL m_bAudioState; - BOOL m_bAudioTrack; - BOOL m_bNiceMouse; - BOOL m_bSetupMode; - HRESULT (*m_fnConfirmDevice)(DDCAPS*, D3DDEVICEDESC7*); - -public: - CD3DEngine* m_pD3DEngine; - CRobotMain* m_pRobotMain; - CSound* m_pSound; - - int m_keyState; - D3DVECTOR m_axeKey; - D3DVECTOR m_axeJoy; - BOOL m_bJoyButton[32]; - FPOINT m_mousePos; - DWORD m_mshMouseWheel; - - float m_aTime; - DWORD m_key[50][2]; -}; - - -#endif // _D3DAPP_H diff --git a/src/d3dengine.cpp b/src/d3dengine.cpp deleted file mode 100644 index bbfb89e..0000000 --- a/src/d3dengine.cpp +++ /dev/null @@ -1,5727 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// D3DEngine.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include - -#include "struct.h" -#include "d3dapp.h" -#include "d3dtextr.h" -#include "d3dutil.h" -#include "d3dmath.h" -#include "d3dengine.h" -#include "language.h" -#include "iman.h" -#include "event.h" -#include "profile.h" -#include "math3d.h" -#include "object.h" -#include "interface.h" -#include "light.h" -#include "text.h" -#include "particule.h" -#include "terrain.h" -#include "water.h" -#include "cloud.h" -#include "blitz.h" -#include "planet.h" -#include "sound.h" - - - -#define SIZEBLOC_TEXTURE 50 -#define SIZEBLOC_TRANSFORM 100 -#define SIZEBLOC_MINMAX 5 -#define SIZEBLOC_LIGHT 10 -#define SIZEBLOC_MATERIAL 100 -#define SIZEBLOC_TRIANGLE 200 - - - -#if 0 -static int debug_blend1 = 1; -static int debug_blend2 = 3; -static int debug_blend3 = 8; -static int debug_blend4 = 0; - -static int table_blend[13] = -{ - D3DBLEND_ZERO, // 0 - D3DBLEND_ONE, // 1 - D3DBLEND_SRCCOLOR, // 2 - D3DBLEND_INVSRCCOLOR, // 3 - D3DBLEND_SRCALPHA, // 4 - D3DBLEND_INVSRCALPHA, // 5 - D3DBLEND_DESTALPHA, // 6 - D3DBLEND_INVDESTALPHA, // 7 - D3DBLEND_DESTCOLOR, // 8 - D3DBLEND_INVDESTCOLOR, // 9 - D3DBLEND_SRCALPHASAT, // 10 - D3DBLEND_BOTHSRCALPHA, // 11 - D3DBLEND_BOTHINVSRCALPHA, // 12 -}; -#endif - -static int s_resol = 0; - - - -// Converts a FLOAT to a DWORD for use in SetRenderState() calls. - -inline DWORD F2DW( FLOAT f ) -{ - return *((DWORD*)&f); -} - - - - -// Application constructor. Sets attributes for the app. - -CD3DEngine::CD3DEngine(CInstanceManager *iMan, CD3DApplication *app) -{ - int i; - - m_iMan = iMan; - m_iMan->AddInstance(CLASS_ENGINE, this); - m_app = app; - - m_light = new CLight(m_iMan, this); - m_text = new CText(m_iMan, this); - m_particule = new CParticule(m_iMan, this); - m_water = new CWater(m_iMan, this); - m_cloud = new CCloud(m_iMan, this); - m_blitz = new CBlitz(m_iMan, this); - m_planet = new CPlanet(m_iMan, this); - m_pD3DDevice = 0; - m_sound = 0; - m_terrain = 0; - - m_dim.x = 640; - m_dim.y = 480; - m_lastDim = m_dim; - m_focus = 0.75f; - m_baseTime = 0; - m_lastTime = 0; - m_absTime = 0.0f; - m_rankView = 0; - m_ambiantColor[0] = 0x80808080; - m_ambiantColor[1] = 0x80808080; - m_fogColor[0] = 0xffffffff; // white - m_fogColor[1] = 0xffffffff; // white - m_deepView[0] = 1000.0f; - m_deepView[1] = 1000.0f; - m_fogStart[0] = 0.75f; - m_fogStart[1] = 0.75f; - m_waterAddColor.r = 0.0f; - m_waterAddColor.g = 0.0f; - m_waterAddColor.b = 0.0f; - m_waterAddColor.a = 0.0f; - m_bPause = FALSE; - m_bRender = TRUE; - m_bMovieLock = FALSE; - m_bShadow = TRUE; - m_bGroundSpot = TRUE; - m_bDirty = TRUE; - m_bFog = TRUE; - m_speed = 1.0f; - m_secondTexNum = 0; - m_eyeDirH = 0.0f; - m_eyeDirV = 0.0f; - m_backgroundName[0] = 0; // no background image - m_backgroundColorUp = 0; - m_backgroundColorDown = 0; - m_backgroundCloudUp = 0; - m_backgroundCloudDown = 0; - m_bBackgroundFull = FALSE; - m_bBackgroundQuarter = FALSE; - m_bOverFront = TRUE; - m_overColor = 0; - m_overMode = D3DSTATETCb; - m_frontsizeName[0] = 0; // no front image - m_hiliteRank[0] = -1; // empty list - m_mousePos = FPOINT(0.5f, 0.5f); - m_mouseType = D3DMOUSENORM; - m_bMouseHide = FALSE; - m_imageSurface = 0; - m_imageCopy = 0; - m_eyePt = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_lookatPt = D3DVECTOR(0.0f, 0.0f, 1.0f); - m_bDrawWorld = TRUE; - m_bDrawFront = FALSE; - m_limitLOD[0] = 100.0f; - m_limitLOD[1] = 200.0f; - m_particuleDensity = 1.0f; - m_clippingDistance = 1.0f; - m_lastClippingDistance = m_clippingDistance; - m_objectDetail = 1.0f; - m_lastObjectDetail = m_objectDetail; - m_terrainVision = 1000.0f; - m_gadgetQuantity = 1.0f; - m_textureQuality = 1; - m_bTotoMode = TRUE; - m_bLensMode = TRUE; - m_bWaterMode = TRUE; - m_bSkyMode = TRUE; - m_bBackForce = TRUE; - m_bPlanetMode = TRUE; - m_bLightMode = TRUE; - m_bEditIndentMode = TRUE; - m_editIndentValue = 4; - m_tracePrecision = 1.0f; - - m_alphaMode = 1; - if ( GetProfileInt("Engine", "AlphaMode", i) ) - { - m_alphaMode = i; - } - - if ( GetProfileInt("Engine", "StateColor", i) && i != -1 ) - { - m_bForceStateColor = TRUE; - m_bStateColor = i; - } - else - { - m_bForceStateColor = FALSE; - m_bStateColor = FALSE; - } - - m_blackSrcBlend[0] = 0; - m_blackDestBlend[0] = 0; - m_whiteSrcBlend[0] = 0; - m_whiteDestBlend[0] = 0; - m_diffuseSrcBlend[0] = 0; - m_diffuseDestBlend[0] = 0; - m_alphaSrcBlend[0] = 0; - m_alphaDestBlend[0] = 0; - - if ( GetProfileInt("Engine", "BlackSrcBlend", i) ) m_blackSrcBlend[0] = i; - if ( GetProfileInt("Engine", "BlackDestBlend", i) ) m_blackDestBlend[0] = i; - if ( GetProfileInt("Engine", "WhiteSrcBlend", i) ) m_whiteSrcBlend[0] = i; - if ( GetProfileInt("Engine", "WhiteDestBlend", i) ) m_whiteDestBlend[0] = i; - if ( GetProfileInt("Engine", "DiffuseSrcBlend", i) ) m_diffuseSrcBlend[0] = i; - if ( GetProfileInt("Engine", "DiffuseDestBlend", i) ) m_diffuseDestBlend[0] = i; - if ( GetProfileInt("Engine", "AlphaSrcBlend", i) ) m_alphaSrcBlend[0] = i; - if ( GetProfileInt("Engine", "AlphaDestBlend", i) ) m_alphaDestBlend[0] = i; - - m_bUpdateGeometry = FALSE; - - for ( i=0 ; i<10 ; i++ ) - { - m_infoText[i][0] = 0; - } - - m_objectPointer = 0; - MemSpace1(m_objectPointer, 0); - - m_objectParam = (D3DObject*)malloc(sizeof(D3DObject)*D3DMAXOBJECT); - ZeroMemory(m_objectParam, sizeof(D3DObject)*D3DMAXOBJECT); - m_objectParamTotal = 0; - - m_shadow = (D3DShadow*)malloc(sizeof(D3DShadow)*D3DMAXSHADOW); - ZeroMemory(m_shadow, sizeof(D3DShadow)*D3DMAXSHADOW); - m_shadowTotal = 0; - - m_groundSpot = (D3DGroundSpot*)malloc(sizeof(D3DGroundSpot)*D3DMAXGROUNDSPOT); - ZeroMemory(m_groundSpot, sizeof(D3DGroundSpot)*D3DMAXGROUNDSPOT); - - ZeroMemory(&m_groundMark, sizeof(D3DGroundMark)); - - D3DTextr_SetTexturePath("textures\\"); -} - -// Application destructor. Free memory. - -CD3DEngine::~CD3DEngine() -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - int l1, l2, l3, l4, l5; - - p1 = m_objectPointer; - for ( l1=0 ; l1totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - for ( l2=0 ; l2totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - for ( l3=0 ; l3totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - for ( l4=0 ; l4totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - free(p6); - } - free(p5); - } - free(p4); - } - free(p3); - } - free(p2); - } - free(p1); - - delete m_light; - delete m_particule; - delete m_water; - delete m_cloud; - delete m_blitz; - delete m_planet; -} - - - -void CD3DEngine::SetD3DDevice(LPDIRECT3DDEVICE7 device) -{ - D3DDEVICEDESC7 ddDesc; - - m_pD3DDevice = device; - m_light->SetD3DDevice(device); - m_text->SetD3DDevice(device); - m_particule->SetD3DDevice(device); - - if ( !m_bForceStateColor ) - { - m_pD3DDevice->GetCaps(&ddDesc); - if( ddDesc.dpcTriCaps.dwTextureBlendCaps & D3DPTBLENDCAPS_ADD ) - { - m_bStateColor = TRUE; - } - else - { - m_bStateColor = FALSE; - } - } - - m_blackSrcBlend[1] = D3DBLEND_ONE; // = 2 - m_blackDestBlend[1] = D3DBLEND_INVSRCCOLOR; // = 4 - m_whiteSrcBlend[1] = D3DBLEND_DESTCOLOR; // = 9 - m_whiteDestBlend[1] = D3DBLEND_ZERO; // = 1 - m_diffuseSrcBlend[1] = D3DBLEND_SRCALPHA; // = 5 - m_diffuseDestBlend[1] = D3DBLEND_DESTALPHA; // = 7 - m_alphaSrcBlend[1] = D3DBLEND_ONE; // = 2 - m_alphaDestBlend[1] = D3DBLEND_INVSRCCOLOR; // = 4 - -//? if ( !m_bStateColor ) m_whiteDestBlend[1] = D3DBLEND_INVSRCALPHA; // = 6 - -// Fix for the graphics bug: - //if ( m_blackSrcBlend[0] ) m_blackSrcBlend[1] = m_blackSrcBlend[0]; - //if ( m_blackDestBlend[0] ) m_blackDestBlend[1] = m_blackDestBlend[0]; - //if ( m_whiteSrcBlend[0] ) m_whiteSrcBlend[1] = m_whiteSrcBlend[0]; - //if ( m_whiteDestBlend[0] ) m_whiteDestBlend[1] = m_whiteDestBlend[0]; - - if ( m_diffuseSrcBlend[0] ) m_diffuseSrcBlend[1] = m_diffuseSrcBlend[0]; - if ( m_diffuseDestBlend[0] ) m_diffuseDestBlend[1] = m_diffuseDestBlend[0]; - if ( m_alphaSrcBlend[0] ) m_alphaSrcBlend[1] = m_alphaSrcBlend[0]; - if ( m_alphaDestBlend[0] ) m_alphaDestBlend[1] = m_alphaDestBlend[0]; - -#if 0 - DWORD pass; - m_pD3DDevice->ValidateDevice(&pass); - char s[100]; - sprintf(s, "NbPass=%d", pass); - SetInfoText(3, s); -#endif -} - -LPDIRECT3DDEVICE7 CD3DEngine::RetD3DDevice() -{ - return m_pD3DDevice; -} - - -// Gives the pointer to the existing terrain. - -void CD3DEngine::SetTerrain(CTerrain* terrain) -{ - m_terrain = terrain; -} - - -// Saving the state of the graphics engine in COLOBOT.INI. - -BOOL CD3DEngine::WriteProfile() -{ - SetProfileInt("Engine", "AlphaMode", m_alphaMode); - - if ( m_bForceStateColor ) - { - SetProfileInt("Engine", "StateColor", m_bStateColor); - } - else - { - SetProfileInt("Engine", "StateColor", -1); - } - - SetProfileInt("Engine", "BlackSrcBlend", m_blackSrcBlend[0]); - SetProfileInt("Engine", "BlackDestBlend", m_blackDestBlend[0]); - SetProfileInt("Engine", "WhiteSrcBlend", m_whiteSrcBlend[0]); - SetProfileInt("Engine", "WhiteDestBlend", m_whiteDestBlend[0]); - SetProfileInt("Engine", "DiffuseSrcBlend", m_diffuseSrcBlend[0]); - SetProfileInt("Engine", "DiffuseDestBlend", m_diffuseDestBlend[0]); - SetProfileInt("Engine", "AlphaSrcBlend", m_alphaSrcBlend[0]); - SetProfileInt("Engine", "AlphaDestBlend", m_alphaDestBlend[0]); - - return TRUE; -} - - -// Setup the app so it can support single-stepping. - -void CD3DEngine::TimeInit() -{ - m_baseTime = timeGetTime(); - m_lastTime = 0; - m_absTime = 0.0f; -} - -void CD3DEngine::TimeEnterGel() -{ - m_stopTime = timeGetTime(); -} - -void CD3DEngine::TimeExitGel() -{ - m_baseTime += timeGetTime() - m_stopTime; -} - -float CD3DEngine::TimeGet() -{ - float aTime, rTime; - - aTime = (timeGetTime()-m_baseTime)*0.001f; // in ms - rTime = (aTime - m_lastTime)*m_speed; - m_absTime += rTime; - m_lastTime = aTime; - - return rTime; -} - - -void CD3DEngine::SetPause(BOOL bPause) -{ - m_bPause = bPause; -} - -BOOL CD3DEngine::RetPause() -{ - return m_bPause; -} - - -void CD3DEngine::SetMovieLock(BOOL bLock) -{ - m_bMovieLock = bLock; -} - -BOOL CD3DEngine::RetMovieLock() -{ - return m_bMovieLock; -} - - -void CD3DEngine::SetShowStat(BOOL bShow) -{ - m_app->SetShowStat(bShow); -} - -BOOL CD3DEngine::RetShowStat() -{ - return m_app->RetShowStat(); -} - - -void CD3DEngine::SetRenderEnable(BOOL bEnable) -{ - m_bRender = bEnable; -} - - -// Prepare a structure to add D3DObjLevel6 -// qq D3DVERTEX2 elements. - -void CD3DEngine::MemSpace6(D3DObjLevel6 *&p, int nb) -{ - D3DObjLevel6* pp; - int total, size; - - if ( p == 0 ) - { - total = SIZEBLOC_TRIANGLE+nb; - size = sizeof(D3DObjLevel6)+sizeof(D3DVERTEX2)*(total-1); - p = (D3DObjLevel6*)malloc(size); - ZeroMemory(p, size); - p->totalPossible = total; - return; - } - - if ( p->totalUsed+nb > p->totalPossible ) - { - total = p->totalPossible+SIZEBLOC_TRIANGLE+nb; - size = sizeof(D3DObjLevel6)+sizeof(D3DVERTEX2)*(total-1); - pp = (D3DObjLevel6*)malloc(size); - ZeroMemory(pp, size); - CopyMemory(pp, p, sizeof(D3DObjLevel6)+sizeof(D3DVERTEX2)*(p->totalPossible-1)); - pp->totalPossible = total; - free(p); - p = pp; - } -} - -// Prepare a structure to add D3DObjLevel5 -// qq elements D3DObjLevel6. - -void CD3DEngine::MemSpace5(D3DObjLevel5 *&p, int nb) -{ - D3DObjLevel5* pp; - int total, size; - - if ( p == 0 ) - { - total = SIZEBLOC_MATERIAL+nb; - size = sizeof(D3DObjLevel5)+sizeof(D3DObjLevel6*)*(total-1); - p = (D3DObjLevel5*)malloc(size); - ZeroMemory(p, size); - p->totalPossible = total; - return; - } - - if ( p->totalUsed+nb > p->totalPossible ) - { - total = p->totalPossible+SIZEBLOC_MATERIAL+nb; - size = sizeof(D3DObjLevel5)+sizeof(D3DObjLevel6*)*(total-1); - pp = (D3DObjLevel5*)malloc(size); - ZeroMemory(pp, size); - CopyMemory(pp, p, sizeof(D3DObjLevel5)+sizeof(D3DObjLevel6*)*(p->totalPossible-1)); - pp->totalPossible = total; - free(p); - p = pp; - } -} - -// Prepare a structure to add D3DObjLevel4 -// qq D3DObjLevel5 elements. - -void CD3DEngine::MemSpace4(D3DObjLevel4 *&p, int nb) -{ - D3DObjLevel4* pp; - int total, size; - - if ( p == 0 ) - { - total = SIZEBLOC_LIGHT+nb; - size = sizeof(D3DObjLevel4)+sizeof(D3DObjLevel5*)*(total-1); - p = (D3DObjLevel4*)malloc(size); - ZeroMemory(p, size); - p->totalPossible = total; - return; - } - - if ( p->totalUsed+nb > p->totalPossible ) - { - total = p->totalPossible+SIZEBLOC_LIGHT+nb; - size = sizeof(D3DObjLevel4)+sizeof(D3DObjLevel5*)*(total-1); - pp = (D3DObjLevel4*)malloc(size); - ZeroMemory(pp, size); - CopyMemory(pp, p, sizeof(D3DObjLevel4)+sizeof(D3DObjLevel5*)*(p->totalPossible-1)); - pp->totalPossible = total; - free(p); - p = pp; - } -} - -// Prepare a structure to add D3DObjLevel3 -// qq D3DObjLevel4 elements. - -void CD3DEngine::MemSpace3(D3DObjLevel3 *&p, int nb) -{ - D3DObjLevel3* pp; - int total, size; - - if ( p == 0 ) - { - total = SIZEBLOC_MINMAX+nb; - size = sizeof(D3DObjLevel3)+sizeof(D3DObjLevel4*)*(total-1); - p = (D3DObjLevel3*)malloc(size); - ZeroMemory(p, size); - p->totalPossible = total; - return; - } - - if ( p->totalUsed+nb > p->totalPossible ) - { - total = p->totalPossible+SIZEBLOC_MINMAX+nb; - size = sizeof(D3DObjLevel3)+sizeof(D3DObjLevel4*)*(total-1); - pp = (D3DObjLevel3*)malloc(size); - ZeroMemory(pp, size); - CopyMemory(pp, p, sizeof(D3DObjLevel3)+sizeof(D3DObjLevel4*)*(p->totalPossible-1)); - pp->totalPossible = total; - free(p); - p = pp; - } -} - -// Prepare a structure to add D3DObjLevel2 -// qq D3DObjLevel3 elements. - -void CD3DEngine::MemSpace2(D3DObjLevel2 *&p, int nb) -{ - D3DObjLevel2* pp; - int total, size; - - if ( p == 0 ) - { - total = SIZEBLOC_TRANSFORM+nb; - size = sizeof(D3DObjLevel2)+sizeof(D3DObjLevel3*)*(total-1); - p = (D3DObjLevel2*)malloc(size); - ZeroMemory(p, size); - p->totalPossible = total; - return; - } - - if ( p->totalUsed+nb > p->totalPossible ) - { - total = p->totalPossible+SIZEBLOC_TRANSFORM+nb; - size = sizeof(D3DObjLevel2)+sizeof(D3DObjLevel3*)*(total-1); - pp = (D3DObjLevel2*)malloc(size); - ZeroMemory(pp, size); - CopyMemory(pp, p, sizeof(D3DObjLevel2)+sizeof(D3DObjLevel3*)*(p->totalPossible-1)); - pp->totalPossible = total; - free(p); - p = pp; - } -} - -// Prepare a structure to add D3DObjLevel1 -// qq D3DObjLevel2 elements. - -void CD3DEngine::MemSpace1(D3DObjLevel1 *&p, int nb) -{ - D3DObjLevel1* pp; - int total, size; - - if ( p == 0 ) - { - total = SIZEBLOC_TEXTURE+nb; - size = sizeof(D3DObjLevel1)+sizeof(D3DObjLevel2*)*(total-1); - p = (D3DObjLevel1*)malloc(size); - ZeroMemory(p, size); - p->totalPossible = total; - return; - } - - if ( p->totalUsed+nb > p->totalPossible ) - { - total = p->totalPossible+SIZEBLOC_TEXTURE+nb; - size = sizeof(D3DObjLevel1)+sizeof(D3DObjLevel2*)*(total-1); - pp = (D3DObjLevel1*)malloc(size); - ZeroMemory(pp, size); - CopyMemory(pp, p, sizeof(D3DObjLevel1)+sizeof(D3DObjLevel2*)*(p->totalPossible-1)); - pp->totalPossible = total; - free(p); - p = pp; - } -} - - -// Returns the number of objects that can still be created. - -int CD3DEngine::RetRestCreate() -{ - return D3DMAXOBJECT-m_objectParamTotal-2; -} - -// Creates a new object. Returns its rank or -1 on error. - -int CD3DEngine::CreateObject() -{ - D3DMATRIX mat; - int i; - - for ( i=0 ; i= m_objectParamTotal ) - { - m_objectParamTotal = i+1; - } - return i; - } - } - OutputDebugString("CD3DEngine::CreateObject() -> Too many object\n"); - return -1; -} - - -// Removes all objects. - -void CD3DEngine::FlushObject() -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - int l1, l2, l3, l4, l5, i; - - p1 = m_objectPointer; - for ( l1=0 ; l1totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - for ( l2=0 ; l2totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - for ( l3=0 ; l3totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - for ( l4=0 ; l4totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - free(p6); - } - free(p5); - } - free(p4); - } - free(p3); - } - free(p2); - p1->table[l1] = 0; - } - p1->totalUsed = 0; - - for ( i=0 ; itotalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - for ( l2=0 ; l2totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - if ( p3->objRank != objRank ) continue; - for ( l3=0 ; l3totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - for ( l4=0 ; l4totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - free(p6); - } - free(p5); - } - free(p4); - } - free(p3); - p2->table[l2] = 0; - } - } - - ShadowDelete(objRank); // removes the shadow - - m_objectParam[objRank].bUsed = FALSE; - - m_objectParamTotal = 0; - for ( i=0 ; i= D3DMAXOBJECT ) return FALSE; - - m_objectParam[objRank].bDrawWorld = bDraw; - return TRUE; -} - -// Indicates whether an object should be drawn over the interface. - -BOOL CD3DEngine::SetDrawFront(int objRank, BOOL bDraw) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; - - m_objectParam[objRank].bDrawFront = bDraw; - return TRUE; -} - - -// Prepare Level 1 to add a triangle. - -D3DObjLevel2* CD3DEngine::AddLevel1(D3DObjLevel1 *&p1, char* texName1, char* texName2) -{ - D3DObjLevel2* p2; - int l1; - - for ( l1=0 ; l1totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - if ( strcmp(p2->texName1, texName1) == 0 && - strcmp(p2->texName2, texName2) == 0 ) - { - MemSpace2(p1->table[l1], 1); - return p1->table[l1]; - } - } - - MemSpace1(p1, 1); - l1 = p1->totalUsed++; - p1->table[l1] = 0; - - MemSpace2(p1->table[l1], 1); - strcpy(p1->table[l1]->texName1, texName1); - strcpy(p1->table[l1]->texName2, texName2); - return p1->table[l1]; -} - -// Prepare Level 2 to add a triangle. - -D3DObjLevel3* CD3DEngine::AddLevel2(D3DObjLevel2 *&p2, int objRank) -{ - D3DObjLevel3* p3; - int l2; - - for ( l2=0 ; l2totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - if ( p3->objRank == objRank ) - { - MemSpace3(p2->table[l2], 1); - return p2->table[l2]; - } - } - - MemSpace2(p2, 1); - l2 = p2->totalUsed++; - p2->table[l2] = 0; - - MemSpace3(p2->table[l2], 1); - p2->table[l2]->objRank = objRank; - return p2->table[l2]; -} - -// Prepare Level 3 to add a triangle. - -D3DObjLevel4* CD3DEngine::AddLevel3(D3DObjLevel3 *&p3, float min, float max) -{ - D3DObjLevel4* p4; - int l3; - - for ( l3=0 ; l3totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( p4->min == min && p4->max == max ) - { - MemSpace4(p3->table[l3], 1); - return p3->table[l3]; - } - } - - MemSpace3(p3, 1); - l3 = p3->totalUsed++; - p3->table[l3] = 0; - - MemSpace4(p3->table[l3], 1); - p3->table[l3]->min = min; - p3->table[l3]->max = max; - return p3->table[l3]; -} - -// Prepare Level 4 to add a triangle. - -D3DObjLevel5* CD3DEngine::AddLevel4(D3DObjLevel4 *&p4, int reserve) -{ - D3DObjLevel5* p5; - int l4; - - for ( l4=0 ; l4totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - if ( p5->reserve == reserve ) - { - MemSpace5(p4->table[l4], 1); - return p4->table[l4]; - } - } - - MemSpace4(p4, 1); - l4 = p4->totalUsed++; - p4->table[l4] = 0; - - MemSpace5(p4->table[l4], 1); - p4->table[l4]->reserve = reserve; - return p4->table[l4]; -} - -// Prepares Level 5 to add vertices. - -D3DObjLevel6* CD3DEngine::AddLevel5(D3DObjLevel5 *&p5, D3DTypeTri type, - const D3DMATERIAL7 &mat, int state, - int nb) -{ - D3DObjLevel6* p6; - int l5; - - if ( type == D3DTYPE6T ) - { - for ( l5=0 ; l5totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - if ( p6->type == type && - memcmp(&p6->material, &mat, sizeof(D3DMATERIAL7)) == 0 && - p6->state == state ) - { - MemSpace6(p5->table[l5], nb); - return p5->table[l5]; - } - } - } - - MemSpace5(p5, 1); - l5 = p5->totalUsed++; - p5->table[l5] = 0; - - MemSpace6(p5->table[l5], nb); - p5->table[l5]->type = type; - p5->table[l5]->material = mat; - p5->table[l5]->state = state; - return p5->table[l5]; -} - -// Adds one or more triangles to an existing object. -// The number must be divisible by 3. - -BOOL CD3DEngine::AddTriangle(int objRank, D3DVERTEX2* vertex, int nb, - const D3DMATERIAL7 &mat, int state, - char* texName1, char* texName2, - float min, float max, BOOL bGlobalUpdate) -{ - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - int i; - - m_lastDim = m_dim; - m_lastObjectDetail = m_objectDetail; - m_lastClippingDistance = m_clippingDistance; - - p2 = AddLevel1(m_objectPointer, texName1, texName2); - p3 = AddLevel2(p2, objRank); - p4 = AddLevel3(p3, min, max); - p5 = AddLevel4(p4, 0); - p6 = AddLevel5(p5, D3DTYPE6T, mat, state, nb); // place for number of vertex - - CopyMemory(&p6->vertex[p6->totalUsed], vertex, sizeof(D3DVERTEX2)*nb); - p6->totalUsed += nb; - - if ( bGlobalUpdate ) - { - m_bUpdateGeometry = TRUE; - } - else - { - for ( i=0 ; ivertex[p6->totalUsed], vertex, sizeof(D3DVERTEX2)*nb); - p6->totalUsed += nb; - - if ( bGlobalUpdate ) - { - m_bUpdateGeometry = TRUE; - } - else - { - for ( i=0 ; itotalUsed++; - p5->table[l5] = buffer; - - if ( bGlobalUpdate ) - { - m_bUpdateGeometry = TRUE; - } - else - { - for ( i=0 ; itotalUsed ; i++ ) - { - m_objectParam[objRank].bboxMin.x = Min(buffer->vertex[i].x, m_objectParam[objRank].bboxMin.x); - m_objectParam[objRank].bboxMin.y = Min(buffer->vertex[i].y, m_objectParam[objRank].bboxMin.y); - m_objectParam[objRank].bboxMin.z = Min(buffer->vertex[i].z, m_objectParam[objRank].bboxMin.z); - m_objectParam[objRank].bboxMax.x = Max(buffer->vertex[i].x, m_objectParam[objRank].bboxMax.x); - m_objectParam[objRank].bboxMax.y = Max(buffer->vertex[i].y, m_objectParam[objRank].bboxMax.y); - m_objectParam[objRank].bboxMax.z = Max(buffer->vertex[i].z, m_objectParam[objRank].bboxMax.z); - } - - m_objectParam[objRank].radius = Max(Length(m_objectParam[objRank].bboxMin), - Length(m_objectParam[objRank].bboxMax)); - } - m_objectParam[objRank].totalTriangle += buffer->totalUsed-2; - - return TRUE; -} - - -// Looking for a list of triangles. - -void CD3DEngine::ChangeLOD() -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - int l1, l2, l3; - float oldLimit[2], newLimit[2]; - float oldTerrain, newTerrain; - - oldLimit[0] = RetLimitLOD(0, TRUE); - oldLimit[1] = RetLimitLOD(1, TRUE); - - newLimit[0] = RetLimitLOD(0, FALSE); - newLimit[1] = RetLimitLOD(1, FALSE); - - oldTerrain = m_terrainVision*m_lastClippingDistance; - newTerrain = m_terrainVision*m_clippingDistance; - - p1 = m_objectPointer; - for ( l1=0 ; l1totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - for ( l2=0 ; l2totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - for ( l3=0 ; l3totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - - if ( IsEqual(p4->min, 0.0f ) && - IsEqual(p4->max, oldLimit[0]) ) - { - p4->max = newLimit[0]; - } - else if ( IsEqual(p4->min, oldLimit[0]) && - IsEqual(p4->max, oldLimit[1]) ) - { - p4->min = newLimit[0]; - p4->max = newLimit[1]; - } - else if ( IsEqual(p4->min, oldLimit[1]) && - IsEqual(p4->max, 1000000.0f ) ) - { - p4->min = newLimit[1]; - } - else if ( IsEqual(p4->min, 0.0f ) && - IsEqual(p4->max, oldTerrain) ) - { - p4->max = newTerrain; - } - } - } - } - - m_lastDim = m_dim; - m_lastObjectDetail = m_objectDetail; - m_lastClippingDistance = m_clippingDistance; -} - -// Looking for a list of triangles. - -D3DObjLevel6* CD3DEngine::SearchTriangle(int objRank, - const D3DMATERIAL7 &mat, int state, - char* texName1, char* texName2, - float min, float max) -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - int l1, l2, l3, l4, l5; - - p1 = m_objectPointer; - for ( l1=0 ; l1totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; -//? if ( strcmp(p2->texName1, texName1) != 0 || -//? strcmp(p2->texName2, texName2) != 0 ) continue; - if ( strcmp(p2->texName1, texName1) != 0 ) continue; - for ( l2=0 ; l2totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - if ( p3->objRank != objRank ) continue; - for ( l3=0 ; l3totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( p4->min != min || - p4->max != max ) continue; - for ( l4=0 ; l4totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; -//? if ( p6->state != state || - if ( (p6->state&(~(D3DSTATEDUALb|D3DSTATEDUALw))) != state || - memcmp(&p6->material, &mat, sizeof(D3DMATERIAL7)) != 0 ) continue; - return p6; - } - } - } - } - } - return 0; -} - -// Secondary changes the texture of an object. - -BOOL CD3DEngine::ChangeSecondTexture(int objRank, char* texName2) -{ - D3DObjLevel2* newp2; - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - int l1, l2; - - p1 = m_objectPointer; - for ( l1=0 ; l1totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - if ( strcmp(p2->texName2, texName2) == 0 ) continue; // already new - for ( l2=0 ; l2totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - if ( p3->objRank != objRank ) continue; - - newp2 = AddLevel1(m_objectPointer, p2->texName1, texName2); - - if ( newp2->totalUsed >= newp2->totalPossible ) continue; // to do better!!! - newp2->table[newp2->totalUsed++] = p3; - - p2->table[l2] = 0; - } - } - return TRUE; -} - - -// Returns the number of triangles of the object. - -int CD3DEngine::RetTotalTriangles(int objRank) -{ - return m_objectParam[objRank].totalTriangle; -} - -// Return qq triangles of an object. -// qq triangles used to extract an object that explodes. -// "Percent" is between 0 and 1. - -int CD3DEngine::GetTriangles(int objRank, float min, float max, - D3DTriangle* buffer, int size, float percent) -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - D3DVERTEX2* pv; - int l1, l2, l3, l4, l5, l6, i, rank; - - rank = 0; - i = 0; - p1 = m_objectPointer; - for ( l1=0 ; l1totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; -//? if ( p2->texName[0] == 0 ) continue; - for ( l2=0 ; l2totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - if ( p3->objRank != objRank ) continue; - for ( l3=0 ; l3totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( p4->min != min || - p4->max != max ) continue; - for ( l4=0 ; l4totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - if ( p6->type == D3DTYPE6T ) - { - pv = &p6->vertex[0]; - for ( l6=0 ; l6totalUsed/3 ; l6++ ) - { - if ( (float)i/rank <= percent ) - { - if ( i >= size ) break; - buffer[i].triangle[0] = pv[0]; - buffer[i].triangle[1] = pv[1]; - buffer[i].triangle[2] = pv[2]; - buffer[i].material = p6->material; - buffer[i].state = p6->state; - strcpy(buffer[i].texName1, p2->texName1); - strcpy(buffer[i].texName2, p2->texName2); - i ++; - } - rank ++; - pv += 3; - } - } - if ( p6->type == D3DTYPE6S ) - { - pv = &p6->vertex[0]; - for ( l6=0 ; l6totalUsed-2 ; l6++ ) - { - if ( (float)i/rank <= percent ) - { - if ( i >= size ) break; - buffer[i].triangle[0] = pv[0]; - buffer[i].triangle[1] = pv[1]; - buffer[i].triangle[2] = pv[2]; - buffer[i].material = p6->material; - buffer[i].state = p6->state; - strcpy(buffer[i].texName1, p2->texName1); - strcpy(buffer[i].texName2, p2->texName2); - i ++; - } - rank ++; - pv += 1; - } - } - } - } - } - } - } - return i; -} - -// Give the box of an object. - -BOOL CD3DEngine::GetBBox(int objRank, D3DVECTOR &min, D3DVECTOR &max) -{ - min = m_objectParam[objRank].bboxMin; - max = m_objectParam[objRank].bboxMax; - return TRUE; -} - - -// Change the texture mapping for a list of triangles. - -BOOL CD3DEngine::ChangeTextureMapping(int objRank, - const D3DMATERIAL7 &mat, int state, - char* texName1, char* texName2, - float min, float max, - D3DMaping mode, - float au, float bu, - float av, float bv) -{ - D3DObjLevel6* p6; - D3DVERTEX2* pv; - int l6, nb; - - p6 = SearchTriangle(objRank, mat, state, texName1, texName2, min, max); - if ( p6 == 0 ) return FALSE; - - pv = &p6->vertex[0]; - nb = p6->totalUsed; - - if ( mode == D3DMAPPINGX ) - { - for ( l6=0 ; l6tu = pv->z*au+bu; - pv->tv = pv->y*av+bv; - pv ++; - } - } - - if ( mode == D3DMAPPINGY ) - { - for ( l6=0 ; l6tu = pv->x*au+bu; - pv->tv = pv->z*av+bv; - pv ++; - } - } - - if ( mode == D3DMAPPINGZ ) - { - for ( l6=0 ; l6tu = pv->x*au+bu; - pv->tv = pv->y*av+bv; - pv ++; - } - } - - if ( mode == D3DMAPPING1X ) - { - for ( l6=0 ; l6tu = pv->x*au+bu; - pv ++; - } - } - - if ( mode == D3DMAPPING1Y ) - { - for ( l6=0 ; l6tv = pv->y*au+bu; - pv ++; - } - } - - if ( mode == D3DMAPPING1Z ) - { - for ( l6=0 ; l6tu = pv->z*au+bu; - pv ++; - } - } - - return TRUE; -} - -// Change the texture mapping for a list of triangles -// to simulate a caterpillar that turns. -// Only the mapping as "u" is changed. -// -// pos: position on the periphery [p] -// tl: length repetitive element of the texture [t] -// ts: beginning of the texture[t] -// tt: total width of the texture [t] -// -// [p] = distance in the 3D world -// [t] = position in the texture (pixels) - -// ^ y 5 -// | 6 o---------o 4 -// | / \ -// | o o -// | 7 | | 3 -// | o current o -// | \ | / -// | 0 o---------o 2 -// | 1 -// -o-----------------------> x -// | -// -// Quand l6=1 : -// 0 1 2 3 4 ... 7 -// o--o---------o--o--o--o-//-o--o development track -// |ps| | -// <--> pe | -// <------------> -// -// Texture : -// o---------------o -// | | -// | o-o-o-o-o | -// | | | | | |<--- texture of the track -// | o-o-o-o-o | -// | | | tl | -// | ->|-|<--- | -// | | | -// o-----|---------o--> u -// | ts | | -// <-----> tt | -// <---------------> - -BOOL CD3DEngine::TrackTextureMapping(int objRank, - const D3DMATERIAL7 &mat, int state, - char* texName1, char* texName2, - float min, float max, - D3DMaping mode, float pos, float factor, - float tl, float ts, float tt) -{ - D3DObjLevel6* p6; - D3DVERTEX2* pv; - D3DVECTOR current; - float ps, pe, pps, ppe, offset; - int l6, nb, i, j, s, e; - int is[6], ie[6]; - - p6 = SearchTriangle(objRank, mat, state, texName1, texName2, min, max); - if ( p6 == 0 ) return FALSE; - - pv = &p6->vertex[0]; - nb = p6->totalUsed; - - if ( nb < 12 || nb%6 != 0 ) return FALSE; - - while ( pos < 0.0f ) - { - pos += 1000000.0f; // never negative! - } - - for ( i=0 ; i<6 ; i++ ) - { - for ( j=0 ; j<6 ; j++ ) - { - if ( pv[i].x == pv[j+6].x && - pv[i].y == pv[j+6].y ) - { - current.x = pv[i].x; // position end link - current.y = pv[i].y; - break; - } - } - } - - ps = 0.0f; // start position on the periphery - for ( l6=0 ; l6= (nb/6)-1 ) break; - for ( i=0 ; i<6 ; i++ ) - { - if ( Abs(pv[i+6].x-current.x) > 0.0001f || - Abs(pv[i+6].y-current.y) > 0.0001f ) - { - current.x = pv[i+6].x; // end next link - current.y = pv[i+6].y; - break; - } - } - ps = pe; // following start position on the periphery - pv += 6; - } - - return TRUE; -} - - -// Updates all the geometric parameters of objects. - -void CD3DEngine::UpdateGeometry() -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - int l1, l2, l3, l4, l5, objRank, i; - - if ( !m_bUpdateGeometry ) return; - - for ( i=0 ; itotalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - for ( l2=0 ; l2totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - objRank = p3->objRank; - for ( l3=0 ; l3totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - for ( l4=0 ; l4totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - - for ( i=0 ; itotalUsed ; i++ ) - { - m_objectParam[objRank].bboxMin.x = Min(p6->vertex[i].x, m_objectParam[objRank].bboxMin.x); - m_objectParam[objRank].bboxMin.y = Min(p6->vertex[i].y, m_objectParam[objRank].bboxMin.y); - m_objectParam[objRank].bboxMin.z = Min(p6->vertex[i].z, m_objectParam[objRank].bboxMin.z); - m_objectParam[objRank].bboxMax.x = Max(p6->vertex[i].x, m_objectParam[objRank].bboxMax.x); - m_objectParam[objRank].bboxMax.y = Max(p6->vertex[i].y, m_objectParam[objRank].bboxMax.y); - m_objectParam[objRank].bboxMax.z = Max(p6->vertex[i].z, m_objectParam[objRank].bboxMax.z); - } - - m_objectParam[objRank].radius = Max(Length(m_objectParam[objRank].bboxMin), - Length(m_objectParam[objRank].bboxMax)); - } - } - } - } - } - - m_bUpdateGeometry = FALSE; -} - - -// Determines whether an object is visible, even partially. -// Transformation of "world" must be done​​! - -BOOL CD3DEngine::IsVisible(int objRank) -{ - D3DVECTOR center; - DWORD flags; - float radius; - - radius = m_objectParam[objRank].radius; - center = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_pD3DDevice->ComputeSphereVisibility(¢er, &radius, 1, 0, &flags); - - if ( flags & D3DSTATUS_CLIPINTERSECTIONALL ) - { - m_objectParam[objRank].bVisible = FALSE; - return FALSE; - } - m_objectParam[objRank].bVisible = TRUE; - return TRUE; -} - - -// Detects the target object with the mouse. -// Returns the rank of the object or -1. - -int CD3DEngine::DetectObject(FPOINT mouse) -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - D3DVERTEX2* pv; - int l1, l2, l3, l4, l5, i, objRank, nearest; - float dist, min; - - min = 1000000.0f; - nearest = -1; - - p1 = m_objectPointer; - for ( l1=0 ; l1totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - for ( l2=0 ; l2totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - objRank = p3->objRank; - if ( m_objectParam[objRank].type == TYPETERRAIN ) continue; - if ( !DetectBBox(objRank, mouse) ) continue; - for ( l3=0 ; l3totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( p4->min != 0.0f ) continue; // LOD B or C? - for ( l4=0 ; l4totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - - if ( p6->type == D3DTYPE6T ) - { - pv = &p6->vertex[0]; - for ( i=0 ; itotalUsed/3 ; i++ ) - { - if ( DetectTriangle(mouse, pv, objRank, dist) && - dist < min ) - { - min = dist; - nearest = objRank; - } - pv += 3; - } - } - if ( p6->type == D3DTYPE6S ) - { - pv = &p6->vertex[0]; - for ( i=0 ; itotalUsed-2 ; i++ ) - { - if ( DetectTriangle(mouse, pv, objRank, dist) && - dist < min ) - { - min = dist; - nearest = objRank; - } - pv += 1; - } - } - } - } - } - } - } - return nearest; -} - -// Detects whether the mouse is in a triangle. - -BOOL CD3DEngine::DetectTriangle(FPOINT mouse, D3DVERTEX2 *triangle, - int objRank, float &dist) -{ - D3DVECTOR p2D[3], p3D; - FPOINT a, b, c; - int i; - - for ( i=0 ; i<3 ; i++ ) - { - p3D.x = triangle[i].x; - p3D.y = triangle[i].y; - p3D.z = triangle[i].z; - if ( !TransformPoint(p2D[i], objRank, p3D) ) return FALSE; - } - - if ( mouse.x < p2D[0].x && - mouse.x < p2D[1].x && - mouse.x < p2D[2].x ) return FALSE; - if ( mouse.x > p2D[0].x && - mouse.x > p2D[1].x && - mouse.x > p2D[2].x ) return FALSE; - if ( mouse.y < p2D[0].y && - mouse.y < p2D[1].y && - mouse.y < p2D[2].y ) return FALSE; - if ( mouse.y > p2D[0].y && - mouse.y > p2D[1].y && - mouse.y > p2D[2].y ) return FALSE; - - a.x = p2D[0].x; - a.y = p2D[0].y; - b.x = p2D[1].x; - b.y = p2D[1].y; - c.x = p2D[2].x; - c.y = p2D[2].y; - if ( !IsInsideTriangle(a, b, c, mouse) ) return FALSE; - - dist = (p2D[0].z+p2D[1].z+p2D[2].z)/3.0f; - return TRUE; -} - -// Detects whether an object is affected by the mouse. - -BOOL CD3DEngine::DetectBBox(int objRank, FPOINT mouse) -{ - D3DVECTOR p, pp; - FPOINT min, max; - int i; - - min.x = 1000000.0f; - min.y = 1000000.0f; - max.x = -1000000.0f; - max.y = -1000000.0f; - - for ( i=0 ; i<8 ; i++ ) - { - if ( i & (1<<0) ) p.x = m_objectParam[objRank].bboxMin.x; - else p.x = m_objectParam[objRank].bboxMax.x; - if ( i & (1<<1) ) p.y = m_objectParam[objRank].bboxMin.y; - else p.y = m_objectParam[objRank].bboxMax.y; - if ( i & (1<<2) ) p.z = m_objectParam[objRank].bboxMin.z; - else p.z = m_objectParam[objRank].bboxMax.z; - if ( TransformPoint(pp, objRank, p) ) - { - if ( pp.x < min.x ) min.x = pp.x; - if ( pp.x > max.x ) max.x = pp.x; - if ( pp.y < min.y ) min.y = pp.y; - if ( pp.y > max.y ) max.y = pp.y; - } - } - - return ( mouse.x >= min.x && - mouse.x <= max.x && - mouse.y >= min.y && - mouse.y <= max.y ); -} - -// Transforms a 3D point (x, y, z) in 2D space (x, y, -) of the window. -// The coordinated p2D.z gives the distance. - -BOOL CD3DEngine::TransformPoint(D3DVECTOR &p2D, int objRank, D3DVECTOR p3D) -{ - p3D = Transform(m_objectParam[objRank].transform, p3D); - p3D = Transform(m_matView, p3D); - - if ( p3D.z < 2.0f ) return FALSE; // behind? - - p2D.x = (p3D.x/p3D.z)*m_matProj._11; - p2D.y = (p3D.y/p3D.z)*m_matProj._22; - p2D.z = p3D.z; - - p2D.x = (p2D.x+1.0f)/2.0f; // [-1..1] -> [0..1] - p2D.y = (p2D.y+1.0f)/2.0f; - - return TRUE; -} - - -// Calculating the distances between the viewpoint and the origin -// of different objects. - -void CD3DEngine::ComputeDistance() -{ - D3DVECTOR v; - int i; - float distance; - - if ( s_resol == 0 ) - { - for ( i=0 ; iIsVideo8MB() ) - { - SetGroundSpot(FALSE); - SetSkyMode(FALSE); - } - - if ( m_app->IsVideo32MB() && bFirst ) - { - SetObjectDetail(2.0f); - } -} - -// Returns the total amount of video memory for textures. - -int CD3DEngine::GetVidMemTotal() -{ - return m_app->GetVidMemTotal(); -} - -BOOL CD3DEngine::IsVideo8MB() -{ - return m_app->IsVideo8MB(); -} - -BOOL CD3DEngine::IsVideo32MB() -{ - return m_app->IsVideo32MB(); -} - - -// Perform the list of all graphics devices available. - -BOOL CD3DEngine::EnumDevices(char *bufDevices, int lenDevices, - char *bufModes, int lenModes, - int &totalDevices, int &selectDevices, - int &totalModes, int &selectModes) -{ - return m_app->EnumDevices(bufDevices, lenDevices, - bufModes, lenModes, - totalDevices, selectDevices, - totalModes, selectModes); -} - -BOOL CD3DEngine::RetFullScreen() -{ - return m_app->RetFullScreen(); -} - -BOOL CD3DEngine::ChangeDevice(char *device, char *mode, BOOL bFull) -{ - return m_app->ChangeDevice(device, mode, bFull); -} - - - -D3DMATRIX* CD3DEngine::RetMatView() -{ - return &m_matView; -} - -D3DMATRIX* CD3DEngine::RetMatLeftView() -{ - return &m_matLeftView; -} - -D3DMATRIX* CD3DEngine::RetMatRightView() -{ - return &m_matRightView; -} - - -// Specifies the location and direction of view. - -void CD3DEngine::SetViewParams(const D3DVECTOR &vEyePt, - const D3DVECTOR &vLookatPt, - const D3DVECTOR &vUpVec, - FLOAT fEyeDistance) -{ -#if 0 - m_eyePt = vEyePt; - - // Adjust camera position for left or right eye along the axis - // perpendicular to the view direction vector and the up vector. - D3DVECTOR vView = (vLookatPt) - (vEyePt); - vView = CrossProduct( vView, (vUpVec) ); - vView = Normalize( vView ) * fEyeDistance; - - D3DVECTOR vLeftEyePt = (vEyePt) + vView; - D3DVECTOR vRightEyePt = (vEyePt) - vView; - - // Set the view matrices - D3DUtil_SetViewMatrix( m_matLeftView, (D3DVECTOR)vLeftEyePt, (D3DVECTOR)vLookatPt, (D3DVECTOR)vUpVec ); - D3DUtil_SetViewMatrix( m_matRightView, (D3DVECTOR)vRightEyePt, (D3DVECTOR)vLookatPt, (D3DVECTOR)vUpVec ); - D3DUtil_SetViewMatrix( m_matView, (D3DVECTOR)vEyePt, (D3DVECTOR)vLookatPt, (D3DVECTOR)vUpVec ); -#else - m_eyePt = vEyePt; - m_lookatPt = vLookatPt; - m_eyeDirH = RotateAngle(vEyePt.x-vLookatPt.x, vEyePt.z-vLookatPt.z); - m_eyeDirV = RotateAngle(Length2d(vEyePt, vLookatPt), vEyePt.y-vLookatPt.y); - - D3DUtil_SetViewMatrix(m_matView, (D3DVECTOR&)vEyePt, (D3DVECTOR&)vLookatPt, (D3DVECTOR&)vUpVec); - - if ( m_sound == 0 ) - { - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - } - m_sound->SetListener(vEyePt, vLookatPt); -#endif -} - - -// Specifies the transformation matrix of an object. - -BOOL CD3DEngine::SetObjectTransform(int objRank, const D3DMATRIX &transform) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; - - m_objectParam[objRank].transform = transform; - return TRUE; -} - -// Gives the transformation matrix of an object. - -BOOL CD3DEngine::GetObjectTransform(int objRank, D3DMATRIX &transform) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; - - transform = m_objectParam[objRank].transform; - return TRUE; -} - -// Specifies the type of an object. - -BOOL CD3DEngine::SetObjectType(int objRank, D3DTypeObj type) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; - - m_objectParam[objRank].type = type; - return TRUE; -} - -// Returns the type of an object. - -D3DTypeObj CD3DEngine::RetObjectType(int objRank) -{ - return m_objectParam[objRank].type; -} - -// Specifies the transparency of an object. - -BOOL CD3DEngine::SetObjectTransparency(int objRank, float value) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; - - m_objectParam[objRank].transparency = value; - return TRUE; -} - - -// Allocates a table for shade, if necessary. - -BOOL CD3DEngine::ShadowCreate(int objRank) -{ - int i; - - // Already allocated? - if ( m_objectParam[objRank].shadowRank != -1 ) return TRUE; - - for ( i=0 ; i= D3DMAXOBJECT ) return FALSE; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return FALSE; - - m_shadow[i].bHide = bHide; - return TRUE; -} - -// Specifies the type of the shadow of the object. - -BOOL CD3DEngine::SetObjectShadowType(int objRank, D3DShadowType type) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return FALSE; - - m_shadow[i].type = type; - return TRUE; -} - -// Specifies the position of the shadow of the object. - -BOOL CD3DEngine::SetObjectShadowPos(int objRank, const D3DVECTOR &pos) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return FALSE; - - m_shadow[i].pos = pos; - return TRUE; -} - -// Specifies the normal shadow to the field of the object. - -BOOL CD3DEngine::SetObjectShadowNormal(int objRank, const D3DVECTOR &n) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return FALSE; - - m_shadow[i].normal = n; - return TRUE; -} - -// Specifies the angle of the shadow of the object. - -BOOL CD3DEngine::SetObjectShadowAngle(int objRank, float angle) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return FALSE; - - m_shadow[i].angle = angle; - return TRUE; -} - -// Specifies the radius of the shadow of the object. - -BOOL CD3DEngine::SetObjectShadowRadius(int objRank, float radius) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return FALSE; - - m_shadow[i].radius = radius; - return TRUE; -} - -// Returns the radius of the shadow of the object. - -float CD3DEngine::RetObjectShadowRadius(int objRank) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return 0.0f; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return FALSE; - - return m_shadow[i].radius; -} - -// Specifies the intensity of the shadow of the object. - -BOOL CD3DEngine::SetObjectShadowIntensity(int objRank, float intensity) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return FALSE; - - m_shadow[i].intensity = intensity; - return TRUE; -} - -// Specifies the height of the shadow of the object. - -BOOL CD3DEngine::SetObjectShadowHeight(int objRank, float h) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return FALSE; - - m_shadow[i].height = h; - return TRUE; -} - - -// Clears all marks on the ground. - -void CD3DEngine::GroundSpotFlush() -{ - LPDIRECTDRAWSURFACE7 surface; - DDSURFACEDESC2 ddsd; - WORD* pbSurf; - char texName[20]; - int s, y; - - ZeroMemory(m_groundSpot, sizeof(D3DGroundSpot)*D3DMAXGROUNDSPOT); - m_bFirstGroundSpot = TRUE; // drawing power first - - for ( s=0 ; s<16 ; s++ ) - { - sprintf(texName, "shadow%.2d.tga", s); - surface = D3DTextr_GetSurface(texName); - if ( surface == 0 ) continue; - - ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(DDSURFACEDESC2); - if ( surface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) != DD_OK ) continue; - - if ( ddsd.ddpfPixelFormat.dwRGBBitCount != 16 ) continue; - - for ( y=0 ; y<(int)ddsd.dwHeight ; y++ ) - { - pbSurf = (WORD*)ddsd.lpSurface; - pbSurf += ddsd.lPitch*y/2; - memset(pbSurf, -1, ddsd.lPitch); // all blank - } - - surface->Unlock(NULL); - } -} - -// Allocates a table for a mark on the ground, if necessary. - -int CD3DEngine::GroundSpotCreate() -{ - int i; - - for ( i=0 ; i 1 ) rank = 1; - - if ( m_rankView == 0 && rank == 1 ) // enters the water? - { - m_light->AdaptLightColor(m_waterAddColor, +1.0f); - } - - if ( m_rankView == 1 && rank == 0 ) // out of the water? - { - m_light->AdaptLightColor(m_waterAddColor, -1.0f); - } - - m_rankView = rank; -} - -int CD3DEngine::RetRankView() -{ - return m_rankView; -} - -// Whether to draw the world from the interface. - -void CD3DEngine::SetDrawWorld(BOOL bDraw) -{ - m_bDrawWorld = bDraw; -} - -// Whether to draw the world on the interface. - -void CD3DEngine::SetDrawFront(BOOL bDraw) -{ - m_bDrawFront = bDraw; -} - -// Color management ambient. -// color = 0x00rrggbb -// rr: red -// gg: green -// bb: blue - -void CD3DEngine::SetAmbiantColor(D3DCOLOR color, int rank) -{ - m_ambiantColor[rank] = color; -} - -D3DCOLOR CD3DEngine::RetAmbiantColor(int rank) -{ - return m_ambiantColor[rank]; -} - - -// Color management under water. - -void CD3DEngine::SetWaterAddColor(D3DCOLORVALUE color) -{ - m_waterAddColor = color; -} - -D3DCOLORVALUE CD3DEngine::RetWaterAddColor() -{ - return m_waterAddColor; -} - - -// Management of the fog color. - -void CD3DEngine::SetFogColor(D3DCOLOR color, int rank) -{ - m_fogColor[rank] = color; -} - -D3DCOLOR CD3DEngine::RetFogColor(int rank) -{ - return m_fogColor[rank]; -} - - -// Management of the depth of field. -// Beyond this distance, nothing is visible. -// Shortly (according SetFogStart), one enters the fog. - -void CD3DEngine::SetDeepView(float length, int rank, BOOL bRef) -{ - if ( bRef ) - { - length *= m_clippingDistance; - } - - m_deepView[rank] = length; -} - -float CD3DEngine::RetDeepView(int rank) -{ - return m_deepView[rank]; -} - - -// Management the start of fog. -// With 0.0, the fog from the point of view (fog max). -// With 1.0, the fog from the depth of field (no fog). - -void CD3DEngine::SetFogStart(float start, int rank) -{ - m_fogStart[rank] = start; -} - -float CD3DEngine::RetFogStart(int rank) -{ - return m_fogStart[rank]; -} - - -// Gives the background image to use. - -void CD3DEngine::SetBackground(char *name, D3DCOLOR up, D3DCOLOR down, - D3DCOLOR cloudUp, D3DCOLOR cloudDown, - BOOL bFull, BOOL bQuarter) -{ - strcpy(m_backgroundName, name); - m_backgroundColorUp = up; - m_backgroundColorDown = down; - m_backgroundCloudUp = cloudUp; - m_backgroundCloudDown = cloudDown; - m_bBackgroundFull = bFull; - m_bBackgroundQuarter = bQuarter; -} - -// Gives the background image used. - -void CD3DEngine::RetBackground(char *name, D3DCOLOR &up, D3DCOLOR &down, - D3DCOLOR &cloudUp, D3DCOLOR &cloudDown, - BOOL &bFull, BOOL &bQuarter) -{ - strcpy(name, m_backgroundName); - up = m_backgroundColorUp; - down = m_backgroundColorDown; - cloudUp = m_backgroundCloudUp; - cloudDown = m_backgroundCloudDown; - bFull = m_bBackgroundFull; - bQuarter = m_bBackgroundQuarter; -} - -// Gives the foreground image to use. - -void CD3DEngine::SetFrontsizeName(char *name) -{ - if ( m_frontsizeName[0] != 0 ) - { - FreeTexture(m_frontsizeName); - } - - strcpy(m_frontsizeName, name); -} - -// Specifies whether to draw the foreground. - -void CD3DEngine::SetOverFront(BOOL bFront) -{ - m_bOverFront = bFront; -} - -// Gives color to the foreground. - -void CD3DEngine::SetOverColor(D3DCOLOR color, int mode) -{ - m_overColor = color; - m_overMode = mode; -} - - - -// Management of the particle density. - -void CD3DEngine::SetParticuleDensity(float value) -{ - if ( value < 0.0f ) value = 0.0f; - if ( value > 2.0f ) value = 2.0f; - m_particuleDensity = value; -} - -float CD3DEngine::RetParticuleDensity() -{ - return m_particuleDensity; -} - -float CD3DEngine::ParticuleAdapt(float factor) -{ - if ( m_particuleDensity == 0.0f ) - { - return 1000000.0f; - } - return factor/m_particuleDensity; -} - -// Management of the distance of clipping. - -void CD3DEngine::SetClippingDistance(float value) -{ - if ( value < 0.5f ) value = 0.5f; - if ( value > 2.0f ) value = 2.0f; - m_clippingDistance = value; -} - -float CD3DEngine::RetClippingDistance() -{ - return m_clippingDistance; -} - -// Management of objects detals. - -void CD3DEngine::SetObjectDetail(float value) -{ - if ( value < 0.0f ) value = 0.0f; - if ( value > 2.0f ) value = 2.0f; - m_objectDetail = value; -} - -float CD3DEngine::RetObjectDetail() -{ - return m_objectDetail; -} - -// The amount of management objects gadgets. - -void CD3DEngine::SetGadgetQuantity(float value) -{ - if ( value < 0.0f ) value = 0.0f; - if ( value > 1.0f ) value = 1.0f; - - m_gadgetQuantity = value; -} - -float CD3DEngine::RetGadgetQuantity() -{ - return m_gadgetQuantity; -} - -// Managing the quality of textures. - -void CD3DEngine::SetTextureQuality(int value) -{ - if ( value < 0 ) value = 0; - if ( value > 2 ) value = 2; - - if ( value != m_textureQuality ) - { - m_textureQuality = value; - LoadAllTexture(); - } -} - -int CD3DEngine::RetTextureQuality() -{ - return m_textureQuality; -} - - -// Management mode of toto. - -void CD3DEngine::SetTotoMode(BOOL bPresent) -{ - m_bTotoMode = bPresent; -} - -BOOL CD3DEngine::RetTotoMode() -{ - return m_bTotoMode; -} - - -// Managing the mode of foreground. - -void CD3DEngine::SetLensMode(BOOL bPresent) -{ - m_bLensMode = bPresent; -} - -BOOL CD3DEngine::RetLensMode() -{ - return m_bLensMode; -} - - -// Managing the mode of water. - -void CD3DEngine::SetWaterMode(BOOL bPresent) -{ - m_bWaterMode = bPresent; -} - -BOOL CD3DEngine::RetWaterMode() -{ - return m_bWaterMode; -} - - -// Managing the mode of sky. - -void CD3DEngine::SetSkyMode(BOOL bPresent) -{ - m_bSkyMode = bPresent; -} - -BOOL CD3DEngine::RetSkyMode() -{ - return m_bSkyMode; -} - - -// Managing the mode of background. - -void CD3DEngine::SetBackForce(BOOL bPresent) -{ - m_bBackForce = bPresent; -} - -BOOL CD3DEngine::RetBackForce() -{ - return m_bBackForce; -} - - -// Managing the mode of planets. - -void CD3DEngine::SetPlanetMode(BOOL bPresent) -{ - m_bPlanetMode = bPresent; -} - -BOOL CD3DEngine::RetPlanetMode() -{ - return m_bPlanetMode; -} - - -// Managing the mode of dymanic lights. - -void CD3DEngine::SetLightMode(BOOL bPresent) -{ - m_bLightMode = bPresent; -} - -BOOL CD3DEngine::RetLightMode() -{ - return m_bLightMode; -} - - -// Management of the indentation mode while editing (CEdit). - -void CD3DEngine::SetEditIndentMode(BOOL bAuto) -{ - m_bEditIndentMode = bAuto; -} - -BOOL CD3DEngine::RetEditIndentMode() -{ - return m_bEditIndentMode; -} - - -// Management in advance of a tab when editing (CEdit). - -void CD3DEngine::SetEditIndentValue(int value) -{ - m_editIndentValue = value; -} - -int CD3DEngine::RetEditIndentValue() -{ - return m_editIndentValue; -} - - -void CD3DEngine::SetSpeed(float speed) -{ - m_speed = speed; -} - -float CD3DEngine::RetSpeed() -{ - return m_speed; -} - - -void CD3DEngine::SetTracePrecision(float factor) -{ - m_tracePrecision = factor; -} - -float CD3DEngine::RetTracePrecision() -{ - return m_tracePrecision; -} - - -// Updates the scene after a change of parameters. - -void CD3DEngine::ApplyChange() -{ - m_deepView[0] /= m_lastClippingDistance; - m_deepView[1] /= m_lastClippingDistance; - - SetFocus(m_focus); - ChangeLOD(); - - m_deepView[0] *= m_clippingDistance; - m_deepView[1] *= m_clippingDistance; -} - - - -// Returns the point of view of the user. - -D3DVECTOR CD3DEngine::RetEyePt() -{ - return m_eyePt; -} - -D3DVECTOR CD3DEngine::RetLookatPt() -{ - return m_lookatPt; -} - -float CD3DEngine::RetEyeDirH() -{ - return m_eyeDirH; -} - -float CD3DEngine::RetEyeDirV() -{ - return m_eyeDirV; -} - -POINT CD3DEngine::RetDim() -{ - return m_dim; -} - - -// Generates an image name of the watch. - -void QuarterName(char *buffer, char *name, int quarter) -{ - while ( *name != 0 ) - { - if ( *name == '.' ) - { - *buffer++ = 'a'+quarter; - } - *buffer++ = *name++; - } - *buffer++ = 0; -} - -// Frees texture. - -BOOL CD3DEngine::FreeTexture(char* name) -{ - if ( name[0] == 0 ) return TRUE; - - if ( D3DTextr_DestroyTexture(name) != S_OK ) - { - return FALSE; - } - return TRUE; -} - -// Load a texture. - -BOOL CD3DEngine::LoadTexture(char* name, int stage) -{ - DWORD mode; - - if ( name[0] == 0 ) return TRUE; - - if ( D3DTextr_GetSurface(name) == NULL ) - { - if ( strstr(name, ".tga") == 0 ) - { - mode = 0; - } - else - { - mode = D3DTEXTR_CREATEWITHALPHA; - } - - if ( D3DTextr_CreateTextureFromFile(name, stage, mode) != S_OK ) - { - return FALSE; - } - - if ( D3DTextr_Restore(name, m_pD3DDevice) != S_OK ) - { - return FALSE; - } - } - return TRUE; -} - -// Load all the textures of the scene. - -BOOL CD3DEngine::LoadAllTexture() -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - int l1, i; - char name[50]; - BOOL bOK = TRUE; - -#if _POLISH - LoadTexture("textp.tga"); -#else - LoadTexture("text.tga"); -#endif - LoadTexture("mouse.tga"); - LoadTexture("button1.tga"); - LoadTexture("button2.tga"); - LoadTexture("button3.tga"); - LoadTexture("effect00.tga"); - LoadTexture("effect01.tga"); - LoadTexture("effect02.tga"); - LoadTexture("map.tga"); - - if ( m_backgroundName[0] != 0 ) - { - if ( m_bBackgroundQuarter ) // image into 4 pieces? - { - for ( i=0 ; i<4 ; i++ ) - { - QuarterName(name, m_backgroundName, i); - LoadTexture(name); - } - } - else - { - LoadTexture(m_backgroundName); - } - } - if ( m_frontsizeName[0] != 0 ) - { - LoadTexture(m_frontsizeName); - } - - m_planet->LoadTexture(); - - p1 = m_objectPointer; - for ( l1=0 ; l1totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - - if ( p2 == 0 || p2->texName1[0] != 0 ) - { - if ( !LoadTexture(p2->texName1, 0) ) bOK = FALSE; - } - - if ( p2 == 0 || p2->texName2[0] != 0 ) - { - if ( !LoadTexture(p2->texName2, 1) ) bOK = FALSE; - } - } - return bOK; -} - - -// Called during initial app startup, this function performs all the -// permanent initialization. - -HRESULT CD3DEngine::OneTimeSceneInit() -{ - return S_OK; -} - - -// Updated after creating objects. - -void CD3DEngine::Update() -{ - ComputeDistance(); - UpdateGeometry(); -} - -// Called once per frame, the call is the entry point for animating -// the scene. - -HRESULT CD3DEngine::FrameMove(float rTime) -{ - m_light->FrameLight(rTime); - m_particule->FrameParticule(rTime); - ComputeDistance(); - UpdateGeometry(); - - if ( m_groundMark.bUsed ) - { - if ( m_groundMark.phase == 1 ) // growing? - { - m_groundMark.intensity += rTime*(1.0f/m_groundMark.delay[0]); - if ( m_groundMark.intensity >= 1.0f ) - { - m_groundMark.intensity = 1.0f; - m_groundMark.fix = 0.0f; - m_groundMark.phase = 2; - } - } - else if ( m_groundMark.phase == 2 ) // fixed? - { - m_groundMark.fix += rTime*(1.0f/m_groundMark.delay[1]); - if ( m_groundMark.fix >= 1.0f ) - { - m_groundMark.phase = 3; - } - } - else if ( m_groundMark.phase == 3 ) // decay? - { - m_groundMark.intensity -= rTime*(1.0f/m_groundMark.delay[2]); - if ( m_groundMark.intensity < 0.0f ) - { - m_groundMark.intensity = 0.0f; - m_groundMark.phase = 0; - m_groundMark.bUsed = FALSE; - } - } - } - - if ( m_sound == 0 ) - { - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - } - m_sound->FrameMove(rTime); - - return S_OK; -} - -// Evolved throughout the game - -void CD3DEngine::StepSimul(float rTime) -{ - m_app->StepSimul(rTime); -} - - - -// Changes the state associated with a material. -// (*) Does not work without this instruction, mystery! - -void CD3DEngine::SetState(int state, D3DCOLOR color) -{ - BOOL bSecond; - - if ( state == m_lastState && - color == m_lastColor ) return; - m_lastState = state; - m_lastColor = color; - - if ( m_alphaMode != 1 && (state & D3DSTATEALPHA) ) - { - state &= ~D3DSTATEALPHA; - - if ( m_alphaMode == 2 ) - { - state |= D3DSTATETTb; - } - } - - if ( state & D3DSTATETTb ) // The transparent black texture? - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_blackSrcBlend[1]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_blackDestBlend[1]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, table_blend[debug_blend1]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, table_blend[debug_blend2]); - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, color); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); // (*) - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - else if ( state & D3DSTATETTw ) // The transparent white texture? - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_whiteSrcBlend[1]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_whiteDestBlend[1]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, table_blend[debug_blend3]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, table_blend[debug_blend4]); - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, ~color); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_ADD); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); // (*) - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - else if ( state & D3DSTATETCb ) // The transparent black color? - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_blackSrcBlend[1]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_blackDestBlend[1]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, table_blend[debug_blend1]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, table_blend[debug_blend2]); - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, color); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - else if ( state & D3DSTATETCw ) // The transparent white color? - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_whiteSrcBlend[1]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_whiteDestBlend[1]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, table_blend[debug_blend3]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, table_blend[debug_blend4]); - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, ~color); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - else if ( state & D3DSTATETD ) // diffuse color as transparent? - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_diffuseSrcBlend[1]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_diffuseDestBlend[1]); - - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - else if ( state & D3DSTATEALPHA ) // image with alpha channel? - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHAFUNC, D3DCMP_GREATER); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHAREF, (DWORD)(128)); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_alphaSrcBlend[1]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_alphaSrcBlend[1]); - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, color); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - } - else // normal ? - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE); - - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - - if ( state & D3DSTATEFOG ) - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE); - } - - bSecond = m_bGroundSpot|m_bDirty; - if ( !m_bGroundSpot && (state & D3DSTATESECOND) != 0 ) bSecond = FALSE; - if ( !m_bDirty && (state & D3DSTATESECOND) == 0 ) bSecond = FALSE; - - if ( (state & D3DSTATEDUALb) && bSecond ) - { - m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); - } - else if ( (state & D3DSTATEDUALw) && bSecond ) - { - m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); - } - else - { - m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - - if ( state & D3DSTATEWRAP ) - { -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_WRAP0, D3DWRAP_U|D3DWRAP_V); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); - } - else if ( state & D3DSTATECLAMP ) - { -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_WRAP0, 0); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); - } - else - { -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_WRAP0, 0); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); - } - - if ( state & D3DSTATE2FACE ) - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); - } - else - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CCW); - } - - if ( state & D3DSTATELIGHT ) - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - } - else - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, m_ambiantColor[m_rankView]); - } -} - -// Specifies a texture to use. - -void CD3DEngine::SetTexture(char *name, int stage) -{ -//? if ( stage == 1 && !m_bDirty ) return; -//? if ( stage == 1 && !m_bShadow ) return; - - if ( strcmp(name, m_lastTexture[stage]) == 0 ) return; - strcpy(m_lastTexture[stage], name); - - m_pD3DDevice->SetTexture(stage, D3DTextr_GetSurface(name)); -} - -// Specifies the material to use. - -void CD3DEngine::SetMaterial(const D3DMATERIAL7 &mat) -{ - if ( memcmp(&mat, &m_lastMaterial, sizeof(D3DMATERIAL7)) == 0 ) return; - m_lastMaterial = mat; - - m_pD3DDevice->SetMaterial(&m_lastMaterial); -} - - -// Deletes a point in a surface (draw in white). - -inline void ClearDot(DDSURFACEDESC2* ddsd, int x, int y) -{ - WORD* pbSurf; - - if ( ddsd->ddpfPixelFormat.dwRGBBitCount != 16 ) return; - - pbSurf = (WORD*)ddsd->lpSurface; - pbSurf += ddsd->lPitch*y/2; - pbSurf += x; - - *pbSurf = 0xffff; // white -} - -// Deletes a point in a surface (draw in white) - -void AddDot(DDSURFACEDESC2* ddsd, int x, int y, D3DCOLORVALUE color) -{ - WORD* pbSurf; - WORD r,g,b, w; - - if ( ddsd->ddpfPixelFormat.dwRGBBitCount != 16 ) return; - - if ( color.r < 0.0f ) color.r = 0.0f; - if ( color.r > 1.0f ) color.r = 1.0f; - r = (int)(color.r*32.0f); - if ( r >= 32 ) r = 31; // 5 bits - - if ( color.g < 0.0f ) color.g = 0.0f; - if ( color.g > 1.0f ) color.g = 1.0f; - g = (int)(color.g*32.0f); - if ( g >= 32 ) g = 31; // 5 bits - - if ( color.b < 0.0f ) color.b = 0.0f; - if ( color.b > 1.0f ) color.b = 1.0f; - b = (int)(color.b*32.0f); - if ( b >= 32 ) b = 31; // 5 bits - - if ( ddsd->ddpfPixelFormat.dwRBitMask == 0xf800 ) // 565 ? - { - w = (r<<11)|(g<<6)|b; - } - else if ( ddsd->ddpfPixelFormat.dwRBitMask == 0x7c00 ) // 555 ? - { - w = (r<<10)|(g<<5)|b; - } - else - { - w = -1; // blank - } - - pbSurf = (WORD*)ddsd->lpSurface; - pbSurf += ddsd->lPitch*y/2; - pbSurf += x; - - *pbSurf &= w; -} - -// Displays a point in a surface. - -void SetDot(DDSURFACEDESC2* ddsd, int x, int y, D3DCOLORVALUE color) -{ - if ( ddsd->ddpfPixelFormat.dwRGBBitCount == 16 ) - { - WORD* pbSurf; - WORD r,g,b, w; - - if ( color.r < 0.0f ) color.r = 0.0f; - if ( color.r > 1.0f ) color.r = 1.0f; - if ( color.g < 0.0f ) color.g = 0.0f; - if ( color.g > 1.0f ) color.g = 1.0f; - if ( color.b < 0.0f ) color.b = 0.0f; - if ( color.b > 1.0f ) color.b = 1.0f; - - r = (int)(color.r*32.0f); - g = (int)(color.g*32.0f); - b = (int)(color.b*32.0f); - - if ( r >= 32 ) r = 31; // 5 bits - if ( g >= 32 ) g = 31; // 5 bits - if ( b >= 32 ) b = 31; // 5 bits - - if ( ddsd->ddpfPixelFormat.dwRBitMask == 0xf800 ) // 565 ? - { - w = (r<<11)|(g<<6)|b; - } - else if ( ddsd->ddpfPixelFormat.dwRBitMask == 0x7c00 ) // 555 ? - { - w = (r<<10)|(g<<5)|b; - } - else - { - w = -1; // blank - } - - pbSurf = (WORD*)ddsd->lpSurface; - pbSurf += ddsd->lPitch*y/2; - pbSurf += x; - - *pbSurf = w; - } - - if ( ddsd->ddpfPixelFormat.dwRGBBitCount == 32 ) // image .tga ? - { - LONG* pbSurf; - LONG r,g,b, w; - - if ( color.r < 0.0f ) color.r = 0.0f; - if ( color.r > 1.0f ) color.r = 1.0f; - if ( color.g < 0.0f ) color.g = 0.0f; - if ( color.g > 1.0f ) color.g = 1.0f; - if ( color.b < 0.0f ) color.b = 0.0f; - if ( color.b > 1.0f ) color.b = 1.0f; - - r = (int)(color.r*256.0f); - g = (int)(color.g*256.0f); - b = (int)(color.b*256.0f); - - if ( r >= 256 ) r = 255; // 8 bits - if ( g >= 256 ) g = 255; // 8 bits - if ( b >= 256 ) b = 255; // 8 bits - - if ( ddsd->ddpfPixelFormat.dwRBitMask == 0xff0000 ) - { - w = (r<<16)|(g<<8)|b; - - pbSurf = (LONG*)ddsd->lpSurface; - pbSurf += ddsd->lPitch*y/4; - pbSurf += x; - - *pbSurf &= 0xff000000; // keeps alpha channel - *pbSurf |= w; - } - } -} - -// Gives a point in a surface. - -D3DCOLORVALUE GetDot(DDSURFACEDESC2* ddsd, int x, int y) -{ - D3DCOLORVALUE color; - - if ( ddsd->ddpfPixelFormat.dwRGBBitCount == 16 ) - { - WORD* pbSurf; - WORD r,g,b, w; - - pbSurf = (WORD*)ddsd->lpSurface; - pbSurf += ddsd->lPitch*y/2; - pbSurf += x; - - w = *pbSurf; - - if ( ddsd->ddpfPixelFormat.dwRBitMask == 0xf800 ) // 565 ? - { - r = (w>>10)&0x003e; - g = (w>> 5)&0x003f; - b = (w<< 1)&0x003e; - } - else if ( ddsd->ddpfPixelFormat.dwRBitMask == 0x7c00 ) // 555 ? - { - r = (w>> 9)&0x003e; - g = (w>> 4)&0x003e; - b = (w<< 1)&0x003e; - } - else - { - r = 0; - g = 0; - b = 0; // black - } - - color.r = (float)r/63.0f; - color.g = (float)g/63.0f; - color.b = (float)b/63.0f; - color.a = 0.0f; - return color; - } - - if ( ddsd->ddpfPixelFormat.dwRGBBitCount == 32 ) // image .tga ? - { - LONG* pbSurf; - LONG r,g,b, w; - - pbSurf = (LONG*)ddsd->lpSurface; - pbSurf += ddsd->lPitch*y/4; - pbSurf += x; - - w = *pbSurf; - - if ( ddsd->ddpfPixelFormat.dwRBitMask == 0xff0000 ) - { - r = (w>>16)&0x00ff; - g = (w>> 8)&0x00ff; - b = (w<< 0)&0x00ff; - } - else - { - r = 0; - g = 0; - b = 0; // black - } - - color.r = (float)r/255.0f; - color.g = (float)g/255.0f; - color.b = (float)b/255.0f; - color.a = 0.0f; - return color; - } - - color.r = 0.0f; - color.g = 0.0f; - color.b = 0.0f; - color.a = 0.0f; // black - return color; -} - -// Draw all the shadows. - -// There is a pixel collection around each of the 16 surfaces: -// -// |<----------------------->|<----------------------->|<---- ... -// 0 | 1 2 253 254|255 | -// |---|---|---|-- ... --|---|---|---| | -// 0 | 1 2 253 254|255 -// |---|---|---|-- ... --|---|---|---| -// -// So we draw in 254x254 pixels surfaces. -// The pixel margin around it is drawn twice (in two adjacent surfaces), -// so that the filter produces the same results! - -void CD3DEngine::RenderGroundSpot() -{ - LPDIRECTDRAWSURFACE7 surface; - DDSURFACEDESC2 ddsd; - WORD* pbSurf; - D3DCOLORVALUE color; - D3DVECTOR pos; - FPOINT min, max; - int s, i, j, dot, ix, iy, y; - float tu, tv, cx, cy, px, py, ppx, ppy; - float intensity, level; - char texName[20]; - BOOL bClear, bSet; - - if ( !m_bFirstGroundSpot && - m_groundMark.drawPos.x == m_groundMark.pos.x && - m_groundMark.drawPos.z == m_groundMark.pos.z && - m_groundMark.drawRadius == m_groundMark.radius && - m_groundMark.drawIntensity == m_groundMark.intensity ) return; - - for ( s=0 ; s<16 ; s++ ) - { - min.x = (s%4)*254.0f-1.0f; // 1 pixel cover - min.y = (s/4)*254.0f-1.0f; - max.x = min.x+254.0f+2.0f; - max.y = min.y+254.0f+2.0f; - - bClear = FALSE; - bSet = FALSE; - - // Calculate the area to be erased. - dot = (int)(m_groundMark.drawRadius/2.0f); - - tu = (m_groundMark.drawPos.x+1600.0f)/3200.0f; - tv = (m_groundMark.drawPos.z+1600.0f)/3200.0f; // 0..1 - - cx = (tu*254.0f*4.0f)-0.5f; - cy = (tv*254.0f*4.0f)-0.5f; - - if ( dot == 0 ) - { - cx += 0.5f; - cy += 0.5f; - } - - px = cx-Mod(cx, 1.0f); - py = cy-Mod(cy, 1.0f); // multiple of 1 - - if ( m_bFirstGroundSpot || - ( m_groundMark.drawRadius != 0.0f && - px+dot >= min.x && py+dot >= min.y && - px-dot <= max.x && py-dot <= max.y ) ) - { - bClear = TRUE; - } - - // Calculate the area to draw. - dot = (int)(m_groundMark.radius/2.0f); - - tu = (m_groundMark.pos.x+1600.0f)/3200.0f; - tv = (m_groundMark.pos.z+1600.0f)/3200.0f; // 0..1 - - cx = (tu*254.0f*4.0f)-0.5f; - cy = (tv*254.0f*4.0f)-0.5f; - - if ( dot == 0 ) - { - cx += 0.5f; - cy += 0.5f; - } - - px = cx-Mod(cx, 1.0f); - py = cy-Mod(cy, 1.0f); // multiple of 1 - - if ( m_groundMark.bUsed && - px+dot >= min.x && py+dot >= min.y && - px-dot <= max.x && py-dot <= max.y ) - { - bSet = TRUE; - } - - if ( bClear || bSet ) - { - // Load the song. - sprintf(texName, "shadow%.2d.tga", s); - surface = D3DTextr_GetSurface(texName); - if ( surface == 0 ) continue; - - ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(DDSURFACEDESC2); - if ( surface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) != DD_OK ) continue; - - // Clears in blank whole piece. - if ( ddsd.ddpfPixelFormat.dwRGBBitCount == 16 ) - { - for ( y=0 ; y<(int)ddsd.dwHeight ; y++ ) - { - pbSurf = (WORD*)ddsd.lpSurface; - pbSurf += ddsd.lPitch*y/2; - memset(pbSurf, -1, ddsd.lPitch); // all blank - } - } - - // Draw the new shadows. - for ( i=0 ; i max.x || py-dot > max.y ) continue; - - for ( iy=-dot ; iy<=dot ; iy++ ) - { - for ( ix=-dot ; ix<=dot ; ix++ ) - { - ppx = px+ix; - ppy = py+iy; - - if ( ppx < min.x || ppy < min.y || - ppx >= max.x || ppy >= max.y ) continue; - - if ( dot == 0 ) - { - intensity = 0.0f; - } - else - { - intensity = Length(ppx-cx, ppy-cy)/dot; - //? intensity = powf(intensity, m_groundSpot[i].smooth); - } - - color.r = m_groundSpot[i].color.r+intensity; - color.g = m_groundSpot[i].color.g+intensity; - color.b = m_groundSpot[i].color.b+intensity; - - ppx -= min.x; // on the texture - ppy -= min.y; - AddDot(&ddsd, (int)ppx, (int)ppy, color); - } - } - } - else - { - for ( iy=0 ; iy<256 ; iy++ ) - { - for ( ix=0 ; ix<256 ; ix++ ) - { - pos.x = (256.0f*(s%4)+ix)*3200.0f/1024.0f - 1600.0f; - pos.z = (256.0f*(s/4)+iy)*3200.0f/1024.0f - 1600.0f; - pos.y = 0.0f; - level = m_terrain->RetFloorLevel(pos, TRUE); - if ( level < m_groundSpot[i].min || - level > m_groundSpot[i].max ) continue; - - if ( level > (m_groundSpot[i].max+m_groundSpot[i].min)/2.0f ) - { - intensity = 1.0f-(m_groundSpot[i].max-level)/m_groundSpot[i].smooth; - } - else - { - intensity = 1.0f-(level-m_groundSpot[i].min)/m_groundSpot[i].smooth; - } - if ( intensity < 0.0f ) intensity = 0.0f; - - color.r = m_groundSpot[i].color.r+intensity; - color.g = m_groundSpot[i].color.g+intensity; - color.b = m_groundSpot[i].color.b+intensity; - - AddDot(&ddsd, ix, iy, color); - } - } - } - } - - if ( bSet ) - { - dot = (int)(m_groundMark.radius/2.0f); - - tu = (m_groundMark.pos.x+1600.0f)/3200.0f; - tv = (m_groundMark.pos.z+1600.0f)/3200.0f; // 0..1 - - cx = (tu*254.0f*4.0f)-0.5f; - cy = (tv*254.0f*4.0f)-0.5f; - - if ( dot == 0 ) - { - cx += 0.5f; - cy += 0.5f; - } - - px = cx-Mod(cx, 1.0f); - py = cy-Mod(cy, 1.0f); // multiple of 1 - - for ( iy=-dot ; iy<=dot ; iy++ ) - { - for ( ix=-dot ; ix<=dot ; ix++ ) - { - ppx = px+ix; - ppy = py+iy; - - if ( ppx < min.x || ppy < min.y || - ppx >= max.x || ppy >= max.y ) continue; - - ppx -= min.x; // on the texture - ppy -= min.y; - - intensity = 1.0f-Length((float)ix, (float)iy)/dot; - if ( intensity <= 0.0f ) continue; - intensity *= m_groundMark.intensity; - - j = (ix+dot) + (iy+dot)*m_groundMark.dx; - if ( m_groundMark.table[j] == 1 ) // green ? - { - color.r = 1.0f-intensity; - color.g = 1.0f; - color.b = 1.0f-intensity; - AddDot(&ddsd, (int)ppx, (int)ppy, color); - } - if ( m_groundMark.table[j] == 2 ) // red ? - { - color.r = 1.0f; - color.g = 1.0f-intensity; - color.b = 1.0f-intensity; - AddDot(&ddsd, (int)ppx, (int)ppy, color); - } - } - } - } - - surface->Unlock(NULL); - } - } - - for ( i=0 ; iSetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE); - - D3DUtil_SetIdentityMatrix(matrix); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); - - ZeroMemory( &material, sizeof(D3DMATERIAL7) ); - material.diffuse.r = 1.0f; - material.diffuse.g = 1.0f; - material.diffuse.b = 1.0f; // white - material.ambient.r = 0.5f; - material.ambient.g = 0.5f; - material.ambient.b = 0.5f; - SetMaterial(material); - -#if _POLISH - SetTexture("textp.tga"); -#else - SetTexture("text.tga"); -#endif - - dp = 0.5f/256.0f; - ts.y = 192.0f/256.0f; - ti.y = 224.0f/256.0f; - ts.y += dp; - ti.y -= dp; - - n = D3DVECTOR(0.0f, 1.0f, 0.0f); - - startDeepView = m_deepView[m_rankView]*m_fogStart[m_rankView]; - endDeepView = m_deepView[m_rankView]; - - lastIntensity = -1.0f; - for ( i=0 ; i pos.y ) // camera on? - { - height = m_eyePt.y-pos.y; - h = m_shadow[i].radius; - max = height*0.5f; - if ( h > max ) h = max; - if ( h > 4.0f ) h = 4.0f; - - D = Length(m_eyePt, pos); - if ( D >= endDeepView ) continue; - d = D*h/height; - - pos.x += (m_eyePt.x-pos.x)*d/D; - pos.z += (m_eyePt.z-pos.z)*d/D; - pos.y += h; - } - else // camera underneath? - { - height = pos.y-m_eyePt.y; - h = m_shadow[i].radius; - max = height*0.1f; - if ( h > max ) h = max; - if ( h > 4.0f ) h = 4.0f; - - D = Length(m_eyePt, pos); - if ( D >= endDeepView ) continue; - d = D*h/height; - - pos.x += (m_eyePt.x-pos.x)*d/D; - pos.z += (m_eyePt.z-pos.z)*d/D; - pos.y -= h; - } - - // The hFactor decreases the intensity and size increases more - // the object is high relative to the ground. - hFactor = m_shadow[i].height/20.0f; - if ( hFactor < 0.0f ) hFactor = 0.0f; - if ( hFactor > 1.0f ) hFactor = 1.0f; - hFactor = powf(1.0f-hFactor, 2.0f); - if ( hFactor < 0.2f ) hFactor = 0.2f; - - radius = m_shadow[i].radius*1.5f; - radius *= 2.0f-hFactor; // greater if high - radius *= 1.0f-d/D; // smaller if close - - if ( m_shadow[i].type == D3DSHADOWNORM ) - { - corner[0].x = +radius; - corner[0].z = +radius; - corner[0].y = 0.0f; - - corner[1].x = -radius; - corner[1].z = +radius; - corner[1].y = 0.0f; - - corner[2].x = +radius; - corner[2].z = -radius; - corner[2].y = 0.0f; - - corner[3].x = -radius; - corner[3].z = -radius; - corner[3].y = 0.0f; - - ts.x = 64.0f/256.0f; - ti.x = 96.0f/256.0f; - } - else - { - rot = RotatePoint(-m_shadow[i].angle, FPOINT(radius, radius)); - corner[0].x = rot.x; - corner[0].z = rot.y; - corner[0].y = 0.0f; - - rot = RotatePoint(-m_shadow[i].angle, FPOINT(-radius, radius)); - corner[1].x = rot.x; - corner[1].z = rot.y; - corner[1].y = 0.0f; - - rot = RotatePoint(-m_shadow[i].angle, FPOINT(radius, -radius)); - corner[2].x = rot.x; - corner[2].z = rot.y; - corner[2].y = 0.0f; - - rot = RotatePoint(-m_shadow[i].angle, FPOINT(-radius, -radius)); - corner[3].x = rot.x; - corner[3].z = rot.y; - corner[3].y = 0.0f; - - if ( m_shadow[i].type == D3DSHADOWWORM ) - { - ts.x = 96.0f/256.0f; - ti.x = 128.0f/256.0f; - } - else - { - ts.x = 64.0f/256.0f; - ti.x = 96.0f/256.0f; - } - } - - corner[0] = Cross(corner[0], m_shadow[i].normal); - corner[1] = Cross(corner[1], m_shadow[i].normal); - corner[2] = Cross(corner[2], m_shadow[i].normal); - corner[3] = Cross(corner[3], m_shadow[i].normal); - - corner[0] += pos; - corner[1] += pos; - corner[2] += pos; - corner[3] += pos; - - ts.x += dp; - ti.x -= dp; - - vertex[0] = D3DVERTEX2(corner[1], n, ts.x, ts.y); - vertex[1] = D3DVERTEX2(corner[0], n, ti.x, ts.y); - vertex[2] = D3DVERTEX2(corner[3], n, ts.x, ti.y); - vertex[3] = D3DVERTEX2(corner[2], n, ti.x, ti.y); - - intensity = (0.5f+m_shadow[i].intensity*0.5f)*hFactor; - - // Decreases the intensity of the shade if you're in the area - // between the beginning and the end of the fog. - if ( D > startDeepView ) - { - intensity *= 1.0f-(D-startDeepView)/(endDeepView-startDeepView); - } - - // Decreases if the intensity is almost horizontal - // with shade (shade very platte). -//? if ( height < 4.0f ) intensity *= height/4.0f; - - if ( intensity == 0.0f ) continue; - - if ( lastIntensity != intensity ) // intensity changed? - { - lastIntensity = intensity; - SetState(D3DSTATETTw, RetColor(intensity)); - } - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - AddStatisticTriangle(2); - } - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE); -} - - -// Called ounces per frame, the call is the entry point for 3d rendering. -// This function sets up render states, clears the -// viewport, and renders the scene. - -HRESULT CD3DEngine::Render() -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - D3DVERTEX2* pv; - int l1, l2, l3, l4, l5, objRank, tState; - CInterface* pInterface; - BOOL bTransparent; - D3DCOLOR color, tColor; - - if ( !m_bRender ) return S_OK; - - m_statisticTriangle = 0; - m_lastState = -1; - m_lastColor = 999; - m_lastTexture[0][0] = 0; - m_lastTexture[1][0] = 0; - ZeroMemory(&m_lastMaterial, sizeof(D3DMATERIAL7)); - - if ( m_bGroundSpot ) - { - RenderGroundSpot(); - } - - // Clear the viewport - if ( m_bSkyMode && m_cloud->RetLevel() != 0.0f ) // clouds? - { - color = m_backgroundCloudDown; - } - else - { - color = m_backgroundColorDown; - } - m_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, - color, 1.0f, 0L ); - - m_light->LightUpdate(); - - // Begin the scene - if( FAILED( m_pD3DDevice->BeginScene() ) ) return S_OK; - - if ( m_bDrawWorld ) - { - DrawBackground(); // draws the background - if ( m_bPlanetMode ) DrawPlanet(); // draws the planets - if ( m_bSkyMode ) m_cloud->Draw(); // draws the clouds - - // Display the objects - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZBIAS, F2DW(16)); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProj); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE); - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, m_fogColor[m_rankView]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_LINEAR); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGSTART, F2DW(m_deepView[m_rankView]*m_fogStart[m_rankView])); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGEND, F2DW(m_deepView[m_rankView])); - - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matView); - - if ( m_bWaterMode ) m_water->DrawBack(); // draws water - - if ( m_bShadow ) - { - // Draw the field. - p1 = m_objectPointer; - for ( l1=0 ; l1totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - SetTexture(p2->texName1, 0); - SetTexture(p2->texName2, 1); - for ( l2=0 ; l2totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - objRank = p3->objRank; - if ( m_objectParam[objRank].type != TYPETERRAIN ) continue; - if ( !m_objectParam[objRank].bDrawWorld ) continue; - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, - &m_objectParam[objRank].transform); - if ( !IsVisible(objRank) ) continue; - m_light->LightUpdate(m_objectParam[objRank].type); - for ( l3=0 ; l3totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( m_objectParam[objRank].distance < p4->min || - m_objectParam[objRank].distance >= p4->max ) continue; - for ( l4=0 ; l4totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - SetMaterial(p6->material); - SetState(p6->state); - if ( p6->type == D3DTYPE6T ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed/3; - } - if ( p6->type == D3DTYPE6S ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed-2; - } - } - } - } - } - } - - DrawShadow(); // draws the shadows - } - - // Draw objects. - bTransparent = FALSE; - p1 = m_objectPointer; - for ( l1=0 ; l1totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - SetTexture(p2->texName1, 0); - SetTexture(p2->texName2, 1); - for ( l2=0 ; l2totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - objRank = p3->objRank; - if ( m_bShadow && m_objectParam[objRank].type == TYPETERRAIN ) continue; - if ( !m_objectParam[objRank].bDrawWorld ) continue; - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, - &m_objectParam[objRank].transform); - if ( !IsVisible(objRank) ) continue; - m_light->LightUpdate(m_objectParam[objRank].type); - for ( l3=0 ; l3totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( m_objectParam[objRank].distance < p4->min || - m_objectParam[objRank].distance >= p4->max ) continue; - for ( l4=0 ; l4totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - SetMaterial(p6->material); - if ( m_objectParam[objRank].transparency != 0.0f ) // transparent ? - { - bTransparent = TRUE; - continue; - } - SetState(p6->state); - if ( p6->type == D3DTYPE6T ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed/3; - } - if ( p6->type == D3DTYPE6S ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed-2; - } - } - } - } - } - } - - if ( bTransparent ) - { - if ( m_bStateColor ) - { - tState = D3DSTATETTb|D3DSTATE2FACE; - tColor = 0x44444444; - } - else - { - tState = D3DSTATETTb; - tColor = 0x88888888; - } - - // Draw transparent objects. - p1 = m_objectPointer; - for ( l1=0 ; l1totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - SetTexture(p2->texName1, 0); - SetTexture(p2->texName2, 1); - for ( l2=0 ; l2totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - objRank = p3->objRank; - if ( m_bShadow && m_objectParam[objRank].type == TYPETERRAIN ) continue; - if ( !m_objectParam[objRank].bDrawWorld ) continue; - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, - &m_objectParam[objRank].transform); - if ( !IsVisible(objRank) ) continue; - m_light->LightUpdate(m_objectParam[objRank].type); - for ( l3=0 ; l3totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( m_objectParam[objRank].distance < p4->min || - m_objectParam[objRank].distance >= p4->max ) continue; - for ( l4=0 ; l4totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - SetMaterial(p6->material); - if ( m_objectParam[objRank].transparency == 0.0f ) continue; - SetState(tState, tColor); - if ( p6->type == D3DTYPE6T ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed/3; - } - if ( p6->type == D3DTYPE6S ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed-2; - } - } - } - } - } - } - } - - m_light->LightUpdate(TYPETERRAIN); - if ( m_bWaterMode ) m_water->DrawSurf(); // draws water -//? m_cloud->Draw(); // draws the clouds - - m_particule->DrawParticule(SH_WORLD); // draws the particles of the 3D world - m_blitz->Draw(); // draws lightning - if ( m_bLensMode ) DrawFrontsize(); // draws the foreground - if ( !m_bOverFront ) DrawOverColor(); // draws the foreground color - } - - // Draw the user interface over the scene. - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); - - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matViewInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProjInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matWorldInterface); - - pInterface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - if ( pInterface != 0 ) - { - pInterface->Draw(); // draws the entire interface - } - m_particule->DrawParticule(SH_INTERFACE); // draws the particles of the interface - - if ( m_bDrawFront ) - { - // Display the objects - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZBIAS, F2DW(16)); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProj); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, m_ambiantColor[m_rankView]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE); - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, m_fogColor[m_rankView]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_LINEAR); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGSTART, F2DW(m_deepView[m_rankView]*m_fogStart[m_rankView])); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGEND, F2DW(m_deepView[m_rankView])); - - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matView); - - p1 = m_objectPointer; - for ( l1=0 ; l1totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - SetTexture(p2->texName1, 0); - SetTexture(p2->texName2, 1); - for ( l2=0 ; l2totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - objRank = p3->objRank; - if ( !m_objectParam[objRank].bDrawFront ) continue; - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, - &m_objectParam[objRank].transform); - if ( !IsVisible(objRank) ) continue; - m_light->LightUpdate(m_objectParam[objRank].type); - for ( l3=0 ; l3totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( m_objectParam[objRank].distance < p4->min || - m_objectParam[objRank].distance >= p4->max ) continue; - for ( l4=0 ; l4totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - SetMaterial(p6->material); - SetState(p6->state); - if ( p6->type == D3DTYPE6T ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed/3; - } - if ( p6->type == D3DTYPE6S ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed-2; - } - } - } - } - } - } - - m_particule->DrawParticule(SH_FRONT); // draws the particles of the 3D world - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); - - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matViewInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProjInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matWorldInterface); - } - - if ( m_bOverFront ) DrawOverColor(); // draws the foreground color - - if ( m_mouseType != D3DMOUSEHIDE ) - { - DrawMouse(); - } - - // End the scene. - m_pD3DDevice->EndScene(); - - DrawHilite(); - return S_OK; -} - - -// Draw the gradient background. - -void CD3DEngine::DrawBackground() -{ - if ( m_bSkyMode && m_cloud->RetLevel() != 0.0f ) // clouds ? - { - if ( m_backgroundCloudUp != m_backgroundCloudDown ) // degraded? - { - DrawBackgroundGradient(m_backgroundCloudUp, m_backgroundCloudDown); - } - } - else - { - if ( m_backgroundColorUp != m_backgroundColorDown ) // degraded? - { - DrawBackgroundGradient(m_backgroundColorUp, m_backgroundColorDown); - } - } - - if ( m_bBackForce || (m_bSkyMode && m_backgroundName[0] != 0) ) - { - DrawBackgroundImage(); // image - } -} - -// Draw the gradient background. - -void CD3DEngine::DrawBackgroundGradient(D3DCOLOR up, D3DCOLOR down) -{ - D3DLVERTEX vertex[4]; // 2 triangles - D3DCOLOR color[3]; - FPOINT p1, p2; - - p1.x = 0.0f; - p1.y = 0.5f; - p2.x = 1.0f; - p2.y = 1.0f; - - color[0] = up; - color[1] = down; - color[2] = 0x00000000; - -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); - - SetTexture("xxx.tga"); // no texture - SetState(D3DSTATENORMAL); - - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matViewInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProjInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matWorldInterface); - - vertex[0] = D3DLVERTEX(D3DVECTOR(p1.x, p1.y, 0.0f), color[1],color[2], 0.0f,0.0f); - vertex[1] = D3DLVERTEX(D3DVECTOR(p1.x, p2.y, 0.0f), color[0],color[2], 0.0f,0.0f); - vertex[2] = D3DLVERTEX(D3DVECTOR(p2.x, p1.y, 0.0f), color[1],color[2], 0.0f,0.0f); - vertex[3] = D3DLVERTEX(D3DVECTOR(p2.x, p2.y, 0.0f), color[0],color[2], 0.0f,0.0f); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, vertex, 4, NULL); - AddStatisticTriangle(2); -} - -// Draws a portion of the image background. - -void CD3DEngine::DrawBackgroundImageQuarter(FPOINT p1, FPOINT p2, char *name) -{ - D3DVERTEX2 vertex[4]; // 2 triangles - D3DVECTOR n; - float u1, u2, v1, v2, h, a; - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal - - if ( m_bBackgroundFull ) - { - u1 = 0.0f; - v1 = 0.0f; - u2 = 1.0f; - v2 = 1.0f; - - if ( m_bBackgroundQuarter ) - { - u1 += 0.5f/512.0f; - v1 += 0.5f/384.0f; - u2 -= 0.5f/512.0f; - v2 -= 0.5f/384.0f; - } - } - else - { - h = 0.5f; // visible area vertically (1=all) - a = m_eyeDirV-PI*0.15f; - if ( a > PI ) a -= PI*2.0f; // a = -PI..PI - if ( a > PI/4.0f ) a = PI/4.0f; - if ( a < -PI/4.0f ) a = -PI/4.0f; - - u1 = -m_eyeDirH/PI; - u2 = u1+1.0f/PI; -//? u1 = -m_eyeDirH/(PI*2.0f); -//? u2 = u1+1.0f/(PI*2.0f); - - v1 = (1.0f-h)*(0.5f+a/(2.0f*PI/4.0f))+0.1f; - v2 = v1+h; - } - -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); - - SetTexture(name); - SetState(D3DSTATEWRAP); - - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matViewInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProjInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matWorldInterface); - - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); - vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); - vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - AddStatisticTriangle(2); -} - -// Draws the image background. - -void CD3DEngine::DrawBackgroundImage() -{ - FPOINT p1, p2; - char name[50]; - - if ( m_bBackgroundQuarter ) - { - p1.x = 0.0f; - p1.y = 0.5f; - p2.x = 0.5f; - p2.y = 1.0f; - QuarterName(name, m_backgroundName, 0); - DrawBackgroundImageQuarter(p1, p2, name); - - p1.x = 0.5f; - p1.y = 0.5f; - p2.x = 1.0f; - p2.y = 1.0f; - QuarterName(name, m_backgroundName, 1); - DrawBackgroundImageQuarter(p1, p2, name); - - p1.x = 0.0f; - p1.y = 0.0f; - p2.x = 0.5f; - p2.y = 0.5f; - QuarterName(name, m_backgroundName, 2); - DrawBackgroundImageQuarter(p1, p2, name); - - p1.x = 0.5f; - p1.y = 0.0f; - p2.x = 1.0f; - p2.y = 0.5f; - QuarterName(name, m_backgroundName, 3); - DrawBackgroundImageQuarter(p1, p2, name); - } - else - { - p1.x = 0.0f; - p1.y = 0.0f; - p2.x = 1.0f; - p2.y = 1.0f; - DrawBackgroundImageQuarter(p1, p2, m_backgroundName); - } -} - -// Draws all the planets. - -void CD3DEngine::DrawPlanet() -{ - if ( !m_planet->PlanetExist() ) return; - -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); - - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matViewInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProjInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matWorldInterface); - - m_planet->Draw(); // draws the planets -} - -// Draws the image foreground. - -void CD3DEngine::DrawFrontsize() -{ - D3DVERTEX2 vertex[4]; // 2 triangles - D3DVECTOR n; - FPOINT p1, p2; - float u1, u2, v1, v2; - - if ( m_frontsizeName[0] == 0 ) return; - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal - - p1.x = 0.0f; - p1.y = 0.0f; - p2.x = 1.0f; - p2.y = 1.0f; - - u1 = -m_eyeDirH/(PI*0.6f)+PI*0.5f; - u2 = u1+0.50f; - - v1 = 0.2f; - v2 = 1.0f; - -#if 0 - char s[100]; - sprintf(s, "h=%.2f v=%.2f u=%.2f;%.2f v=%.2f;%.2f", m_eyeDirH, m_eyeDirV, u1, u2, v1, v2); - SetInfoText(3, s); -#endif - - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); - vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); - vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); - -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); - - SetTexture(m_frontsizeName); - SetState(D3DSTATECLAMP|D3DSTATETTb); - - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matViewInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProjInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matWorldInterface); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - AddStatisticTriangle(2); -} - -// Draws the foreground color. - -void CD3DEngine::DrawOverColor() -{ - D3DLVERTEX vertex[4]; // 2 triangles - D3DCOLOR color[3]; - FPOINT p1, p2; - - if ( !m_bStateColor ) return; - if ( (m_overColor == 0x00000000 && m_overMode == D3DSTATETCb) || - (m_overColor == 0xffffffff && m_overMode == D3DSTATETCw) ) return; - - p1.x = 0.0f; - p1.y = 0.0f; - p2.x = 1.0f; - p2.y = 1.0f; - - color[0] = m_overColor; - color[1] = m_overColor; - color[2] = 0x00000000; - -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); - - SetTexture("xxx.tga"); // no texture - SetState(m_overMode); - - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matViewInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProjInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matWorldInterface); - - vertex[0] = D3DLVERTEX(D3DVECTOR(p1.x, p1.y, 0.0f), color[1],color[2], 0.0f,0.0f); - vertex[1] = D3DLVERTEX(D3DVECTOR(p1.x, p2.y, 0.0f), color[0],color[2], 0.0f,0.0f); - vertex[2] = D3DLVERTEX(D3DVECTOR(p2.x, p1.y, 0.0f), color[1],color[2], 0.0f,0.0f); - vertex[3] = D3DLVERTEX(D3DVECTOR(p2.x, p2.y, 0.0f), color[0],color[2], 0.0f,0.0f); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, vertex, 4, NULL); - AddStatisticTriangle(2); -} - - -// Lists the ranks of objects and subobjects selected. - -void CD3DEngine::SetHiliteRank(int *rankList) -{ - int i; - - i = 0; - while ( *rankList != -1 ) - { - m_hiliteRank[i++] = *rankList++; - } - m_hiliteRank[i] = -1; // terminator -} - -// Give the box in the 2D screen of any object. - -BOOL CD3DEngine::GetBBox2D(int objRank, FPOINT &min, FPOINT &max) -{ - D3DVECTOR p, pp; - int i; - - min.x = 1000000.0f; - min.y = 1000000.0f; - max.x = -1000000.0f; - max.y = -1000000.0f; - - for ( i=0 ; i<8 ; i++ ) - { - if ( i & (1<<0) ) p.x = m_objectParam[objRank].bboxMin.x; - else p.x = m_objectParam[objRank].bboxMax.x; - if ( i & (1<<1) ) p.y = m_objectParam[objRank].bboxMin.y; - else p.y = m_objectParam[objRank].bboxMax.y; - if ( i & (1<<2) ) p.z = m_objectParam[objRank].bboxMin.z; - else p.z = m_objectParam[objRank].bboxMax.z; - if ( TransformPoint(pp, objRank, p) ) - { - if ( pp.x < min.x ) min.x = pp.x; - if ( pp.x > max.x ) max.x = pp.x; - if ( pp.y < min.y ) min.y = pp.y; - if ( pp.y > max.y ) max.y = pp.y; - } - } - - if ( min.x == 1000000.0f || - min.y == 1000000.0f || - max.x == -1000000.0f || - max.y == -1000000.0f ) return FALSE; - - return TRUE; -} - -// Determines the rectangle of the object highlighted, which will be designed by CD3DApplication. - -void CD3DEngine::DrawHilite() -{ - FPOINT min, max, omin, omax; - int i; - - min.x = 1000000.0f; - min.y = 1000000.0f; - max.x = -1000000.0f; - max.y = -1000000.0f; - - i = 0; - while ( m_hiliteRank[i] != -1 ) - { - if ( GetBBox2D(m_hiliteRank[i++], omin, omax) ) - { - min.x = Min(min.x, omin.x); - min.y = Min(min.y, omin.y); - max.x = Max(max.x, omax.x); - max.y = Max(max.y, omax.y); - } - } - - if ( min.x == 1000000.0f || - min.y == 1000000.0f || - max.x == -1000000.0f || - max.y == -1000000.0f ) - { - m_bHilite = FALSE; // not highlighted - } - else - { - m_hiliteP1 = min; - m_hiliteP2 = max; - m_bHilite = TRUE; - } -} - -// Give the rectangle highlighted by drawing CD3DApplication. - -BOOL CD3DEngine::GetHilite(FPOINT &p1, FPOINT &p2) -{ - p1 = m_hiliteP1; - p2 = m_hiliteP2; - return m_bHilite; -} - - -// Triangles adds qq records for statistics. - -void CD3DEngine::AddStatisticTriangle(int nb) -{ - m_statisticTriangle += nb; -} - -// Returns the number of triangles rendered. - -int CD3DEngine::RetStatisticTriangle() -{ - return m_statisticTriangle; -} - -BOOL CD3DEngine::GetSpriteCoord(int &x, int &y) -{ - D3DVIEWPORT7 vp; - D3DVECTOR v, vv; - - return FALSE; - //? - vv = D3DVECTOR(0.0f, 0.0f, 0.0f); - if ( !TransformPoint(v, 20*20+1, vv) ) return FALSE; - - m_pD3DDevice->GetViewport(&vp); - v.x *= vp.dwWidth/2; - v.y *= vp.dwHeight/2; - v.x = v.x+vp.dwWidth/2; - v.y = vp.dwHeight-(v.y+vp.dwHeight/2); - - x = (int)v.x; - y = (int)v.y; - return TRUE; -} - - -// Tests whether to exclude a point. - -BOOL IsExcludeColor(FPOINT *pExclu, int x, int y) -{ - int i; - - i = 0; - while ( pExclu[i+0].x != 0.0f || pExclu[i+0].y != 0.0f || - pExclu[i+1].y != 0.0f || pExclu[i+1].y != 0.0f ) - { - if ( x >= (int)(pExclu[i+0].x*256.0f) && - x < (int)(pExclu[i+1].x*256.0f) && - y >= (int)(pExclu[i+0].y*256.0f) && - y < (int)(pExclu[i+1].y*256.0f) ) return TRUE; // exclude - - i += 2; - } - - return FALSE; // point to include -} - -// Change the color of a texture. - -BOOL CD3DEngine::ChangeColor(char *name, - D3DCOLORVALUE colorRef1, D3DCOLORVALUE colorNew1, - D3DCOLORVALUE colorRef2, D3DCOLORVALUE colorNew2, - float tolerance1, float tolerance2, - FPOINT ts, FPOINT ti, - FPOINT *pExclu, float shift, BOOL bHSV) -{ - LPDIRECTDRAWSURFACE7 surface; - DDSURFACEDESC2 ddsd; - D3DCOLORVALUE color; - ColorHSV cr1, cn1, cr2, cn2, c; - int dx, dy, x, y, sx, sy, ex, ey; - - D3DTextr_Invalidate(name); - LoadTexture(name); // reloads the initial texture - - if ( colorRef1.r == colorNew1.r && - colorRef1.g == colorNew1.g && - colorRef1.b == colorNew1.b && - colorRef2.r == colorNew2.r && - colorRef2.g == colorNew2.g && - colorRef2.b == colorNew2.b ) return TRUE; - - surface = D3DTextr_GetSurface(name); - if ( surface == 0 ) return FALSE; - - ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(DDSURFACEDESC2); - if ( surface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) != DD_OK ) return FALSE; - - dx = ddsd.dwWidth; - dy = ddsd.dwHeight; - - sx = (int)(ts.x*dx); - sy = (int)(ts.y*dy); - ex = (int)(ti.x*dx); - ey = (int)(ti.y*dy); - - RGB2HSV(colorRef1, cr1); - RGB2HSV(colorNew1, cn1); - RGB2HSV(colorRef2, cr2); - RGB2HSV(colorNew2, cn2); - - for ( y=sy ; y 0.01f && Abs(c.h-cr1.h) < tolerance1 ) - { - c.h += cn1.h-cr1.h; - c.s += cn1.s-cr1.s; - c.v += cn1.v-cr1.v; - if ( c.h < 0.0f ) c.h -= 1.0f; - if ( c.h > 1.0f ) c.h += 1.0f; - HSV2RGB(c, color); - color.r += shift; - color.g += shift; - color.b += shift; - ::SetDot(&ddsd, x, y, color); - } - else - if ( tolerance2 != -1.0f && - c.s > 0.01f && Abs(c.h-cr2.h) < tolerance2 ) - { - c.h += cn2.h-cr2.h; - c.s += cn2.s-cr2.s; - c.v += cn2.v-cr2.v; - if ( c.h < 0.0f ) c.h -= 1.0f; - if ( c.h > 1.0f ) c.h += 1.0f; - HSV2RGB(c, color); - color.r += shift; - color.g += shift; - color.b += shift; - ::SetDot(&ddsd, x, y, color); - } - } - else - { - if ( Abs(color.r-colorRef1.r)+ - Abs(color.g-colorRef1.g)+ - Abs(color.b-colorRef1.b) < tolerance1*3.0f ) - { - color.r = colorNew1.r+color.r-colorRef1.r+shift; - color.g = colorNew1.g+color.g-colorRef1.g+shift; - color.b = colorNew1.b+color.b-colorRef1.b+shift; - ::SetDot(&ddsd, x, y, color); - } - else - if ( tolerance2 != -1 && - Abs(color.r-colorRef2.r)+ - Abs(color.g-colorRef2.g)+ - Abs(color.b-colorRef2.b) < tolerance2*3.0f ) - { - color.r = colorNew2.r+color.r-colorRef2.r+shift; - color.g = colorNew2.g+color.g-colorRef2.g+shift; - color.b = colorNew2.b+color.b-colorRef2.b+shift; - ::SetDot(&ddsd, x, y, color); - } - } - } - } - - surface->Unlock(NULL); - return TRUE; -} - - -// Open an image to work directly in it. - -BOOL CD3DEngine::OpenImage(char *name) -{ -//? D3DTextr_Invalidate(name); -//? LoadTexture(name); - - m_imageSurface = D3DTextr_GetSurface(name); - if ( m_imageSurface == 0 ) return FALSE; - - ZeroMemory(&m_imageDDSD, sizeof(DDSURFACEDESC2)); - m_imageDDSD.dwSize = sizeof(DDSURFACEDESC2); - if ( m_imageSurface->Lock(NULL, &m_imageDDSD, DDLOCK_WAIT, NULL) != DD_OK ) - { - return FALSE; - } - - if ( m_imageDDSD.ddpfPixelFormat.dwRGBBitCount != 16 ) - { - m_imageSurface->Unlock(NULL); - return FALSE; - } - - m_imageDX = m_imageDDSD.dwWidth; - m_imageDY = m_imageDDSD.dwHeight; - - return TRUE; -} - -// Copy the working image. - -BOOL CD3DEngine::CopyImage() -{ - WORD* pbSurf; - int y; - - if ( m_imageCopy == 0 ) - { - m_imageCopy = (WORD*)malloc(m_imageDX*m_imageDY*sizeof(WORD)); - } - - for ( y=0 ; y 0 ) - { - for ( y=0 ; y=-dx ; x-- ) - { - m_imageCopy[x+y*m_imageDX] = m_imageCopy[x+dx+y*m_imageDX]; - } - } - } - - if ( dy > 0 ) - { - for ( y=0 ; y=-dy ; y-- ) - { - memcpy(m_imageCopy+y*m_imageDX, m_imageCopy+(y+dy)*m_imageDX, m_imageDX*sizeof(WORD)); - } - } - - return TRUE; -} - -// Draws a point in the image work. - -BOOL CD3DEngine::SetDot(int x, int y, D3DCOLORVALUE color) -{ - WORD* pbSurf; - WORD r,g,b, w; - - if ( x < 0 || x >= m_imageDX || - y < 0 || y >= m_imageDY ) return FALSE; - -#if 1 - if ( color.r < 0.0f ) color.r = 0.0f; - if ( color.r > 1.0f ) color.r = 1.0f; - if ( color.g < 0.0f ) color.g = 0.0f; - if ( color.g > 1.0f ) color.g = 1.0f; - if ( color.b < 0.0f ) color.b = 0.0f; - if ( color.b > 1.0f ) color.b = 1.0f; - - r = (int)(color.r*32.0f); - g = (int)(color.g*32.0f); - b = (int)(color.b*32.0f); - - if ( r >= 32 ) r = 31; // 5 bits - if ( g >= 32 ) g = 31; // 5 bits - if ( b >= 32 ) b = 31; // 5 bits -#else - r = (int)(color.r*31.0f); - g = (int)(color.g*31.0f); - b = (int)(color.b*31.0f); -#endif - - if ( m_imageDDSD.ddpfPixelFormat.dwRBitMask == 0xf800 ) // 565 ? - { - w = (r<<11)|(g<<6)|b; - } - else if ( m_imageDDSD.ddpfPixelFormat.dwRBitMask == 0x7c00 ) // 555 ? - { - w = (r<<10)|(g<<5)|b; - } - else - { - w = -1; // blank - } - - pbSurf = (WORD*)m_imageDDSD.lpSurface; - pbSurf += m_imageDDSD.lPitch*y/2; - pbSurf += x; - - *pbSurf = w; - return TRUE; -} - -// Closes the working image. - -BOOL CD3DEngine::CloseImage() -{ - m_imageSurface->Unlock(NULL); - return TRUE; -} - - -// Writes a .BMP screenshot. - -BOOL CD3DEngine::WriteScreenShot(char *filename, int width, int height) -{ - return m_app->WriteScreenShot(filename, width, height); -} - -// Initializes an hDC on the rendering surface. - -BOOL CD3DEngine::GetRenderDC(HDC &hDC) -{ - return m_app->GetRenderDC(hDC); -} - -// Frees the hDC of the rendering surface. - -BOOL CD3DEngine::ReleaseRenderDC(HDC &hDC) -{ - return m_app->ReleaseRenderDC(hDC); -} - -PBITMAPINFO CD3DEngine::CreateBitmapInfoStruct(HBITMAP hBmp) -{ - return m_app->CreateBitmapInfoStruct(hBmp); -} - -BOOL CD3DEngine::CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC) -{ - return m_app->CreateBMPFile(pszFile, pbi, hBMP, hDC); -} - -// Returns the pointer to the class cText. - -CText* CD3DEngine::RetText() -{ - return m_text; -} - - -// Managing of information text displayed in the window. - -void CD3DEngine::SetInfoText(int line, char* text) -{ - strcpy(m_infoText[line], text); -} - -char* CD3DEngine::RetInfoText(int line) -{ - return m_infoText[line]; -} - - - -// Specifies the length of the camera. -// 0.75 = normal -// 1.50 = wide-angle - -void CD3DEngine::SetFocus(float focus) -{ - D3DVIEWPORT7 vp; - float fAspect; - - m_focus = focus; - - if ( m_pD3DDevice != 0 ) - { - m_pD3DDevice->GetViewport(&vp); - m_dim.x = vp.dwWidth; - m_dim.y = vp.dwHeight; - } - - fAspect = ((float)m_dim.y) / m_dim.x; -//? D3DUtil_SetProjectionMatrix(m_matProj, m_focus, fAspect, 0.5f, m_deepView[m_rankView]); - D3DUtil_SetProjectionMatrix(m_matProj, m_focus, fAspect, 0.5f, m_deepView[0]); -} - -float CD3DEngine::RetFocus() -{ - return m_focus; -} - -// - -void CD3DEngine::UpdateMatProj() -{ - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProj); -} - - - -// Ignores key presses. - -void CD3DEngine::FlushPressKey() -{ - m_app->FlushPressKey(); -} - -// Resets the default keys. - -void CD3DEngine::ResetKey() -{ - m_app->ResetKey(); -} - -// Modifies a button. - -void CD3DEngine::SetKey(int keyRank, int option, int key) -{ - m_app->SetKey(keyRank, option, key); -} - -// Gives a key. - -int CD3DEngine::RetKey(int keyRank, int option) -{ - return m_app->RetKey(keyRank, option); -} - - -// Use the joystick or keyboard. - -void CD3DEngine::SetJoystick(BOOL bEnable) -{ - m_app->SetJoystick(bEnable); -} - -BOOL CD3DEngine::RetJoystick() -{ - return m_app->RetJoystick(); -} - - -void CD3DEngine::SetDebugMode(BOOL bMode) -{ - m_app->SetDebugMode(bMode); -} - -BOOL CD3DEngine::RetDebugMode() -{ - return m_app->RetDebugMode(); -} - -BOOL CD3DEngine::RetSetupMode() -{ - return m_app->RetSetupMode(); -} - - -// Indicates whether a point is visible. - -BOOL CD3DEngine::IsVisiblePoint(const D3DVECTOR &pos) -{ - return ( Length(m_eyePt, pos) <= m_deepView[0] ); -} - - -// Initialize scene objects. - -HRESULT CD3DEngine::InitDeviceObjects() -{ - // Set miscellaneous render states. - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SHADEMODE, D3DSHADE_GOURAUD); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID); - - // Set up the textures. - D3DTextr_RestoreAllTextures(m_pD3DDevice); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_LINEAR); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTFN_LINEAR); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTFG_LINEAR); - - SetFocus(m_focus); - - // Definitions of the matrices for the interface. - D3DUtil_SetIdentityMatrix(m_matWorldInterface); - - D3DUtil_SetIdentityMatrix(m_matViewInterface); - m_matViewInterface._41 = -0.5f; - m_matViewInterface._42 = -0.5f; - m_matViewInterface._43 = 1.0f; - - D3DUtil_SetIdentityMatrix(m_matProjInterface); - m_matProjInterface._11 = 2.0f; - m_matProjInterface._22 = 2.0f; - m_matProjInterface._34 = 1.0f; - m_matProjInterface._43 = -1.0f; - m_matProjInterface._44 = 0.0f; - - return S_OK; -} - - -// Restore all surfaces. - -HRESULT CD3DEngine::RestoreSurfaces() -{ - return S_OK; -} - - -// Called when the app is exitting, or the device is being changed, -// this function deletes any device dependant objects. - -HRESULT CD3DEngine::DeleteDeviceObjects() -{ - D3DTextr_InvalidateAllTextures(); - return S_OK; -} - - -// Called before the app exits, this function gives the app the chance -// to cleanup after itself. - -HRESULT CD3DEngine::FinalCleanup() -{ - return S_OK; -} - - -// Overrrides the main WndProc, so the sample can do custom message -// handling (e.g. processing mouse, keyboard, or menu commands). - -LRESULT CD3DEngine::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) -{ -#if 0 - if ( uMsg == WM_KEYDOWN ) // Alt+key ? - { - if ( wParam == 'Q' ) - { - debug_blend1 ++; - if ( debug_blend1 > 13 ) debug_blend1 = 0; - } - if ( wParam == 'W' ) - { - debug_blend2 ++; - if ( debug_blend2 > 13 ) debug_blend2 = 0; - } - if ( wParam == 'E' ) - { - debug_blend3 ++; - if ( debug_blend3 > 13 ) debug_blend3 = 0; - } - if ( wParam == 'R' ) - { - debug_blend4 ++; - if ( debug_blend4 > 13 ) debug_blend4 = 0; - } - char s[100]; - sprintf(s, "src=%d, dest=%d, src=%d, dest=%d", debug_blend1, debug_blend2, debug_blend3, debug_blend4); - SetInfoText(4, s); - } -#endif - -#if 1 - if ( uMsg == WM_SYSKEYDOWN ) // Alt+key ? - { - if ( wParam == VK_F7 ) // Alt+F7 ? - { - s_resol = 0; - } - if ( wParam == VK_F8 ) // Alt+F8 ? - { - s_resol = 1; - } - if ( wParam == VK_F9 ) // Alt+F9 ? - { - s_resol = 2; - } - if ( wParam == VK_F10 ) // Alt+F10 ? - { - s_resol = 3; - } - } -#endif - - return 0; -} - - -// Mouse control. - -void CD3DEngine::MoveMousePos(FPOINT pos) -{ - m_mousePos = pos; - m_app->SetMousePos(pos); -} - -void CD3DEngine::SetMousePos(FPOINT pos) -{ - m_mousePos = pos; -} - -FPOINT CD3DEngine::RetMousePos() -{ - return m_mousePos; -} - -void CD3DEngine::SetMouseType(D3DMouse type) -{ - m_mouseType = type; -} - -D3DMouse CD3DEngine::RetMouseType() -{ - return m_mouseType; -} - -void CD3DEngine::SetMouseHide(BOOL bHide) -{ - if ( m_bMouseHide == bHide ) return; - - if ( bHide ) // hide the mouse? - { - m_bNiceMouse = m_app->RetNiceMouse(); - if ( !m_bNiceMouse ) - { - m_app->SetNiceMouse(TRUE); - } - m_bMouseHide = TRUE; - } - else // shows the mouse? - { - if ( !m_bNiceMouse ) - { - m_app->SetNiceMouse(FALSE); - } - m_bMouseHide = FALSE; - } -} - -BOOL CD3DEngine::RetMouseHide() -{ - return m_bMouseHide; -} - -void CD3DEngine::SetNiceMouse(BOOL bNice) -{ - m_app->SetNiceMouse(bNice); -} - -BOOL CD3DEngine::RetNiceMouse() -{ - return m_app->RetNiceMouse(); -} - -BOOL CD3DEngine::RetNiceMouseCap() -{ - return m_app->RetNiceMouseCap(); -} - -// Draws the sprite of the mouse. - -void CD3DEngine::DrawMouse() -{ - D3DMATERIAL7 material; - FPOINT pos, ppos, dim; - int i; - - typedef struct - { - D3DMouse type; - int icon1, icon2, iconShadow; - int mode1, mode2; - float hotx, hoty; - } - Mouse; - - static Mouse table[] = - { - { D3DMOUSENORM, 0, 1,32, D3DSTATETTw, D3DSTATETTb, 1.0f, 1.0f}, - { D3DMOUSEWAIT, 2, 3,33, D3DSTATETTw, D3DSTATETTb, 8.0f, 12.0f}, - { D3DMOUSEHAND, 4, 5,34, D3DSTATETTw, D3DSTATETTb, 7.0f, 2.0f}, - { D3DMOUSENO, 6, 7,35, D3DSTATETTw, D3DSTATETTb, 10.0f, 10.0f}, - { D3DMOUSEEDIT, 8, 9,-1, D3DSTATETTb, D3DSTATETTw, 6.0f, 10.0f}, - { D3DMOUSECROSS, 10,11,-1, D3DSTATETTb, D3DSTATETTw, 10.0f, 10.0f}, - { D3DMOUSEMOVEV, 12,13,-1, D3DSTATETTb, D3DSTATETTw, 5.0f, 11.0f}, - { D3DMOUSEMOVEH, 14,15,-1, D3DSTATETTb, D3DSTATETTw, 11.0f, 5.0f}, - { D3DMOUSEMOVED, 16,17,-1, D3DSTATETTb, D3DSTATETTw, 9.0f, 9.0f}, - { D3DMOUSEMOVEI, 18,19,-1, D3DSTATETTb, D3DSTATETTw, 9.0f, 9.0f}, - { D3DMOUSEMOVE, 20,21,-1, D3DSTATETTb, D3DSTATETTw, 11.0f, 11.0f}, - { D3DMOUSETARGET, 22,23,-1, D3DSTATETTb, D3DSTATETTw, 15.0f, 15.0f}, - { D3DMOUSESCROLLL, 24,25,43, D3DSTATETTb, D3DSTATETTw, 2.0f, 9.0f}, - { D3DMOUSESCROLLR, 26,27,44, D3DSTATETTb, D3DSTATETTw, 17.0f, 9.0f}, - { D3DMOUSESCROLLU, 28,29,45, D3DSTATETTb, D3DSTATETTw, 9.0f, 2.0f}, - { D3DMOUSESCROLLD, 30,31,46, D3DSTATETTb, D3DSTATETTw, 9.0f, 17.0f}, - { D3DMOUSEHIDE }, - }; - - if ( m_bMouseHide ) return; - if ( !m_app->RetNiceMouse() ) return; // mouse windows? - - ZeroMemory( &material, sizeof(D3DMATERIAL7) ); - material.diffuse.r = 1.0f; - material.diffuse.g = 1.0f; - material.diffuse.b = 1.0f; - material.ambient.r = 0.5f; - material.ambient.g = 0.5f; - material.ambient.b = 0.5f; - SetMaterial(material); - - SetTexture("mouse.tga"); - - i = 0; - while ( table[i].type != D3DMOUSEHIDE ) - { - if ( m_mouseType == table[i].type ) - { - dim.x = 0.05f*0.75f; - dim.y = 0.05f; - - pos.x = m_mousePos.x - (table[i].hotx*dim.x)/32.0f; - pos.y = m_mousePos.y - ((32.0f-table[i].hoty)*dim.y)/32.0f; - - ppos.x = pos.x+(4.0f/640.0f); - ppos.y = pos.y-(3.0f/480.0f); - SetState(D3DSTATETTw); - DrawSprite(ppos, dim, table[i].iconShadow); - - SetState(table[i].mode1); - DrawSprite(pos, dim, table[i].icon1); - - SetState(table[i].mode2); - DrawSprite(pos, dim, table[i].icon2); - break; - } - i ++; - } -} - -// Draws the sprite of the mouse. - -void CD3DEngine::DrawSprite(FPOINT pos, FPOINT dim, int icon) -{ - D3DVERTEX2 vertex[4]; // 2 triangles - FPOINT p1, p2; - D3DVECTOR n; - float u1, u2, v1, v2, dp; - - if ( icon == -1 ) return; - - p1.x = pos.x; - p1.y = pos.y; - p2.x = pos.x + dim.x; - p2.y = pos.y + dim.y; - - u1 = (32.0f/256.0f)*(icon%8); - v1 = (32.0f/256.0f)*(icon/8); // u-v texture - u2 = (32.0f/256.0f)+u1; - v2 = (32.0f/256.0f)+v1; - - dp = 0.5f/256.0f; - u1 += dp; - v1 += dp; - u2 -= dp; - v2 -= dp; - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal - - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); - vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); - vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - AddStatisticTriangle(2); -} - diff --git a/src/d3dengine.h b/src/d3dengine.h deleted file mode 100644 index a99db93..0000000 --- a/src/d3dengine.h +++ /dev/null @@ -1,686 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// d3dengine.h - -#ifndef _D3DENGINE_H_ -#define _D3DENGINE_H_ - - -#include "struct.h" - - -class CD3DApplication; -class CInstanceManager; -class CObject; -class CLight; -class CText; -class CParticule; -class CWater; -class CCloud; -class CBlitz; -class CPlanet; -class CSound; -class CTerrain; - - -#define D3DMAXOBJECT 1200 -#define D3DMAXSHADOW 500 -#define D3DMAXGROUNDSPOT 100 - - -enum D3DTypeObj -{ - TYPENULL = 0, // object doesn't exist - TYPETERRAIN = 1, // terrain - TYPEFIX = 2, // fixed object - TYPEVEHICULE = 3, // moving object - TYPEDESCENDANT = 4, // part of a moving object - TYPEQUARTZ = 5, // fixed object type quartz - TYPEMETAL = 6, // fixed object type metal -}; - -enum D3DTypeTri -{ - D3DTYPE6T = 1, // triangles - D3DTYPE6S = 2, // surfaces -}; - -enum D3DMaping -{ - D3DMAPPINGX = 1, - D3DMAPPINGY = 2, - D3DMAPPINGZ = 3, - D3DMAPPING1X = 4, - D3DMAPPING1Y = 5, - D3DMAPPING1Z = 6, -}; - -enum D3DMouse -{ - D3DMOUSEHIDE = 0, // no mouse - D3DMOUSENORM = 1, - D3DMOUSEWAIT = 2, - D3DMOUSEEDIT = 3, - D3DMOUSEHAND = 4, - D3DMOUSECROSS = 5, - D3DMOUSESHOW = 6, - D3DMOUSENO = 7, - D3DMOUSEMOVE = 8, // + - D3DMOUSEMOVEH = 9, // - - D3DMOUSEMOVEV = 10, // | - D3DMOUSEMOVED = 11, // / - D3DMOUSEMOVEI = 12, // \ // - D3DMOUSESCROLLL = 13, // << - D3DMOUSESCROLLR = 14, // >> - D3DMOUSESCROLLU = 15, // ^ - D3DMOUSESCROLLD = 16, // v - D3DMOUSETARGET = 17, -}; - -enum D3DShadowType -{ - D3DSHADOWNORM = 0, - D3DSHADOWWORM = 1, -}; - - -#define D3DSTATENORMAL 0 // normal opaque materials -#define D3DSTATETTb (1<<0) // the transparent texture (black = no) -#define D3DSTATETTw (1<<1) // the transparent texture (white = no) -#define D3DSTATETD (1<<2) // the transparent diffuse color -#define D3DSTATEWRAP (1<<3) // texture wrappe -#define D3DSTATECLAMP (1<<4) // texture borders with solid color -#define D3DSTATELIGHT (1<<5) // light texture (ambient max) -#define D3DSTATEDUALb (1<<6) // double black texturing -#define D3DSTATEDUALw (1<<7) // double white texturing -#define D3DSTATEPART1 (1<<8) // part 1 (no change in. MOD!) -#define D3DSTATEPART2 (1<<9) // part 2 -#define D3DSTATEPART3 (1<<10) // part 3 -#define D3DSTATEPART4 (1<<11) // part 4 -#define D3DSTATE2FACE (1<<12) // double-sided face -#define D3DSTATEALPHA (1<<13) // image using alpha channel -#define D3DSTATESECOND (1<<14) // always use 2nd floor texturing -#define D3DSTATEFOG (1<<15) // causes the fog -#define D3DSTATETCb (1<<16) // the transparent color (black = no) -#define D3DSTATETCw (1<<17) // the transparent color (white = no) - - -typedef struct -{ - D3DVERTEX2 triangle[3]; - D3DMATERIAL7 material; - int state; - char texName1[20]; - char texName2[20]; -} -D3DTriangle; - - -typedef struct -{ - int totalPossible; - int totalUsed; - D3DMATERIAL7 material; - int state; - D3DTypeTri type; // D3DTYPE6x - D3DVERTEX2 vertex[1]; -} -D3DObjLevel6; - -typedef struct -{ - int totalPossible; - int totalUsed; - int reserve; - D3DObjLevel6* table[1]; -} -D3DObjLevel5; - -typedef struct -{ - int totalPossible; - int totalUsed; - float min, max; - D3DObjLevel5* table[1]; -} -D3DObjLevel4; - -typedef struct -{ - int totalPossible; - int totalUsed; - int objRank; - D3DObjLevel4* table[1]; -} -D3DObjLevel3; - -typedef struct -{ - int totalPossible; - int totalUsed; - char texName1[20]; - char texName2[20]; - D3DObjLevel3* table[1]; -} -D3DObjLevel2; - -typedef struct -{ - int totalPossible; - int totalUsed; - D3DObjLevel2* table[1]; -} -D3DObjLevel1; - - -typedef struct -{ - char bUsed; // TRUE -> object exists - char bVisible; // TRUE -> visible object - char bDrawWorld; // TRUE -> shape behind the interface - char bDrawFront; // TRUE -> shape before the interface - int totalTriangle; // number of triangles used - D3DTypeObj type; // type of the object (TYPE*) - D3DMATRIX transform; // transformation matrix - float distance; // distance point of view - original - D3DVECTOR bboxMin; // bounding box of the object - D3DVECTOR bboxMax; // (the origin 0, 0, 0 is always included) - float radius; // radius of the sphere at the origin - int shadowRank; // rank of the associated shadow - float transparency; // transparency of the object (0 .. 1) -} -D3DObject; - -typedef struct -{ - char bUsed; // TRUE -> object exists - char bHide; // TRUE -> invisible shadow (object carried by ex.) - int objRank; // rank of the object - D3DShadowType type; // type of shadow - D3DVECTOR pos; // position for the shadow - D3DVECTOR normal; // normal terrain - float angle; // angle of the shadow - float radius; // radius of the shadow - float intensity; // intensity of the shadow - float height; // height from the ground -} -D3DShadow; - -typedef struct -{ - char bUsed; // TRUE -> object exists - D3DCOLORVALUE color; // color of the shadow - float min, max; // altitudes min / max - float smooth; // transition area - D3DVECTOR pos; // position for the shadow - float radius; // radius of the shadow - D3DVECTOR drawPos; // drawn to position the shade - float drawRadius; // radius of the shadow drawn -} -D3DGroundSpot; - -typedef struct -{ - char bUsed; // TRUE -> object exists - char bDraw; // TRUE -> drawn mark - int phase; // 1 = increase, 2 = fixed, 3 = decrease - float delay[3]; // time for 3 phases - float fix; // fixed time - D3DVECTOR pos; // position for marks - float radius; // radius of marks - float intensity; // color intensity - D3DVECTOR drawPos; // drawn in position marks - float drawRadius; // radius marks drawn - float drawIntensity; // current drawn - int dx, dy; // dimensions table - char* table; // pointer to the table -} -D3DGroundMark; - - - -class CD3DEngine -{ -public: - CD3DEngine(CInstanceManager *iMan, CD3DApplication *app); - ~CD3DEngine(); - - void SetD3DDevice(LPDIRECT3DDEVICE7 device); - LPDIRECT3DDEVICE7 RetD3DDevice(); - - void SetTerrain(CTerrain* terrain); - - BOOL WriteProfile(); - - void SetPause(BOOL bPause); - BOOL RetPause(); - - void SetMovieLock(BOOL bLock); - BOOL RetMovieLock(); - - void SetShowStat(BOOL bShow); - BOOL RetShowStat(); - - void SetRenderEnable(BOOL bEnable); - - HRESULT OneTimeSceneInit(); - HRESULT InitDeviceObjects(); - HRESULT DeleteDeviceObjects(); - HRESULT RestoreSurfaces(); - HRESULT Render(); - HRESULT FrameMove(float rTime); - void StepSimul(float rTime); - HRESULT FinalCleanup(); - void AddStatisticTriangle(int nb); - int RetStatisticTriangle(); - void SetHiliteRank(int *rankList); - BOOL GetHilite(FPOINT &p1, FPOINT &p2); - BOOL GetSpriteCoord(int &x, int &y); - void SetInfoText(int line, char* text); - char* RetInfoText(int line); - LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - void FirstExecuteAdapt(BOOL bFirst); - int GetVidMemTotal(); - BOOL IsVideo8MB(); - BOOL IsVideo32MB(); - - BOOL EnumDevices(char *bufDevices, int lenDevices, char *bufModes, int lenModes, int &totalDevices, int &selectDevices, int &totalModes, int &selectModes); - BOOL RetFullScreen(); - BOOL ChangeDevice(char *device, char *mode, BOOL bFull); - - D3DMATRIX* RetMatView(); - D3DMATRIX* RetMatLeftView(); - D3DMATRIX* RetMatRightView(); - - void TimeInit(); - void TimeEnterGel(); - void TimeExitGel(); - float TimeGet(); - - int RetRestCreate(); - int CreateObject(); - void FlushObject(); - BOOL DeleteObject(int objRank); - BOOL SetDrawWorld(int objRank, BOOL bDraw); - BOOL SetDrawFront(int objRank, BOOL bDraw); - BOOL AddTriangle(int objRank, D3DVERTEX2* vertex, int nb, const D3DMATERIAL7 &mat, int state, char* texName1, char* texName2, float min, float max, BOOL bGlobalUpdate); - BOOL AddSurface(int objRank, D3DVERTEX2* vertex, int nb, const D3DMATERIAL7 &mat, int state, char* texName1, char* texName2, float min, float max, BOOL bGlobalUpdate); - BOOL AddQuick(int objRank, D3DObjLevel6* buffer, char* texName1, char* texName2, float min, float max, BOOL bGlobalUpdate); - D3DObjLevel6* SearchTriangle(int objRank, const D3DMATERIAL7 &mat, int state, char* texName1, char* texName2, float min, float max); - void ChangeLOD(); - BOOL ChangeSecondTexture(int objRank, char* texName2); - int RetTotalTriangles(int objRank); - int GetTriangles(int objRank, float min, float max, D3DTriangle* buffer, int size, float percent); - BOOL GetBBox(int objRank, D3DVECTOR &min, D3DVECTOR &max); - BOOL ChangeTextureMapping(int objRank, const D3DMATERIAL7 &mat, int state, char* texName1, char* texName2, float min, float max, D3DMaping mode, float au, float bu, float av, float bv); - BOOL TrackTextureMapping(int objRank, const D3DMATERIAL7 &mat, int state, char* texName1, char* texName2, float min, float max, D3DMaping mode, float pos, float factor, float tl, float ts, float tt); - BOOL SetObjectTransform(int objRank, const D3DMATRIX &transform); - BOOL GetObjectTransform(int objRank, D3DMATRIX &transform); - BOOL SetObjectType(int objRank, D3DTypeObj type); - D3DTypeObj RetObjectType(int objRank); - BOOL SetObjectTransparency(int objRank, float value); - - BOOL ShadowCreate(int objRank); - void ShadowDelete(int objRank); - BOOL SetObjectShadowHide(int objRank, BOOL bHide); - BOOL SetObjectShadowType(int objRank, D3DShadowType type); - BOOL SetObjectShadowPos(int objRank, const D3DVECTOR &pos); - BOOL SetObjectShadowNormal(int objRank, const D3DVECTOR &n); - BOOL SetObjectShadowAngle(int objRank, float angle); - BOOL SetObjectShadowRadius(int objRank, float radius); - BOOL SetObjectShadowIntensity(int objRank, float intensity); - BOOL SetObjectShadowHeight(int objRank, float h); - float RetObjectShadowRadius(int objRank); - - void GroundSpotFlush(); - int GroundSpotCreate(); - void GroundSpotDelete(int rank); - BOOL SetObjectGroundSpotPos(int rank, const D3DVECTOR &pos); - BOOL SetObjectGroundSpotRadius(int rank, float radius); - BOOL SetObjectGroundSpotColor(int rank, D3DCOLORVALUE color); - BOOL SetObjectGroundSpotMinMax(int rank, float min, float max); - BOOL SetObjectGroundSpotSmooth(int rank, float smooth); - - int GroundMarkCreate(D3DVECTOR pos, float radius, float delay1, float delay2, float delay3, int dx, int dy, char* table); - BOOL GroundMarkDelete(int rank); - - void Update(); - - void SetViewParams(const D3DVECTOR &vEyePt, const D3DVECTOR &vLookatPt, const D3DVECTOR &vUpVec, FLOAT fEyeDistance); - - BOOL FreeTexture(char* name); - BOOL LoadTexture(char* name, int stage=0); - BOOL LoadAllTexture(); - - void SetLimitLOD(int rank, float limit); - float RetLimitLOD(int rank, BOOL bLast=FALSE); - - void SetTerrainVision(float vision); - - void SetGroundSpot(BOOL bMode); - BOOL RetGroundSpot(); - void SetShadow(BOOL bMode); - BOOL RetShadow(); - void SetDirty(BOOL bMode); - BOOL RetDirty(); - void SetFog(BOOL bMode); - BOOL RetFog(); - BOOL RetStateColor(); - - void SetSecondTexture(int texNum); - int RetSecondTexture(); - - void SetRankView(int rank); - int RetRankView(); - - void SetDrawWorld(BOOL bDraw); - void SetDrawFront(BOOL bDraw); - - void SetAmbiantColor(D3DCOLOR color, int rank=0); - D3DCOLOR RetAmbiantColor(int rank=0); - - void SetWaterAddColor(D3DCOLORVALUE color); - D3DCOLORVALUE RetWaterAddColor(); - - void SetFogColor(D3DCOLOR color, int rank=0); - D3DCOLOR RetFogColor(int rank=0); - - void SetDeepView(float length, int rank=0, BOOL bRef=FALSE); - float RetDeepView(int rank=0); - - void SetFogStart(float start, int rank=0); - float RetFogStart(int rank=0); - - void SetBackground(char *name, D3DCOLOR up=0, D3DCOLOR down=0, D3DCOLOR cloudUp=0, D3DCOLOR cloudDown=0, BOOL bFull=FALSE, BOOL bQuarter=FALSE); - void RetBackground(char *name, D3DCOLOR &up, D3DCOLOR &down, D3DCOLOR &cloudUp, D3DCOLOR &cloudDown, BOOL &bFull, BOOL &bQuarter); - void SetFrontsizeName(char *name); - void SetOverFront(BOOL bFront); - void SetOverColor(D3DCOLOR color=0, int mode=D3DSTATETCb); - - void SetParticuleDensity(float value); - float RetParticuleDensity(); - float ParticuleAdapt(float factor); - - void SetClippingDistance(float value); - float RetClippingDistance(); - - void SetObjectDetail(float value); - float RetObjectDetail(); - - void SetGadgetQuantity(float value); - float RetGadgetQuantity(); - - void SetTextureQuality(int value); - int RetTextureQuality(); - - void SetTotoMode(BOOL bPresent); - BOOL RetTotoMode(); - - void SetLensMode(BOOL bPresent); - BOOL RetLensMode(); - - void SetWaterMode(BOOL bPresent); - BOOL RetWaterMode(); - - void SetBlitzMode(BOOL bPresent); - BOOL RetBlitzMode(); - - void SetSkyMode(BOOL bPresent); - BOOL RetSkyMode(); - - void SetBackForce(BOOL bPresent); - BOOL RetBackForce(); - - void SetPlanetMode(BOOL bPresent); - BOOL RetPlanetMode(); - - void SetLightMode(BOOL bPresent); - BOOL RetLightMode(); - - void SetEditIndentMode(BOOL bAuto); - BOOL RetEditIndentMode(); - - void SetEditIndentValue(int value); - int RetEditIndentValue(); - - void SetSpeed(float speed); - float RetSpeed(); - - void SetTracePrecision(float factor); - float RetTracePrecision(); - - void SetFocus(float focus); - float RetFocus(); - D3DVECTOR RetEyePt(); - D3DVECTOR RetLookatPt(); - float RetEyeDirH(); - float RetEyeDirV(); - POINT RetDim(); - void UpdateMatProj(); - - void ApplyChange(); - - void FlushPressKey(); - void ResetKey(); - void SetKey(int keyRank, int option, int key); - int RetKey(int keyRank, int option); - - void SetJoystick(BOOL bEnable); - BOOL RetJoystick(); - - void SetDebugMode(BOOL bMode); - BOOL RetDebugMode(); - BOOL RetSetupMode(); - - BOOL IsVisiblePoint(const D3DVECTOR &pos); - - int DetectObject(FPOINT mouse); - void SetState(int state, D3DCOLOR color=0xffffffff); - void SetTexture(char *name, int stage=0); - void SetMaterial(const D3DMATERIAL7 &mat); - - void MoveMousePos(FPOINT pos); - void SetMousePos(FPOINT pos); - FPOINT RetMousePos(); - void SetMouseType(D3DMouse type); - D3DMouse RetMouseType(); - void SetMouseHide(BOOL bHide); - BOOL RetMouseHide(); - void SetNiceMouse(BOOL bNice); - BOOL RetNiceMouse(); - BOOL RetNiceMouseCap(); - - CText* RetText(); - - BOOL ChangeColor(char *name, D3DCOLORVALUE colorRef1, D3DCOLORVALUE colorNew1, D3DCOLORVALUE colorRef2, D3DCOLORVALUE colorNew2, float tolerance1, float tolerance2, FPOINT ts, FPOINT ti, FPOINT *pExclu=0, float shift=0.0f, BOOL bHSV=FALSE); - BOOL OpenImage(char *name); - BOOL CopyImage(); - BOOL LoadImage(); - BOOL ScrollImage(int dx, int dy); - BOOL SetDot(int x, int y, D3DCOLORVALUE color); - BOOL CloseImage(); - BOOL WriteScreenShot(char *filename, int width, int height); - BOOL GetRenderDC(HDC &hDC); - BOOL ReleaseRenderDC(HDC &hDC); - PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp); - BOOL CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC); - -protected: - void MemSpace1(D3DObjLevel1 *&p, int nb); - void MemSpace2(D3DObjLevel2 *&p, int nb); - void MemSpace3(D3DObjLevel3 *&p, int nb); - void MemSpace4(D3DObjLevel4 *&p, int nb); - void MemSpace5(D3DObjLevel5 *&p, int nb); - void MemSpace6(D3DObjLevel6 *&p, int nb); - - D3DObjLevel2* AddLevel1(D3DObjLevel1 *&p1, char* texName1, char* texName2); - D3DObjLevel3* AddLevel2(D3DObjLevel2 *&p2, int objRank); - D3DObjLevel4* AddLevel3(D3DObjLevel3 *&p3, float min, float max); - D3DObjLevel5* AddLevel4(D3DObjLevel4 *&p4, int reserve); - D3DObjLevel6* AddLevel5(D3DObjLevel5 *&p5, D3DTypeTri type, const D3DMATERIAL7 &mat, int state, int nb); - - BOOL IsVisible(int objRank); - BOOL DetectBBox(int objRank, FPOINT mouse); - BOOL DetectTriangle(FPOINT mouse, D3DVERTEX2 *triangle, int objRank, float &dist); - BOOL TransformPoint(D3DVECTOR &p2D, int objRank, D3DVECTOR p3D); - void ComputeDistance(); - void UpdateGeometry(); - void RenderGroundSpot(); - void DrawShadow(); - void DrawBackground(); - void DrawBackgroundGradient(D3DCOLOR up, D3DCOLOR down); - void DrawBackgroundImageQuarter(FPOINT p1, FPOINT p2, char *name); - void DrawBackgroundImage(); - void DrawPlanet(); - void DrawFrontsize(); - void DrawOverColor(); - BOOL GetBBox2D(int objRank, FPOINT &min, FPOINT &max); - void DrawHilite(); - void DrawMouse(); - void DrawSprite(FPOINT pos, FPOINT dim, int icon); - -protected: - CInstanceManager* m_iMan; - CD3DApplication* m_app; - LPDIRECT3DDEVICE7 m_pD3DDevice; - CText* m_text; - CLight* m_light; - CParticule* m_particule; - CWater* m_water; - CCloud* m_cloud; - CBlitz* m_blitz; - CPlanet* m_planet; - CSound* m_sound; - CTerrain* m_terrain; - - int m_blackSrcBlend[2]; - int m_blackDestBlend[2]; - int m_whiteSrcBlend[2]; - int m_whiteDestBlend[2]; - int m_diffuseSrcBlend[2]; - int m_diffuseDestBlend[2]; - int m_alphaSrcBlend[2]; - int m_alphaDestBlend[2]; - - D3DMATRIX m_matProj; - D3DMATRIX m_matLeftView; - D3DMATRIX m_matRightView; - D3DMATRIX m_matView; - float m_focus; - - D3DMATRIX m_matWorldInterface; - D3DMATRIX m_matProjInterface; - D3DMATRIX m_matViewInterface; - - DWORD m_baseTime; - DWORD m_stopTime; - float m_absTime; - float m_lastTime; - float m_speed; - BOOL m_bPause; - BOOL m_bRender; - BOOL m_bMovieLock; - - POINT m_dim; - POINT m_lastDim; - D3DObjLevel1* m_objectPointer; - int m_objectParamTotal; - D3DObject* m_objectParam; - int m_shadowTotal; - D3DShadow* m_shadow; - D3DGroundSpot* m_groundSpot; - D3DGroundMark m_groundMark; - D3DVECTOR m_eyePt; - D3DVECTOR m_lookatPt; - float m_eyeDirH; - float m_eyeDirV; - int m_rankView; - D3DCOLOR m_ambiantColor[2]; - D3DCOLOR m_backColor[2]; - D3DCOLOR m_fogColor[2]; - float m_deepView[2]; - float m_fogStart[2]; - D3DCOLORVALUE m_waterAddColor; - int m_statisticTriangle; - BOOL m_bUpdateGeometry; - char m_infoText[10][200]; - int m_alphaMode; - BOOL m_bStateColor; - BOOL m_bForceStateColor; - BOOL m_bGroundSpot; - BOOL m_bShadow; - BOOL m_bDirty; - BOOL m_bFog; - BOOL m_bFirstGroundSpot; - int m_secondTexNum; - char m_backgroundName[50]; - D3DCOLOR m_backgroundColorUp; - D3DCOLOR m_backgroundColorDown; - D3DCOLOR m_backgroundCloudUp; - D3DCOLOR m_backgroundCloudDown; - BOOL m_bBackgroundFull; - BOOL m_bBackgroundQuarter; - BOOL m_bOverFront; - D3DCOLOR m_overColor; - int m_overMode; - char m_frontsizeName[50]; - BOOL m_bDrawWorld; - BOOL m_bDrawFront; - float m_limitLOD[2]; - float m_particuleDensity; - float m_clippingDistance; - float m_lastClippingDistance; - float m_objectDetail; - float m_lastObjectDetail; - float m_terrainVision; - float m_gadgetQuantity; - int m_textureQuality; - BOOL m_bTotoMode; - BOOL m_bLensMode; - BOOL m_bWaterMode; - BOOL m_bSkyMode; - BOOL m_bBackForce; - BOOL m_bPlanetMode; - BOOL m_bLightMode; - BOOL m_bEditIndentMode; - int m_editIndentValue; - float m_tracePrecision; - - int m_hiliteRank[100]; - BOOL m_bHilite; - FPOINT m_hiliteP1; - FPOINT m_hiliteP2; - - int m_lastState; - D3DCOLOR m_lastColor; - char m_lastTexture[2][50]; - D3DMATERIAL7 m_lastMaterial; - - FPOINT m_mousePos; - D3DMouse m_mouseType; - BOOL m_bMouseHide; - BOOL m_bNiceMouse; - - LPDIRECTDRAWSURFACE7 m_imageSurface; - DDSURFACEDESC2 m_imageDDSD; - WORD* m_imageCopy; - int m_imageDX; - int m_imageDY; -}; - - -#endif //_D3DENGINE_H_ diff --git a/src/d3denum.cpp b/src/d3denum.cpp deleted file mode 100644 index 46497d8..0000000 --- a/src/d3denum.cpp +++ /dev/null @@ -1,621 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -//----------------------------------------------------------------------------- -// File: D3DEnum.cpp -// -// Desc: Functions to enumerate DDraw/D3D drivers, devices, and modes. -// -// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved -//----------------------------------------------------------------------------- -#define STRICT -#include -#include -#include -#include "d3denum.h" -#include "d3dutil.h" // For DEBUG_MSG -#include "d3dres.h" // For dialog controls - - - - -//----------------------------------------------------------------------------- -// Global data for the enumerator functions -//----------------------------------------------------------------------------- -static HRESULT (*g_fnAppConfirmFn)(DDCAPS*, D3DDEVICEDESC7*) = NULL; - -static D3DEnum_DeviceInfo g_pDeviceList[20]; -static DWORD g_dwNumDevicesEnumerated = 0L; -static DWORD g_dwNumDevices = 0L; - - - - -//----------------------------------------------------------------------------- -// Name: SortModesCallback() -// Desc: Callback function for sorting display modes. -//----------------------------------------------------------------------------- -int SortModesCallback( const VOID* arg1, const VOID* arg2 ) -{ - DDSURFACEDESC2* p1 = (DDSURFACEDESC2*)arg1; - DDSURFACEDESC2* p2 = (DDSURFACEDESC2*)arg2; - - if( p1->dwWidth < p2->dwWidth ) - return -1; - if( p1->dwWidth > p2->dwWidth ) - return +1; - - if( p1->dwHeight < p2->dwHeight ) - return -1; - if( p1->dwHeight > p2->dwHeight ) - return +1; - - if( p1->ddpfPixelFormat.dwRGBBitCount < p2->ddpfPixelFormat.dwRGBBitCount ) - return -1; - if( p1->ddpfPixelFormat.dwRGBBitCount > p2->ddpfPixelFormat.dwRGBBitCount ) - return +1; - - return 0; -} - - - - -//----------------------------------------------------------------------------- -// Name: ModeEnumCallback() -// Desc: Callback function for enumerating display modes. -//----------------------------------------------------------------------------- -static HRESULT WINAPI ModeEnumCallback( DDSURFACEDESC2* pddsd, - VOID* pParentInfo ) -{ - D3DEnum_DeviceInfo* pDevice = (D3DEnum_DeviceInfo*)pParentInfo; - - // Reallocate storage for the modes - DDSURFACEDESC2* pddsdNewModes = new DDSURFACEDESC2[pDevice->dwNumModes+1]; - memcpy( pddsdNewModes, pDevice->pddsdModes, - pDevice->dwNumModes * sizeof(DDSURFACEDESC2) ); - delete pDevice->pddsdModes; - pDevice->pddsdModes = pddsdNewModes; - - // Add the new mode - pDevice->pddsdModes[pDevice->dwNumModes++] = (*pddsd); - - return DDENUMRET_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: DeviceEnumCallback() -// Desc: Callback function for enumerating devices -//----------------------------------------------------------------------------- -static HRESULT WINAPI DeviceEnumCallback( TCHAR* strDesc, TCHAR* strName, - D3DDEVICEDESC7* pDesc, - VOID* pParentInfo ) -{ - DWORD i; - - // Keep track of # of devices that were enumerated - g_dwNumDevicesEnumerated++; - - D3DEnum_DeviceInfo* pDriverInfo = (D3DEnum_DeviceInfo*)pParentInfo; - D3DEnum_DeviceInfo* pDeviceInfo = &g_pDeviceList[g_dwNumDevices]; - ZeroMemory( pDeviceInfo, sizeof(D3DEnum_DeviceInfo) ); - - // Select either the HAL or HEL device desc: - pDeviceInfo->bHardware = pDesc->dwDevCaps & D3DDEVCAPS_HWRASTERIZATION; - memcpy( &pDeviceInfo->ddDeviceDesc, pDesc, sizeof(D3DDEVICEDESC7) ); - - // Set up device info for this device - pDeviceInfo->bDesktopCompatible = pDriverInfo->bDesktopCompatible; - pDeviceInfo->ddDriverCaps = pDriverInfo->ddDriverCaps; - pDeviceInfo->ddHELCaps = pDriverInfo->ddHELCaps; - pDeviceInfo->guidDevice = pDesc->deviceGUID; - pDeviceInfo->pDeviceGUID = &pDeviceInfo->guidDevice; - pDeviceInfo->pddsdModes = new DDSURFACEDESC2[pDriverInfo->dwNumModes]; - - // Copy the driver GUID and description for the device - if( pDriverInfo->pDriverGUID ) - { - pDeviceInfo->guidDriver = pDriverInfo->guidDriver; - pDeviceInfo->pDriverGUID = &pDeviceInfo->guidDriver; - lstrcpyn( pDeviceInfo->strDesc, pDriverInfo->strDesc, 39 ); - } - else - { - pDeviceInfo->pDriverGUID = NULL; - lstrcpyn( pDeviceInfo->strDesc, strName, 39 ); - } - -//? if( strstr(strName, "T&L") != 0 ) return D3DENUMRET_OK; - - // Avoid duplicates: only enum HW devices for secondary DDraw drivers. - if( NULL != pDeviceInfo->pDriverGUID && FALSE == pDeviceInfo->bHardware ) - return D3DENUMRET_OK; - - // Give the app a chance to accept or reject this device. - if( g_fnAppConfirmFn ) - if( FAILED( g_fnAppConfirmFn( &pDeviceInfo->ddDriverCaps, - &pDeviceInfo->ddDeviceDesc ) ) ) - return D3DENUMRET_OK; - - // Build list of supported modes for the device - for( i=0; idwNumModes; i++ ) - { - DDSURFACEDESC2 ddsdMode = pDriverInfo->pddsdModes[i]; - DWORD dwRenderDepths = pDeviceInfo->ddDeviceDesc.dwDeviceRenderBitDepth; - DWORD dwDepth = ddsdMode.ddpfPixelFormat.dwRGBBitCount; - - // Accept modes that are compatable with the device - if( ( ( dwDepth == 32 ) && ( dwRenderDepths & DDBD_32 ) ) || - ( ( dwDepth == 24 ) && ( dwRenderDepths & DDBD_24 ) ) || - ( ( dwDepth == 16 ) && ( dwRenderDepths & DDBD_16 ) ) ) - { - // Copy compatible modes to the list of device-supported modes - pDeviceInfo->pddsdModes[pDeviceInfo->dwNumModes++] = ddsdMode; - - // Record whether the device has any stereo modes - if( ddsdMode.ddsCaps.dwCaps2 & DDSCAPS2_STEREOSURFACELEFT ) - pDeviceInfo->bStereoCompatible = TRUE; - } - } - - // Bail if the device has no supported modes - if( 0 == pDeviceInfo->dwNumModes ) - return D3DENUMRET_OK; - - // Find a 640x480x16 mode for the default fullscreen mode - for( i=0; idwNumModes; i++ ) - { - if( ( pDeviceInfo->pddsdModes[i].dwWidth == 640 ) && - ( pDeviceInfo->pddsdModes[i].dwHeight == 480 ) && - ( pDeviceInfo->pddsdModes[i].ddpfPixelFormat.dwRGBBitCount == 16 ) ) - { - pDeviceInfo->ddsdFullscreenMode = pDeviceInfo->pddsdModes[i]; - pDeviceInfo->dwCurrentMode = i; - } - } - - // Select whether the device is initially windowed - pDeviceInfo->bWindowed = pDeviceInfo->bDesktopCompatible; - - // Accept the device and return - g_dwNumDevices++; - - return D3DENUMRET_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: DriverEnumCallback() -// Desc: Callback function for enumerating drivers. -//----------------------------------------------------------------------------- -static BOOL WINAPI DriverEnumCallback( GUID* pGUID, TCHAR* strDesc, - TCHAR* strName, VOID*, HMONITOR ) -{ - D3DEnum_DeviceInfo d3dDeviceInfo; - LPDIRECTDRAW7 pDD; - LPDIRECT3D7 pD3D; - HRESULT hr; - - // Use the GUID to create the DirectDraw object - hr = DirectDrawCreateEx( pGUID, (VOID**)&pDD, IID_IDirectDraw7, NULL ); - if( FAILED(hr) ) - { - DEBUG_MSG( _T("Can't create DDraw during enumeration!") ); - return D3DENUMRET_OK; - } - - // Create a D3D object, to enumerate the d3d devices - hr = pDD->QueryInterface( IID_IDirect3D7, (VOID**)&pD3D ); - if( FAILED(hr) ) - { - pDD->Release(); - DEBUG_MSG( _T("Can't query IDirect3D7 during enumeration!") ); - return D3DENUMRET_OK; - } - - // Copy data to a device info structure - ZeroMemory( &d3dDeviceInfo, sizeof(d3dDeviceInfo) ); - lstrcpyn( d3dDeviceInfo.strDesc, strDesc, 39 ); - d3dDeviceInfo.ddDriverCaps.dwSize = sizeof(DDCAPS); - d3dDeviceInfo.ddHELCaps.dwSize = sizeof(DDCAPS); - pDD->GetCaps( &d3dDeviceInfo.ddDriverCaps, &d3dDeviceInfo.ddHELCaps ); - if( pGUID ) - { - d3dDeviceInfo.guidDriver = (*pGUID); - d3dDeviceInfo.pDriverGUID = &d3dDeviceInfo.guidDriver; - } - - // Record whether the device can render into a desktop window - if( d3dDeviceInfo.ddDriverCaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED ) - if( NULL == d3dDeviceInfo.pDriverGUID ) - d3dDeviceInfo.bDesktopCompatible = TRUE; - - // Enumerate the fullscreen display modes. - pDD->EnumDisplayModes( 0, NULL, &d3dDeviceInfo, ModeEnumCallback ); - - // Sort list of display modes - qsort( d3dDeviceInfo.pddsdModes, d3dDeviceInfo.dwNumModes, - sizeof(DDSURFACEDESC2), SortModesCallback ); - - // Now, enumerate all the 3D devices - pD3D->EnumDevices( DeviceEnumCallback, &d3dDeviceInfo ); - - // Clean up and return - SAFE_DELETE( d3dDeviceInfo.pddsdModes ); - pD3D->Release(); - pDD->Release(); - - return DDENUMRET_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DEnum_EnumerateDevices() -// Desc: Enumerates all drivers, devices, and modes. The callback function is -// called each device, to confirm that the device supports the feature -// set required by the app. -//----------------------------------------------------------------------------- -HRESULT D3DEnum_EnumerateDevices( HRESULT (*AppConfirmFn)(DDCAPS*, D3DDEVICEDESC7*) ) -{ - // Store the device enumeration callback function - g_fnAppConfirmFn = AppConfirmFn; - - // Enumerate drivers, devices, and modes - DirectDrawEnumerateEx( DriverEnumCallback, NULL, - DDENUM_ATTACHEDSECONDARYDEVICES | - DDENUM_DETACHEDSECONDARYDEVICES | - DDENUM_NONDISPLAYDEVICES ); - - // Make sure devices were actually enumerated - if( 0 == g_dwNumDevicesEnumerated ) - { - DEBUG_MSG( _T("No devices and/or modes were enumerated!") ); - return D3DENUMERR_ENUMERATIONFAILED; - } - if( 0 == g_dwNumDevices ) - { - DEBUG_MSG( _T("No enumerated devices were accepted!") ); - DEBUG_MSG( _T("Try enabling the D3D Reference Rasterizer.") ); - return D3DENUMERR_SUGGESTREFRAST; - } - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DEnum_FreeResources() -// Desc: Cleans up any memory allocated during device enumeration -//----------------------------------------------------------------------------- -VOID D3DEnum_FreeResources() -{ - for( DWORD i=0; ibDesktopCompatible ) - bWindowed = FALSE; - - // Add a list of devices to the device combo box - for( DWORD device = 0; device < dwNumDevices; device++ ) - { - D3DEnum_DeviceInfo* pDevice = &pDeviceList[device]; - - // Add device name to the combo box - DWORD dwItem = ComboBox_AddString( hwndDevice, pDevice->strDesc ); - - // Set the remaining UI states for the current device - if( pDevice == pCurrentDevice ) - { - // Set the combobox selection on the current device - ComboBox_SetCurSel( hwndDevice, dwItem ); - - // Enable/set the fullscreen checkbox, as appropriate - if( hwndWindowed ) - { - EnableWindow( hwndWindowed, pDevice->bDesktopCompatible ); - Button_SetCheck( hwndWindowed, bWindowed ); - } - - // Enable/set the stereo checkbox, as appropriate - if( hwndStereo ) - { - EnableWindow( hwndStereo, pDevice->bStereoCompatible && !bWindowed ); - Button_SetCheck( hwndStereo, bStereo ); - } - - // Enable/set the fullscreen modes combo, as appropriate - EnableWindow( hwndMode, !bWindowed ); - EnableWindow( hwndFullscreenText, !bWindowed ); - - // Build the list of fullscreen modes - for( DWORD mode = 0; mode < pDevice->dwNumModes; mode++ ) - { - DDSURFACEDESC2* pddsdMode = &pDevice->pddsdModes[mode]; - - // Skip non-stereo modes, if the device is in stereo mode - if( 0 == (pddsdMode->ddsCaps.dwCaps2&DDSCAPS2_STEREOSURFACELEFT) ) - if( bStereo ) - continue; - - TCHAR strMode[80]; - wsprintf( strMode, _T("%ld x %ld x %ld"), - pddsdMode->dwWidth, pddsdMode->dwHeight, - pddsdMode->ddpfPixelFormat.dwRGBBitCount ); - - // Add mode desc to the combo box - DWORD dwItem = ComboBox_AddString( hwndMode, strMode ); - - // Set the item data to identify this mode - ComboBox_SetItemData( hwndMode, dwItem, mode ); - - // Set the combobox selection on the current mode - if( mode == dwCurrentMode ) - ComboBox_SetCurSel( hwndMode, dwItem ); - - // Since not all modes support stereo, select a default mode in - // case none was chosen yet. - if( bStereo && ( CB_ERR == ComboBox_GetCurSel( hwndMode ) ) ) - ComboBox_SetCurSel( hwndMode, dwItem ); - } - } - } -} - - - - -//----------------------------------------------------------------------------- -// Name: ChangeDeviceProc() -// Desc: Windows message handling function for the device select dialog -//----------------------------------------------------------------------------- -static INT_PTR CALLBACK ChangeDeviceProc( HWND hDlg, UINT uiMsg, WPARAM wParam, - LPARAM lParam ) -{ - static D3DEnum_DeviceInfo** ppDeviceArg; - static D3DEnum_DeviceInfo* pCurrentDevice; - static DWORD dwCurrentMode; - static BOOL bCurrentWindowed; - static BOOL bCurrentStereo; - - // Get access to the enumerated device list - D3DEnum_DeviceInfo* pDeviceList; - DWORD dwNumDevices; - D3DEnum_GetDevices( &pDeviceList, &dwNumDevices ); - - // Handle the initialization message - if( WM_INITDIALOG == uiMsg ) - { - // Get the app's current device, passed in as an lParam argument - ppDeviceArg = (D3DEnum_DeviceInfo**)lParam; - if( NULL == ppDeviceArg ) - return FALSE; - - // Setup temp storage pointers for dialog - pCurrentDevice = (*ppDeviceArg); - dwCurrentMode = pCurrentDevice->dwCurrentMode; - bCurrentWindowed = pCurrentDevice->bWindowed; - bCurrentStereo = pCurrentDevice->bStereo; - - UpdateDialogControls( hDlg, pCurrentDevice, dwCurrentMode, - bCurrentWindowed, bCurrentStereo ); - - return TRUE; - } - else if( WM_COMMAND == uiMsg ) - { - HWND hwndDevice = GetDlgItem( hDlg, IDC_DEVICE_COMBO ); - HWND hwndMode = GetDlgItem( hDlg, IDC_MODE_COMBO ); - HWND hwndWindowed = GetDlgItem( hDlg, IDC_WINDOWED_CHECKBOX ); - HWND hwndStereo = GetDlgItem( hDlg, IDC_STEREO_CHECKBOX ); - - // Get current UI state - DWORD dwDevice = ComboBox_GetCurSel( hwndDevice ); - DWORD dwModeItem = ComboBox_GetCurSel( hwndMode ); - DWORD dwMode = ComboBox_GetItemData( hwndMode, dwModeItem ); - BOOL bWindowed = hwndWindowed ? Button_GetCheck( hwndWindowed ) : 0; - BOOL bStereo = hwndStereo ? Button_GetCheck( hwndStereo ) : 0; - - D3DEnum_DeviceInfo* pDevice = &pDeviceList[dwDevice]; - - if( IDOK == LOWORD(wParam) ) - { - // Handle the case when the user hits the OK button. Check if any - // of the options were changed - if( pDevice != pCurrentDevice || dwMode != dwCurrentMode || - bWindowed != bCurrentWindowed || bStereo != bCurrentStereo ) - { - // Return the newly selected device and its new properties - (*ppDeviceArg) = pDevice; - pDevice->bWindowed = bWindowed; - pDevice->bStereo = bStereo; - pDevice->dwCurrentMode = dwMode; - pDevice->ddsdFullscreenMode = pDevice->pddsdModes[dwMode]; - - EndDialog( hDlg, IDOK ); - } - else - EndDialog( hDlg, IDCANCEL ); - - return TRUE; - } - else if( IDCANCEL == LOWORD(wParam) ) - { - // Handle the case when the user hits the Cancel button - EndDialog( hDlg, IDCANCEL ); - return TRUE; - } - else if( CBN_SELENDOK == HIWORD(wParam) ) - { - if( LOWORD(wParam) == IDC_DEVICE_COMBO ) - { - // Handle the case when the user chooses the device combo - dwMode = pDeviceList[dwDevice].dwCurrentMode; - bWindowed = pDeviceList[dwDevice].bWindowed; - bStereo = pDeviceList[dwDevice].bStereo; - } - } - - // Keep the UI current - UpdateDialogControls( hDlg, &pDeviceList[dwDevice], dwMode, bWindowed, bStereo ); - return TRUE; - } - - return FALSE; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DEnum_UserChangeDevice() -// Desc: Pops up a dialog which allows the user to select a new device. -//----------------------------------------------------------------------------- -HRESULT D3DEnum_UserChangeDevice( D3DEnum_DeviceInfo** ppDevice ) -{ - if( IDOK == DialogBoxParam( (HINSTANCE)GetModuleHandle(NULL), - MAKEINTRESOURCE(IDD_CHANGEDEVICE), - GetForegroundWindow(), - ChangeDeviceProc, (LPARAM)ppDevice ) ) - return S_OK; - - return E_FAIL; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DEnum_SelectDefaultDevice() -// Desc: Pick a default device, preferably hardware and desktop compatible. -//----------------------------------------------------------------------------- -HRESULT D3DEnum_SelectDefaultDevice( D3DEnum_DeviceInfo** ppDevice, - DWORD dwFlags ) -{ - // Check arguments - if( NULL == ppDevice ) - return E_INVALIDARG; - - // Get access to the enumerated device list - D3DEnum_DeviceInfo* pDeviceList; - DWORD dwNumDevices; - D3DEnum_GetDevices( &pDeviceList, &dwNumDevices ); - - // Look for windowable software, hardware, and hardware TnL devices - D3DEnum_DeviceInfo* pRefRastDevice = NULL; - D3DEnum_DeviceInfo* pSoftwareDevice = NULL; - D3DEnum_DeviceInfo* pHardwareDevice = NULL; - D3DEnum_DeviceInfo* pHardwareTnLDevice = NULL; - - for( DWORD i=0; ibWindowed = TRUE; - - return S_OK; -} - - - - - diff --git a/src/d3denum.h b/src/d3denum.h deleted file mode 100644 index e728ffb..0000000 --- a/src/d3denum.h +++ /dev/null @@ -1,136 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -//----------------------------------------------------------------------------- -// File: D3DEnum.h -// -// Desc: Functions to enumerate DDraw/D3D drivers, devices, and modes. -// -// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved -//----------------------------------------------------------------------------- -#ifndef D3DENUM_H -#define D3DENUM_H -#include - - -//----------------------------------------------------------------------------- -// Flag and error definitions -//----------------------------------------------------------------------------- -#define D3DENUM_SOFTWAREONLY 0x00000001 // Software-devices only flag - -#define D3DENUMERR_NODIRECTDRAW 0x81000001 // Could not create DDraw -#define D3DENUMERR_ENUMERATIONFAILED 0x81000002 // Enumeration failed -#define D3DENUMERR_SUGGESTREFRAST 0x81000003 // Suggest using the RefRast -#define D3DENUMERR_NOCOMPATIBLEDEVICES 0x81000004 // No devices were found that - // meet the app's desired - // capabilities -#define D3DENUMERR_ENGINE 0x81000005 // 3D engine error -#define D3DENUMERR_ROBOT 0x81000006 // robot error -#define D3DENUMERR_SOUND 0x81000007 // sound error - - -//----------------------------------------------------------------------------- -// Name: struct D3DEnum_DeviceInfo -// Desc: Structure to hold info about the enumerated Direct3D devices. -//----------------------------------------------------------------------------- -struct D3DEnum_DeviceInfo -{ - // D3D Device info - TCHAR strDesc[40]; - GUID* pDeviceGUID; - D3DDEVICEDESC7 ddDeviceDesc; - BOOL bHardware; - - // DDraw Driver info - GUID* pDriverGUID; - DDCAPS ddDriverCaps; - DDCAPS ddHELCaps; - - // DDraw Mode Info - DDSURFACEDESC2 ddsdFullscreenMode; - BOOL bWindowed; - BOOL bStereo; - - // For internal use (apps should not need to use these) - GUID guidDevice; - GUID guidDriver; - DDSURFACEDESC2* pddsdModes; - DWORD dwNumModes; - DWORD dwCurrentMode; - BOOL bDesktopCompatible; - BOOL bStereoCompatible; -}; - - -// For code not yet switched to new struct name -typedef D3DEnum_DeviceInfo D3DDEVICEINFO; - - - - -//----------------------------------------------------------------------------- -// Name: D3DEnum_EnumerateDevices() -// Desc: Enumerates all drivers, devices, and modes. The callback function is -// called each device, to confirm that the device supports the feature -// set required by the app. -//----------------------------------------------------------------------------- -HRESULT D3DEnum_EnumerateDevices( HRESULT (*fn)(DDCAPS*, D3DDEVICEDESC7*) ); - - - - -//----------------------------------------------------------------------------- -// Name: D3DEnum_FreeResources() -// Desc: Cleans up any memory allocated during device enumeration -//----------------------------------------------------------------------------- -VOID D3DEnum_FreeResources(); - - - - -//----------------------------------------------------------------------------- -// Name: D3DEnum_GetDevices() -// Desc: Returns a ptr to the array of enumerated D3DDEVICEINFO structures. -//----------------------------------------------------------------------------- -VOID D3DEnum_GetDevices( D3DEnum_DeviceInfo** ppDevices, DWORD* pdwCount ); - - - - -//----------------------------------------------------------------------------- -// Name: D3DEnum_SelectDefaultDevice() -// Desc: Picks a driver based on a set of passed in criteria. The -// D3DENUM_SOFTWAREONLY flag can be used to pick a software device. -//----------------------------------------------------------------------------- -HRESULT D3DEnum_SelectDefaultDevice( D3DEnum_DeviceInfo** pDevice, - DWORD dwFlags = 0L ); - - - - -//----------------------------------------------------------------------------- -// Name: D3DEnum_UserChangeDevice() -// Desc: Pops up a dialog which allows the user to select a new device. -//----------------------------------------------------------------------------- -HRESULT D3DEnum_UserChangeDevice( D3DEnum_DeviceInfo** ppDevice ); - - - - -#endif // D3DENUM_H - - - diff --git a/src/d3dframe.cpp b/src/d3dframe.cpp deleted file mode 100644 index 3207a4b..0000000 --- a/src/d3dframe.cpp +++ /dev/null @@ -1,623 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -//----------------------------------------------------------------------------- -// File: D3DFrame.cpp -// -// Desc: Class functions to implement a Direct3D app framework. -// -// Copyright (c) 1995-1999 by Microsoft, all rights reserved -//----------------------------------------------------------------------------- -#define STRICT -#include -#include -#include -#include "d3dframe.h" -#include "d3dutil.h" - - - - -//----------------------------------------------------------------------------- -// Name: CD3DFramework7() -// Desc: The constructor. Clears static variables -//----------------------------------------------------------------------------- -CD3DFramework7::CD3DFramework7() -{ - m_hWnd = NULL; - m_bIsFullscreen = FALSE; - m_bIsStereo = FALSE; - m_dwRenderWidth = 0L; - m_dwRenderHeight = 0L; - - m_pddsFrontBuffer = NULL; - m_pddsBackBuffer = NULL; - m_pddsBackBufferLeft = NULL; - - m_pddsZBuffer = NULL; - m_pd3dDevice = NULL; - m_pDD = NULL; - m_pD3D = NULL; - m_dwDeviceMemType = NULL; -} - - - - -//----------------------------------------------------------------------------- -// Name: ~CD3DFramework7() -// Desc: The destructor. Deletes all objects -//----------------------------------------------------------------------------- -CD3DFramework7::~CD3DFramework7() -{ - DestroyObjects(); -} - - - - -//----------------------------------------------------------------------------- -// Name: DestroyObjects() -// Desc: Cleans everything up upon deletion. This code returns an error -// if any of the objects have remaining reference counts. -//----------------------------------------------------------------------------- -HRESULT CD3DFramework7::DestroyObjects() -{ - LONG nDD = 0L; // Number of outstanding DDraw references - LONG nD3D = 0L; // Number of outstanding D3DDevice references - - if( m_pDD ) - { - HRESULT err = m_pDD->SetCooperativeLevel( m_hWnd, DDSCL_NORMAL ); - char s[100]; - sprintf(s, "SetCooperativeLevel error=%d\n", err); - OutputDebugString(s); - } - - // Do a safe check for releasing the D3DDEVICE. RefCount must be zero. - if( m_pd3dDevice ) - if( 0 < ( nD3D = m_pd3dDevice->Release() ) ) - DEBUG_MSG( _T("Error: D3DDevice object is still referenced!") ); - m_pd3dDevice = NULL; - - SAFE_RELEASE( m_pddsBackBuffer ); - SAFE_RELEASE( m_pddsBackBufferLeft ); - SAFE_RELEASE( m_pddsZBuffer ); - SAFE_RELEASE( m_pddsFrontBuffer ); - SAFE_RELEASE( m_pD3D ); - - if( m_pDD ) - { - // Do a safe check for releasing DDRAW. RefCount must be zero. - if( 0 < ( nDD = m_pDD->Release() ) ) - DEBUG_MSG( _T("Error: DDraw object is still referenced!") ); - } - m_pDD = NULL; - - // Return successful, unless there are outstanding DD or D3DDevice refs. - return ( nDD==0 && nD3D==0 ) ? S_OK : D3DFWERR_NONZEROREFCOUNT; -} - - - - -//----------------------------------------------------------------------------- -// Name: Initialize() -// Desc: Creates the internal objects for the framework -//----------------------------------------------------------------------------- -HRESULT CD3DFramework7::Initialize( HWND hWnd, GUID* pDriverGUID, - GUID* pDeviceGUID, DDSURFACEDESC2* pMode, - DWORD dwFlags ) -{ - HRESULT hr; - - // Check params. Note: A NULL mode is valid for windowed modes only. - if( ( NULL==hWnd ) || ( NULL==pDeviceGUID ) || - ( NULL==pMode && (dwFlags&D3DFW_FULLSCREEN) ) ) - return E_INVALIDARG; - - // Setup state for windowed/fullscreen mode - m_hWnd = hWnd; - m_bIsStereo = FALSE; - m_bIsFullscreen = ( dwFlags & D3DFW_FULLSCREEN ) ? TRUE : FALSE; - - // Support stereoscopic viewing for fullscreen modes which support it - if( ( dwFlags & D3DFW_STEREO ) && ( dwFlags & D3DFW_FULLSCREEN ) ) - if( pMode->ddsCaps.dwCaps2 & DDSCAPS2_STEREOSURFACELEFT ) - m_bIsStereo = TRUE; - - // Create the D3D rendering environment (surfaces, device, viewport, etc.) - if( FAILED( hr = CreateEnvironment( pDriverGUID, pDeviceGUID, pMode, - dwFlags ) ) ) - { - DestroyObjects(); - return hr; - } - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: CreateEnvironment() -// Desc: Creates the internal objects for the framework -//----------------------------------------------------------------------------- -HRESULT CD3DFramework7::CreateEnvironment( GUID* pDriverGUID, GUID* pDeviceGUID, - DDSURFACEDESC2* pMode, DWORD dwFlags ) -{ - HRESULT hr; - - // Select the default memory type, for whether the device is HW or SW - if( IsEqualIID( *pDeviceGUID, IID_IDirect3DHALDevice) ) - m_dwDeviceMemType = DDSCAPS_VIDEOMEMORY; - else if( IsEqualIID( *pDeviceGUID, IID_IDirect3DTnLHalDevice) ) - m_dwDeviceMemType = DDSCAPS_VIDEOMEMORY; - else - m_dwDeviceMemType = DDSCAPS_SYSTEMMEMORY; - - // Create the DDraw object - hr = CreateDirectDraw( pDriverGUID, dwFlags ); - if( FAILED( hr ) ) - return hr; - - // Create the front and back buffers, and attach a clipper - if( dwFlags & D3DFW_FULLSCREEN ) - hr = CreateFullscreenBuffers( pMode ); - else - hr = CreateWindowedBuffers(); - if( FAILED( hr ) ) - return hr; - - // Create the Direct3D object and the Direct3DDevice object - hr = CreateDirect3D( pDeviceGUID ); - if( FAILED( hr ) ) - return hr; - - // Create and attach the zbuffer - if( dwFlags & D3DFW_ZBUFFER ) - hr = CreateZBuffer( pDeviceGUID ); - if( FAILED( hr ) ) - return hr; - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: EnumZBufferFormatsCallback() -// Desc: Simply returns the first matching enumerated z-buffer format -//----------------------------------------------------------------------------- -static HRESULT WINAPI EnumZBufferFormatsCallback( DDPIXELFORMAT* pddpf, - VOID* pContext ) -{ - DDPIXELFORMAT* pddpfOut = (DDPIXELFORMAT*)pContext; - - if( pddpfOut->dwRGBBitCount == pddpf->dwRGBBitCount ) - { - (*pddpfOut) = (*pddpf); - return D3DENUMRET_CANCEL; - } - - return D3DENUMRET_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: CreateDirectDraw() -// Desc: Create the DirectDraw interface -//----------------------------------------------------------------------------- -HRESULT CD3DFramework7::CreateDirectDraw( GUID* pDriverGUID, DWORD dwFlags ) -{ - // Create the DirectDraw interface, and query for the DD7 interface - if( FAILED( DirectDrawCreateEx( pDriverGUID, (VOID**)&m_pDD, - IID_IDirectDraw7, NULL ) ) ) - { - DEBUG_MSG( _T("Could not create DirectDraw") ); - return D3DFWERR_NODIRECTDRAW; - } - - // Set the Windows cooperative level - DWORD dwCoopFlags = DDSCL_NORMAL; - if( m_bIsFullscreen ) - dwCoopFlags = DDSCL_ALLOWREBOOT|DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN; - - // By defualt, set the flag to allow D3D to optimize floating point calcs - if( 0L == ( dwFlags & D3DFW_NO_FPUSETUP ) ) - dwCoopFlags |= DDSCL_FPUSETUP; - - if( FAILED( m_pDD->SetCooperativeLevel( m_hWnd, dwCoopFlags ) ) ) - { - DEBUG_MSG( _T("Couldn't set coop level") ); - return D3DFWERR_COULDNTSETCOOPLEVEL; - } - - // Check that we are NOT in a palettized display. That case will fail, - // since the framework doesn't use palettes. - DDSURFACEDESC2 ddsd; - ddsd.dwSize = sizeof(ddsd); - m_pDD->GetDisplayMode( &ddsd ); - if( ddsd.ddpfPixelFormat.dwRGBBitCount <= 8 ) - return D3DFWERR_INVALIDMODE; - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: CreateFullscreenBuffers() -// Desc: Creates the primary and (optional) backbuffer for rendering. -// Windowed mode and fullscreen mode are handled differently. -//----------------------------------------------------------------------------- -HRESULT CD3DFramework7::CreateFullscreenBuffers( DDSURFACEDESC2* pddsd ) -{ - HRESULT hr; - - // Get the dimensions of the screen bounds - // Store the rectangle which contains the renderer - SetRect( &m_rcScreenRect, 0, 0, pddsd->dwWidth, pddsd->dwHeight ); - m_dwRenderWidth = m_rcScreenRect.right - m_rcScreenRect.left; - m_dwRenderHeight = m_rcScreenRect.bottom - m_rcScreenRect.top; - - // Set the display mode to the requested dimensions. Check for - // 320x200x8 modes, and set flag to avoid using ModeX - DWORD dwModeFlags = 0; - - if( (320==m_dwRenderWidth) && (200==m_dwRenderHeight) && - (8==pddsd->ddpfPixelFormat.dwRGBBitCount) ) - dwModeFlags |= DDSDM_STANDARDVGAMODE; - - if( FAILED( m_pDD->SetDisplayMode( m_dwRenderWidth, m_dwRenderHeight, - pddsd->ddpfPixelFormat.dwRGBBitCount, - pddsd->dwRefreshRate, dwModeFlags ) ) ) - { - DEBUG_MSG( _T("Can't set display mode") ); - return D3DFWERR_BADDISPLAYMODE; - } - - // Setup to create the primary surface w/backbuffer - DDSURFACEDESC2 ddsd; - ZeroMemory( &ddsd, sizeof(ddsd) ); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | - DDSCAPS_FLIP | DDSCAPS_COMPLEX; - ddsd.dwBackBufferCount = 1; - - // Support for stereoscopic viewing - if( m_bIsStereo ) - { - ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; - ddsd.ddsCaps.dwCaps2 |= DDSCAPS2_STEREOSURFACELEFT; - } - - // Create the primary surface - if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL ) ) ) - { - DEBUG_MSG( _T("Error: Can't create primary surface") ); - if( hr != DDERR_OUTOFVIDEOMEMORY ) - return D3DFWERR_NOPRIMARY; - DEBUG_MSG( _T("Error: Out of video memory") ); - return DDERR_OUTOFVIDEOMEMORY; - } - - // Get the backbuffer, which was created along with the primary. - DDSCAPS2 ddscaps = { DDSCAPS_BACKBUFFER, 0, 0, 0 }; - if( FAILED( hr = m_pddsFrontBuffer->GetAttachedSurface( &ddscaps, - &m_pddsBackBuffer ) ) ) - { - DEBUG_ERR( hr, _T("Error: Can't get the backbuffer") ); - return D3DFWERR_NOBACKBUFFER; - } - - // Increment the backbuffer count (for consistency with windowed mode) - m_pddsBackBuffer->AddRef(); - - // Support for stereoscopic viewing - if( m_bIsStereo ) - { - // Get the left backbuffer, which was created along with the primary. - DDSCAPS2 ddscaps = { 0, DDSCAPS2_STEREOSURFACELEFT, 0, 0 }; - if( FAILED( hr = m_pddsBackBuffer->GetAttachedSurface( &ddscaps, - &m_pddsBackBufferLeft ) ) ) - { - DEBUG_ERR( hr, _T("Error: Can't get the left backbuffer") ); - return D3DFWERR_NOBACKBUFFER; - } - m_pddsBackBufferLeft->AddRef(); - } - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: CreateWindowedBuffers() -// Desc: Creates the primary and (optional) backbuffer for rendering. -// Windowed mode and fullscreen mode are handled differently. -//----------------------------------------------------------------------------- -HRESULT CD3DFramework7::CreateWindowedBuffers() -{ - HRESULT hr; - - // Get the dimensions of the viewport and screen bounds - GetClientRect( m_hWnd, &m_rcScreenRect ); - ClientToScreen( m_hWnd, (POINT*)&m_rcScreenRect.left ); - ClientToScreen( m_hWnd, (POINT*)&m_rcScreenRect.right ); - m_dwRenderWidth = m_rcScreenRect.right - m_rcScreenRect.left; - m_dwRenderHeight = m_rcScreenRect.bottom - m_rcScreenRect.top; - - // Create the primary surface - DDSURFACEDESC2 ddsd; - ZeroMemory( &ddsd, sizeof(ddsd) ); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - - if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL ) ) ) - { - DEBUG_MSG( _T("Error: Can't create primary surface") ); - if( hr != DDERR_OUTOFVIDEOMEMORY ) - return D3DFWERR_NOPRIMARY; - DEBUG_MSG( _T("Error: Out of video memory") ); - return DDERR_OUTOFVIDEOMEMORY; - } - - // If in windowed-mode, create a clipper object - LPDIRECTDRAWCLIPPER pcClipper; - if( FAILED( hr = m_pDD->CreateClipper( 0, &pcClipper, NULL ) ) ) - { - DEBUG_MSG( _T("Error: Couldn't create clipper") ); - return D3DFWERR_NOCLIPPER; - } - - // Associate the clipper with the window - pcClipper->SetHWnd( 0, m_hWnd ); - m_pddsFrontBuffer->SetClipper( pcClipper ); - SAFE_RELEASE( pcClipper ); - - // Create a backbuffer - ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; - ddsd.dwWidth = m_dwRenderWidth; - ddsd.dwHeight = m_dwRenderHeight; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; - - if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsBackBuffer, NULL ) ) ) - { - DEBUG_ERR( hr, _T("Error: Couldn't create the backbuffer") ); - if( hr != DDERR_OUTOFVIDEOMEMORY ) - return D3DFWERR_NOBACKBUFFER; - DEBUG_MSG( _T("Error: Out of video memory") ); - return DDERR_OUTOFVIDEOMEMORY; - } - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: CreateDirect3D() -// Desc: Create the Direct3D interface -//----------------------------------------------------------------------------- -HRESULT CD3DFramework7::CreateDirect3D( GUID* pDeviceGUID ) -{ - // Query DirectDraw for access to Direct3D - if( FAILED( m_pDD->QueryInterface( IID_IDirect3D7, (VOID**)&m_pD3D ) ) ) - { - DEBUG_MSG( _T("Couldn't get the Direct3D interface") ); - return D3DFWERR_NODIRECT3D; - } - - // Create the device - if( FAILED( m_pD3D->CreateDevice( *pDeviceGUID, m_pddsBackBuffer, - &m_pd3dDevice) ) ) - { - DEBUG_MSG( _T("Couldn't create the D3DDevice") ); - return D3DFWERR_NO3DDEVICE; - } - - // Finally, set the viewport for the newly created device - D3DVIEWPORT7 vp = { 0, 0, m_dwRenderWidth, m_dwRenderHeight, 0.0f, 1.0f }; - - if( FAILED( m_pd3dDevice->SetViewport( &vp ) ) ) - { - DEBUG_MSG( _T("Error: Couldn't set current viewport to device") ); - return D3DFWERR_NOVIEWPORT; - } - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: CreateZBuffer() -// Desc: Internal function called by Create() to make and attach a zbuffer -// to the renderer -//----------------------------------------------------------------------------- -HRESULT CD3DFramework7::CreateZBuffer( GUID* pDeviceGUID ) -{ - HRESULT hr; - - // Check if the device supports z-bufferless hidden surface removal. If so, - // we don't really need a z-buffer - D3DDEVICEDESC7 ddDesc; - m_pd3dDevice->GetCaps( &ddDesc ); - if( ddDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR ) - return S_OK; - - // Get z-buffer dimensions from the render target - DDSURFACEDESC2 ddsd; - ddsd.dwSize = sizeof(ddsd); - m_pddsBackBuffer->GetSurfaceDesc( &ddsd ); - - // Setup the surface desc for the z-buffer. - ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT; - ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | m_dwDeviceMemType; - ddsd.ddpfPixelFormat.dwSize = 0; // Tag the pixel format as unitialized - - // Get an appropiate pixel format from enumeration of the formats. On the - // first pass, we look for a zbuffer dpeth which is equal to the frame - // buffer depth (as some cards unfornately require this). - m_pD3D->EnumZBufferFormats( *pDeviceGUID, EnumZBufferFormatsCallback, - (VOID*)&ddsd.ddpfPixelFormat ); - if( 0 == ddsd.ddpfPixelFormat.dwSize ) - { - // Try again, just accepting any 16-bit zbuffer - ddsd.ddpfPixelFormat.dwRGBBitCount = 16; - m_pD3D->EnumZBufferFormats( *pDeviceGUID, EnumZBufferFormatsCallback, - (VOID*)&ddsd.ddpfPixelFormat ); - - if( 0 == ddsd.ddpfPixelFormat.dwSize ) - { - DEBUG_MSG( _T("Device doesn't support requested zbuffer format") ); - return D3DFWERR_NOZBUFFER; - } - } - - // Create and attach a z-buffer - if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsZBuffer, NULL ) ) ) - { - DEBUG_MSG( _T("Error: Couldn't create a ZBuffer surface") ); - if( hr != DDERR_OUTOFVIDEOMEMORY ) - return D3DFWERR_NOZBUFFER; - DEBUG_MSG( _T("Error: Out of video memory") ); - return DDERR_OUTOFVIDEOMEMORY; - } - - if( FAILED( m_pddsBackBuffer->AddAttachedSurface( m_pddsZBuffer ) ) ) - { - DEBUG_MSG( _T("Error: Couldn't attach zbuffer to render surface") ); - return D3DFWERR_NOZBUFFER; - } - - // For stereoscopic viewing, attach zbuffer to left surface as well - if( m_bIsStereo ) - { - if( FAILED( m_pddsBackBufferLeft->AddAttachedSurface( m_pddsZBuffer ) ) ) - { - DEBUG_MSG( _T("Error: Couldn't attach zbuffer to left render surface") ); - return D3DFWERR_NOZBUFFER; - } - } - - // Finally, this call rebuilds internal structures - if( FAILED( m_pd3dDevice->SetRenderTarget( m_pddsBackBuffer, 0L ) ) ) - { - DEBUG_MSG( _T("Error: SetRenderTarget() failed after attaching zbuffer!") ); - return D3DFWERR_NOZBUFFER; - } - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: RestoreSurfaces() -// Desc: Checks for lost surfaces and restores them if lost. Note: Don't -// restore render surface, since it's just a duplicate ptr. -//----------------------------------------------------------------------------- -HRESULT CD3DFramework7::RestoreSurfaces() -{ - // Restore all surfaces (including video memory vertex buffers) - m_pDD->RestoreAllSurfaces(); - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: Move() -// Desc: Moves the screen rect for windowed renderers -//----------------------------------------------------------------------------- -VOID CD3DFramework7::Move( INT x, INT y ) -{ - if( TRUE == m_bIsFullscreen ) - return; - - SetRect( &m_rcScreenRect, x, y, x + m_dwRenderWidth, y + m_dwRenderHeight ); -} - - - - -//----------------------------------------------------------------------------- -// Name: FlipToGDISurface() -// Desc: Puts the GDI surface in front of the primary, so that dialog -// boxes and other windows drawing funcs may happen. -//----------------------------------------------------------------------------- -HRESULT CD3DFramework7::FlipToGDISurface( BOOL bDrawFrame ) -{ - if( m_pDD && m_bIsFullscreen ) - { - m_pDD->FlipToGDISurface(); - - if( bDrawFrame ) - { - DrawMenuBar( m_hWnd ); - RedrawWindow( m_hWnd, NULL, NULL, RDW_FRAME ); - } - } - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: ShowFrame() -// Desc: Show the frame on the primary surface, via a blt or a flip. -//----------------------------------------------------------------------------- -HRESULT CD3DFramework7::ShowFrame() -{ - if( NULL == m_pddsFrontBuffer ) - return D3DFWERR_NOTINITIALIZED; - - if( m_bIsFullscreen ) - { - // We are in fullscreen mode, so perform a flip. - if( m_bIsStereo ) - return m_pddsFrontBuffer->Flip( NULL, DDFLIP_WAIT | DDFLIP_STEREO ); - else - return m_pddsFrontBuffer->Flip( NULL, DDFLIP_WAIT ); - } - else - { - // We are in windowed mode, so perform a blit. - return m_pddsFrontBuffer->Blt( &m_rcScreenRect, m_pddsBackBuffer, - NULL, DDBLT_WAIT, NULL ); - } -} - - - diff --git a/src/d3dframe.h b/src/d3dframe.h deleted file mode 100644 index 8e41b83..0000000 --- a/src/d3dframe.h +++ /dev/null @@ -1,142 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -//----------------------------------------------------------------------------- -// File: D3DFrame.h -// -// Desc: Class to manage the Direct3D environment objects such as buffers, -// viewports, and 3D devices. -// -// The class is initialized with the Initialize() function, after which -// the Get????() functions can be used to access the objects needed for -// rendering. If the device or display needs to be changed, the -// ChangeDevice() function can be called. If the display window is moved -// the changes need to be reported with the Move() function. -// -// After rendering a frame, the ShowFrame() function filps or blits the -// backbuffer contents to the primary. If surfaces are lost, they can be -// restored with the RestoreSurfaces() function. Finally, if normal -// Windows output is needed, the FlipToGDISurface() provides a GDI -// surface to draw on. -// -// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved -//----------------------------------------------------------------------------- -#ifndef D3DFRAME_H -#define D3DFRAME_H -#include -#include - - - - -//----------------------------------------------------------------------------- -// Name: CD3DFramework7 -// Desc: The Direct3D sample framework class for DX7. Maintains the D3D -// surfaces and device used for 3D rendering. -//----------------------------------------------------------------------------- -class CD3DFramework7 -{ - // Internal variables for the framework class - HWND m_hWnd; // The window object - BOOL m_bIsFullscreen; // Fullscreen vs. windowed - BOOL m_bIsStereo; // Stereo view mode - DWORD m_dwRenderWidth; // Dimensions of the render target - DWORD m_dwRenderHeight; - RECT m_rcScreenRect; // Screen rect for window - LPDIRECTDRAW7 m_pDD; // The DirectDraw object - LPDIRECT3D7 m_pD3D; // The Direct3D object - LPDIRECT3DDEVICE7 m_pd3dDevice; // The D3D device - LPDIRECTDRAWSURFACE7 m_pddsFrontBuffer; // The primary surface - LPDIRECTDRAWSURFACE7 m_pddsBackBuffer; // The backbuffer surface - LPDIRECTDRAWSURFACE7 m_pddsBackBufferLeft; // For stereo modes - LPDIRECTDRAWSURFACE7 m_pddsZBuffer; // The zbuffer surface - DWORD m_dwDeviceMemType; - - // Internal functions for the framework class - HRESULT CreateZBuffer( GUID* ); - HRESULT CreateFullscreenBuffers( DDSURFACEDESC2* ); - HRESULT CreateWindowedBuffers(); - HRESULT CreateDirectDraw( GUID*, DWORD ); - HRESULT CreateDirect3D( GUID* ); - HRESULT CreateEnvironment( GUID*, GUID*, DDSURFACEDESC2*, DWORD ); - -public: - // Access functions for DirectX objects - LPDIRECTDRAW7 GetDirectDraw() { return m_pDD; } - LPDIRECT3D7 GetDirect3D() { return m_pD3D; } - LPDIRECT3DDEVICE7 GetD3DDevice() { return m_pd3dDevice; } - LPDIRECTDRAWSURFACE7 GetFrontBuffer() { return m_pddsFrontBuffer; } - LPDIRECTDRAWSURFACE7 GetBackBuffer() { return m_pddsBackBuffer; } - LPDIRECTDRAWSURFACE7 GetRenderSurface() { return m_pddsBackBuffer; } - LPDIRECTDRAWSURFACE7 GetRenderSurfaceLeft() { return m_pddsBackBufferLeft; } - - // Functions to aid rendering - HRESULT RestoreSurfaces(); - HRESULT ShowFrame(); - HRESULT FlipToGDISurface( BOOL bDrawFrame = FALSE ); - - // Functions for managing screen and viewport bounds - BOOL IsFullscreen() { return m_bIsFullscreen; } - BOOL IsStereo() { return m_bIsStereo; } - VOID Move( INT x, INT y ); - - // Creates the Framework - HRESULT Initialize( HWND hWnd, GUID* pDriverGUID, GUID* pDeviceGUID, - DDSURFACEDESC2* pddsd, DWORD dwFlags ); - HRESULT DestroyObjects(); - - CD3DFramework7(); - ~CD3DFramework7(); -}; - - - - -//----------------------------------------------------------------------------- -// Flags used for the Initialize() method of a CD3DFramework object -//----------------------------------------------------------------------------- -#define D3DFW_FULLSCREEN 0x00000001 // Use fullscreen mode -#define D3DFW_STEREO 0x00000002 // Use stereo-scopic viewing -#define D3DFW_ZBUFFER 0x00000004 // Create and use a zbuffer -#define D3DFW_NO_FPUSETUP 0x00000008 // Don't use default DDSCL_FPUSETUP flag - - - - -//----------------------------------------------------------------------------- -// Errors that the Initialize() and ChangeDriver() calls may return -//----------------------------------------------------------------------------- -#define D3DFWERR_INITIALIZATIONFAILED 0x82000000 -#define D3DFWERR_NODIRECTDRAW 0x82000001 -#define D3DFWERR_COULDNTSETCOOPLEVEL 0x82000002 -#define D3DFWERR_NODIRECT3D 0x82000003 -#define D3DFWERR_NO3DDEVICE 0x82000004 -#define D3DFWERR_NOZBUFFER 0x82000005 -#define D3DFWERR_INVALIDZBUFFERDEPTH 0x82000006 -#define D3DFWERR_NOVIEWPORT 0x82000007 -#define D3DFWERR_NOPRIMARY 0x82000008 -#define D3DFWERR_NOCLIPPER 0x82000009 -#define D3DFWERR_BADDISPLAYMODE 0x8200000a -#define D3DFWERR_NOBACKBUFFER 0x8200000b -#define D3DFWERR_NONZEROREFCOUNT 0x8200000c -#define D3DFWERR_NORENDERTARGET 0x8200000d -#define D3DFWERR_INVALIDMODE 0x8200000e -#define D3DFWERR_NOTINITIALIZED 0x8200000f - - -#endif // D3DFRAME_H - - diff --git a/src/d3dmath.cpp b/src/d3dmath.cpp deleted file mode 100644 index 2686215..0000000 --- a/src/d3dmath.cpp +++ /dev/null @@ -1,343 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -//----------------------------------------------------------------------------- -// File: D3DMath.cpp -// -// Desc: Shortcut macros and functions for using DX objects -// -// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved -//----------------------------------------------------------------------------- -#define D3D_OVERLOADS -#define STRICT -#include -#include -#include "d3dmath.h" - - - - -//----------------------------------------------------------------------------- -// Name: D3DMath_MatrixMultiply() -// Desc: Does the matrix operation: [Q] = [A] * [B]. Note that the order of -// this operation was changed from the previous version of the DXSDK. -//----------------------------------------------------------------------------- -VOID D3DMath_MatrixMultiply( D3DMATRIX& q, D3DMATRIX& a, D3DMATRIX& b ) -{ - FLOAT* pA = (FLOAT*)&a; - FLOAT* pB = (FLOAT*)&b; - FLOAT pM[16]; - - ZeroMemory( pM, sizeof(D3DMATRIX) ); - - for( WORD i=0; i<4; i++ ) - for( WORD j=0; j<4; j++ ) - for( WORD k=0; k<4; k++ ) - pM[4*i+j] += pA[4*i+k] * pB[4*k+j]; - - memcpy( &q, pM, sizeof(D3DMATRIX) ); -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DMath_MatrixInvert() -// Desc: Does the matrix operation: [Q] = inv[A]. Note: this function only -// works for matrices with [0 0 0 1] for the 4th column. -//----------------------------------------------------------------------------- -HRESULT D3DMath_MatrixInvert( D3DMATRIX& q, D3DMATRIX& a ) -{ - if( fabs(a._44 - 1.0f) > .001f) - return E_INVALIDARG; - if( fabs(a._14) > .001f || fabs(a._24) > .001f || fabs(a._34) > .001f ) - return E_INVALIDARG; - - FLOAT fDetInv = 1.0f / ( a._11 * ( a._22 * a._33 - a._23 * a._32 ) - - a._12 * ( a._21 * a._33 - a._23 * a._31 ) + - a._13 * ( a._21 * a._32 - a._22 * a._31 ) ); - - q._11 = fDetInv * ( a._22 * a._33 - a._23 * a._32 ); - q._12 = -fDetInv * ( a._12 * a._33 - a._13 * a._32 ); - q._13 = fDetInv * ( a._12 * a._23 - a._13 * a._22 ); - q._14 = 0.0f; - - q._21 = -fDetInv * ( a._21 * a._33 - a._23 * a._31 ); - q._22 = fDetInv * ( a._11 * a._33 - a._13 * a._31 ); - q._23 = -fDetInv * ( a._11 * a._23 - a._13 * a._21 ); - q._24 = 0.0f; - - q._31 = fDetInv * ( a._21 * a._32 - a._22 * a._31 ); - q._32 = -fDetInv * ( a._11 * a._32 - a._12 * a._31 ); - q._33 = fDetInv * ( a._11 * a._22 - a._12 * a._21 ); - q._34 = 0.0f; - - q._41 = -( a._41 * q._11 + a._42 * q._21 + a._43 * q._31 ); - q._42 = -( a._41 * q._12 + a._42 * q._22 + a._43 * q._32 ); - q._43 = -( a._41 * q._13 + a._42 * q._23 + a._43 * q._33 ); - q._44 = 1.0f; - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DMath_VectorMatrixMultiply() -// Desc: Multiplies a vector by a matrix -//----------------------------------------------------------------------------- -HRESULT D3DMath_VectorMatrixMultiply( D3DVECTOR& vDest, D3DVECTOR& vSrc, - D3DMATRIX& mat) -{ - FLOAT x = vSrc.x*mat._11 + vSrc.y*mat._21 + vSrc.z* mat._31 + mat._41; - FLOAT y = vSrc.x*mat._12 + vSrc.y*mat._22 + vSrc.z* mat._32 + mat._42; - FLOAT z = vSrc.x*mat._13 + vSrc.y*mat._23 + vSrc.z* mat._33 + mat._43; - FLOAT w = vSrc.x*mat._14 + vSrc.y*mat._24 + vSrc.z* mat._34 + mat._44; - - if( fabs( w ) < g_EPSILON ) - return E_INVALIDARG; - - vDest.x = x/w; - vDest.y = y/w; - vDest.z = z/w; - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DMath_VertexMatrixMultiply() -// Desc: Multiplies a vertex by a matrix -//----------------------------------------------------------------------------- -HRESULT D3DMath_VertexMatrixMultiply( D3DVERTEX& vDest, D3DVERTEX& vSrc, - D3DMATRIX& mat ) -{ - HRESULT hr; - D3DVECTOR* pSrcVec = (D3DVECTOR*)&vSrc.x; - D3DVECTOR* pDestVec = (D3DVECTOR*)&vDest.x; - - if( SUCCEEDED( hr = D3DMath_VectorMatrixMultiply( *pDestVec, *pSrcVec, - mat ) ) ) - { - pSrcVec = (D3DVECTOR*)&vSrc.nx; - pDestVec = (D3DVECTOR*)&vDest.nx; - hr = D3DMath_VectorMatrixMultiply( *pDestVec, *pSrcVec, mat ); - } - return hr; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DMath_QuaternionFromRotation() -// Desc: Converts a normalized axis and angle to a unit quaternion. -//----------------------------------------------------------------------------- -VOID D3DMath_QuaternionFromRotation( FLOAT& x, FLOAT& y, FLOAT& z, FLOAT& w, - D3DVECTOR& v, FLOAT fTheta ) -{ - x = sinf( fTheta/2.0f ) * v.x; - y = sinf( fTheta/2.0f ) * v.y; - z = sinf( fTheta/2.0f ) * v.z; - w = cosf( fTheta/2.0f ); -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DMath_RotationFromQuaternion() -// Desc: Converts a normalized axis and angle to a unit quaternion. -//----------------------------------------------------------------------------- -VOID D3DMath_RotationFromQuaternion( D3DVECTOR& v, FLOAT& fTheta, - FLOAT x, FLOAT y, FLOAT z, FLOAT w ) - -{ - fTheta = acosf(w) * 2.0f; - v.x = x / sinf( fTheta/2.0f ); - v.y = y / sinf( fTheta/2.0f ); - v.z = z / sinf( fTheta/2.0f ); -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DMath_QuaternionFromAngles() -// Desc: Converts euler angles to a unit quaternion. -//----------------------------------------------------------------------------- -VOID D3DMath_QuaternionFromAngles( FLOAT& x, FLOAT& y, FLOAT& z, FLOAT& w, - FLOAT fYaw, FLOAT fPitch, FLOAT fRoll ) - -{ - FLOAT fSinYaw = sinf( fYaw/2.0f ); - FLOAT fSinPitch = sinf( fPitch/2.0f ); - FLOAT fSinRoll = sinf( fRoll/2.0f ); - FLOAT fCosYaw = cosf( fYaw/2.0f ); - FLOAT fCosPitch = cosf( fPitch/2.0f ); - FLOAT fCosRoll = cosf( fRoll/2.0f ); - - x = fSinRoll * fCosPitch * fCosYaw - fCosRoll * fSinPitch * fSinYaw; - y = fCosRoll * fSinPitch * fCosYaw + fSinRoll * fCosPitch * fSinYaw; - z = fCosRoll * fCosPitch * fSinYaw - fSinRoll * fSinPitch * fCosYaw; - w = fCosRoll * fCosPitch * fCosYaw + fSinRoll * fSinPitch * fSinYaw; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DMath_MatrixFromQuaternion() -// Desc: Converts a unit quaternion into a rotation matrix. -//----------------------------------------------------------------------------- -VOID D3DMath_MatrixFromQuaternion( D3DMATRIX& mat, FLOAT x, FLOAT y, FLOAT z, - FLOAT w ) -{ - FLOAT xx = x*x; FLOAT yy = y*y; FLOAT zz = z*z; - FLOAT xy = x*y; FLOAT xz = x*z; FLOAT yz = y*z; - FLOAT wx = w*x; FLOAT wy = w*y; FLOAT wz = w*z; - - mat._11 = 1 - 2 * ( yy + zz ); - mat._12 = 2 * ( xy - wz ); - mat._13 = 2 * ( xz + wy ); - - mat._21 = 2 * ( xy + wz ); - mat._22 = 1 - 2 * ( xx + zz ); - mat._23 = 2 * ( yz - wx ); - - mat._31 = 2 * ( xz - wy ); - mat._32 = 2 * ( yz + wx ); - mat._33 = 1 - 2 * ( xx + yy ); - - mat._14 = mat._24 = mat._34 = 0.0f; - mat._41 = mat._42 = mat._43 = 0.0f; - mat._44 = 1.0f; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DMath_QuaternionFromMatrix() -// Desc: Converts a rotation matrix into a unit quaternion. -//----------------------------------------------------------------------------- -VOID D3DMath_QuaternionFromMatrix( FLOAT& x, FLOAT& y, FLOAT& z, FLOAT& w, - D3DMATRIX& mat ) -{ - if( mat._11 + mat._22 + mat._33 > 0.0f ) - { - FLOAT s = sqrtf( mat._11 + mat._22 + mat._33 + mat._44 ); - - x = (mat._23-mat._32) / (2*s); - y = (mat._31-mat._13) / (2*s); - z = (mat._12-mat._21) / (2*s); - w = 0.5f * s; - } - else - { - - - } - FLOAT xx = x*x; FLOAT yy = y*y; FLOAT zz = z*z; - FLOAT xy = x*y; FLOAT xz = x*z; FLOAT yz = y*z; - FLOAT wx = w*x; FLOAT wy = w*y; FLOAT wz = w*z; - - mat._11 = 1 - 2 * ( yy + zz ); - mat._12 = 2 * ( xy - wz ); - mat._13 = 2 * ( xz + wy ); - - mat._21 = 2 * ( xy + wz ); - mat._22 = 1 - 2 * ( xx + zz ); - mat._23 = 2 * ( yz - wx ); - - mat._31 = 2 * ( xz - wy ); - mat._32 = 2 * ( yz + wx ); - mat._33 = 1 - 2 * ( xx + yy ); - - mat._14 = mat._24 = mat._34 = 0.0f; - mat._41 = mat._42 = mat._43 = 0.0f; - mat._44 = 1.0f; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DMath_QuaternionMultiply() -// Desc: Mulitples two quaternions together as in {Q} = {A} * {B}. -//----------------------------------------------------------------------------- -VOID D3DMath_QuaternionMultiply( FLOAT& Qx, FLOAT& Qy, FLOAT& Qz, FLOAT& Qw, - FLOAT Ax, FLOAT Ay, FLOAT Az, FLOAT Aw, - FLOAT Bx, FLOAT By, FLOAT Bz, FLOAT Bw ) -{ - FLOAT Dx = Ax*Bw + Ay*Bz - Az*By + Aw*Bx; - FLOAT Dy = -Ax*Bz + Ay*Bw + Az*Bx + Aw*By; - FLOAT Dz = Ax*By - Ay*Bx + Az*Bw + Aw*Bz; - FLOAT Dw = -Ax*Bx - Ay*By - Az*Bz + Aw*Bw; - - Qx = Dx; Qy = Dy; Qz = Dz; Qw = Dw; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DMath_SlerpQuaternions() -// Desc: Compute a quaternion which is the spherical linear interpolation -// between two other quaternions by dvFraction. -//----------------------------------------------------------------------------- -VOID D3DMath_QuaternionSlerp( FLOAT& Qx, FLOAT& Qy, FLOAT& Qz, FLOAT& Qw, - FLOAT Ax, FLOAT Ay, FLOAT Az, FLOAT Aw, - FLOAT Bx, FLOAT By, FLOAT Bz, FLOAT Bw, - FLOAT fAlpha ) -{ - // Compute dot product (equal to cosine of the angle between quaternions) - FLOAT fCosTheta = Ax*Bx + Ay*By + Az*Bz + Aw*Bw; - - // Check angle to see if quaternions are in opposite hemispheres - if( fCosTheta < 0.0f ) - { - // If so, flip one of the quaterions - fCosTheta = -fCosTheta; - Bx = -Bx; By = -By; Bz = -Bz; Bw = -Bw; - } - - // Set factors to do linear interpolation, as a special case where the - // quaternions are close together. - FLOAT fBeta = 1.0f - fAlpha; - - // If the quaternions aren't close, proceed with spherical interpolation - if( 1.0f - fCosTheta > 0.001f ) - { - FLOAT fTheta = acosf( fCosTheta ); - - fBeta = sinf( fTheta*fBeta ) / sinf( fTheta); - fAlpha = sinf( fTheta*fAlpha ) / sinf( fTheta); - } - - // Do the interpolation - Qx = fBeta*Ax + fAlpha*Bx; - Qy = fBeta*Ay + fAlpha*By; - Qz = fBeta*Az + fAlpha*Bz; - Qw = fBeta*Aw + fAlpha*Bw; -} - - - - diff --git a/src/d3dmath.h b/src/d3dmath.h deleted file mode 100644 index d28707d..0000000 --- a/src/d3dmath.h +++ /dev/null @@ -1,97 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -//----------------------------------------------------------------------------- -// File: D3DMath.h -// -// Desc: Math functions and shortcuts for Direct3D programming. -// -// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved -//----------------------------------------------------------------------------- -#ifndef D3DMATH_H -#define D3DMATH_H -#include -#include - - -//----------------------------------------------------------------------------- -// Useful Math constants -//----------------------------------------------------------------------------- -const FLOAT g_PI = 3.14159265358979323846f; // Pi -const FLOAT g_2_PI = 6.28318530717958623200f; // 2 * Pi -const FLOAT g_PI_DIV_2 = 1.57079632679489655800f; // Pi / 2 -const FLOAT g_PI_DIV_4 = 0.78539816339744827900f; // Pi / 4 -const FLOAT g_INV_PI = 0.31830988618379069122f; // 1 / Pi -const FLOAT g_DEGTORAD = 0.01745329251994329547f; // Degrees to Radians -const FLOAT g_RADTODEG = 57.29577951308232286465f; // Radians to Degrees -const FLOAT g_HUGE = 1.0e+38f; // Huge number for FLOAT -const FLOAT g_EPSILON = 1.0e-5f; // Tolerance for FLOATs - - - - -//----------------------------------------------------------------------------- -// Fuzzy compares (within tolerance) -//----------------------------------------------------------------------------- -inline BOOL D3DMath_IsZero( FLOAT a, FLOAT fTol = g_EPSILON ) -{ return ( a <= 0.0f ) ? ( a >= -fTol ) : ( a <= fTol ); } - - - - -//----------------------------------------------------------------------------- -// Matrix functions -//----------------------------------------------------------------------------- -VOID D3DMath_MatrixMultiply( D3DMATRIX& q, D3DMATRIX& a, D3DMATRIX& b ); -HRESULT D3DMath_MatrixInvert( D3DMATRIX& q, D3DMATRIX& a ); - - - - -//----------------------------------------------------------------------------- -// Vector functions -//----------------------------------------------------------------------------- -HRESULT D3DMath_VectorMatrixMultiply( D3DVECTOR& vDest, D3DVECTOR& vSrc, - D3DMATRIX& mat); -HRESULT D3DMath_VertexMatrixMultiply( D3DVERTEX& vDest, D3DVERTEX& vSrc, - D3DMATRIX& mat ); - - - - -//----------------------------------------------------------------------------- -// Quaternion functions -//----------------------------------------------------------------------------- -VOID D3DMath_QuaternionFromRotation( FLOAT& x, FLOAT& y, FLOAT& z, FLOAT& w, - D3DVECTOR& v, FLOAT fTheta ); -VOID D3DMath_RotationFromQuaternion( D3DVECTOR& v, FLOAT& fTheta, - FLOAT x, FLOAT y, FLOAT z, FLOAT w ); -VOID D3DMath_QuaternionFromAngles( FLOAT& x, FLOAT& y, FLOAT& z, FLOAT& w, - FLOAT fYaw, FLOAT fPitch, FLOAT fRoll ); -VOID D3DMath_MatrixFromQuaternion( D3DMATRIX& mat, FLOAT x, FLOAT y, FLOAT z, - FLOAT w ); -VOID D3DMath_QuaternionFromMatrix( FLOAT &x, FLOAT &y, FLOAT &z, FLOAT &w, - D3DMATRIX& mat ); -VOID D3DMath_QuaternionMultiply( FLOAT& Qx, FLOAT& Qy, FLOAT& Qz, FLOAT& Qw, - FLOAT Ax, FLOAT Ay, FLOAT Az, FLOAT Aw, - FLOAT Bx, FLOAT By, FLOAT Bz, FLOAT Bw ); -VOID D3DMath_QuaternionSlerp( FLOAT& Qx, FLOAT& Qy, FLOAT& Qz, FLOAT& Qw, - FLOAT Ax, FLOAT Ay, FLOAT Az, FLOAT Aw, - FLOAT Bx, FLOAT By, FLOAT Bz, FLOAT Bw, - FLOAT fAlpha ); - - -#endif // D3DMATH_H diff --git a/src/d3dres.h b/src/d3dres.h deleted file mode 100644 index d3f8ba8..0000000 --- a/src/d3dres.h +++ /dev/null @@ -1,59 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -//----------------------------------------------------------------------------- -// File: D3DRes.h -// -// Desc: Resource definitions required by the CD3DApplication class. -// Any application using the CD3DApplication class must include resources -// with the following identifiers. -// -// Copyright (c) 1999 Microsoft Corporation. All rights reserved. -//----------------------------------------------------------------------------- -#ifndef D3DRES_H -#define D3DRES_H - - -#define IDI_MAIN_ICON 101 // Application icon -#define IDR_MAIN_ACCEL 113 // Keyboard accelerator -#define IDR_MENU 141 // Application menu -#define IDR_POPUP 142 // Popup menu -#define IDD_ABOUT 143 // About dialog box -#define IDD_CHANGEDEVICE 144 // "Change Device" dialog box -#define IDC_CURSORHAND 149 -#define IDC_CURSORSCROLLL 150 -#define IDC_CURSORSCROLLR 151 -#define IDC_CURSORSCROLLU 152 -#define IDC_CURSORSCROLLD 153 -#define IDC_CURSORTARGET 154 - -#define IDC_DEVICE_COMBO 1000 // Device combobox for "Change Device" dlg -#define IDC_MODE_COMBO 1001 // Mode combobox for "Change Device" dlg -#define IDC_WINDOWED_CHECKBOX 1012 // Checkbox for windowed-mode -#define IDC_STEREO_CHECKBOX 1013 // Checkbox for stereo modes -#define IDC_FULLSCREEN_TEXT 1014 // Group box text label - -#define IDM_ABOUT 40001 // Command to invoke About dlg -#define IDM_CHANGEDEVICE 40002 // Command to invoke "Change Device" dlg -#define IDM_TOGGLEFULLSCREEN 40003 // Command to toggle fullscreen mode -#define IDM_TOGGLESTART 40004 // Command to toggle frame animation -#define IDM_SINGLESTEP 40005 // Command to single step frame animation -#define IDM_EXIT 40006 // Command to exit the application - - - - -#endif // D3DRES_H diff --git a/src/d3dtextr.cpp b/src/d3dtextr.cpp deleted file mode 100644 index cceab99..0000000 --- a/src/d3dtextr.cpp +++ /dev/null @@ -1,1080 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -//----------------------------------------------------------------------------- -// File: D3DTextr.cpp -// -// Desc: Functions to manage textures, including creating (loading from a -// file), restoring lost surfaces, invalidating, and destroying. -// -// Note: the implementation of these fucntions maintain an internal list -// of loaded textures. After creation, individual textures are referenced -// via their ASCII names. -// -// Copyright (c) 1996-1999 Microsoft Corporation. All rights reserved -//----------------------------------------------------------------------------- -#define STRICT -#include -#include -#include "d3dtextr.h" -#include "d3dutil.h" -#include "language.h" -#include "misc.h" - - - - -//----------------------------------------------------------------------------- -// Macros, function prototypes and static variable -//----------------------------------------------------------------------------- -static TCHAR g_strTexturePath[512] = _T(""); // Path for files -static BOOL g_bDebugMode = FALSE; - - - -void D3DTextr_SetDebugMode(BOOL bDebug) -{ - g_bDebugMode = bDebug; -} - - - -//----------------------------------------------------------------------------- -// Name: TextureContainer -// Desc: Linked list structure to hold info per texture -//----------------------------------------------------------------------------- -struct TextureContainer -{ - TextureContainer* m_pNext; // Linked list ptr - - TCHAR m_strName[80]; // Name of texture (doubles as image filename) - DWORD m_dwWidth; - DWORD m_dwHeight; - DWORD m_dwStage; // Texture stage (for multitexture devices) - DWORD m_dwBPP; - DWORD m_dwFlags; - BOOL m_bHasAlpha; - - LPDIRECTDRAWSURFACE7 m_pddsSurface; // Surface of the texture - HBITMAP m_hbmBitmap; // Bitmap containing texture image - DWORD* m_pRGBAData; - -public: - HRESULT LoadImageData(); - HRESULT LoadBitmapFile( TCHAR* strPathname ); - HRESULT LoadTargaFile( TCHAR* strPathname, TCHAR* strFilename ); - HRESULT Restore( LPDIRECT3DDEVICE7 pd3dDevice ); - HRESULT CopyBitmapToSurface(); - HRESULT CopyRGBADataToSurface(); - - TextureContainer( TCHAR* strName, DWORD dwStage, DWORD dwFlags ); - ~TextureContainer(); -}; - -// Local list of textures -static TextureContainer* g_ptcTextureList = NULL; - - - - -//----------------------------------------------------------------------------- -// Name: CD3DTextureManager -// Desc: Class used to automatically construct and destruct the static -// texture engine class. -//----------------------------------------------------------------------------- -class CD3DTextureManager -{ -public: - CD3DTextureManager() {} - ~CD3DTextureManager() { if( g_ptcTextureList ) delete g_ptcTextureList; } -}; - -// Global instance -CD3DTextureManager g_StaticTextureEngine; - - - - -//----------------------------------------------------------------------------- -// Name: struct TEXTURESEARCHINFO -// Desc: Structure used to search for texture formats -//----------------------------------------------------------------------------- -struct TEXTURESEARCHINFO -{ - DWORD dwDesiredBPP; // Input for texture format search - BOOL bUseAlpha; - BOOL bUsePalette; - BOOL bFoundGoodFormat; - - DDPIXELFORMAT* pddpf; // Output of texture format search -}; - - - - -//----------------------------------------------------------------------------- -// Name: TextureSearchCallback() -// Desc: Enumeration callback routine to find a best-matching texture format. -// The param data is the DDPIXELFORMAT of the best-so-far matching -// texture. Note: the desired BPP is passed in the dwSize field, and the -// default BPP is passed in the dwFlags field. -//----------------------------------------------------------------------------- -static HRESULT CALLBACK TextureSearchCallback( DDPIXELFORMAT* pddpf, - VOID* param ) -{ - if( NULL==pddpf || NULL==param ) - return DDENUMRET_OK; - - TEXTURESEARCHINFO* ptsi = (TEXTURESEARCHINFO*)param; - - // Skip any funky modes - if( pddpf->dwFlags & (DDPF_LUMINANCE|DDPF_BUMPLUMINANCE|DDPF_BUMPDUDV) ) - return DDENUMRET_OK; - - // Check for palettized formats - if( ptsi->bUsePalette ) - { - if( !( pddpf->dwFlags & DDPF_PALETTEINDEXED8 ) ) - return DDENUMRET_OK; - - // Accept the first 8-bit palettized format we get - memcpy( ptsi->pddpf, pddpf, sizeof(DDPIXELFORMAT) ); - ptsi->bFoundGoodFormat = TRUE; - return DDENUMRET_CANCEL; - } - - // Else, skip any paletized formats (all modes under 16bpp) - if( pddpf->dwRGBBitCount < 16 ) - return DDENUMRET_OK; - - // Skip any FourCC formats - if( pddpf->dwFourCC != 0 ) - return DDENUMRET_OK; - - // Skip any ARGB 4444 formats (which are best used for pre-authored - // content designed speciafically for an ARGB 4444 format). - if( pddpf->dwRGBAlphaBitMask == 0x0000f000 ) - return DDENUMRET_OK; - - // Make sure current alpha format agrees with requested format type - if( (ptsi->bUseAlpha==TRUE) && !(pddpf->dwFlags&DDPF_ALPHAPIXELS) ) - return DDENUMRET_OK; - if( (ptsi->bUseAlpha==FALSE) && (pddpf->dwFlags&DDPF_ALPHAPIXELS) ) - return DDENUMRET_OK; - - // Check if we found a good match - if( pddpf->dwRGBBitCount == ptsi->dwDesiredBPP ) - { - memcpy( ptsi->pddpf, pddpf, sizeof(DDPIXELFORMAT) ); - ptsi->bFoundGoodFormat = TRUE; - return DDENUMRET_CANCEL; - } - - return DDENUMRET_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: FindTexture() -// Desc: Searches the internal list of textures for a texture specified by -// its name. Returns the structure associated with that texture. -//----------------------------------------------------------------------------- -static TextureContainer* FindTexture( TCHAR* strTextureName ) -{ - TextureContainer* ptcTexture = g_ptcTextureList; - - while( ptcTexture ) - { - if( !lstrcmpi( strTextureName, ptcTexture->m_strName ) ) - return ptcTexture; - ptcTexture = ptcTexture->m_pNext; - } - - return NULL; -} - - - - -//----------------------------------------------------------------------------- -// Name: TextureContainer() -// Desc: Constructor for a texture object -//----------------------------------------------------------------------------- -TextureContainer::TextureContainer( TCHAR* strName, DWORD dwStage, - DWORD dwFlags ) -{ - lstrcpy( m_strName, strName ); - m_dwWidth = 0; - m_dwHeight = 0; - m_dwStage = dwStage; - m_dwBPP = 0; - m_dwFlags = dwFlags; - m_bHasAlpha = 0; - - m_pddsSurface = NULL; - m_hbmBitmap = NULL; - m_pRGBAData = NULL; - - // Add the texture to the head of the global texture list - m_pNext = g_ptcTextureList; - g_ptcTextureList = this; - -} - - - - -//----------------------------------------------------------------------------- -// Name: ~TextureContainer() -// Desc: Destructs the contents of the texture container -//----------------------------------------------------------------------------- -TextureContainer::~TextureContainer() -{ - SAFE_RELEASE( m_pddsSurface ); - SAFE_DELETE( m_pRGBAData ); - DeleteObject( m_hbmBitmap ); - - // Remove the texture container from the global list - if( g_ptcTextureList == this ) - g_ptcTextureList = m_pNext; - else - { - for( TextureContainer* ptc=g_ptcTextureList; ptc; ptc=ptc->m_pNext ) - if( ptc->m_pNext == this ) - ptc->m_pNext = m_pNext; - } -} - - - - -//----------------------------------------------------------------------------- -// Name: LoadImageData() -// Desc: Loads the texture map's image data -//----------------------------------------------------------------------------- -HRESULT TextureContainer::LoadImageData() -{ - TCHAR* strExtension; - TCHAR strMetaname[256]; - TCHAR strFilename[256]; - - if ( g_bDebugMode ) - { - if ( _tcsrchr( m_strName, _T('\\') ) == 0 ) - { - lstrcpy( strMetaname, "" ); - lstrcpy( strFilename, g_strTexturePath ); - lstrcat( strFilename, m_strName ); - } - else - { - lstrcpy( strMetaname, "" ); - lstrcpy( strFilename, m_strName ); - } - } - else - { - if ( _tcsrchr( m_strName, _T('\\') ) == 0 ) - { -#if _SCHOOL - lstrcpy( strMetaname, "ceebot1.dat" ); -#else - lstrcpy( strMetaname, "colobot1.dat" ); -#endif - lstrcpy( strFilename, m_strName ); - } - else - { - lstrcpy( strMetaname, "" ); - lstrcpy( strFilename, m_strName ); - } - } - - if ( !g_metafile.IsExist(strMetaname, strFilename) ) - { - return DDERR_NOTFOUND; - } - - // Get the filename extension - if ( NULL == ( strExtension = _tcsrchr( m_strName, _T('.') ) ) ) - { - return DDERR_UNSUPPORTED; - } - - // Load bitmap files - if ( strMetaname[0] == 0 && !lstrcmpi( strExtension, _T(".bmp") ) ) - { - return LoadBitmapFile( strFilename ); - } - - // Load targa files - if ( !lstrcmpi( strExtension, _T(".tga") ) ) - { - return LoadTargaFile( strMetaname, strFilename ); - } - - // Can add code here to check for other file formats before failing - return DDERR_UNSUPPORTED; -} - - - - -//----------------------------------------------------------------------------- -// Name: LoadBitmapFile() -// Desc: Loads data from a .bmp file, and stores it in a bitmap structure. -//----------------------------------------------------------------------------- -HRESULT TextureContainer::LoadBitmapFile( TCHAR* strPathname ) -{ - // Try to load the bitmap as a file - m_hbmBitmap = (HBITMAP)LoadImage( NULL, strPathname, IMAGE_BITMAP, 0, 0, - LR_LOADFROMFILE|LR_CREATEDIBSECTION ); - if( m_hbmBitmap ) - return S_OK; - - return DDERR_NOTFOUND; -} - - - - -//----------------------------------------------------------------------------- -// Name: LoadTargaFile() -// Desc: Loads RGBA data from a .tga file, and stores it in allocated memory -// for the specified texture container -//----------------------------------------------------------------------------- -HRESULT TextureContainer::LoadTargaFile( TCHAR* strMetaname, TCHAR* strFilename ) -{ - if( g_metafile.Open(strMetaname, strFilename) != 0 ) - return E_FAIL; - - struct TargaHeader - { - BYTE IDLength; - BYTE ColormapType; - BYTE ImageType; - BYTE ColormapSpecification[5]; - WORD XOrigin; - WORD YOrigin; - WORD ImageWidth; - WORD ImageHeight; - BYTE PixelDepth; - BYTE ImageDescriptor; - } tga; - - g_metafile.Read(&tga, sizeof(TargaHeader)); - - // Only true color, non-mapped images are supported - if( ( 0 != tga.ColormapType ) || - ( tga.ImageType != 10 && tga.ImageType != 2 ) ) - { - g_metafile.Close(); - return E_FAIL; - } - - // Skip the ID field. The first byte of the header is the length of this field - if( tga.IDLength ) - { - g_metafile.Seek(tga.IDLength); - } - - m_dwWidth = tga.ImageWidth; - m_dwHeight = tga.ImageHeight; - m_dwBPP = tga.PixelDepth; - m_pRGBAData = new DWORD[m_dwWidth*m_dwHeight]; - - if( m_pRGBAData == NULL ) - { - g_metafile.Close(); - return E_FAIL; - } - - for( DWORD y=0; yGetCaps( &ddDesc) ) ) - return E_FAIL; - - // Setup the new surface desc - DDSURFACEDESC2 ddsd; - D3DUtil_InitSurfaceDesc( ddsd ); - ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH| - DDSD_PIXELFORMAT|DDSD_TEXTURESTAGE; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; - ddsd.dwTextureStage = m_dwStage; - ddsd.dwWidth = m_dwWidth; - ddsd.dwHeight = m_dwHeight; - - // Turn on texture management for hardware devices - if( ddDesc.deviceGUID == IID_IDirect3DHALDevice ) - ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE; - else if( ddDesc.deviceGUID == IID_IDirect3DTnLHalDevice ) - ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE; - else - ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; - - // Adjust width and height to be powers of 2, if the device requires it - if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2 ) - { - for( ddsd.dwWidth=1; m_dwWidth>ddsd.dwWidth; ddsd.dwWidth<<=1 ); - for( ddsd.dwHeight=1; m_dwHeight>ddsd.dwHeight; ddsd.dwHeight<<=1 ); - } - - // Limit max texture sizes, if the driver can't handle large textures - DWORD dwMaxWidth = ddDesc.dwMaxTextureWidth; - DWORD dwMaxHeight = ddDesc.dwMaxTextureHeight; - ddsd.dwWidth = min( ddsd.dwWidth, ( dwMaxWidth ? dwMaxWidth : 256 ) ); - ddsd.dwHeight = min( ddsd.dwHeight, ( dwMaxHeight ? dwMaxHeight : 256 ) ); - - // Make the texture square, if the driver requires it - if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY ) - { - if( ddsd.dwWidth > ddsd.dwHeight ) ddsd.dwHeight = ddsd.dwWidth; - else ddsd.dwWidth = ddsd.dwHeight; - } - - // Setup the structure to be used for texture enumration. - TEXTURESEARCHINFO tsi; - tsi.bFoundGoodFormat = FALSE; - tsi.pddpf = &ddsd.ddpfPixelFormat; - tsi.dwDesiredBPP = m_dwBPP; - tsi.bUsePalette = ( m_dwBPP <= 8 ); - tsi.bUseAlpha = m_bHasAlpha; - if( m_dwFlags & D3DTEXTR_16BITSPERPIXEL ) - tsi.dwDesiredBPP = 16; - else if( m_dwFlags & D3DTEXTR_32BITSPERPIXEL ) - tsi.dwDesiredBPP = 32; - - if( m_dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) ) - { - if( tsi.bUsePalette ) - { - if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE ) - { - tsi.bUseAlpha = TRUE; - tsi.bUsePalette = TRUE; - } - else - { - tsi.bUseAlpha = TRUE; - tsi.bUsePalette = FALSE; - } - } - } - - // Enumerate the texture formats, and find the closest device-supported - // texture pixel format - pd3dDevice->EnumTextureFormats( TextureSearchCallback, &tsi ); - - // If we couldn't find a format, let's try a default format - if( FALSE == tsi.bFoundGoodFormat ) - { - tsi.bUsePalette = FALSE; - tsi.dwDesiredBPP = 16; - pd3dDevice->EnumTextureFormats( TextureSearchCallback, &tsi ); - - // If we still fail, we cannot create this texture - if( FALSE == tsi.bFoundGoodFormat ) - return E_FAIL; - } - - // Get the DirectDraw interface for creating surfaces - LPDIRECTDRAW7 pDD; - LPDIRECTDRAWSURFACE7 pddsRender; - pd3dDevice->GetRenderTarget( &pddsRender ); - pddsRender->GetDDInterface( (VOID**)&pDD ); - pddsRender->Release(); - - // Create a new surface for the texture - HRESULT hr = pDD->CreateSurface( &ddsd, &m_pddsSurface, NULL ); - - // Done with DDraw - pDD->Release(); - - if( FAILED(hr) ) - return hr; - - // For bitmap-based textures, copy the bitmap image. - if( m_hbmBitmap ) - return CopyBitmapToSurface(); - - if( m_pRGBAData ) - return CopyRGBADataToSurface(); - - // At this point, code can be added to handle other file formats (such as - // .dds files, .jpg files, etc.). - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: CopyBitmapToSurface() -// Desc: Copies the image of a bitmap into a surface -//----------------------------------------------------------------------------- -HRESULT TextureContainer::CopyBitmapToSurface() -{ - // Get a DDraw object to create a temporary surface - LPDIRECTDRAW7 pDD; - m_pddsSurface->GetDDInterface( (VOID**)&pDD ); - - // Get the bitmap structure (to extract width, height, and bpp) - BITMAP bm; - GetObject( m_hbmBitmap, sizeof(BITMAP), &bm ); - - // Setup the new surface desc - DDSURFACEDESC2 ddsd; - ddsd.dwSize = sizeof(ddsd); - m_pddsSurface->GetSurfaceDesc( &ddsd ); - ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT| - DDSD_TEXTURESTAGE; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE|DDSCAPS_SYSTEMMEMORY; - ddsd.ddsCaps.dwCaps2 = 0L; - ddsd.dwWidth = bm.bmWidth; - ddsd.dwHeight = bm.bmHeight; - - // Create a new surface for the texture - LPDIRECTDRAWSURFACE7 pddsTempSurface; - HRESULT hr; - if( FAILED( hr = pDD->CreateSurface( &ddsd, &pddsTempSurface, NULL ) ) ) - { - pDD->Release(); - return hr; - } - - // Get a DC for the bitmap - HDC hdcBitmap = CreateCompatibleDC( NULL ); - if( NULL == hdcBitmap ) - { - pddsTempSurface->Release(); - pDD->Release(); - return hr; - } - SelectObject( hdcBitmap, m_hbmBitmap ); - - // Handle palettized textures. Need to attach a palette - if( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 ) - { - LPDIRECTDRAWPALETTE pPalette; - DWORD dwPaletteFlags = DDPCAPS_8BIT|DDPCAPS_ALLOW256; - DWORD pe[256]; - WORD wNumColors = GetDIBColorTable( hdcBitmap, 0, 256, (RGBQUAD*)pe ); - - // Create the color table - for( WORD i=0; iCreatePalette( dwPaletteFlags, (PALETTEENTRY*)pe, &pPalette, NULL ); - pddsTempSurface->SetPalette( pPalette ); - m_pddsSurface->SetPalette( pPalette ); - SAFE_RELEASE( pPalette ); - } - - // Copy the bitmap image to the surface. - HDC hdcSurface; - if( SUCCEEDED( pddsTempSurface->GetDC( &hdcSurface ) ) ) - { - BitBlt( hdcSurface, 0, 0, bm.bmWidth, bm.bmHeight, hdcBitmap, 0, 0, - SRCCOPY ); - pddsTempSurface->ReleaseDC( hdcSurface ); - } - DeleteDC( hdcBitmap ); - - // Copy the temp surface to the real texture surface - m_pddsSurface->Blt( NULL, pddsTempSurface, NULL, DDBLT_WAIT, NULL ); - - // Done with the temp surface - pddsTempSurface->Release(); - - // For textures with real alpha (not palettized), set transparent bits - if( ddsd.ddpfPixelFormat.dwRGBAlphaBitMask ) - { - if( m_dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) ) - { - // Lock the texture surface - DDSURFACEDESC2 ddsd; - ddsd.dwSize = sizeof(ddsd); - while( m_pddsSurface->Lock( NULL, &ddsd, 0, NULL ) == - DDERR_WASSTILLDRAWING ); - - DWORD dwAlphaMask = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask; - DWORD dwRGBMask = ( ddsd.ddpfPixelFormat.dwRBitMask | - ddsd.ddpfPixelFormat.dwGBitMask | - ddsd.ddpfPixelFormat.dwBBitMask ); - DWORD dwColorkey = 0x00000000; // Colorkey on black - if( m_dwFlags & D3DTEXTR_TRANSPARENTWHITE ) - dwColorkey = dwRGBMask; // Colorkey on white - - // Add an opaque alpha value to each non-colorkeyed pixel - for( DWORD y=0; yUnlock( NULL ); - } - } - - pDD->Release(); - - return S_OK;; -} - - - - -//----------------------------------------------------------------------------- -// Name: CopyRGBADataToSurface() -// Desc: Invalidates the current texture objects and rebuilds new ones -// using the new device. -//----------------------------------------------------------------------------- -HRESULT TextureContainer::CopyRGBADataToSurface() -{ - // Get a DDraw object to create a temporary surface - LPDIRECTDRAW7 pDD; - m_pddsSurface->GetDDInterface( (VOID**)&pDD ); - - // Setup the new surface desc - DDSURFACEDESC2 ddsd; - ddsd.dwSize = sizeof(ddsd); - m_pddsSurface->GetSurfaceDesc( &ddsd ); - ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT| - DDSD_TEXTURESTAGE; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE|DDSCAPS_SYSTEMMEMORY; - ddsd.ddsCaps.dwCaps2 = 0L; - ddsd.dwWidth = m_dwWidth; - ddsd.dwHeight = m_dwHeight; - - // Create a new surface for the texture - LPDIRECTDRAWSURFACE7 pddsTempSurface; - HRESULT hr; - if( FAILED( hr = pDD->CreateSurface( &ddsd, &pddsTempSurface, NULL ) ) ) - { - pDD->Release(); - return NULL; - } - - while( pddsTempSurface->Lock( NULL, &ddsd, 0, 0 ) == DDERR_WASSTILLDRAWING ); - DWORD lPitch = ddsd.lPitch; - BYTE* pBytes = (BYTE*)ddsd.lpSurface; - - DWORD dwRMask = ddsd.ddpfPixelFormat.dwRBitMask; - DWORD dwGMask = ddsd.ddpfPixelFormat.dwGBitMask; - DWORD dwBMask = ddsd.ddpfPixelFormat.dwBBitMask; - DWORD dwAMask = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask; - - DWORD dwRShiftL = 8, dwRShiftR = 0; - DWORD dwGShiftL = 8, dwGShiftR = 0; - DWORD dwBShiftL = 8, dwBShiftR = 0; - DWORD dwAShiftL = 8, dwAShiftR = 0; - - DWORD dwMask; - for( dwMask=dwRMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwRShiftR++; - for( ; dwMask; dwMask>>=1 ) dwRShiftL--; - - for( dwMask=dwGMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwGShiftR++; - for( ; dwMask; dwMask>>=1 ) dwGShiftL--; - - for( dwMask=dwBMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwBShiftR++; - for( ; dwMask; dwMask>>=1 ) dwBShiftL--; - - for( dwMask=dwAMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwAShiftR++; - for( ; dwMask; dwMask>>=1 ) dwAShiftL--; - - for( DWORD y=0; y>24)&0x000000ff); - BYTE g = (BYTE)((dwPixel>>16)&0x000000ff); - BYTE b = (BYTE)((dwPixel>> 8)&0x000000ff); - BYTE a = (BYTE)((dwPixel>> 0)&0x000000ff); - - DWORD dr = ((r>>(dwRShiftL))<>(dwGShiftL))<>(dwBShiftL))<>(dwAShiftL))<Unlock(0); - - // Copy the temp surface to the real texture surface - m_pddsSurface->Blt( NULL, pddsTempSurface, NULL, DDBLT_WAIT, NULL ); - - // Done with the temp objects - pddsTempSurface->Release(); - pDD->Release(); - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DTextr_SetTexturePath() -// Desc: Enumeration callback routine to find a best-matching texture format. -//----------------------------------------------------------------------------- -VOID D3DTextr_SetTexturePath( TCHAR* strTexturePath ) -{ - if( NULL == strTexturePath ) - strTexturePath = _T(""); - lstrcpy( g_strTexturePath, strTexturePath ); -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DTextr_CreateTextureFromFile() -// Desc: Is passed a filename and creates a local Bitmap from that file. -// The texture can not be used until it is restored, however. -//----------------------------------------------------------------------------- -HRESULT D3DTextr_CreateTextureFromFile( TCHAR* strName, DWORD dwStage, - DWORD dwFlags ) -{ - // Check parameters - if( NULL == strName ) - return E_INVALIDARG; - - // Check first to see if the texture is already loaded - if( NULL != FindTexture( strName ) ) - return S_OK; - - // Allocate and add the texture to the linked list of textures; - TextureContainer* ptcTexture = new TextureContainer( strName, dwStage, - dwFlags ); - if( NULL == ptcTexture ) - return E_OUTOFMEMORY; - - // Create a bitmap and load the texture file into it, - if( FAILED( ptcTexture->LoadImageData() ) ) - { - delete ptcTexture; - return E_FAIL; - } - - // Save the image's dimensions - if( ptcTexture->m_hbmBitmap ) - { - BITMAP bm; - GetObject( ptcTexture->m_hbmBitmap, sizeof(BITMAP), &bm ); - ptcTexture->m_dwWidth = (DWORD)bm.bmWidth; - ptcTexture->m_dwHeight = (DWORD)bm.bmHeight; - ptcTexture->m_dwBPP = (DWORD)bm.bmBitsPixel; - } - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DTextr_CreateEmptyTexture() -// Desc: Creates an empty texture. -//----------------------------------------------------------------------------- -HRESULT D3DTextr_CreateEmptyTexture( TCHAR* strName, DWORD dwWidth, - DWORD dwHeight, DWORD dwStage, - DWORD dwFlags ) -{ - // Check parameters - if( NULL == strName ) - return E_INVALIDARG; - - // Check first to see if the texture is already loaded - if( NULL != FindTexture( strName ) ) - return E_FAIL; - - // Allocate and add the texture to the linked list of textures; - TextureContainer* ptcTexture = new TextureContainer( strName, dwStage, - dwFlags ); - if( NULL == ptcTexture ) - return E_OUTOFMEMORY; - - // Save dimensions - ptcTexture->m_dwWidth = dwWidth; - ptcTexture->m_dwHeight = dwHeight; - ptcTexture->m_dwBPP = 16; - if( ptcTexture->m_dwFlags & D3DTEXTR_32BITSPERPIXEL ) - ptcTexture->m_dwBPP = 32; - - // Save alpha usage flag - if( dwFlags & D3DTEXTR_CREATEWITHALPHA ) - ptcTexture->m_bHasAlpha = TRUE; - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DTextr_Restore() -// Desc: Invalidates the current texture objects and rebuilds new ones -// using the new device. -//----------------------------------------------------------------------------- -HRESULT D3DTextr_Restore( TCHAR* strName, LPDIRECT3DDEVICE7 pd3dDevice ) -{ - TextureContainer* ptcTexture = FindTexture( strName ); - if( NULL == ptcTexture ) - return DDERR_NOTFOUND; - - // Restore the texture (this recreates the new surface for this device). - return ptcTexture->Restore( pd3dDevice ); -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DTextr_RestoreAllTextures() -// Desc: This function is called when a mode is changed. It updates all -// texture objects to be valid with the new device. -//----------------------------------------------------------------------------- -HRESULT D3DTextr_RestoreAllTextures( LPDIRECT3DDEVICE7 pd3dDevice ) -{ - TextureContainer* ptcTexture = g_ptcTextureList; - - while( ptcTexture ) - { - D3DTextr_Restore( ptcTexture->m_strName, pd3dDevice ); - ptcTexture = ptcTexture->m_pNext; - } - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DTextr_Invalidate() -// Desc: Used to bump a texture out of (video) memory, this function -// actually destroys the d3dtexture and ddsurface of the texture -//----------------------------------------------------------------------------- -HRESULT D3DTextr_Invalidate( TCHAR* strName ) -{ - TextureContainer* ptcTexture = FindTexture( strName ); - if( NULL == ptcTexture ) - return DDERR_NOTFOUND; - - SAFE_RELEASE( ptcTexture->m_pddsSurface ); - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DTextr_InvalidateAllTextures() -// Desc: This function is called when a mode is changed. It invalidates -// all texture objects so their device can be safely released. -//----------------------------------------------------------------------------- -HRESULT D3DTextr_InvalidateAllTextures() -{ - TextureContainer* ptcTexture = g_ptcTextureList; - - while( ptcTexture ) - { - SAFE_RELEASE( ptcTexture->m_pddsSurface ); - ptcTexture = ptcTexture->m_pNext; - } - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DTextr_DestroyTexture() -// Desc: Frees the resources for the specified texture container -//----------------------------------------------------------------------------- -HRESULT D3DTextr_DestroyTexture( TCHAR* strName ) -{ - TextureContainer* ptcTexture = FindTexture( strName ); - - SAFE_DELETE( ptcTexture ); - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DTextr_GetSurface() -// Desc: Returns a pointer to a d3dSurface from the name of the texture -//----------------------------------------------------------------------------- -LPDIRECTDRAWSURFACE7 D3DTextr_GetSurface( TCHAR* strName ) -{ - TextureContainer* ptcTexture = FindTexture( strName ); - - return ptcTexture ? ptcTexture->m_pddsSurface : NULL; -} - - - - - diff --git a/src/d3dtextr.h b/src/d3dtextr.h deleted file mode 100644 index 54a79bb..0000000 --- a/src/d3dtextr.h +++ /dev/null @@ -1,80 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -//----------------------------------------------------------------------------- -// File: D3DTextr.h -// -// Desc: Functions to manage textures, including creating (loading from a -// file), restoring lost surfaces, invalidating, and destroying. -// -// Note: the implementation of these fucntions maintain an internal list -// of loaded textures. After creation, individual textures are referenced -// via their ASCII names. -// -// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved -//----------------------------------------------------------------------------- -#ifndef D3DTEXTR_H -#define D3DTEXTR_H -#include -#include - - - - -//----------------------------------------------------------------------------- -// Access functions for loaded textures. Note: these functions search -// an internal list of the textures, and use the texture associated with the -// ASCII name. -//----------------------------------------------------------------------------- -LPDIRECTDRAWSURFACE7 D3DTextr_GetSurface( TCHAR* strName ); - - - - -//----------------------------------------------------------------------------- -// Texture invalidation and restoration functions -//----------------------------------------------------------------------------- -HRESULT D3DTextr_Invalidate( TCHAR* strName ); -HRESULT D3DTextr_Restore( TCHAR* strName, LPDIRECT3DDEVICE7 pd3dDevice ); -HRESULT D3DTextr_InvalidateAllTextures(); -HRESULT D3DTextr_RestoreAllTextures( LPDIRECT3DDEVICE7 pd3dDevice ); - - - - -//----------------------------------------------------------------------------- -// Texture creation and deletion functions -//----------------------------------------------------------------------------- -#define D3DTEXTR_TRANSPARENTWHITE 0x00000001 -#define D3DTEXTR_TRANSPARENTBLACK 0x00000002 -#define D3DTEXTR_32BITSPERPIXEL 0x00000004 -#define D3DTEXTR_16BITSPERPIXEL 0x00000008 -#define D3DTEXTR_CREATEWITHALPHA 0x00000010 - - -HRESULT D3DTextr_CreateTextureFromFile( TCHAR* strName, DWORD dwStage=0L, - DWORD dwFlags=0L ); -HRESULT D3DTextr_CreateEmptyTexture( TCHAR* strName, DWORD dwWidth, - DWORD dwHeight, DWORD dwStage, - DWORD dwFlags ); -HRESULT D3DTextr_DestroyTexture( TCHAR* strName ); -VOID D3DTextr_SetTexturePath( TCHAR* strTexturePath ); - -void D3DTextr_SetDebugMode(BOOL bDebug); - - - -#endif // D3DTEXTR_H diff --git a/src/d3dutil.cpp b/src/d3dutil.cpp deleted file mode 100644 index b4a0eb7..0000000 --- a/src/d3dutil.cpp +++ /dev/null @@ -1,327 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -//----------------------------------------------------------------------------- -// File: D3DUtil.cpp -// -// Desc: Shortcut macros and functions for using DX objects -// -// -// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved -//----------------------------------------------------------------------------- -#define D3D_OVERLOADS -#define STRICT -#include -#include -#include -#include "d3dutil.h" - - - - -//----------------------------------------------------------------------------- -// Name: D3DUtil_GetDXSDKMediaPath() -// Desc: Returns the DirectX SDK media path, as stored in the system registry -// during the SDK install. -//----------------------------------------------------------------------------- -const TCHAR* D3DUtil_GetDXSDKMediaPath() -{ - static TCHAR strNull[2] = _T(""); - static TCHAR strPath[512]; - HKEY key; - DWORD type, size = 512; - - // Open the appropriate registry key - LONG result = RegOpenKeyEx( HKEY_LOCAL_MACHINE, - _T("Software\\Microsoft\\DirectX"), - 0, KEY_READ, &key ); - if( ERROR_SUCCESS != result ) - return strNull; - - result = RegQueryValueEx( key, _T("DXSDK Samples Path"), NULL, - &type, (BYTE*)strPath, &size ); - RegCloseKey( key ); - - if( ERROR_SUCCESS != result ) - return strNull; - - lstrcat( strPath, _T("\\D3DIM\\Media\\") ); - - return strPath; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DUtil_InitSurfaceDesc() -// Desc: Helper function called to build a DDSURFACEDESC2 structure, -// typically before calling CreateSurface() or GetSurfaceDesc() -//----------------------------------------------------------------------------- -VOID D3DUtil_InitSurfaceDesc( DDSURFACEDESC2& ddsd, DWORD dwFlags, - DWORD dwCaps ) -{ - ZeroMemory( &ddsd, sizeof(ddsd) ); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = dwFlags; - ddsd.ddsCaps.dwCaps = dwCaps; - ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DUtil_InitMaterial() -// Desc: Helper function called to build a D3DMATERIAL7 structure -//----------------------------------------------------------------------------- -VOID D3DUtil_InitMaterial( D3DMATERIAL7& mtrl, FLOAT r, FLOAT g, FLOAT b, - FLOAT a ) -{ - ZeroMemory( &mtrl, sizeof(D3DMATERIAL7) ); - mtrl.dcvDiffuse.r = mtrl.dcvAmbient.r = r; - mtrl.dcvDiffuse.g = mtrl.dcvAmbient.g = g; - mtrl.dcvDiffuse.b = mtrl.dcvAmbient.b = b; - mtrl.dcvDiffuse.a = mtrl.dcvAmbient.a = a; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DUtil_InitLight() -// Desc: Initializes a D3DLIGHT7 structure -//----------------------------------------------------------------------------- -VOID D3DUtil_InitLight( D3DLIGHT7& light, D3DLIGHTTYPE ltType, - FLOAT x, FLOAT y, FLOAT z ) -{ - ZeroMemory( &light, sizeof(D3DLIGHT7) ); - light.dltType = ltType; - light.dcvDiffuse.r = 1.0f; - light.dcvDiffuse.g = 1.0f; - light.dcvDiffuse.b = 1.0f; - light.dcvSpecular = light.dcvDiffuse; - light.dvPosition.x = light.dvDirection.x = x; - light.dvPosition.y = light.dvDirection.y = y; - light.dvPosition.z = light.dvDirection.z = z; - light.dvAttenuation0 = 1.0f; - light.dvRange = D3DLIGHT_RANGE_MAX; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DUtil_SetViewMatrix() -// Desc: Given an eye point, a lookat point, and an up vector, this -// function builds a 4x4 view matrix. -//----------------------------------------------------------------------------- -HRESULT D3DUtil_SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom, - D3DVECTOR& vAt, D3DVECTOR& vWorldUp ) -{ - // Get the z basis vector, which points straight ahead. This is the - // difference from the eyepoint to the lookat point. - D3DVECTOR vView = vAt - vFrom; - - FLOAT fLength = Magnitude( vView ); - if( fLength < 1e-6f ) - return E_INVALIDARG; - - // Normalize the z basis vector - vView /= fLength; - - // Get the dot product, and calculate the projection of the z basis - // vector onto the up vector. The projection is the y basis vector. - FLOAT fDotProduct = DotProduct( vWorldUp, vView ); - - D3DVECTOR vUp = vWorldUp - fDotProduct * vView; - - // If this vector has near-zero length because the input specified a - // bogus up vector, let's try a default up vector - if( 1e-6f > ( fLength = Magnitude( vUp ) ) ) - { - vUp = D3DVECTOR( 0.0f, 1.0f, 0.0f ) - vView.y * vView; - - // If we still have near-zero length, resort to a different axis. - if( 1e-6f > ( fLength = Magnitude( vUp ) ) ) - { - vUp = D3DVECTOR( 0.0f, 0.0f, 1.0f ) - vView.z * vView; - - if( 1e-6f > ( fLength = Magnitude( vUp ) ) ) - return E_INVALIDARG; - } - } - - // Normalize the y basis vector - vUp /= fLength; - - // The x basis vector is found simply with the cross product of the y - // and z basis vectors - D3DVECTOR vRight = CrossProduct( vUp, vView ); - - // Start building the matrix. The first three rows contains the basis - // vectors used to rotate the view to point at the lookat point - D3DUtil_SetIdentityMatrix( mat ); - mat._11 = vRight.x; mat._12 = vUp.x; mat._13 = vView.x; - mat._21 = vRight.y; mat._22 = vUp.y; mat._23 = vView.y; - mat._31 = vRight.z; mat._32 = vUp.z; mat._33 = vView.z; - - // Do the translation values (rotations are still about the eyepoint) - mat._41 = - DotProduct( vFrom, vRight ); - mat._42 = - DotProduct( vFrom, vUp ); - mat._43 = - DotProduct( vFrom, vView ); - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DUtil_SetProjectionMatrix() -// Desc: Sets the passed in 4x4 matrix to a perpsective projection matrix built -// from the field-of-view (fov, in y), aspect ratio, near plane (D), -// and far plane (F). Note that the projection matrix is normalized for -// element [3][4] to be 1.0. This is performed so that W-based range fog -// will work correctly. -//----------------------------------------------------------------------------- -HRESULT D3DUtil_SetProjectionMatrix( D3DMATRIX& mat, FLOAT fFOV, FLOAT fAspect, - FLOAT fNearPlane, FLOAT fFarPlane ) -{ - if( fabs(fFarPlane-fNearPlane) < 0.01f ) - return E_INVALIDARG; - if( fabs(sin(fFOV/2)) < 0.01f ) - return E_INVALIDARG; - - FLOAT w = fAspect * ( cosf(fFOV/2)/sinf(fFOV/2) ); - FLOAT h = 1.0f * ( cosf(fFOV/2)/sinf(fFOV/2) ); - FLOAT Q = fFarPlane / ( fFarPlane - fNearPlane ); - - ZeroMemory( &mat, sizeof(D3DMATRIX) ); - mat._11 = w; - mat._22 = h; - mat._33 = Q; - mat._34 = 1.0f; - mat._43 = -Q*fNearPlane; - - return S_OK; -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DUtil_SetRotateXMatrix() -// Desc: Create Rotation matrix about X axis -//----------------------------------------------------------------------------- -VOID D3DUtil_SetRotateXMatrix( D3DMATRIX& mat, FLOAT fRads ) -{ - D3DUtil_SetIdentityMatrix( mat ); - mat._22 = cosf( fRads ); - mat._23 = sinf( fRads ); - mat._32 = -sinf( fRads ); - mat._33 = cosf( fRads ); -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DUtil_SetRotateYMatrix() -// Desc: Create Rotation matrix about Y axis -//----------------------------------------------------------------------------- -VOID D3DUtil_SetRotateYMatrix( D3DMATRIX& mat, FLOAT fRads ) -{ - D3DUtil_SetIdentityMatrix( mat ); - mat._11 = cosf( fRads ); - mat._13 = -sinf( fRads ); - mat._31 = sinf( fRads ); - mat._33 = cosf( fRads ); -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DUtil_SetRotateZMatrix() -// Desc: Create Rotation matrix about Z axis -//----------------------------------------------------------------------------- -VOID D3DUtil_SetRotateZMatrix( D3DMATRIX& mat, FLOAT fRads ) -{ - D3DUtil_SetIdentityMatrix( mat ); - mat._11 = cosf( fRads ); - mat._12 = sinf( fRads ); - mat._21 = -sinf( fRads ); - mat._22 = cosf( fRads ); -} - - - - -//----------------------------------------------------------------------------- -// Name: D3DUtil_SetRotationMatrix -// Desc: Create a Rotation matrix about vector direction -//----------------------------------------------------------------------------- -VOID D3DUtil_SetRotationMatrix( D3DMATRIX& mat, D3DVECTOR& vDir, FLOAT fRads ) -{ - FLOAT fCos = cosf( fRads ); - FLOAT fSin = sinf( fRads ); - D3DVECTOR v = Normalize( vDir ); - - mat._11 = ( v.x * v.x ) * ( 1.0f - fCos ) + fCos; - mat._12 = ( v.x * v.y ) * ( 1.0f - fCos ) - (v.z * fSin); - mat._13 = ( v.x * v.z ) * ( 1.0f - fCos ) + (v.y * fSin); - - mat._21 = ( v.y * v.x ) * ( 1.0f - fCos ) + (v.z * fSin); - mat._22 = ( v.y * v.y ) * ( 1.0f - fCos ) + fCos ; - mat._23 = ( v.y * v.z ) * ( 1.0f - fCos ) - (v.x * fSin); - - mat._31 = ( v.z * v.x ) * ( 1.0f - fCos ) - (v.y * fSin); - mat._32 = ( v.z * v.y ) * ( 1.0f - fCos ) + (v.x * fSin); - mat._33 = ( v.z * v.z ) * ( 1.0f - fCos ) + fCos; - - mat._14 = mat._24 = mat._34 = 0.0f; - mat._41 = mat._42 = mat._43 = 0.0f; - mat._44 = 1.0f; -} - - - - -//----------------------------------------------------------------------------- -// Name: _DbgOut() -// Desc: Outputs a message to the debug stream -//----------------------------------------------------------------------------- -HRESULT _DbgOut( TCHAR* strFile, DWORD dwLine, HRESULT hr, TCHAR* strMsg ) -{ - TCHAR buffer[256]; - wsprintf( buffer, _T("%s(%ld): "), strFile, dwLine ); - OutputDebugString( buffer ); - OutputDebugString( strMsg ); - - if( hr ) - { - wsprintf( buffer, _T("(hr=%08lx)\n"), hr ); - OutputDebugString( buffer ); - } - - OutputDebugString( _T("\n") ); - - return hr; -} - - - diff --git a/src/d3dutil.h b/src/d3dutil.h deleted file mode 100644 index 494722d..0000000 --- a/src/d3dutil.h +++ /dev/null @@ -1,114 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -//----------------------------------------------------------------------------- -// File: D3DUtil.h -// -// Desc: Helper functions and typing shortcuts for Direct3D programming. -// -// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved -//----------------------------------------------------------------------------- -#ifndef D3DUTIL_H -#define D3DUTIL_H -#include -#include - - - - -//----------------------------------------------------------------------------- -// Miscellaneous helper functions -//----------------------------------------------------------------------------- -const TCHAR* D3DUtil_GetDXSDKMediaPath(); - -#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } -#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } - - - - -//----------------------------------------------------------------------------- -// Short cut functions for creating and using DX structures -//----------------------------------------------------------------------------- -VOID D3DUtil_InitDeviceDesc( D3DDEVICEDESC7& ddDevDesc ); -VOID D3DUtil_InitSurfaceDesc( DDSURFACEDESC2& ddsd, DWORD dwFlags=0, - DWORD dwCaps=0 ); -VOID D3DUtil_InitMaterial( D3DMATERIAL7& mtrl, FLOAT r=0.0f, FLOAT g=0.0f, - FLOAT b=0.0f, FLOAT a=1.0f ); -VOID D3DUtil_InitLight( D3DLIGHT7& light, D3DLIGHTTYPE ltType, - FLOAT x=0.0f, FLOAT y=0.0f, FLOAT z=0.0f ); - - - - -//----------------------------------------------------------------------------- -// D3D Matrix functions. For performance reasons, some functions are inline. -//----------------------------------------------------------------------------- -HRESULT D3DUtil_SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom, - D3DVECTOR& vAt, D3DVECTOR& vUp ); -HRESULT D3DUtil_SetProjectionMatrix( D3DMATRIX& mat, FLOAT fFOV = 1.570795f, - FLOAT fAspect = 1.0f, - FLOAT fNearPlane = 1.0f, - FLOAT fFarPlane = 1000.0f ); - -inline VOID D3DUtil_SetIdentityMatrix( D3DMATRIX& m ) -{ - m._12 = m._13 = m._14 = m._21 = m._23 = m._24 = 0.0f; - m._31 = m._32 = m._34 = m._41 = m._42 = m._43 = 0.0f; - m._11 = m._22 = m._33 = m._44 = 1.0f; -} - -inline VOID D3DUtil_SetTranslateMatrix( D3DMATRIX& m, FLOAT tx, FLOAT ty, - FLOAT tz ) -{ D3DUtil_SetIdentityMatrix( m ); m._41 = tx; m._42 = ty; m._43 = tz; } - -inline VOID D3DUtil_SetTranslateMatrix( D3DMATRIX& m, D3DVECTOR& v ) -{ D3DUtil_SetTranslateMatrix( m, v.x, v.y, v.z ); } - -inline VOID D3DUtil_SetScaleMatrix( D3DMATRIX& m, FLOAT sx, FLOAT sy, - FLOAT sz ) -{ D3DUtil_SetIdentityMatrix( m ); m._11 = sx; m._22 = sy; m._33 = sz; } - -inline VOID SetScaleMatrix( D3DMATRIX& m, D3DVECTOR& v ) -{ D3DUtil_SetScaleMatrix( m, v.x, v.y, v.z ); } - -VOID D3DUtil_SetRotateXMatrix( D3DMATRIX& mat, FLOAT fRads ); -VOID D3DUtil_SetRotateYMatrix( D3DMATRIX& mat, FLOAT fRads ); -VOID D3DUtil_SetRotateZMatrix( D3DMATRIX& mat, FLOAT fRads ); -VOID D3DUtil_SetRotationMatrix( D3DMATRIX& mat, D3DVECTOR& vDir, - FLOAT fRads ); - - - - -//----------------------------------------------------------------------------- -// Debug printing support -//----------------------------------------------------------------------------- - -HRESULT _DbgOut( TCHAR*, DWORD, HRESULT, TCHAR* ); - -#if defined(DEBUG) | defined(_DEBUG) - #define DEBUG_MSG(str) _DbgOut( __FILE__, (DWORD)__LINE__, 0, str ) - #define DEBUG_ERR(hr,str) _DbgOut( __FILE__, (DWORD)__LINE__, hr, str ) -#else - #define DEBUG_MSG(str) (0L) - #define DEBUG_ERR(hr,str) (hr) -#endif - - - - -#endif // D3DUTIL_H diff --git a/src/dd.cpp b/src/dd.cpp deleted file mode 100644 index 75e332a..0000000 --- a/src/dd.cpp +++ /dev/null @@ -1,175 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// Compilation of a procedure with a "dot". - -int cPoint(CBotVar* &var, CBotString& retClass, void* user) -{ - if ( var == 0 ) return CBotErrLowParam; - - if ( var->GivType() <= CBotTypDouble ) - { - var = var->GivNext(); - if ( var == 0 ) return CBotErrLowParam; - if ( var->GivType() > CBotTypDouble ) return CBotErrBadNum; - var = var->GivNext(); - if ( var == 0 ) return CBotErrLowParam; - if ( var->GivType() > CBotTypDouble ) return CBotErrBadNum; - var = var->GivNext(); - return 0; - } - - if ( var->GivType() == CBotTypClass ) - { - if ( !var->IsElemOfClass("point") ) return CBotErrBadParam; - var = var->GivNext(); - return 0; - } - - return CBotErrBadParam; -} - -// Gives a parameter of type "point". - -BOOL GetPoint(CBotVar* &var, int& exception, D3DVECTOR& pos) -{ - CBotVar *pX, *pY, *pZ; - - if ( var->GivType() <= CBotTypDouble ) - { - pos.x = var->GivValFloat()*UNIT; - var = var->GivNext(); - - pos.z = var->GivValFloat()*UNIT; - var = var->GivNext(); - - pos.y = var->GivValFloat()*UNIT; - var = var->GivNext(); - } - else - { - pX = var->GivItem("x"); - if ( pX == NULL ) - { - exception = CBotErrUndefItem; return TRUE; - } - pos.x = pX->GivValFloat()*UNIT; - - pY = var->GivItem("y"); - if ( pY == NULL ) - { - exception = CBotErrUndefItem; return TRUE; - } - pos.z = pY->GivValFloat()*UNIT; // attention y -> z ! - - pZ = var->GivItem("z"); - if ( pZ == NULL ) - { - exception = CBotErrUndefItem; return TRUE; - } - pos.y = pZ->GivValFloat()*UNIT; // attention z -> y ! - - var = var->GivNext(); - } - return TRUE; -} - - - -// Compilation of the instruction "space(center, rMin, rMax, dist)". - -int cSpace(CBotVar* &var, CBotString& retClass, void* user) -{ - int ret; - - retClass = "point"; - - if ( var == 0 ) return CBotTypIntrinsic; - ret = cPoint(var, retClass, user); - if ( ret != 0 ) return ret; - - if ( var == 0 ) return CBotTypIntrinsic; - if ( var->GivType() > CBotTypDouble ) return CBotErrBadNum; - var = var->GivNext(); - - if ( var == 0 ) return CBotTypIntrinsic; - if ( var->GivType() > CBotTypDouble ) return CBotErrBadNum; - var = var->GivNext(); - - if ( var == 0 ) return CBotTypIntrinsic; - if ( var->GivType() > CBotTypDouble ) return CBotErrBadNum; - var = var->GivNext(); - - if ( var != 0 ) return CBotErrOverParam; - return CBotTypIntrinsic; -} - -// Instruction "space(center, rMin, rMax, dist)". - -BOOL rSpace(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - CBotVar* pSub; - D3DVECTOR center; - float rMin, rMax, dist; - - rMin = 5.0f*UNIT; - rMax = 50.0f*UNIT; - dist = 4.0f*UNIT; - - if ( var == 0 ) - { - center = pThis->RetPosition(0); - } - else - { - if ( !GetPoint(var, exception, center) ) return TRUE; - - if ( var != 0 ) - { - rMin = var->GivValFloat()*UNIT; - var = var->GivNext(); - - if ( var != 0 ) - { - rMax = var->GivValFloat()*UNIT; - var = var->GivNext(); - - if ( var != 0 ) - { - dist = var->GivValFloat()*UNIT; - var = var->GivNext(); - } - } - } - } - script->m_main->FreeSpace(center, rMin, rMax, dist, pThis); - - if ( result != 0 ) - { - pSub = result->GivItemList(); - if ( pSub != 0 ) - { - pSub->SetValFloat(center.x/UNIT); - pSub = pSub->GivNext(); // "y" - pSub->SetValFloat(center.z/UNIT); - pSub = pSub->GivNext(); // "z" - pSub->SetValFloat(center.y/UNIT); - } - } - return TRUE; -} diff --git a/src/displayinfo.cpp b/src/displayinfo.cpp deleted file mode 100644 index 473a805..0000000 --- a/src/displayinfo.cpp +++ /dev/null @@ -1,1222 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// displayinfo.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "language.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "restext.h" -#include "math3d.h" -#include "robotmain.h" -#include "camera.h" -#include "object.h" -#include "motion.h" -#include "motiontoto.h" -#include "interface.h" -#include "button.h" -#include "slider.h" -#include "edit.h" -#include "group.h" -#include "window.h" -#include "particule.h" -#include "light.h" -#include "text.h" -#include "cbottoken.h" -#include "displayinfo.h" - - - - -// Object's constructor. - -CDisplayInfo::CDisplayInfo(CInstanceManager* iMan) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_STUDIO, this); - - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); - m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); - - m_bInfoMaximized = TRUE; - m_bInfoMinimized = FALSE; - - m_infoFinalPos = m_infoActualPos = m_infoNormalPos = FPOINT(0.00f, 0.00f); - m_infoFinalDim = m_infoActualPos = m_infoNormalDim = FPOINT(1.00f, 1.00f); - - m_lightSuppl = -1; - m_toto = 0; -} - -// Object's destructor. - -CDisplayInfo::~CDisplayInfo() -{ - m_iMan->DeleteInstance(CLASS_STUDIO, this); -} - - -// Management of an event. - -BOOL CDisplayInfo::EventProcess(const Event &event) -{ - CWindow* pw; - CEdit* edit; - CSlider* slider; - CMotionToto* toto; - - if ( event.event == EVENT_FRAME ) - { - EventFrame(event); - HyperUpdate(); - } - - if ( event.event == EVENT_MOUSEMOVE ) - { - if ( m_toto != 0 ) - { - toto = (CMotionToto*)m_toto->RetMotion(); - if ( toto != 0 ) - { - toto->SetMousePos(event.pos); - } - } - } - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw != 0 ) - { - if ( event.event == pw->RetEventMsgClose() ) - { - Event newEvent = event; - newEvent.event = EVENT_OBJECT_INFOOK; - m_event->AddEvent(newEvent); - } - - if ( event.event == EVENT_SATCOM_HUSTON ) - { - ChangeIndexButton(SATCOM_HUSTON); - } - if ( event.event == EVENT_SATCOM_SAT ) - { - ChangeIndexButton(SATCOM_SAT); - } -//? if ( event.event == EVENT_SATCOM_OBJECT ) -//? { -//? ChangeIndexButton(SATCOM_OBJECT); -//? } - if ( event.event == EVENT_SATCOM_LOADING ) - { - ChangeIndexButton(SATCOM_LOADING); - } - if ( event.event == EVENT_SATCOM_PROG ) - { - ChangeIndexButton(SATCOM_PROG); - } - if ( event.event == EVENT_SATCOM_SOLUCE ) - { - ChangeIndexButton(SATCOM_SOLUCE); - } - - if ( event.event == EVENT_HYPER_HOME || - event.event == EVENT_HYPER_PREV || - event.event == EVENT_HYPER_NEXT ) - { - edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); - if ( edit != 0 ) - { - edit->HyperGo(event.event); - HyperUpdate(); - } - } - - if ( event.event == EVENT_HYPER_SIZE1 ) // size 1? - { - m_main->SetFontSize(9.0f); - slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); - if ( slider != 0 ) slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f); - ViewDisplayInfo(); - } - if ( event.event == EVENT_HYPER_SIZE2 ) // size 2? - { - m_main->SetFontSize(10.0f); - slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); - if ( slider != 0 ) slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f); - ViewDisplayInfo(); - } - if ( event.event == EVENT_HYPER_SIZE3 ) // size 3? - { - m_main->SetFontSize(12.0f); - slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); - if ( slider != 0 ) slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f); - ViewDisplayInfo(); - } - if ( event.event == EVENT_HYPER_SIZE4 ) // size 4? - { - m_main->SetFontSize(15.0f); - slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); - if ( slider != 0 ) slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f); - ViewDisplayInfo(); - } - - if ( event.event == EVENT_STUDIO_SIZE ) // size? - { - slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); - if ( slider == 0 ) return FALSE; - m_main->SetFontSize(9.0f+slider->RetVisibleValue()*6.0f); - ViewDisplayInfo(); - } - - if ( event.event == EVENT_HYPER_COPY ) // copy ? - { - edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); - if ( edit != 0 ) - { - edit->Copy(); - } - } - - if ( event.event == EVENT_LBUTTONDOWN || - event.event == EVENT_LBUTTONUP ) - { - UpdateCopyButton(); - } - - if ( event.event == EVENT_WINDOW4 ) // window moved? - { - m_infoNormalPos = m_infoActualPos = m_infoFinalPos = pw->RetPos(); - m_infoNormalDim = m_infoActualDim = m_infoFinalDim = pw->RetDim(); - AdjustDisplayInfo(m_infoActualPos, m_infoActualDim); - } - if ( event.event == pw->RetEventMsgReduce() ) - { - if ( m_bInfoMinimized ) - { - m_infoFinalPos = m_infoNormalPos; - m_infoFinalDim = m_infoNormalDim; - m_bInfoMinimized = FALSE; - m_bInfoMaximized = FALSE; - } - else - { - m_infoFinalPos.x = 0.00f; - m_infoFinalPos.y = -0.34f; - m_infoFinalDim.x = 1.00f; - m_infoFinalDim.y = 0.40f; - m_bInfoMinimized = TRUE; - m_bInfoMaximized = FALSE; - } -//? m_main->SetEditFull(m_bInfoMaximized); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw != 0 ) - { - pw->SetMaximized(m_bInfoMaximized); - pw->SetMinimized(m_bInfoMinimized); - } - } - if ( event.event == pw->RetEventMsgFull() ) - { - if ( m_bInfoMaximized ) - { - m_infoFinalPos = m_infoNormalPos; - m_infoFinalDim = m_infoNormalDim; - m_bInfoMinimized = FALSE; - m_bInfoMaximized = FALSE; - } - else - { - m_infoFinalPos.x = 0.00f; - m_infoFinalPos.y = 0.00f; - m_infoFinalDim.x = 1.00f; - m_infoFinalDim.y = 1.00f; - m_bInfoMinimized = FALSE; - m_bInfoMaximized = TRUE; - } -//? m_main->SetEditFull(m_bInfoMaximized); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw != 0 ) - { - pw->SetMaximized(m_bInfoMaximized); - pw->SetMinimized(m_bInfoMinimized); - } - } - } - return TRUE; -} - - -// The brain is changing by time. - -BOOL CDisplayInfo::EventFrame(const Event &event) -{ - float time; - - if ( m_infoFinalPos.x != m_infoActualPos.x || - m_infoFinalPos.y != m_infoActualPos.y || - m_infoFinalDim.x != m_infoActualDim.x || - m_infoFinalDim.y != m_infoActualDim.y ) - { - time = event.rTime*20.0f; - m_infoActualPos.x += (m_infoFinalPos.x-m_infoActualPos.x)*time; - m_infoActualPos.y += (m_infoFinalPos.y-m_infoActualPos.y)*time; - m_infoActualDim.x += (m_infoFinalDim.x-m_infoActualDim.x)*time; - m_infoActualDim.y += (m_infoFinalDim.y-m_infoActualDim.y)*time; - AdjustDisplayInfo(m_infoActualPos, m_infoActualDim); - } - - return TRUE; -} - - -// Updates the buttons for hyperlinks. - -void CDisplayInfo::HyperUpdate() -{ - CWindow* pw; - CEdit* edit; - CButton* button; - BOOL bEnable; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw == 0 ) return; - edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); - if ( edit == 0 ) return; - - button = (CButton*)pw->SearchControl(EVENT_HYPER_HOME); - if ( button != 0 ) - { - bEnable = edit->HyperTest(EVENT_HYPER_HOME); - button->SetState(STATE_ENABLE, bEnable); - } - - button = (CButton*)pw->SearchControl(EVENT_HYPER_PREV); - if ( button != 0 ) - { - bEnable = edit->HyperTest(EVENT_HYPER_PREV); - button->SetState(STATE_ENABLE, bEnable); - } - - button = (CButton*)pw->SearchControl(EVENT_HYPER_NEXT); - if ( button != 0 ) - { - bEnable = edit->HyperTest(EVENT_HYPER_NEXT); - button->SetState(STATE_ENABLE, bEnable); - } -} - - -// Beginning of the display of information. - -void CDisplayInfo::StartDisplayInfo(char *filename, int index, BOOL bSoluce) -{ - D3DLIGHT7 light; - FPOINT pos, dim; - CWindow* pw; - CEdit* edit; - CButton* button; - CSlider* slider; - CMotionToto* toto; - - m_index = index; - m_bSoluce = bSoluce; - -//? CreateObjectsFile(); - - m_bEditLock = m_main->RetEditLock(); - if ( m_bEditLock ) // edition running program? - { - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw != 0 ) - { - pw->ClearState(STATE_ENABLE); // CStudio inactive - } - } - - m_main->SetEditLock(TRUE, FALSE); - m_main->SetEditFull(FALSE); - m_bInitPause = m_engine->RetPause(); - m_engine->SetPause(TRUE); - m_infoCamera = m_camera->RetType(); - m_camera->SetType(CAMERA_INFO); - - pos = m_infoActualPos = m_infoFinalPos; - dim = m_infoActualDim = m_infoFinalDim; - pw = m_interface->CreateWindows(pos, dim, 4, EVENT_WINDOW4); - if ( pw == 0 ) return; -//? pw->SetClosable(TRUE); -//? GetResource(RES_TEXT, RT_DISINFO_TITLE, res); -//? pw->SetName(res); -//? pw->SetMinDim(FPOINT(0.56f, 0.40f)); -//? pw->SetMaximized(m_bInfoMaximized); -//? pw->SetMinimized(m_bInfoMinimized); -//? m_main->SetEditFull(m_bInfoMaximized); - - edit = pw->CreateEdit(pos, dim, 0, EVENT_EDIT1); - if ( edit == 0 ) return; - edit->SetState(STATE_SHADOW); - edit->SetMultiFont(TRUE); - edit->SetMaxChar(10000); - edit->SetFontType(FONT_COLOBOT); - edit->SetSoluceMode(bSoluce); - edit->ReadText(filename); - edit->HyperHome(filename); - edit->SetEditCap(FALSE); // just to see! - edit->SetHiliteCap(FALSE); - edit->SetFocus(TRUE); - - ViewDisplayInfo(); - - button = pw->CreateButton(pos, dim, 128+57, EVENT_SATCOM_HUSTON); - button->SetState(STATE_SHADOW); -#if _TEEN -#if !_ENGLISH - button = pw->CreateButton(pos, dim, 46, EVENT_SATCOM_SAT); -#endif -#else - button = pw->CreateButton(pos, dim, 128+58, EVENT_SATCOM_SAT); -#endif - button->SetState(STATE_SHADOW); -//? button = pw->CreateButton(pos, dim, 128+59, EVENT_SATCOM_OBJECT); -//? button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 53, EVENT_SATCOM_LOADING); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 128+60, EVENT_SATCOM_PROG); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 20, EVENT_SATCOM_SOLUCE); - button->SetState(STATE_SHADOW); - - pw->CreateGroup(pos, dim, 18, EVENT_LABEL1); // arrow > - pw->CreateGroup(pos, dim, 19, EVENT_LABEL2); // symbol SatCom - - button = pw->CreateButton(pos, dim, 55, EVENT_HYPER_PREV); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 48, EVENT_HYPER_NEXT); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 30, EVENT_HYPER_HOME); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 82, EVENT_HYPER_SIZE1); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 83, EVENT_HYPER_SIZE2); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 90, EVENT_HYPER_SIZE3); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 91, EVENT_HYPER_SIZE4); - button->SetState(STATE_SHADOW); - slider = pw->CreateSlider(pos, dim, 0, EVENT_STUDIO_SIZE); - slider->SetState(STATE_SHADOW); - slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f); - button = pw->CreateButton(pos, dim, 61, EVENT_HYPER_COPY); - button->SetState(STATE_SHADOW); - HyperUpdate(); - - button = pw->CreateButton(pos, dim, -1, EVENT_OBJECT_INFOOK); - button->SetState(STATE_SHADOW); - button->SetState(STATE_SIMPLY); - button->SetState(STATE_DEFAULT); - pw->CreateGroup(pos, dim, 21, EVENT_LABEL3); // symbol stand-by - - AdjustDisplayInfo(m_infoActualPos, m_infoActualDim); - UpdateIndexButton(); - - m_engine->SetDrawWorld(FALSE); // doesn't draw anything in the interface - m_engine->SetDrawFront(TRUE); // toto draws on the interface - m_particule->SetFrameUpdate(SH_WORLD, FALSE); // particles break into world - - m_toto = SearchToto(); - if ( m_toto != 0 ) - { - m_toto->SetDrawFront(TRUE); - - toto = (CMotionToto*)m_toto->RetMotion(); - if ( toto != 0 ) - { - toto->StartDisplayInfo(); - } - } - - ZeroMemory(&light, sizeof(light)); - light.dltType = D3DLIGHT_DIRECTIONAL; - light.dcvDiffuse.r = 1.0f; - light.dcvDiffuse.g = 1.0f; - light.dcvDiffuse.b = 1.0f; - light.dvDirection = D3DVECTOR(1.0f, 0.0f, 1.0f); - m_lightSuppl = m_light->CreateLight(); - m_light->SetLight(m_lightSuppl, light); - m_light->SetLightExcluType(m_lightSuppl, TYPETERRAIN); -} - -// Repositions all controls editing. - -void CDisplayInfo::AdjustDisplayInfo(FPOINT wpos, FPOINT wdim) -{ - CWindow* pw; - CEdit* edit; - CButton* button; - CSlider* slider; - CGroup* group; - FPOINT pos, dim; - - wpos.x = 50.0f/640.0f; - wpos.y = 30.0f/480.0f; - wdim.x = 540.0f/640.0f; - wdim.y = 420.0f/480.0f; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw != 0 ) - { - pw->SetPos(wpos); - pw->SetDim(wdim); - wdim = pw->RetDim(); - } - - pos.x = (50.0f+10.0f)/640.0f; - pos.y = (30.0f+10.0f+24.0f+10.0f+324.0f-48.0f)/480.0f; - dim.x = 48.0f/640.0f; - dim.y = 48.0f/480.0f; - button = (CButton*)pw->SearchControl(EVENT_SATCOM_HUSTON); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.y -= (48.0f+4.0f)/480.0f; - button = (CButton*)pw->SearchControl(EVENT_SATCOM_SAT); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } -//? pos.y -= (48.0f+4.0f)/480.0f; -//? button = (CButton*)pw->SearchControl(EVENT_SATCOM_OBJECT); -//? if ( button != 0 ) -//? { -//? button->SetPos(pos); -//? button->SetDim(dim); -//? } - pos.y -= (48.0f+4.0f)/480.0f; - button = (CButton*)pw->SearchControl(EVENT_SATCOM_LOADING); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.y -= (48.0f+4.0f)/480.0f; - button = (CButton*)pw->SearchControl(EVENT_SATCOM_PROG); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.y -= (48.0f+4.0f)/480.0f; - button = (CButton*)pw->SearchControl(EVENT_SATCOM_SOLUCE); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - - pos.x = (50.0f+10.0f+5.0f)/640.0f; - pos.y = (30.0f+10.0f+4.0f)/480.0f; - dim.x = (48.0f-10.0f)/640.0f; - dim.y = 24.0f/480.0f; - button = (CButton*)pw->SearchControl(EVENT_OBJECT_INFOOK); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - - pos.x = (50.0f+10.0f+48.0f+10.0f)/640.0f; - pos.y = (30.0f+10.0f)/480.0f; - dim.x = 462.0f/640.0f; - dim.y = 358.0f/480.0f; - edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); - if ( edit != 0 ) - { - edit->SetPos(pos); - edit->SetDim(dim); - } - - pos.x = (50.0f+10.0f+48.0f+10.0f)/640.0f; - pos.y = (30.0f+10.0f+358.0f+10.0f)/480.0f; - dim.x = 32.0f/640.0f; - dim.y = 32.0f/480.0f; - button = (CButton*)pw->SearchControl(EVENT_HYPER_PREV); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x += 35.0f/640.0f; - button = (CButton*)pw->SearchControl(EVENT_HYPER_NEXT); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x += 35.0f/640.0f; - button = (CButton*)pw->SearchControl(EVENT_HYPER_HOME); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - - pos.x += 50.0f/640.0f; - button = (CButton*)pw->SearchControl(EVENT_HYPER_SIZE1); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x += 35.0f/640.0f; - button = (CButton*)pw->SearchControl(EVENT_HYPER_SIZE2); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x += 35.0f/640.0f; - button = (CButton*)pw->SearchControl(EVENT_HYPER_SIZE3); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x += 35.0f/640.0f; - button = (CButton*)pw->SearchControl(EVENT_HYPER_SIZE4); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x += 35.0f/640.0f; - dim.x = 18.0f/640.0f; - slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); - if ( slider != 0 ) - { - slider->SetPos(pos); - slider->SetDim(dim); - } - pos.x += 50.0f/640.0f; - dim.x = 32.0f/640.0f; - button = (CButton*)pw->SearchControl(EVENT_HYPER_COPY); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - - pos.x = (50.0f+10.0f)/640.0f; - pos.y = (30.0f+10.0f+24.0f+10.0f+324.0f+6.0f)/480.0f; - dim.x = 48.0f/640.0f; - dim.y = 40.0f/480.0f; - group = (CGroup*)pw->SearchControl(EVENT_LABEL2); // symbol SatCom - if ( group != 0 ) - { - group->SetPos(pos); - group->SetDim(dim); - } - - pos.x = (50.0f+10.0f+14.0f)/640.0f; - pos.y = (30.0f+10.0f+6.0f)/480.0f; - dim.x = 20.0f/640.0f; - dim.y = 20.0f/480.0f; - group = (CGroup*)pw->SearchControl(EVENT_LABEL3); // symbol stand-by - if ( group != 0 ) - { - group->SetPos(pos); - group->SetDim(dim); - } -} - -// Change the index button. - -void CDisplayInfo::ChangeIndexButton(int index) -{ - CWindow* pw; - CEdit* edit; - char* filename; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw == 0 ) return; - - if ( m_index != -1 ) - { - m_main->SetDisplayInfoPosition(m_index, RetPosition()); - } - m_index = index; - - edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); - if ( edit != 0 ) - { - filename = m_main->RetDisplayInfoName(m_index); - edit->ReadText(filename); - edit->HyperHome(filename); - SetPosition(m_main->RetDisplayInfoPosition(m_index)); - } - - UpdateIndexButton(); -} - -// Adapts the index buttons. - -void CDisplayInfo::UpdateIndexButton() -{ - CWindow* pw; - CButton* button; - CGroup* group; - CEdit* edit; - FPOINT pos, dim; - char* filename; - char* loading; - - static int table[SATCOM_MAX] = - { - 0, // SATCOM_HUSTON - 1, // SATCOM_SAT - -1, // SATCOM_OBJECT - 2, // SATCOM_LOADING - 3, // SATCOM_PROG - 4, // SATCOM_SOLUCE - }; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw == 0 ) return; - - button = (CButton*)pw->SearchControl(EVENT_SATCOM_HUSTON); - if ( button != 0 ) - { - button->SetState(STATE_CHECK, m_index==SATCOM_HUSTON); - filename = m_main->RetDisplayInfoName(SATCOM_HUSTON); - button->SetState(STATE_VISIBLE, filename[0]!=0); - } - - button = (CButton*)pw->SearchControl(EVENT_SATCOM_SAT); - if ( button != 0 ) - { - button->SetState(STATE_CHECK, m_index==SATCOM_SAT); - filename = m_main->RetDisplayInfoName(SATCOM_SAT); - button->SetState(STATE_VISIBLE, filename[0]!=0); - } - -//? button = (CButton*)pw->SearchControl(EVENT_SATCOM_OBJECT); -//? if ( button != 0 ) -//? { -//? button->SetState(STATE_CHECK, m_index==SATCOM_OBJECT); -//? filename = m_main->RetDisplayInfoName(SATCOM_OBJECT); -//? button->SetState(STATE_VISIBLE, filename[0]!=0); -//? } - - loading = 0; - button = (CButton*)pw->SearchControl(EVENT_SATCOM_LOADING); - if ( button != 0 ) - { - button->SetState(STATE_CHECK, m_index==SATCOM_LOADING); - loading = m_main->RetDisplayInfoName(SATCOM_LOADING); - button->SetState(STATE_VISIBLE, loading[0]!=0); - } - - button = (CButton*)pw->SearchControl(EVENT_SATCOM_PROG); - if ( button != 0 ) - { - button->SetState(STATE_CHECK, m_index==SATCOM_PROG); - filename = m_main->RetDisplayInfoName(SATCOM_PROG); - button->SetState(STATE_VISIBLE, filename[0]!=0 && (m_index==SATCOM_LOADING||m_index==SATCOM_PROG||(loading!=0&&loading[0]==0))); - } - - button = (CButton*)pw->SearchControl(EVENT_SATCOM_SOLUCE); - if ( button != 0 ) - { - button->SetState(STATE_CHECK, m_index==SATCOM_SOLUCE); - filename = m_main->RetDisplayInfoName(SATCOM_SOLUCE); - button->SetState(STATE_VISIBLE, filename[0]!=0 && m_bSoluce); - } - - group = (CGroup*)pw->SearchControl(EVENT_LABEL1); - if ( group != 0 ) - { - if ( m_index == -1 ) - { - group->ClearState(STATE_VISIBLE); - } - else - { - group->SetState(STATE_VISIBLE); - - pos.x = (50.0f+10.0f+48.0f-3.0f)/640.0f; - pos.y = (30.0f+10.0f+24.0f+10.0f+324.0f-48.0f-1.0f)/480.0f; - pos.y -= (48.0f+4.0f)/480.0f*table[m_index]; - dim.x = 15.0f/640.0f; - dim.y = 48.0f/480.0f; - group->SetPos(pos); - group->SetDim(dim); - } - } - -#if 0 - button = (CButton*)pw->SearchControl(EVENT_HYPER_COPY); - if ( button != 0 ) - { - button->SetState(STATE_VISIBLE, m_index==SATCOM_LOADING); - } -#endif - - edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); - if ( edit != 0 ) - { -//? edit->SetHiliteCap(m_index==SATCOM_LOADING); - edit->SetHiliteCap(TRUE); - } - - UpdateCopyButton(); -} - -// Adjusts the copy button. - -void CDisplayInfo::UpdateCopyButton() -{ - CWindow* pw; - CButton* button; - CEdit* edit; - int c1, c2; - -//? if ( m_index != SATCOM_LOADING ) return; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw == 0 ) return; - - button = (CButton*)pw->SearchControl(EVENT_HYPER_COPY); - if ( button == 0 ) return; - - edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); - if ( edit == 0 ) return; - - edit->GetCursor(c1, c2); - button->SetState(STATE_ENABLE, c1!=c2); - -} - -// End of the display of information. - -void CDisplayInfo::StopDisplayInfo() -{ - CWindow* pw; - CMotionToto* toto; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw == 0 ) return; - - m_interface->DeleteControl(EVENT_WINDOW4); - - if ( m_bEditLock ) // editing running program? - { - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw != 0 ) - { - pw->SetState(STATE_ENABLE); // CStudio operating - } - } - else - { - if ( !m_bInitPause ) m_engine->SetPause(FALSE); - m_main->SetEditLock(FALSE, FALSE); - } - m_camera->SetType(m_infoCamera); - - m_engine->SetDrawWorld(TRUE); // draws all on the interface - m_engine->SetDrawFront(FALSE); // draws nothing on the interface - m_particule->SetFrameUpdate(SH_WORLD, TRUE); - m_particule->FlushParticule(SH_FRONT); - m_particule->FlushParticule(SH_INTERFACE); - - if ( m_toto != 0 ) - { - toto = (CMotionToto*)m_toto->RetMotion(); - if ( toto != 0 ) - { - toto->StopDisplayInfo(); - } - } - - m_light->DeleteLight(m_lightSuppl); - m_lightSuppl = -1; -} - - -// Specifies the position. - -void CDisplayInfo::SetPosition(int pos) -{ - CWindow* pw; - CEdit* edit; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw == 0 ) return; - - edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); - if ( edit == 0 ) return; - - edit->SetFirstLine(pos); -} - -// Returns the position. - -int CDisplayInfo::RetPosition() -{ - CWindow* pw; - CEdit* edit; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw == 0 ) return 0; - - edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); - if ( edit == 0 ) return 0; - - return edit->RetFirstLine(); -} - - - -// Changing the size of the display of information. - -void CDisplayInfo::ViewDisplayInfo() -{ - CWindow* pw; - CEdit* edit; - POINT dim; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw == 0 ) return; - - edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); - if ( edit == 0 ) return; - - dim = m_engine->RetDim(); - edit->SetFontSize(m_main->RetFontSize()/(dim.x/640.0f)); -} - -// Returns the object human. - -CObject* CDisplayInfo::SearchToto() -{ - ObjectType type; - CObject* pObj; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type == OBJECT_TOTO ) - { - return pObj; - } - } - return 0; -} - - -// Creating the list of objects. - -typedef struct -{ - int total; - ObjectType type; -} -ObjectList; - -void ObjectAdd(ObjectList list[], ObjectType type) -{ - int i; - - for ( i=0 ; i<200 ; i++ ) - { - if ( list[i].total == 0 ) - { - list[i].total ++; - list[i].type = type; - list[i+1].total = 0; - return; - } - if ( list[i].type == type ) - { - list[i].total ++; - return; - } - } -} - -void ObjectWrite(FILE* file, ObjectList list[], int i) -{ - char line[100]; - char res[100]; - char* p; - - if ( list[i].total < 10 ) - { - sprintf(line, "\\c; %dx \\n;\\l;", list[i].total); - } - else - { - sprintf(line, "\\c;%dx \\n;\\l;", list[i].total); - } - - GetResource(RES_OBJECT, list[i].type, res); - if ( res[0] == 0 ) return; - strcat(line, res); - - strcat(line, "\\u "); - p = RetHelpFilename(list[i].type); - if ( p[0] == 0 ) return; - strcat(line, p+5); // skip "help\" - p = strstr(line, ".txt"); - if ( p != 0 ) *p = 0; - strcat(line, ";\n"); - fputs(line, file); -} - -// Creates the file containing the list of objects. - -void CDisplayInfo::CreateObjectsFile() -{ - FILE* file; - CObject* pObj; - ObjectType type; - ObjectList list[200]; - char line[100]; - int i; - BOOL bRadar, bAtLeast; - - file = fopen("help\\objects.txt", "w"); - if ( file == 0 ) return; - - list[0].total = 0; // empty list - bRadar = FALSE; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetActif() ) continue; - if ( !pObj->RetSelectable() ) continue; - if ( pObj->RetProxyActivate() ) continue; - - type = pObj->RetType(); - if ( type == OBJECT_NULL ) continue; - if ( type == OBJECT_FIX ) continue; - - ObjectAdd(list, type); - - if ( type == OBJECT_RADAR ) bRadar = TRUE; - } - - if ( bRadar ) - { - GetResource(RES_TEXT, RT_SATCOM_LIST, line); - fputs(line, file); - bAtLeast = FALSE; - for ( i=0 ; i<200 ; i++ ) - { - if ( list[i].total == 0 ) break; // end of the list? - - if ( list[i].type == OBJECT_BASE || - list[i].type == OBJECT_HUMAN ) - { - ObjectWrite(file, list, i); - bAtLeast = TRUE; - } - } - if ( !bAtLeast ) - { - GetResource(RES_TEXT, RT_SATCOM_NULL, line); - fputs(line, file); - } - - strcpy(line, "\n"); - fputs(line, file); - GetResource(RES_TEXT, RT_SATCOM_BOT, line); - fputs(line, file); - bAtLeast = FALSE; - for ( i=0 ; i<200 ; i++ ) - { - if ( list[i].total == 0 ) break; // end of the list? - - if ( list[i].type == OBJECT_MOBILEwt || - list[i].type == OBJECT_MOBILEtt || - list[i].type == OBJECT_MOBILEft || - list[i].type == OBJECT_MOBILEit || - list[i].type == OBJECT_MOBILEwa || - list[i].type == OBJECT_MOBILEta || - list[i].type == OBJECT_MOBILEfa || - list[i].type == OBJECT_MOBILEia || - list[i].type == OBJECT_MOBILEwc || - list[i].type == OBJECT_MOBILEtc || - list[i].type == OBJECT_MOBILEfc || - list[i].type == OBJECT_MOBILEic || - list[i].type == OBJECT_MOBILEwi || - list[i].type == OBJECT_MOBILEti || - list[i].type == OBJECT_MOBILEfi || - list[i].type == OBJECT_MOBILEii || - list[i].type == OBJECT_MOBILEws || - list[i].type == OBJECT_MOBILEts || - list[i].type == OBJECT_MOBILEfs || - list[i].type == OBJECT_MOBILEis || - list[i].type == OBJECT_MOBILErt || - list[i].type == OBJECT_MOBILErc || - list[i].type == OBJECT_MOBILErr || - list[i].type == OBJECT_MOBILErs || - list[i].type == OBJECT_MOBILEsa || - list[i].type == OBJECT_MOBILEtg || - list[i].type == OBJECT_MOBILEdr ) - { - ObjectWrite(file, list, i); - bAtLeast = TRUE; - } - } - if ( !bAtLeast ) - { - GetResource(RES_TEXT, RT_SATCOM_NULL, line); - fputs(line, file); - } - - strcpy(line, "\n"); - fputs(line, file); - GetResource(RES_TEXT, RT_SATCOM_BUILDING, line); - fputs(line, file); - bAtLeast = FALSE; - for ( i=0 ; i<200 ; i++ ) - { - if ( list[i].total == 0 ) break; // end of the list? - - if ( list[i].type == OBJECT_DERRICK || - list[i].type == OBJECT_FACTORY || - list[i].type == OBJECT_STATION || - list[i].type == OBJECT_CONVERT || - list[i].type == OBJECT_REPAIR || - list[i].type == OBJECT_DESTROYER|| - list[i].type == OBJECT_TOWER || - list[i].type == OBJECT_NEST || - list[i].type == OBJECT_RESEARCH || - list[i].type == OBJECT_RADAR || - list[i].type == OBJECT_ENERGY || - list[i].type == OBJECT_LABO || - list[i].type == OBJECT_NUCLEAR || - list[i].type == OBJECT_START || - list[i].type == OBJECT_END || - list[i].type == OBJECT_INFO || - list[i].type == OBJECT_PARA || - list[i].type == OBJECT_TARGET1 || - list[i].type == OBJECT_TARGET2 || - list[i].type == OBJECT_SAFE || - list[i].type == OBJECT_HUSTON ) - { - ObjectWrite(file, list, i); - bAtLeast = TRUE; - } - } - if ( !bAtLeast ) - { - GetResource(RES_TEXT, RT_SATCOM_NULL, line); - fputs(line, file); - } - - strcpy(line, "\n"); - fputs(line, file); - GetResource(RES_TEXT, RT_SATCOM_FRET, line); - fputs(line, file); - bAtLeast = FALSE; - for ( i=0 ; i<200 ; i++ ) - { - if ( list[i].total == 0 ) break; // end of the list? - - if ( list[i].type == OBJECT_STONE || - list[i].type == OBJECT_URANIUM || - list[i].type == OBJECT_METAL || - list[i].type == OBJECT_POWER || - list[i].type == OBJECT_ATOMIC || - list[i].type == OBJECT_BULLET || - list[i].type == OBJECT_BBOX || - list[i].type == OBJECT_TNT ) - { - ObjectWrite(file, list, i); - bAtLeast = TRUE; - } - } - if ( !bAtLeast ) - { - GetResource(RES_TEXT, RT_SATCOM_NULL, line); - fputs(line, file); - } - - strcpy(line, "\n"); - fputs(line, file); - GetResource(RES_TEXT, RT_SATCOM_ALIEN, line); - fputs(line, file); - bAtLeast = FALSE; - for ( i=0 ; i<200 ; i++ ) - { - if ( list[i].total == 0 ) break; // end of the list? - - if ( list[i].type == OBJECT_MOTHER || - list[i].type == OBJECT_ANT || - list[i].type == OBJECT_BEE || - list[i].type == OBJECT_WORM || - list[i].type == OBJECT_SPIDER ) - { - ObjectWrite(file, list, i); - bAtLeast = TRUE; - } - } - if ( !bAtLeast ) - { - GetResource(RES_TEXT, RT_SATCOM_NULL, line); - fputs(line, file); - } - } - else - { - GetResource(RES_TEXT, RT_SATCOM_ERROR1, line); - fputs(line, file); - GetResource(RES_TEXT, RT_SATCOM_ERROR2, line); - fputs(line, file); - } - - strcpy(line, "\n"); - fputs(line, file); - - fclose(file); -} - - diff --git a/src/displayinfo.h b/src/displayinfo.h deleted file mode 100644 index 61b87ee..0000000 --- a/src/displayinfo.h +++ /dev/null @@ -1,92 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// displayinfo.h - -#ifndef _DISPLAYINFO_H_ -#define _DISPLAYINFO_H_ - - -#include "struct.h" -#include "camera.h" - - -class CInstanceManager; -class CD3DEngine; -class CEvent; -class CRobotMain; -class CCamera; -class CInterface; -class CObject; -class CParticule; -class CLight; - - -class CDisplayInfo -{ -public: - CDisplayInfo(CInstanceManager* iMan); - ~CDisplayInfo(); - - BOOL EventProcess(const Event &event); - - void StartDisplayInfo(char *filename, int index, BOOL bSoluce); - void StopDisplayInfo(); - - void SetPosition(int pos); - int RetPosition(); - -protected: - BOOL EventFrame(const Event &event); - void HyperUpdate(); - void AdjustDisplayInfo(FPOINT wpos, FPOINT wdim); - void ChangeIndexButton(int index); - void UpdateIndexButton(); - void UpdateCopyButton(); - void ViewDisplayInfo(); - CObject* SearchToto(); - void CreateObjectsFile(); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CEvent* m_event; - CRobotMain* m_main; - CCamera* m_camera; - CInterface* m_interface; - CParticule* m_particule; - CLight* m_light; - - BOOL m_bInfoMaximized; - BOOL m_bInfoMinimized; - - int m_index; - CameraType m_infoCamera; - FPOINT m_infoNormalPos; - FPOINT m_infoNormalDim; - FPOINT m_infoActualPos; - FPOINT m_infoActualDim; - FPOINT m_infoFinalPos; - FPOINT m_infoFinalDim; - int m_lightSuppl; - BOOL m_bEditLock; - BOOL m_bInitPause; - BOOL m_bSoluce; - CObject* m_toto; -}; - - -#endif //_DISPLAYINFO_H_ diff --git a/src/displaytext.cpp b/src/displaytext.cpp deleted file mode 100644 index a56bf9f..0000000 --- a/src/displaytext.cpp +++ /dev/null @@ -1,615 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// displaytext.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "event.h" -#include "misc.h" -#include "restext.h" -#include "iman.h" -#include "object.h" -#include "motion.h" -#include "motiontoto.h" -#include "interface.h" -#include "button.h" -#include "label.h" -#include "window.h" -#include "group.h" -#include "text.h" -#include "sound.h" -#include "displaytext.h" - - - -#define FONTSIZE 12.0f - - - -// Object's constructor. - -CDisplayText::CDisplayText(CInstanceManager* iMan) -{ - int i; - - m_iMan = iMan; - m_iMan->AddInstance(CLASS_DISPLAYTEXT, this); - - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - - for ( i=0 ; iDeleteInstance(CLASS_DISPLAYTEXT, this); -} - - -// Destroys the object. - -void CDisplayText::DeleteObject() -{ - m_interface->DeleteControl(EVENT_WINDOW2); -} - - -// Management of an event. - -BOOL CDisplayText::EventProcess(const Event &event) -{ - int i; - - if ( m_engine->RetPause() ) return TRUE; - - if ( event.event == EVENT_FRAME ) - { - for ( i=0 ; i 0.0f ) break; - if ( !ClearLastText() ) break; - } - } - - return TRUE; -} - - -// Displays an error. - -void CDisplayText::DisplayError(Error err, CObject* pObj, float time) -{ - D3DVECTOR pos; - float h, d; - - if ( pObj == 0 ) return; - - pos = pObj->RetPosition(0); - h = RetIdealHeight(pObj); - d = RetIdealDist(pObj); - DisplayError(err, pos, h, d, time); -} - -// Displays an error. - -void CDisplayText::DisplayError(Error err, D3DVECTOR goal, float height, - float dist, float time) -{ - TextType type; - char text[100]; - - if ( err == ERR_OK ) return; - -#if 0 - type = TT_INFO; - if ( err < INFO_FIRST ) - { - type = TT_ERROR; - } - if ( err == ERR_TOWER_POWER || - err == ERR_RESEARCH_POWER || - err == ERR_ENERGY_EMPTY || - err == ERR_LABO_NULL || - err == ERR_NUCLEAR_EMPTY || - err == ERR_CONVERT_EMPTY ) - { - type = TT_WARNING; - } -#else - type = TT_WARNING; - if ( err >= INFO_FIRST ) - { - type = TT_INFO; - } - if ( err == ERR_BAT_VIRUS || - err == ERR_VEH_VIRUS || - err == ERR_DELETEMOBILE || - err == ERR_DELETEBUILDING || - err == ERR_TOOMANY || - err == INFO_LOST ) - { - type = TT_ERROR; - } -#endif - - GetResource(RES_ERR, err, text); - DisplayText(text, goal, height, dist, time, type); -} - -// Displays text. - -void CDisplayText::DisplayText(char *text, CObject* pObj, - float time, TextType type) -{ - D3DVECTOR pos; - float h, d; - - if ( pObj == 0 ) return; - - pos = pObj->RetPosition(0); - h = RetIdealHeight(pObj); - d = RetIdealDist(pObj); - DisplayText(text, pos, h, d, time, type); -} - -// Displays text. - -void CDisplayText::DisplayText(char *text, D3DVECTOR goal, float height, - float dist, float time, TextType type) -{ - CObject* toto; - CMotion* motion; - CWindow* pw; - CButton* button; - CGroup* group; - CLabel* label; - FPOINT pos, ppos, dim; - Sound sound; - float hLine, hBox; - int nLine, icon, i; - - if ( !m_bEnable ) return; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); - if ( pw == 0 ) - { - pos.x = 0.0f; - pos.y = 0.0f; - dim.x = 0.0f; - dim.y = 0.0f; - pw = m_interface->CreateWindows(pos, dim, 10, EVENT_WINDOW2); - } - - hBox = 0.045f; - hLine = m_engine->RetText()->RetHeight(FONTSIZE, FONT_COLOBOT); - - nLine = 0; - for ( i=0 ; iSearchControl(EventMsg(EVENT_DT_GROUP0+i)); - if ( group == 0 ) break; - nLine ++; - } - - if ( nLine == MAXDTLINE ) - { - ClearLastText(); - nLine --; - } - - pos.x = 0.10f; - pos.y = 0.92f-hBox-hBox*nLine; - dim.x = 0.80f; - dim.y = hBox; - - icon = 1; // yellow - if ( type == TT_ERROR ) icon = 9; // red - if ( type == TT_WARNING ) icon = 10; // blue - if ( type == TT_INFO ) icon = 8; // green - if ( type == TT_MESSAGE ) icon = 11; // yellow - pw->CreateGroup(pos, dim, icon, EventMsg(EVENT_DT_GROUP0+nLine)); - - pw->SetTrashEvent(FALSE); - - ppos = pos; - ppos.y -= hLine/2.0f; - label = pw->CreateLabel(ppos, dim, -1, EventMsg(EVENT_DT_LABEL0+nLine), text); - if ( label != 0 ) - { - label->SetFontSize(FONTSIZE); - } - - dim.x = dim.y*0.75f; - pos.x -= dim.x; - button = pw->CreateButton(pos, dim, 14, EventMsg(EVENT_DT_VISIT0+nLine)); - - if ( goal.x == 0.0f && - goal.y == 0.0f && - goal.z == 0.0f ) - { - button->ClearState(STATE_ENABLE); - } - - m_bExist[nLine] = TRUE; - m_visitGoal[nLine] = goal; - m_visitDist[nLine] = dist; - m_visitHeight[nLine] = height; - m_time[nLine] = time*m_delayFactor; - - toto = SearchToto(); - if ( toto != 0 ) - { - motion = toto->RetMotion(); - if ( motion != 0 ) - { - if ( type == TT_ERROR ) - { - motion->SetAction(MT_ERROR, 4.0f); - } - if ( type == TT_WARNING ) - { - motion->SetAction(MT_WARNING, 4.0f); - } - if ( type == TT_INFO ) - { - motion->SetAction(MT_INFO, 4.0f); - } - if ( type == TT_MESSAGE ) - { - motion->SetAction(MT_MESSAGE, 4.0f); - } - } - } - - if ( m_bHide ) - { - HideText(m_bHide); // hide all - } - else - { - sound = SOUND_CLICK; - if ( type == TT_ERROR ) sound = SOUND_ERROR; - if ( type == TT_WARNING ) sound = SOUND_WARNING; - if ( type == TT_INFO ) sound = SOUND_INFO; - if ( type == TT_MESSAGE ) sound = SOUND_MESSAGE; - - if ( sound != SOUND_CLICK ) - { - m_sound->Play(sound); - } - } -} - -// Clears all text. - -void CDisplayText::ClearText() -{ - CWindow* pw; - int i; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); - - for ( i=0 ; iDeleteControl(EventMsg(EVENT_DT_GROUP0+i)); - pw->DeleteControl(EventMsg(EVENT_DT_LABEL0+i)); - pw->DeleteControl(EventMsg(EVENT_DT_VISIT0+i)); - } - m_bExist[i] = FALSE; - m_visitGoal[i] = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_visitDist[i] = 0.0f; - m_visitHeight[i] = 0.0f; - m_time[i] = 0.0f; - } -} - -// Hides or shows all texts. - -void CDisplayText::HideText(BOOL bHide) -{ - CWindow* pw; - CGroup* pg; - CLabel* pl; - CButton* pb; - int i; - - m_bHide = bHide; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); - if ( pw == 0 ) return; - - for ( i=0 ; iSearchControl(EventMsg(EVENT_DT_GROUP0+i)); - if ( pg != 0 ) - { - pg->SetState(STATE_VISIBLE, !bHide); - } - - pl = (CLabel* )pw->SearchControl(EventMsg(EVENT_DT_LABEL0+i)); - if ( pl != 0 ) - { - pl->SetState(STATE_VISIBLE, !bHide); - } - - pb = (CButton*)pw->SearchControl(EventMsg(EVENT_DT_VISIT0+i)); - if ( pb != 0 ) - { - pb->SetState(STATE_VISIBLE, !bHide); - } - } -} - -// Removes the last text (top of the list). - -BOOL CDisplayText::ClearLastText() -{ - CWindow *pw; - CButton *pb1, *pb2; - CGroup *pg1, *pg2; - CLabel *pl1, *pl2; - int i; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); - if ( pw == 0 ) return FALSE; - - pb2 = (CButton*)pw->SearchControl(EVENT_DT_VISIT0); - if ( pb2 == 0 ) return FALSE; // same not of first-line - pg2 = (CGroup*)pw->SearchControl(EVENT_DT_GROUP0); - if ( pg2 == 0 ) return FALSE; - pl2 = (CLabel*)pw->SearchControl(EVENT_DT_LABEL0); - if ( pl2 == 0 ) return FALSE; - - for ( i=0 ; iSearchControl(EventMsg(EVENT_DT_VISIT0+i+1)); - if ( pb2 == 0 ) break; - - pg2 = (CGroup*)pw->SearchControl(EventMsg(EVENT_DT_GROUP0+i+1)); - if ( pg2 == 0 ) break; - - pl2 = (CLabel*)pw->SearchControl(EventMsg(EVENT_DT_LABEL0+i+1)); - if ( pl2 == 0 ) break; - - pb1->SetState(STATE_ENABLE, pb2->TestState(STATE_ENABLE)); - pg1->SetIcon(pg2->RetIcon()); - pl1->SetName(pl2->RetName()); - - m_time[i] = m_time[i+1]; - m_visitGoal[i] = m_visitGoal[i+1]; - m_visitDist[i] = m_visitDist[i+1]; - m_visitHeight[i] = m_visitHeight[i+1]; // shift - } - - pw->DeleteControl(EventMsg(EVENT_DT_VISIT0+i)); - pw->DeleteControl(EventMsg(EVENT_DT_GROUP0+i)); - pw->DeleteControl(EventMsg(EVENT_DT_LABEL0+i)); - m_bExist[i] = FALSE; - return TRUE; -} - - -// Specifies the factor of time. - -void CDisplayText::SetDelay(float factor) -{ - m_delayFactor = factor; -} - - -// Enables the display of text. - -void CDisplayText::SetEnable(BOOL bEnable) -{ - m_bEnable = bEnable; -} - - -// Returns the goal during a visit. - -D3DVECTOR CDisplayText::RetVisitGoal(EventMsg event) -{ - int i; - - i = event-EVENT_DT_VISIT0; - if ( i < 0 || i >= MAXDTLINE ) return D3DVECTOR(0.0f, 0.0f, 0.0f); - return m_visitGoal[i]; -} - -// Returns the distance during a visit. - -float CDisplayText::RetVisitDist(EventMsg event) -{ - int i; - - i = event-EVENT_DT_VISIT0; - if ( i < 0 || i >= MAXDTLINE ) return 0.0f; - return m_visitDist[i]; -} - -// Returns the height on a visit. - -float CDisplayText::RetVisitHeight(EventMsg event) -{ - int i; - - i = event-EVENT_DT_VISIT0; - if ( i < 0 || i >= MAXDTLINE ) return 0.0f; - return m_visitHeight[i]; -} - - -// Ranges from ideal visit for a given object. - -float CDisplayText::RetIdealDist(CObject* pObj) -{ - ObjectType type; - - if ( pObj == 0 ) return 40.0f; - - type = pObj->RetType(); - if ( type == OBJECT_PORTICO ) return 200.0f; - if ( type == OBJECT_BASE ) return 200.0f; - if ( type == OBJECT_NUCLEAR ) return 100.0f; - if ( type == OBJECT_PARA ) return 100.0f; - if ( type == OBJECT_SAFE ) return 100.0f; - if ( type == OBJECT_TOWER ) return 80.0f; - - return 60.0f; -} - -// Returns the height of ideal visit for a given object. - -float CDisplayText::RetIdealHeight(CObject* pObj) -{ - ObjectType type; - - if ( pObj == 0 ) return 5.0f; - - type = pObj->RetType(); - if ( type == OBJECT_DERRICK ) return 35.0f; - if ( type == OBJECT_FACTORY ) return 22.0f; - if ( type == OBJECT_REPAIR ) return 30.0f; - if ( type == OBJECT_DESTROYER) return 30.0f; - if ( type == OBJECT_STATION ) return 13.0f; - if ( type == OBJECT_CONVERT ) return 20.0f; - if ( type == OBJECT_TOWER ) return 30.0f; - if ( type == OBJECT_RESEARCH ) return 22.0f; - if ( type == OBJECT_RADAR ) return 19.0f; - if ( type == OBJECT_INFO ) return 19.0f; - if ( type == OBJECT_ENERGY ) return 20.0f; - if ( type == OBJECT_LABO ) return 16.0f; - if ( type == OBJECT_NUCLEAR ) return 40.0f; - if ( type == OBJECT_PARA ) return 40.0f; - if ( type == OBJECT_SAFE ) return 20.0f; - - return 15.0f; -} - - -// Removes all visits. - -void CDisplayText::ClearVisit() -{ - CWindow* pw; - CButton* pb; - int i; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); - if ( pw == 0 ) return; - - for ( i=0 ; iSearchControl(EventMsg(EVENT_DT_VISIT0+i)); - if ( pb == 0 ) break; - pb->SetIcon(14); // eyes - } -} - -// Puts a button in "visit". - -void CDisplayText::SetVisit(EventMsg event) -{ - CWindow* pw; - CButton* pb; - int i; - - i = event-EVENT_DT_VISIT0; - if ( i < 0 || i >= MAXDTLINE ) return; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); - if ( pw == 0 ) return; - pb = (CButton*)pw->SearchControl(EventMsg(EVENT_DT_VISIT0+i)); - if ( pb == 0 ) return; - pb->SetIcon(48); // > -} - -// Indicates whether a button is set to "visit". - -BOOL CDisplayText::IsVisit(EventMsg event) -{ - CWindow* pw; - CButton* pb; - int i; - - i = event-EVENT_DT_VISIT0; - if ( i < 0 || i >= MAXDTLINE ) return FALSE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); - if ( pw == 0 ) return FALSE; - pb = (CButton*)pw->SearchControl(EventMsg(EVENT_DT_VISIT0+i)); - if ( pb == 0 ) return FALSE; - return (pb->RetIcon() == 48); // > ? -} - - -// Returns the object toto. - -CObject* CDisplayText::SearchToto() -{ - ObjectType type; - CObject* pObj; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type == OBJECT_TOTO ) - { - return pObj; - } - } - return 0; -} - diff --git a/src/displaytext.h b/src/displaytext.h deleted file mode 100644 index 6a54e1f..0000000 --- a/src/displaytext.h +++ /dev/null @@ -1,96 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// displaytext.h - -#ifndef _DISPLAYTEXT_H_ -#define _DISPLAYTEXT_H_ - - -#include "d3dengine.h" - - -class CInstanceManager; -class CD3DEngine; -class CInterface; -class CObject; -class CSound; - - -enum TextType -{ - TT_ERROR = 1, - TT_WARNING = 2, - TT_INFO = 3, - TT_MESSAGE = 4, -}; - -#define MAXDTLINE 4 - - -class CDisplayText -{ -public: - CDisplayText(CInstanceManager* iMan); - ~CDisplayText(); - - void DeleteObject(); - - BOOL EventProcess(const Event &event); - - void DisplayError(Error err, CObject* pObj, float time=10.0f); - void DisplayError(Error err, D3DVECTOR goal, float height=15.0f, float dist=60.0f, float time=10.0f); - void DisplayText(char *text, CObject* pObj, float time=10.0f, TextType type=TT_INFO); - void DisplayText(char *text, D3DVECTOR goal, float height=15.0f, float dist=60.0f, float time=10.0f, TextType type=TT_INFO); - void HideText(BOOL bHide); - void ClearText(); - BOOL ClearLastText(); - void SetDelay(float factor); - void SetEnable(BOOL bEnable); - - D3DVECTOR RetVisitGoal(EventMsg event); - float RetVisitDist(EventMsg event); - float RetVisitHeight(EventMsg event); - - float RetIdealDist(CObject* pObj); - float RetIdealHeight(CObject* pObj); - - void ClearVisit(); - void SetVisit(EventMsg event); - BOOL IsVisit(EventMsg event); - -protected: - CObject* SearchToto(); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CInterface* m_interface; - CSound* m_sound; - - BOOL m_bExist[MAXDTLINE]; - float m_time[MAXDTLINE]; - D3DVECTOR m_visitGoal[MAXDTLINE]; - float m_visitDist[MAXDTLINE]; - float m_visitHeight[MAXDTLINE]; - - BOOL m_bHide; - BOOL m_bEnable; - float m_delayFactor; -}; - - -#endif //_DISPLAYTEXT_H_ diff --git a/src/edit.cpp b/src/edit.cpp deleted file mode 100644 index f15b0c2..0000000 --- a/src/edit.cpp +++ /dev/null @@ -1,3318 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// edit.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "language.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "restext.h" -#include "scroll.h" -#include "text.h" -#include "edit.h" - - -#define MARGX (5.0f/640.0f) -#define MARGY (5.0f/480.0f) -#define MARGYS (4.0f/480.0f) -#define MARGY1 (1.0f/480.0f) -#define DELAY_DBCLICK 0.3f // time limit for double-click -#define DELAY_SCROLL 0.1f // time limit for scroll -#define BIG_FONT 1.6f // expansion for \b; - - - - -// Indicates whether a character is a space. - -BOOL IsSpace(int character) -{ - return ( character == ' ' || - character == '\t' || - character == '\n' ); -} - -// Indicates whether a character is part of a word. - -BOOL IsWord(int character) -{ - char c; - - c = tolower(RetNoAccent(character)); - - return ( (c >= 'a' && c <= 'z') || - (c >= '0' && c <= '9') || - c == '_' ); -} - -// Indicates whether a character is a word separator. - -BOOL IsSep(int character) -{ - if ( IsSpace(character) ) return FALSE; - return !IsWord(character); -} - - - -// Object's constructor. - -CEdit::CEdit(CInstanceManager* iMan) : CControl(iMan) -{ - FPOINT pos; - int i; - - m_maxChar = 100; - m_text = (char*)malloc(sizeof(char)*(m_maxChar+1)); - m_format = 0; - m_len = 0; - - m_fontType = FONT_COURIER; - m_scroll = 0; - m_bEdit = TRUE; - m_bHilite = TRUE; - m_bInsideScroll = TRUE; - m_bCapture = FALSE; - m_bDisplaySpec = FALSE; - m_bSoluce = FALSE; - m_bGeneric = FALSE; - m_bAutoIndent = FALSE; - m_cursor1 = 0; - m_cursor2 = 0; - m_column = 0; - m_imageTotal = 0; - - HyperFlush(); - - for ( i=0 ; iCreate(pos, dim, -1, EVENT_NULL); - MoveAdjust(); - } - - return TRUE; -} - - -void CEdit::SetPos(FPOINT pos) -{ - CControl::SetPos(pos); - MoveAdjust(); -} - -void CEdit::SetDim(FPOINT dim) -{ - CControl::SetDim(dim); - MoveAdjust(); -} - -void CEdit::MoveAdjust() -{ - FPOINT pos, dim; - float height; - - m_lineDescent = m_engine->RetText()->RetDescent(m_fontSize, m_fontType); - m_lineAscent = m_engine->RetText()->RetAscent(m_fontSize, m_fontType); - m_lineHeight = m_engine->RetText()->RetHeight(m_fontSize, m_fontType); - - height = m_dim.y-(m_bMulti?MARGY*2.0f:MARGY1); - m_lineVisible = (int)(height/m_lineHeight); - - if ( m_scroll != 0 ) - { - if ( m_bInsideScroll ) - { - pos.x = m_pos.x+m_dim.x-MARGX-SCROLL_WIDTH; - pos.y = m_pos.y+MARGYS; - dim.x = SCROLL_WIDTH; - dim.y = m_dim.y-MARGYS*2.0f; - } - else - { - pos.x = m_pos.x+m_dim.x-SCROLL_WIDTH; - pos.y = m_pos.y; - dim.x = SCROLL_WIDTH; - dim.y = m_dim.y; - } - m_scroll->SetPos(pos); - m_scroll->SetDim(dim); - } - - Justif(); - - if ( m_lineFirst > m_lineTotal-m_lineVisible ) - { - m_lineFirst = m_lineTotal-m_lineVisible; - if ( m_lineFirst < 0 ) m_lineFirst = 0; - } - - pos.x = m_pos.x+m_dim.x-(m_bMulti?SCROLL_WIDTH:0.0f); - pos.y = m_pos.y; - GlintCreate(pos, FALSE, FALSE); -} - - -// Management of an event. - -BOOL CEdit::EventProcess(const Event &event) -{ - BOOL bShift, bControl; - - if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; - - if ( event.event == EVENT_KEYDOWN && - event.param == VK_WHEELUP && - Detect(event.pos) ) - { - Scroll(m_lineFirst-3, TRUE); - return TRUE; - } - if ( event.event == EVENT_KEYDOWN && - event.param == VK_WHEELDOWN && - Detect(event.pos) ) - { - Scroll(m_lineFirst+3, TRUE); - return TRUE; - } - - CControl::EventProcess(event); - - if ( event.event == EVENT_FRAME ) - { - m_time += event.rTime; - m_timeBlink += event.rTime; - } - - if ( event.event == EVENT_MOUSEMOVE ) - { - if ( Detect(event.pos) && - event.pos.x < m_pos.x+m_dim.x-(m_bMulti?MARGX+SCROLL_WIDTH:0.0f) ) - { - if ( m_bEdit ) - { - m_engine->SetMouseType(D3DMOUSEEDIT); - } - else - { - if ( IsLinkPos(event.pos) ) - { - m_engine->SetMouseType(D3DMOUSEHAND); - } - else - { - m_engine->SetMouseType(D3DMOUSENORM); - } - } - } - } - - if ( m_scroll != 0 && !m_bGeneric ) - { - m_scroll->EventProcess(event); - - if ( event.event == m_scroll->RetEventMsg() ) - { - Scroll(); - return TRUE; - } - } - - if ( event.event == EVENT_KEYDOWN && m_bFocus ) - { - bShift = (event.keyState&KS_SHIFT); - bControl = (event.keyState&KS_CONTROL); - - if ( (event.param == 'X' && !bShift && bControl) || - (event.param == VK_DELETE && bShift && !bControl) ) - { - Cut(); - return TRUE; - } - if ( (event.param == 'C' && !bShift && bControl) || - (event.param == VK_INSERT && !bShift && bControl) ) - { - Copy(); - return TRUE; - } - if ( (event.param == 'V' && !bShift && bControl) || - (event.param == VK_INSERT && bShift && !bControl) ) - { - Paste(); - return TRUE; - } - - if ( event.param == 'A' && !bShift && bControl ) - { - SetCursor(999999, 0); - return TRUE; - } - - if ( event.param == 'O' && !bShift && bControl ) - { - Event newEvent; - m_event->MakeEvent(newEvent, EVENT_STUDIO_OPEN); - m_event->AddEvent(newEvent); - } - if ( event.param == 'S' && !bShift && bControl ) - { - Event newEvent; - m_event->MakeEvent(newEvent, EVENT_STUDIO_SAVE); - m_event->AddEvent(newEvent); - } - - if ( event.param == 'Z' && !bShift && bControl ) - { - Undo(); - return TRUE; - } - - if ( event.param == 'U' && !bShift && bControl ) - { - if ( MinMaj(FALSE) ) return TRUE; - } - if ( event.param == 'U' && bShift && bControl ) - { - if ( MinMaj(TRUE) ) return TRUE; - } - - if ( event.param == VK_TAB && !bShift && !bControl && !m_bAutoIndent ) - { - if ( Shift(FALSE) ) return TRUE; - } - if ( event.param == VK_TAB && bShift && !bControl && !m_bAutoIndent ) - { - if ( Shift(TRUE) ) return TRUE; - } - - if ( m_bEdit ) - { - if ( event.param == VK_LEFT ) - { - MoveChar(-1, bControl, bShift); - return TRUE; - } - if ( event.param == VK_RIGHT ) - { - MoveChar(1, bControl, bShift); - return TRUE; - } - if ( event.param == VK_UP ) - { - MoveLine(-1, bControl, bShift); - return TRUE; - } - if ( event.param == VK_DOWN ) - { - MoveLine(1, bControl, bShift); - return TRUE; - } - - if ( event.param == VK_PRIOR ) // PageUp ? - { - MoveLine(-(m_lineVisible-1), bControl, bShift); - return TRUE; - } - if ( event.param == VK_NEXT ) // PageDown ? - { - MoveLine(m_lineVisible-1, bControl, bShift); - return TRUE; - } - } - else - { - if ( event.param == VK_LEFT || - event.param == VK_UP ) - { - Scroll(m_lineFirst-1, TRUE); - return TRUE; - } - if ( event.param == VK_RIGHT || - event.param == VK_DOWN ) - { - Scroll(m_lineFirst+1, TRUE); - return TRUE; - } - - if ( event.param == VK_PRIOR ) // PageUp ? - { - Scroll(m_lineFirst-(m_lineVisible-1), TRUE); - return TRUE; - } - if ( event.param == VK_NEXT ) // PageDown ? - { - Scroll(m_lineFirst+(m_lineVisible-1), TRUE); - return TRUE; - } - } - - if ( event.param == VK_HOME ) - { - MoveHome(bControl, bShift); - return TRUE; - } - if ( event.param == VK_END ) - { - MoveEnd(bControl, bShift); - return TRUE; - } - - if ( event.param == VK_BACK ) // backspace ( <- ) ? - { - Delete(-1); - SendModifEvent(); - return TRUE; - } - if ( event.param == VK_DELETE ) - { - Delete(1); - SendModifEvent(); - return TRUE; - } - - if ( event.param == VK_RETURN ) - { - Insert('\n'); - SendModifEvent(); - return TRUE; - } - if ( event.param == VK_TAB ) - { - Insert('\t'); - SendModifEvent(); - return TRUE; - } - } - - if ( event.event == EVENT_CHAR && m_bFocus ) - { - if ( event.param >= ' ' && event.param <= 255 ) - { - Insert((char)event.param); - SendModifEvent(); - return TRUE; - } - } - - if ( event.event == EVENT_FOCUS ) - { - if ( event.param == m_eventMsg ) - { - m_bFocus = TRUE; - } - else - { - m_bFocus = FALSE; - } - } - - if ( event.event == EVENT_LBUTTONDOWN ) - { - m_mouseFirstPos = event.pos; - m_mouseLastPos = event.pos; - if ( Detect(event.pos) ) - { - if ( event.pos.x < m_pos.x+m_dim.x-(m_bMulti?MARGX+SCROLL_WIDTH:0.0f) ) - { - MouseClick(event.pos); - if ( m_bEdit || m_bHilite ) m_bCapture = TRUE; - } - m_bFocus = TRUE; - } - else - { - m_bFocus = FALSE; - } - } - - if ( event.event == EVENT_MOUSEMOVE && m_bCapture ) - { - m_mouseLastPos = event.pos; - MouseMove(event.pos); - } - - if ( event.event == EVENT_FRAME && m_bCapture ) - { - MouseMove(m_mouseLastPos); - } - - if ( event.event == EVENT_LBUTTONUP ) - { - if ( Detect(event.pos) ) - { - if ( event.pos.x < m_pos.x+m_dim.x-(m_bMulti?MARGX+SCROLL_WIDTH:0.0f) ) - { - MouseRelease(m_mouseFirstPos); - } - } - if ( m_bCapture ) - { - if ( m_timeLastClick+DELAY_DBCLICK > m_time ) // double-click ? - { - MouseDoubleClick(event.pos); - } - m_timeLastClick = m_time; - m_bCapture = FALSE; - } - } - - return TRUE; -} - - -// Sends an event to indicate that the text was modified. - -void CEdit::SendModifEvent() -{ - Event newEvent; - - m_event->MakeEvent(newEvent, m_eventMsg); - m_event->AddEvent(newEvent); -} - - -// Detects whether the mouse is over a hyperlink character. - -BOOL CEdit::IsLinkPos(FPOINT pos) -{ - int i; - - if ( m_format == 0 ) return FALSE; - - i = MouseDetect(pos); - if ( i == -1 ) return FALSE; - if ( i >= m_len ) return FALSE; - - if ( (m_format[i]&COLOR_MASK) == COLOR_LINK ) return TRUE; - return FALSE; -} - - -// Positions the cursor after a double click. - -void CEdit::MouseDoubleClick(FPOINT mouse) -{ - int i, character; - - if ( m_bMulti ) // Multi-line? - { - i = MouseDetect(mouse); - if ( i == -1 ) return; - - while ( i > 0 ) - { - character = (unsigned char)m_text[i-1]; - if ( !IsWord(character) ) break; - i --; - } - m_cursor2 = i; - - while ( i < m_len ) - { - character = (unsigned char)m_text[i]; - if ( !IsWord(character) ) break; - i ++; - } - m_cursor1 = i; - } - else // single-line? - { - m_cursor2 = 0; - m_cursor1 = m_len; // selects all - } - - m_bUndoForce = TRUE; - - Justif(); - ColumnFix(); -} - -// Positions the cursor when clicked. - -void CEdit::MouseClick(FPOINT mouse) -{ - int i; - - i = MouseDetect(mouse); - if ( i == -1 ) return; - - if ( m_bEdit || m_bHilite ) - { - m_cursor1 = i; - m_cursor2 = i; - m_bUndoForce = TRUE; - m_timeBlink = 0.0f; // lights the cursor immediately - ColumnFix(); - } -} - -// Positions the cursor when clicked released. - -void CEdit::MouseRelease(FPOINT mouse) -{ - int i, j, rank; - - i = MouseDetect(mouse); - if ( i == -1 ) return; - - if ( !m_bEdit ) - { - if ( m_format != 0 && i < m_len && m_cursor1 == m_cursor2 && - (m_format[i]&COLOR_MASK) == COLOR_LINK ) - { - rank = -1; - for ( j=0 ; j<=i ; j++ ) - { - if ( (j == 0 || (m_format[j-1]&COLOR_MASK) != COLOR_LINK) && - (m_format[j+0]&COLOR_MASK) == COLOR_LINK ) - { - rank ++; - } - } - HyperJump(m_link[rank].name, m_link[rank].marker); - } - } -} - -// Positions the cursor after movement. - -void CEdit::MouseMove(FPOINT mouse) -{ - int i; - - if ( m_bMulti && - m_timeLastScroll+DELAY_SCROLL <= m_time ) - { - if ( mouse.y > m_pos.y+m_dim.y ) // above? - { - Scroll(m_lineFirst-1, FALSE); - mouse.y = m_pos.y+m_dim.y-MARGY-m_lineHeight/2.0f; - } - if ( mouse.y < m_pos.y ) // lower? - { - Scroll(m_lineFirst+1, FALSE); - mouse.y = m_pos.y+m_dim.y-MARGY-m_lineVisible*m_lineHeight+m_lineHeight/2.0f; - } - m_timeLastScroll = m_time; - } - - i = MouseDetect(mouse); - if ( i != -1 ) - { - m_cursor1 = i; - m_bUndoForce = TRUE; - m_timeBlink = 0.0f; // lights the cursor immediately - ColumnFix(); - } -} - -// Positions the cursor when clicked. - -int CEdit::MouseDetect(FPOINT mouse) -{ - FPOINT pos; - float indentLength, offset, size; - int i, len, c; - BOOL bTitle; - - if ( m_bAutoIndent ) - { - indentLength = m_engine->RetText()->RetCharWidth(' ', 0.0f, m_fontSize, m_fontStretch, m_fontType) - * m_engine->RetEditIndentValue(); - } - - pos.y = m_pos.y+m_dim.y-m_lineHeight-(m_bMulti?MARGY:MARGY1); - for ( i=m_lineFirst ; i= m_lineFirst+m_lineVisible ) break; - - pos.x = m_pos.x+(10.0f/640.0f); - if ( m_bAutoIndent ) - { - pos.x += indentLength*m_lineIndent[i]; - } - offset = mouse.x-pos.x; - - if ( bTitle ) pos.y -= m_lineHeight; - - if ( mouse.y > pos.y ) - { - len = m_lineOffset[i+1] - m_lineOffset[i]; - - if ( m_format == 0 ) - { - c = m_engine->RetText()->Detect(m_text+m_lineOffset[i], - len, offset, m_fontSize, - m_fontStretch, m_fontType); - } - else - { - size = m_fontSize; - if ( bTitle ) size *= BIG_FONT; - - c = m_engine->RetText()->Detect(m_text+m_lineOffset[i], - m_format+m_lineOffset[i], - len, offset, size, - m_fontStretch); - } - return m_lineOffset[i]+c; - } - - if ( bTitle ) i ++; - pos.y -= m_lineHeight; - } - return -1; -} - - -// Clears all history. - -void CEdit::HyperFlush() -{ - m_historyTotal = 0; - m_historyCurrent = -1; -} - -// Indicates which is the home page. - -void CEdit::HyperHome(char *filename) -{ - HyperFlush(); - HyperAdd(filename, 0); -} - -// Performs a hyper jump through a link. - -void CEdit::HyperJump(char *name, char *marker) -{ - char filename[100]; - char sMarker[100]; - int i, line, pos; - - if ( m_historyCurrent >= 0 ) - { - m_history[m_historyCurrent].firstLine = m_lineFirst; - } - - strcpy(sMarker, marker); - -//? sprintf(filename, "help\\%s.txt", name); - if ( name[0] == '%' ) - { - UserDir(filename, name, ""); - strcat(filename, ".txt"); - } - else - { - sprintf(filename, "help\\%s.txt", name); - } - if ( ReadText(filename) ) - { - Justif(); - - line = 0; - for ( i=0 ; i= m_lineOffset[i] ) - { - line = i; - } - } - break; - } - } - - SetFirstLine(line); - HyperAdd(filename, line); - } -} - -// Adds text to the history of visited. - -BOOL CEdit::HyperAdd(char *filename, int firstLine) -{ - if ( m_historyCurrent >= EDITHISTORYMAX-1 ) return FALSE; - - m_historyCurrent ++; - strcpy(m_history[m_historyCurrent].filename, filename); - m_history[m_historyCurrent].firstLine = firstLine; - - m_historyTotal = m_historyCurrent+1; - return TRUE; -} - -// Indicates whether a button EVENT_HYPER_ * is active or not. - -BOOL CEdit::HyperTest(EventMsg event) -{ - if ( event == EVENT_HYPER_HOME ) - { - return ( m_historyCurrent > 0 ); - } - - if ( event == EVENT_HYPER_PREV ) - { - return ( m_historyCurrent > 0 ); - } - - if ( event == EVENT_HYPER_NEXT ) - { - return ( m_historyCurrent < m_historyTotal-1 ); - } - - return FALSE; -} - -// Performs the action corresponding to a button EVENT_HYPER_ *. - -BOOL CEdit::HyperGo(EventMsg event) -{ - if ( !HyperTest(event) ) return FALSE; - - m_history[m_historyCurrent].firstLine = m_lineFirst; - - if ( event == EVENT_HYPER_HOME ) - { - m_historyCurrent = 0; - } - - if ( event == EVENT_HYPER_PREV ) - { - m_historyCurrent --; - } - - if ( event == EVENT_HYPER_NEXT ) - { - m_historyCurrent ++; - } - - ReadText(m_history[m_historyCurrent].filename); - Justif(); - SetFirstLine(m_history[m_historyCurrent].firstLine); - return TRUE; -} - - -// Draw the editable line. - -void CEdit::Draw() -{ - FPOINT pos, ppos, dim, start, end; - float size, indentLength; - int i, j, beg, len, c1, c2, o1, o2, eol, iIndex, line; - - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - if ( m_state & STATE_SHADOW ) - { - DrawShadow(m_pos, m_dim); - } - - pos.x = m_pos.x; - pos.y = m_pos.y; - dim.x = m_dim.x; - if ( !m_bInsideScroll ) dim.x -= m_bMulti?SCROLL_WIDTH:0.0f; - dim.y = m_dim.y; - DrawBack(pos, dim); // background - - // Displays all lines. - c1 = m_cursor1; - c2 = m_cursor2; - if ( c1 > c2 ) Swap(c1, c2); // always c1 <= c2 - - if ( m_bInsideScroll ) - { - dim.x -= m_bMulti?SCROLL_WIDTH:0.0f + (1.0f/640.0f); - } - - if ( m_bAutoIndent ) - { - indentLength = m_engine->RetText()->RetCharWidth(' ', 0.0f, m_fontSize, m_fontStretch, m_fontType) - * m_engine->RetEditIndentValue(); - } - - pos.y = m_pos.y+m_dim.y-m_lineHeight-(m_bMulti?MARGY:MARGY1); - for ( i=m_lineFirst ; i= m_lineFirst+m_lineVisible ) break; - - pos.x = m_pos.x+(10.0f/640.0f); - if ( m_bAutoIndent ) - { - for ( j=0 ; jRetText()->DrawText(&s, 1, pos, 1.0f, 1, m_fontSize, m_fontStretch, m_fontType, 0); - pos.x += indentLength; - } - } - - beg = m_lineOffset[i]; - len = m_lineOffset[i+1] - m_lineOffset[i]; - - ppos = pos; - size = m_fontSize; - - // Headline \b;? - if ( beg+len < m_len && m_format != 0 && - (m_format[beg]&TITLE_MASK) == TITLE_BIG ) - { - start.x = ppos.x-MARGX; - end.x = dim.x-MARGX*2.0f; - start.y = ppos.y-(m_bMulti?0.0f:MARGY1)-m_lineHeight*(BIG_FONT-1.0f); - end.y = m_lineHeight*BIG_FONT; - DrawPart(start, end, 2); // blue gradient background -> - - size *= BIG_FONT; - ppos.y -= m_lineHeight*(BIG_FONT-1.0f); - } - - // As \t;? - if ( beg+len < m_len && m_format != 0 && - (m_format[beg]&TITLE_MASK) == TITLE_NORM ) - { - start.x = ppos.x-MARGX; - end.x = dim.x-MARGX*2.0f; - start.y = ppos.y-(m_bMulti?0.0f:MARGY1); - end.y = m_lineHeight; - DrawPart(start, end, 2); // blue gradient background -> - } - - // Subtitle \s;? - if ( beg+len < m_len && m_format != 0 && - (m_format[beg]&TITLE_MASK) == TITLE_LITTLE ) - { - start.x = ppos.x-MARGX; - end.x = dim.x-MARGX*2.0f; - start.y = ppos.y-(m_bMulti?0.0f:MARGY1); - end.y = m_lineHeight; - DrawPart(start, end, 3); // yellow background gradient -> - } - - // Table \tab;? - if ( beg+len < m_len && m_format != 0 && - (m_format[beg]&COLOR_MASK) == COLOR_TABLE ) - { - start.x = ppos.x-MARGX; - end.x = dim.x-MARGX*2.0f; - start.y = ppos.y-(m_bMulti?0.0f:MARGY1); - end.y = m_lineHeight; - DrawPart(start, end, 11); // fond orange d�grad� -> - } - - // Image \image; ? - if ( beg+len < m_len && m_format != 0 && - (m_format[beg]&IMAGE_MASK) != 0 ) - { - line = 1; - while ( true ) // includes the image slices - { - if ( i+line >= m_lineTotal || - i+line >= m_lineFirst+m_lineVisible || - (m_format[beg+line]&IMAGE_MASK) == 0 ) break; - line ++; - } - - iIndex = m_text[beg]; // character = index in m_image - pos.y -= m_lineHeight*(line-1); - DrawImage(pos, m_image[iIndex].name, - m_image[iIndex].width*(m_fontSize/SMALLFONT), - m_image[iIndex].offset, m_image[iIndex].height*line, line); - pos.y -= m_lineHeight; - i += line-1; - continue; - } - - if ( ((m_bEdit && m_bFocus && m_bHilite) || - (!m_bEdit && m_bHilite) ) && - c1 != c2 && beg <= c2 && beg+len >= c1 ) // selected area? - { - o1 = c1; if ( o1 < beg ) o1 = beg; - o2 = c2; if ( o2 > beg+len ) o2 = beg+len; - - if ( m_format == 0 ) - { - start.x = ppos.x+m_engine->RetText()->RetStringWidth(m_text+beg, o1-beg, size, m_fontStretch, m_fontType); - end.x = m_engine->RetText()->RetStringWidth(m_text+o1, o2-o1, size, m_fontStretch, m_fontType); - } - else - { - start.x = ppos.x+m_engine->RetText()->RetStringWidth(m_text+beg, m_format+beg, o1-beg, size, m_fontStretch); - end.x = m_engine->RetText()->RetStringWidth(m_text+o1, m_format+o1, o2-o1, size, m_fontStretch); - } - - start.y = ppos.y-(m_bMulti?0.0f:MARGY1); - end.y = m_lineHeight; - if ( m_format != 0 && (m_format[beg]&TITLE_MASK) == TITLE_BIG ) end.y *= BIG_FONT; - DrawPart(start, end, 1); // plain yellow background - } - - eol = 16; // > - if ( len > 0 && m_text[beg+len-1] == '\n' ) - { - len --; // does not display the '\ n' - eol = 0; // nothing - } - if ( beg+len >= m_len ) - { - eol = 2; // square (eot) - } - if ( !m_bMulti || !m_bDisplaySpec ) eol = 0; - if ( m_format == 0 ) - { - m_engine->RetText()->DrawText(m_text+beg, len, ppos, m_dim.x, 1, size, m_fontStretch, m_fontType, eol); - } - else - { - m_engine->RetText()->DrawText(m_text+beg, m_format+beg, len, ppos, m_dim.x, 1, size, m_fontStretch, eol); - } - - pos.y -= m_lineHeight; - - if ( i < m_lineTotal-2 && m_lineOffset[i+1] == m_lineOffset[i+2] ) - { - pos.y -= m_lineHeight; // double jump line \b; - i ++; - } - } - - // Shows the cursor. - if ( (m_bEdit && m_bFocus && m_bHilite && Mod(m_timeBlink, 1.0f) <= 0.5f) ) // it blinks - { - pos.y = m_pos.y+m_dim.y-m_lineHeight-(m_bMulti?MARGY:MARGY1*2.0f); - for ( i=m_lineFirst ; iRetText()->DimText(m_text+m_lineOffset[i], len, - pos, 1, size, - m_fontStretch, m_fontType, - start, end); - } - else - { - m_engine->RetText()->DimText(m_text+m_lineOffset[i], - m_format+m_lineOffset[i], - len, pos, 1, size, - m_fontStretch, - start, end); - } - - pos.x = end.x; - break; - } - pos.y -= m_lineHeight; - } - pos.x -= 1.0f/640.0f; - dim.x = 2.0f/640.0f; - dim.y = m_lineHeight; - DrawPart(pos, dim, 0); // red - } - - if ( m_scroll != 0 && !m_bGeneric ) - { - m_scroll->Draw(); - } -} - -// Draw an image part. - -void CEdit::DrawImage(FPOINT pos, char *name, float width, - float offset, float height, int nbLine) -{ - FPOINT uv1, uv2, dim; - float dp; - char filename[100]; - -//? sprintf(filename, "diagram\\%s.bmp", name); - UserDir(filename, name, "diagram"); - strcat(filename, ".bmp"); - - m_engine->SetTexture(filename); - m_engine->SetState(D3DSTATENORMAL); - - uv1.x = 0.0f; - uv2.x = 1.0f; - uv1.y = offset; - uv2.y = offset+height; - - dp = 0.5f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - dim.x = width; - dim.y = m_lineHeight*nbLine; - DrawIcon(pos, dim, uv1, uv2); -} - -// Draw the background. - -void CEdit::DrawBack(FPOINT pos, FPOINT dim) -{ - FPOINT uv1,uv2, corner; - float dp; - - if ( m_bGeneric ) return; - - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - - if ( m_bMulti ) - { - uv1.x = 128.0f/256.0f; // light blue - uv1.y = 64.0f/256.0f; - uv2.x = 160.0f/256.0f; - uv2.y = 96.0f/256.0f; - } - else - { - uv1.x = 160.0f/256.0f; // medium blue - uv1.y = 192.0f/256.0f; - uv2.x = 192.0f/256.0f; - uv2.y = 224.0f/256.0f; - } - if ( m_icon == 1 ) - { - uv1.x = 192.0f/256.0f; // orange - uv1.y = 96.0f/256.0f; - uv2.x = 224.0f/256.0f; - uv2.y = 128.0f/256.0f; - } - - dp = 0.5f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - if ( m_bMulti ) - { - corner.x = 10.0f/640.0f; - corner.y = 10.0f/480.0f; - DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); - } - else - { - DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); - } -} - -// Draws an icon background. - -void CEdit::DrawPart(FPOINT pos, FPOINT dim, int icon) -{ - FPOINT uv1, uv2; - float dp; - -#if _POLISH - m_engine->SetTexture("textp.tga"); -#else - m_engine->SetTexture("text.tga"); -#endif - m_engine->SetState(D3DSTATENORMAL); - - uv1.x = (16.0f/256.0f)*(icon%16); - uv1.y = (240.0f/256.0f); - uv2.x = (16.0f/256.0f)+uv1.x; - uv2.y = (16.0f/256.0f)+uv1.y; - - dp = 0.5f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - DrawIcon(pos, dim, uv1, uv2); -} - - -// Give the text to edit. - -void CEdit::SetText(char *text, BOOL bNew) -{ - int i, j, font; - BOOL bBOL; - - if ( !bNew ) UndoMemorize(OPERUNDO_SPEC); - - m_len = strlen(text); - if ( m_len > m_maxChar ) m_len = m_maxChar; - - if ( m_format == 0 ) - { - if ( m_bAutoIndent ) - { - j = 0; - bBOL = TRUE; - for ( i=0 ; i max ) max = max-1; - - strncpy(buffer, m_text, max); - buffer[max] = 0; -} - -// Returns the length of the text. - -int CEdit::RetTextLength() -{ - return m_len; -} - - - -// Returns a name in a command. -// \x nom1 nom2 nom3; - -void GetNameParam(char *cmd, int rank, char *buffer) -{ - int i; - - for ( i=0 ; iFreeTexture(filename); - } -} - -// Reads the texture of an image. - -void CEdit::LoadImage(char *name) -{ - char filename[100]; - -//? sprintf(filename, "diagram\\%s.bmp", name); - UserDir(filename, name, "diagram"); - strcat(filename, ".bmp"); - m_engine->LoadTexture(filename); -} - -// Read from a text file. - -BOOL CEdit::ReadText(char *filename, int addSize) -{ - FILE *file = NULL; - char *buffer; - int len, i, j, n, font, iIndex, iLines, iCount, iLink, res; - char iName[50]; - char text[50]; - float iWidth; - KeyRank key; - BOOL bInSoluce, bBOL; - - if ( filename[0] == 0 ) return FALSE; - file = fopen(filename, "rb"); - if ( file == NULL ) return FALSE; - - fseek(file, 0, SEEK_END); - len = ftell(file); - fseek(file, 0, SEEK_SET); - - m_maxChar = len+addSize+100; - m_len = len; - m_cursor1 = 0; - m_cursor2 = 0; - - FreeImage(); - delete m_text; - m_text = (char*)malloc(sizeof(char)*(m_maxChar+1)); - buffer = (char*)malloc(sizeof(char)*(m_maxChar+1)); - fread(buffer, 1, len, file); - - if ( m_format != 0 ) - { - delete m_format; - m_format = (char*)malloc(sizeof(char)*m_maxChar); - } - - fclose(file); - - bInSoluce = FALSE; - font = m_fontType; - iIndex = 0; - iLink = 0; - m_imageTotal = 0; - m_markerTotal = 0; - i = j = 0; - bBOL = TRUE; - while ( i < m_len ) - { - if ( m_bAutoIndent ) - { - if ( buffer[i] == '\t' ) - { - if ( !bBOL ) - { - m_text[j] = buffer[i]; - if ( m_format != 0 ) m_format[j] = font; - j ++; - } - i ++; - continue; // removes the tabs - } - bBOL = ( buffer[i] == '\n' || buffer[i] == '\r' ); - } - - if ( buffer[i] == '\r' ) // removes \ r - { - i ++; - } - else if ( m_format != 0 && buffer[i] == '\\' && buffer[i+2] == ';' ) - { - if ( buffer[i+1] == 'n' ) // normal ? - { - if ( m_bSoluce || !bInSoluce ) - { - font &= ~FONT_MASK; - font |= FONT_COLOBOT; - } - i += 3; - } - else if ( buffer[i+1] == 'c' ) // cbot ? - { - if ( m_bSoluce || !bInSoluce ) - { - font &= ~FONT_MASK; - font |= FONT_COURIER; - } - i += 3; - } - else if ( buffer[i+1] == 'b' ) // big title ? - { - if ( m_bSoluce || !bInSoluce ) - { - font &= ~TITLE_MASK; - font |= TITLE_BIG; - } - i += 3; - } - else if ( buffer[i+1] == 't' ) // title ? - { - if ( m_bSoluce || !bInSoluce ) - { - font &= ~TITLE_MASK; - font |= TITLE_NORM; - } - i += 3; - } - else if ( buffer[i+1] == 's' ) // subtitle ? - { - if ( m_bSoluce || !bInSoluce ) - { - font &= ~TITLE_MASK; - font |= TITLE_LITTLE; - } - i += 3; - } - else if ( buffer[i+1] == 'l' ) // link ? - { - if ( m_bSoluce || !bInSoluce ) - { - font &= ~COLOR_MASK; - font |= COLOR_LINK; - } - i += 3; - } - else - { - i += 3; - } - } - else if ( m_format != 0 && - buffer[i+0] == '\\' && // \u marker name; ? - buffer[i+1] == 'u' && - buffer[i+2] == ' ' ) - { - if ( m_bSoluce || !bInSoluce ) - { - if ( iLink < EDITLINKMAX ) - { - GetNameParam(buffer+i+3, 0, m_link[iLink].name); - GetNameParam(buffer+i+3, 1, m_link[iLink].marker); - iLink ++; - } - font &= ~COLOR_MASK; - } - i += strchr(buffer+i, ';')-(buffer+i)+1; - } - else if ( m_format != 0 && - buffer[i+0] == '\\' && // \m marker; ? - buffer[i+1] == 'm' && - buffer[i+2] == ' ' ) - { - if ( m_bSoluce || !bInSoluce ) - { - if ( m_markerTotal < EDITLINKMAX ) - { - GetNameParam(buffer+i+3, 0, m_marker[m_markerTotal].name); - m_marker[m_markerTotal].pos = j; - m_markerTotal ++; - } - } - i += strchr(buffer+i, ';')-(buffer+i)+1; - } - else if ( m_format != 0 && - buffer[i+0] == '\\' && // \image name lx ly; ? - buffer[i+1] == 'i' && - buffer[i+2] == 'm' && - buffer[i+3] == 'a' && - buffer[i+4] == 'g' && - buffer[i+5] == 'e' && - buffer[i+6] == ' ' ) - { - if ( m_bSoluce || !bInSoluce ) - { -#if _DEMO - strcpy(iName, "demo"); -#else - GetNameParam(buffer+i+7, 0, iName); -#endif -//? iWidth = m_lineHeight*RetValueParam(buffer+i+7, 1); - iWidth = (float)RetValueParam(buffer+i+7, 1); - iWidth *= m_engine->RetText()->RetHeight(SMALLFONT, FONT_COLOBOT); - iLines = RetValueParam(buffer+i+7, 2); - LoadImage(iName); - - // A part of image per line of text. - for ( iCount=0 ; iCountRetKey(key, 0); - if ( res != 0 ) - { - if ( GetResource(RES_KEY, res, iName) ) - { - m_text[j] = ' '; - m_format[j] = font; - j ++; - n = 0; - while ( iName[n] != 0 ) - { - m_text[j] = iName[n++]; - m_format[j] = font; - j ++; - } - m_text[j] = ' '; - m_format[j] = font; - j ++; - - res = m_engine->RetKey(key, 1); - if ( res != 0 ) - { - if ( GetResource(RES_KEY, res, iName) ) - { - GetResource(RES_TEXT, RT_KEY_OR, text); - n = 0; - while ( text[n] != 0 ) - { - m_text[j] = text[n++]; - m_format[j] = font&~COLOR_MASK; - j ++; - } - n = 0; - while ( iName[n] != 0 ) - { - m_text[j] = iName[n++]; - m_format[j] = font; - j ++; - } - m_text[j] = ' '; - m_format[j] = font; - j ++; - } - } - while ( buffer[i++] != ';' ); - continue; - } - } - } - m_text[j] = '?'; - m_format[j] = font; - j ++; - } - while ( buffer[i++] != ';' ); - } - else - { - if ( m_bSoluce || !bInSoluce ) - { - m_text[j] = buffer[i]; - if ( m_format != 0 ) m_format[j] = font; - j ++; - } - i ++; - - font &= ~TITLE_MASK; // reset title - - if ( (font&COLOR_MASK) == COLOR_TABLE ) - { - font &= ~COLOR_TABLE; - } - } - } - m_len = j; - m_imageTotal = iIndex; - - delete buffer; - - Justif(); - ColumnFix(); - return TRUE; -} - -// Writes all the text in a file. - -BOOL CEdit::WriteText(char *filename) -{ - FILE* file; - char buffer[1000+20]; - int i, j, k, n; - float iDim; - - if ( filename[0] == 0 ) return FALSE; - file = fopen(filename, "wb"); - if ( file == NULL ) return FALSE; - - if ( m_bAutoIndent ) - { - iDim = m_dim.x; - m_dim.x = 1000.0f; // puts an infinite width! - Justif(); - } - - i = j = k = 0; - while ( m_text[i] != 0 && i < m_len ) - { - if ( m_bAutoIndent && i == m_lineOffset[k] ) - { - for ( n=0 ; n= 1000-1 ) - { - fwrite(buffer, 1, j, file); - j = 0; - } - - i ++; - } - if ( j > 0 ) - { - fwrite(buffer, 1, j, file); - } - - fclose(file); - - if ( m_bAutoIndent ) - { - m_dim.x = iDim; // presents the initial width - Justif(); - } - - return TRUE; -} - - -// Manage the number of max characters editable. - -void CEdit::SetMaxChar(int max) -{ - m_maxChar = max; - FreeImage(); - delete m_text; - m_text = (char*)malloc(sizeof(char)*(m_maxChar+1)); - - if ( m_format != 0 ) - { - delete m_format; - m_format = (char*)malloc(sizeof(char)*m_maxChar); - } - - m_len = 0; - m_cursor1 = 0; - m_cursor2 = 0; - Justif(); - UndoFlush(); -} - -int CEdit::RetMaxChar() -{ - return m_maxChar; -} - - -// Mode management "editable". - -void CEdit::SetEditCap(BOOL bMode) -{ - m_bEdit = bMode; -} - -BOOL CEdit::RetEditCap() -{ - return m_bEdit; -} - -// Mode management "hilitable" (that's the franch). - -void CEdit::SetHiliteCap(BOOL bEnable) -{ - m_bHilite = bEnable; -} - -BOOL CEdit::RetHiliteCap() -{ - return m_bHilite; -} - -// Lift in / out connection. - -void CEdit::SetInsideScroll(BOOL bInside) -{ - m_bInsideScroll = bInside; -} - -BOOL CEdit::RetInsideScroll() -{ - return m_bInsideScroll; -} - -// Specifies whether to display the links showing the solution. - -void CEdit::SetSoluceMode(BOOL bSoluce) -{ - m_bSoluce = bSoluce; -} - -BOOL CEdit::RetSoluceMode() -{ - return m_bSoluce; -} - -// Indicates whether the text is a defile that generic. - -void CEdit::SetGenericMode(BOOL bGeneric) -{ - m_bGeneric = bGeneric; -} - -BOOL CEdit::RetGenericMode() -{ - return m_bGeneric; -} - - -// Management of automatic indentation mode with {}. - -void CEdit::SetAutoIndent(BOOL bMode) -{ - m_bAutoIndent = bMode; -} - -BOOL CEdit::RetAutoIndent() -{ - return m_bAutoIndent; -} - - - -// Moves the cursors. - -void CEdit::SetCursor(int cursor1, int cursor2) -{ - if ( cursor1 > m_len ) cursor1 = m_len; - if ( cursor2 > m_len ) cursor2 = m_len; - - m_cursor1 = cursor1; - m_cursor2 = cursor2; - m_bUndoForce = TRUE; - ColumnFix(); -} - -// Returns the sliders. - -void CEdit::GetCursor(int &cursor1, int &cursor2) -{ - cursor1 = m_cursor1; - cursor2 = m_cursor2; -} - - -// Displayed line modifies the first. - -void CEdit::SetFirstLine(int rank) -{ - Scroll(rank, TRUE); -} - -// Returns the first displayed line. - -int CEdit::RetFirstLine() -{ - if ( m_historyTotal > 0 ) - { - if ( m_historyCurrent == 0 ) - { - return m_lineFirst; - } - else - { - return m_history[0].firstLine; - } - } - return m_lineFirst; -} - - -// Shows the selected area. - -void CEdit::ShowSelect() -{ - int cursor1, cursor2, line; - - if ( m_cursor1 < m_cursor2 ) - { - cursor1 = m_cursor1; - cursor2 = m_cursor2; - } - else - { - cursor1 = m_cursor2; - cursor2 = m_cursor1; - } - - line = RetCursorLine(cursor2); - if ( line >= m_lineFirst+m_lineVisible ) - { - line -= m_lineVisible-1; - if ( line < 0 ) line = 0; - Scroll(line, FALSE); - } - - line = RetCursorLine(cursor1); - if ( line < m_lineFirst ) - { - Scroll(line, FALSE); - } -} - - -// Management of the display mode of special characters. - -void CEdit::SetDisplaySpec(BOOL bDisplay) -{ - m_bDisplaySpec = bDisplay; -} - -BOOL CEdit::RetDisplaySpec() -{ - return m_bDisplaySpec; -} - - -// Multi-fonts mode management. - -void CEdit::SetMultiFont(BOOL bMulti) -{ - if ( bMulti ) - { - delete m_format; - m_format = (char*)malloc(sizeof(char)*m_maxChar); - memset(m_format, 0, m_maxChar); - } - else - { - delete m_format; - m_format = 0; - } -} - -BOOL CEdit::RetMultiFont() -{ - return ( m_format != 0 ); -} - - -// Management of the character size. - -void CEdit::SetFontSize(float size) -{ - CControl::SetFontSize(size); - - MoveAdjust(); -} - - -// Moves according to the visible lift. - -void CEdit::Scroll() -{ - float value; - - if ( m_scroll != 0 ) - { - value = m_scroll->RetVisibleValue(); - value *= m_lineTotal-m_lineVisible; - Scroll((int)(value+0.5f), TRUE); - } -} - -// Moves according to the visible lift. - -void CEdit::Scroll(int pos, BOOL bAdjustCursor) -{ - int max, line; - - m_lineFirst = pos; - - if ( m_lineFirst < 0 ) m_lineFirst = 0; - - max = m_lineTotal-m_lineVisible; - if ( max < 0 ) max = 0; - if ( m_lineFirst > max ) m_lineFirst = max; - - line = RetCursorLine(m_cursor1); - - if ( bAdjustCursor && m_bEdit ) - { - // Cursor too high? - if ( line < m_lineFirst ) - { - MoveLine(m_lineFirst-line, FALSE, FALSE); - return; - } - - // Cursor too low? - if ( line >= m_lineFirst+m_lineVisible ) - { - MoveLine(m_lineFirst+m_lineVisible-line-1, FALSE, FALSE); - return; - } - } - - Justif(); -} - -// Moves the cursor to the beginning of the line. - -void CEdit::MoveHome(BOOL bWord, BOOL bSelect) -{ - int begin, tab; - - if ( bWord ) - { - m_cursor1 = 0; - } - else - { - begin = m_cursor1; - while ( begin > 0 && m_text[begin-1] != '\n' ) - { - begin --; - } - - tab = begin; - while ( tab < m_len && (m_text[tab] == '\t' || m_text[tab] == ' ') ) - { - tab ++; - } - - if ( m_cursor1 == tab ) - { - m_cursor1 = begin; - } - else - { - m_cursor1 = tab; - } - } - if ( !bSelect ) m_cursor2 = m_cursor1; - - m_bUndoForce = TRUE; - Justif(); - ColumnFix(); -} - -// Moves the cursor to the end of the line. - -void CEdit::MoveEnd(BOOL bWord, BOOL bSelect) -{ - if ( bWord ) - { - m_cursor1 = m_len; - } - else - { - while ( m_cursor1 < m_len && m_text[m_cursor1] != '\n' ) - { - m_cursor1 ++; - } - } - if ( !bSelect ) m_cursor2 = m_cursor1; - - m_bUndoForce = TRUE; - Justif(); - ColumnFix(); -} - -// Moves the cursor through characters. - -void CEdit::MoveChar(int move, BOOL bWord, BOOL bSelect) -{ - int character; - - if ( move == -1 ) // back? - { - if ( bWord ) - { - while ( m_cursor1 > 0 ) - { - character = (unsigned char)m_text[m_cursor1-1]; - if ( !IsSpace(character) ) break; - m_cursor1 --; - } - - if ( m_cursor1 > 0 ) - { - character = (unsigned char)m_text[m_cursor1-1]; - if ( IsSpace(character) ) - { - while ( m_cursor1 > 0 ) - { - character = (unsigned char)m_text[m_cursor1-1]; - if ( !IsSpace(character) ) break; - m_cursor1 --; - } - } - else if ( IsWord(character) ) - { - while ( m_cursor1 > 0 ) - { - character = (unsigned char)m_text[m_cursor1-1]; - if ( !IsWord(character) ) break; - m_cursor1 --; - } - } - else if ( IsSep(character) ) - { - while ( m_cursor1 > 0 ) - { - character = (unsigned char)m_text[m_cursor1-1]; - if ( !IsSep(character) ) break; - m_cursor1 --; - } - } - } - } - else - { - m_cursor1 --; - if ( m_cursor1 < 0 ) m_cursor1 = 0; - } - } - - if ( move == 1 ) // advance? - { - if ( bWord ) - { - if ( m_cursor1 < m_len ) - { - character = (unsigned char)m_text[m_cursor1]; - if ( IsSpace(character) ) - { - while ( m_cursor1 < m_len ) - { - character = (unsigned char)m_text[m_cursor1]; - if ( !IsSpace(character) ) break; - m_cursor1 ++; - } - } - else if ( IsWord(character) ) - { - while ( m_cursor1 < m_len ) - { - character = (unsigned char)m_text[m_cursor1]; - if ( !IsWord(character) ) break; - m_cursor1 ++; - } - } - else if ( IsSep(character) ) - { - while ( m_cursor1 < m_len ) - { - character = (unsigned char)m_text[m_cursor1]; - if ( !IsSep(character) ) break; - m_cursor1 ++; - } - } - } - - while ( m_cursor1 < m_len ) - { - character = (unsigned char)m_text[m_cursor1]; - if ( !IsSpace(character) ) break; - m_cursor1 ++; - } - } - else - { - m_cursor1 ++; - if ( m_cursor1 > m_len ) m_cursor1 = m_len; - } - } - - if ( !bSelect ) m_cursor2 = m_cursor1; - - m_bUndoForce = TRUE; - Justif(); - ColumnFix(); -} - -// Moves the cursor lines. - -void CEdit::MoveLine(int move, BOOL bWord, BOOL bSelect) -{ - float column, indentLength; - int i, line, c; - - if ( move == 0 ) return; - - for ( i=0 ; i>move ; i-- ) // back? - { - while ( m_cursor1 > 0 && m_text[m_cursor1-1] != '\n' ) - { - m_cursor1 --; - } - if ( m_cursor1 != 0 ) - { - m_cursor1 --; - while ( m_cursor1 > 0 ) - { - if ( m_text[--m_cursor1] == '\n' ) - { - m_cursor1 ++; - break; - } - } - } - } - - for ( i=0 ; iRetText()->RetCharWidth(' ', 0.0f, m_fontSize, m_fontStretch, m_fontType) - * m_engine->RetEditIndentValue(); - column -= indentLength*m_lineIndent[line]; - } - - if ( m_format == 0 ) - { - c = m_engine->RetText()->Detect(m_text+m_lineOffset[line], - m_lineOffset[line+1]-m_lineOffset[line], - column, m_fontSize, - m_fontStretch, m_fontType); - } - else - { - c = m_engine->RetText()->Detect(m_text+m_lineOffset[line], - m_format+m_lineOffset[line], - m_lineOffset[line+1]-m_lineOffset[line], - column, m_fontSize, m_fontStretch); - } - - m_cursor1 = m_lineOffset[line]+c; - if ( !bSelect ) m_cursor2 = m_cursor1; - - m_bUndoForce = TRUE; - Justif(); -} - -// Sets the horizontal position. - -void CEdit::ColumnFix() -{ - float indentLength; - int line; - - line = RetCursorLine(m_cursor1); - - if ( m_format == 0 ) - { - m_column = m_engine->RetText()->RetStringWidth - ( - m_text+m_lineOffset[line], - m_cursor1-m_lineOffset[line], - m_fontSize, m_fontStretch, m_fontType - ); - } - else - { - m_column = m_engine->RetText()->RetStringWidth - ( - m_text+m_lineOffset[line], - m_format+m_lineOffset[line], - m_cursor1-m_lineOffset[line], - m_fontSize, m_fontStretch - ); - } - - if ( m_bAutoIndent ) - { - indentLength = m_engine->RetText()->RetCharWidth(' ', 0.0f, m_fontSize, m_fontStretch, m_fontType) - * m_engine->RetEditIndentValue(); - m_column += indentLength*m_lineIndent[line]; - } -} - - -// Cut the selected characters or entire line. - -BOOL CEdit::Cut() -{ - HGLOBAL hg; - char* text; - char c; - int c1, c2, start, len, i, j; - - if ( !m_bEdit ) return FALSE; - - c1 = m_cursor1; - c2 = m_cursor2; - if ( c1 > c2 ) Swap(c1, c2); // always c1 <= c2 - - if ( c1 == c2 ) - { - while ( c1 > 0 ) - { - if ( m_text[c1-1] == '\n' ) break; - c1 --; - } - while ( c2 < m_len ) - { - c2 ++; - if ( m_text[c2-1] == '\n' ) break; - } - } - - if ( c1 == c2 ) return FALSE; - - start = c1; - len = c2-c1; - - if ( !(hg = GlobalAlloc(GMEM_DDESHARE, len*2+1)) ) - { - return FALSE; - } - if ( !(text = (char*)GlobalLock(hg)) ) - { - GlobalFree(hg); - return FALSE; - } - - j = 0; - for ( i=start ; i c2 ) Swap(c1, c2); // always c1 <= c2 - - if ( c1 == c2 ) - { - while ( c1 > 0 ) - { - if ( m_text[c1-1] == '\n' ) break; - c1 --; - } - while ( c2 < m_len ) - { - c2 ++; - if ( m_text[c2-1] == '\n' ) break; - } - } - - if ( c1 == c2 ) return FALSE; - - start = c1; - len = c2-c1; - - if ( !(hg = GlobalAlloc(GMEM_DDESHARE, len*2+1)) ) - { - return FALSE; - } - if ( !(text = (char*)GlobalLock(hg)) ) - { - GlobalFree(hg); - return FALSE; - } - - j = 0; - for ( i=start ; iRetEditIndentValue() ; i++ ) - { - InsertOne(' '); - } - } - else - { - InsertOne(character); - } - } - else - { - InsertOne(character); - } - - Justif(); - ColumnFix(); -} - -// Inserts a plain character. - -void CEdit::InsertOne(char character) -{ - int i; - - if ( !m_bEdit ) return; - if ( !m_bMulti && character == '\n' ) return; - - if ( m_cursor1 != m_cursor2 ) - { - DeleteOne(0); // deletes the selected characters - } - - if ( m_len >= m_maxChar ) return; - - for ( i=m_len ; i>=m_cursor1 ; i-- ) - { - m_text[i] = m_text[i-1]; // shoot - - if ( m_format != 0 ) - { - m_format[i] = m_format[i-1]; // shoot - } - } - - m_len ++; - - m_text[m_cursor1] = character; - - if ( m_format != 0 ) - { - m_format[m_cursor1] = 0; - } - - m_cursor1++; - m_cursor2 = m_cursor1; -} - -// Deletes the character left of cursor or all selected characters. - -void CEdit::Delete(int dir) -{ - if ( !m_bEdit ) return; - - UndoMemorize(OPERUNDO_DELETE); - DeleteOne(dir); - - Justif(); - ColumnFix(); -} - -// Deletes the character left of cursor or all selected plain characters. - -void CEdit::DeleteOne(int dir) -{ - int i, end, hole; - - if ( !m_bEdit ) return; - - if ( m_cursor1 == m_cursor2 ) - { - if ( dir < 0 ) - { - if ( m_cursor1 == 0 ) return; - m_cursor1 --; - } - else - { - if ( m_cursor2 == m_len ) return; - m_cursor2 ++; - } - } - - if ( m_cursor1 > m_cursor2 ) Swap(m_cursor1, m_cursor2); - hole = m_cursor2-m_cursor1; - end = m_len-hole; - for ( i=m_cursor1 ; i 0 ) - { - if ( m_text[i-1] == '\n' ) return nb; - if ( m_text[i-1] != '\t' ) return -1; - nb ++; - i --; - } - return nb; -} - -// Adds or removes qq tabs. - -void CEdit::IndentTabAdjust(int number) -{ - int i; - - for ( i=0 ; inumber ; i-- ) // delete? - { - DeleteOne(-1); - } -} - - -// Indent the left or right the entire selection. - -BOOL CEdit::Shift(BOOL bLeft) -{ - BOOL bInvert = FALSE; - int c1, c2, i; - - if ( m_cursor1 == m_cursor2 ) return FALSE; - - UndoMemorize(OPERUNDO_SPEC); - - c1 = m_cursor1; - c2 = m_cursor2; - if ( c1 > c2 ) - { - Swap(c1, c2); // always c1 <= c2 - bInvert = TRUE; - } - - if ( c1 > 0 ) - { - if ( m_text[c1-1] != '\n' ) return FALSE; - } - if ( c2 < m_len ) - { - if ( m_text[c2-1] != '\n' ) return FALSE; - } - - if ( bLeft ) // shifts left? - { - i = c1; - while ( i < c2 ) - { - if ( m_text[i] == '\t' ) - { - m_cursor1 = i; - m_cursor2 = i+1; - DeleteOne(0); - c2 --; - } - while ( i < c2 && m_text[i++] != '\n' ); - } - } - else // shifts right? - { - i = c1; - while ( i < c2 ) - { - m_cursor1 = m_cursor2 = i; - InsertOne('\t'); - c2 ++; - while ( i < c2 && m_text[i++] != '\n' ); - } - } - - if ( bInvert ) Swap(c1, c2); - m_cursor1 = c1; - m_cursor2 = c2; - - Justif(); - ColumnFix(); - SendModifEvent(); - return TRUE; -} - -// Min conversion <-> shift the selection. - -BOOL CEdit::MinMaj(BOOL bMaj) -{ - int c1, c2, i, character; - - if ( m_cursor1 == m_cursor2 ) return FALSE; - - UndoMemorize(OPERUNDO_SPEC); - - c1 = m_cursor1; - c2 = m_cursor2; - if ( c1 > c2 ) Swap(c1, c2); // alwyas c1 <= c2 - - for ( i=c1 ; iRetText()->RetCharWidth(' ', 0.0f, m_fontSize, m_fontStretch, m_fontType) - * m_engine->RetEditIndentValue(); - } - - bString = bRem = FALSE; - i = 0; - while ( TRUE ) - { - bDual = FALSE; - - width = m_dim.x-(10.0f/640.0f)*2.0f-(m_bMulti?MARGX*2.0f+SCROLL_WIDTH:0.0f); - if ( m_bAutoIndent ) - { - width -= indentLength*m_lineIndent[m_lineTotal-1]; - } - - if ( m_format == 0 ) - { - i += m_engine->RetText()->Justif(m_text+i, m_len-i, width, - m_fontSize, m_fontStretch, - m_fontType); - } - else - { - size = m_fontSize; - - if ( (m_format[i]&TITLE_MASK) == TITLE_BIG ) // headline? - { - size *= BIG_FONT; - bDual = TRUE; - } - - if ( (m_format[i]&IMAGE_MASK) != 0 ) // image part? - { - i ++; // jumps just a character (index in m_image) - } - else - { - i += m_engine->RetText()->Justif(m_text+i, m_format+i, - m_len-i, width, - size, m_fontStretch); - } - } - - if ( i >= m_len ) break; - - if ( m_bAutoIndent ) - { - for ( j=m_lineOffset[m_lineTotal-1] ; j= EDITLINEMAX-2 ) break; - } - if ( m_len > 0 && m_text[m_len-1] == '\n' ) - { - m_lineOffset[m_lineTotal] = m_len; - m_lineIndent[m_lineTotal] = 0; - m_lineTotal ++; - } - m_lineOffset[m_lineTotal] = m_len; - m_lineIndent[m_lineTotal] = 0; - - if ( m_bAutoIndent ) - { - for ( i=0 ; i<=m_lineTotal ; i++ ) - { - if ( m_text[m_lineOffset[i]] == '}' ) - { - if ( m_lineIndent[i] > 0 ) m_lineIndent[i] --; - } - } - } - - if ( m_bMulti ) - { - if ( m_bEdit ) - { - line = RetCursorLine(m_cursor1); - if ( line < m_lineFirst ) - { - m_lineFirst = line; - } - if ( line >= m_lineFirst+m_lineVisible ) - { - m_lineFirst = line-m_lineVisible+1; - } - } - } - else - { - m_lineFirst = 0; - } - - if ( m_scroll != 0 ) - { - if ( m_lineTotal <= m_lineVisible ) - { - m_scroll->SetVisibleRatio(1.0f); - m_scroll->SetVisibleValue(0.0f); - m_scroll->SetArrowStep(0.0f); - } - else - { - value = (float)m_lineVisible/m_lineTotal; - m_scroll->SetVisibleRatio(value); - - value = (float)m_lineFirst/(m_lineTotal-m_lineVisible); - m_scroll->SetVisibleValue(value); - - value = (float)1.0f/(m_lineTotal-m_lineVisible); - m_scroll->SetArrowStep(value); - } - } - - m_timeBlink = 0.0f; // lights the cursor immediately -} - -// Returns the rank of the line where the cursor is located. - -int CEdit::RetCursorLine(int cursor) -{ - int line, i; - - line = 0; - for ( i=0 ; i= m_lineOffset[i] ) - { - line = i; - } - } - return line; -} - - -// Flush the buffer undo. - -void CEdit::UndoFlush() -{ - int i; - - for ( i=0 ; i=1 ; i-- ) - { - m_undo[i] = m_undo[i-1]; - } - - len = m_len; - if ( len == 0 ) len ++; - m_undo[0].text = (char*)malloc(sizeof(char)*(len+1)); - memcpy(m_undo[0].text, m_text, m_len); - m_undo[0].len = m_len; - - m_undo[0].cursor1 = m_cursor1; - m_undo[0].cursor2 = m_cursor2; - m_undo[0].lineFirst = m_lineFirst; -} - -// Back to previous state. - -BOOL CEdit::UndoRecall() -{ - int i; - - if ( m_undo[0].text == 0 ) return FALSE; - - m_len = m_undo[0].len; - memcpy(m_text, m_undo[0].text, m_len); - - m_cursor1 = m_undo[0].cursor1; - m_cursor2 = m_undo[0].cursor2; - m_lineFirst = m_undo[0].lineFirst; - - for ( i=0 ; i multi-line - BOOL m_bEdit; // TRUE -> editable - BOOL m_bHilite; // TRUE -> hilitable - BOOL m_bInsideScroll; // TRUE -> lift as part - BOOL m_bDisplaySpec; // TRUE -> displays the special characters - BOOL m_bMultiFont; // TRUE -> more fonts possible - BOOL m_bSoluce; // TRUE -> shows the links-solution - BOOL m_bGeneric; // TRUE -> generic that defile - BOOL m_bAutoIndent; // TRUE -> automatic indentation - float m_lineHeight; // height of a row - float m_lineAscent; // height above the baseline - float m_lineDescent; // height below the baseline - int m_lineVisible; // total number of viewable lines - int m_lineFirst; // the first line displayed - int m_lineTotal; // number lines used (in m_lineOffset) - int m_lineOffset[EDITLINEMAX]; - char m_lineIndent[EDITLINEMAX]; - int m_imageTotal; - ImageLine m_image[EDITIMAGEMAX]; - HyperLink m_link[EDITLINKMAX]; - int m_markerTotal; - HyperMarker m_marker[EDITLINKMAX]; - int m_historyTotal; - int m_historyCurrent; - HyperHistory m_history[EDITHISTORYMAX]; - float m_time; // absolute time - float m_timeBlink; - float m_timeLastClick; - float m_timeLastScroll; - FPOINT m_mouseFirstPos; - FPOINT m_mouseLastPos; - float m_column; - - BOOL m_bCapture; - - BOOL m_bUndoForce; - OperUndo m_undoOper; - EditUndo m_undo[EDITUNDOMAX]; -}; - - -#endif //_EDIT_H_ diff --git a/src/editvalue.cpp b/src/editvalue.cpp deleted file mode 100644 index ce8515c..0000000 --- a/src/editvalue.cpp +++ /dev/null @@ -1,380 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// editvalue.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "edit.h" -#include "button.h" -#include "editvalue.h" - - - - -// Object's constructor. - -CEditValue::CEditValue(CInstanceManager* iMan) : CControl(iMan) -{ - m_edit = 0; - m_buttonUp = 0; - m_buttonDown = 0; - - m_type = EVT_100; // % - m_stepValue = 0.1f; // 10% - m_minValue = 0.0f; // 0% - m_maxValue = 1.0f; // 100% -} - -// Object's destructor. - -CEditValue::~CEditValue() -{ - delete m_edit; - delete m_buttonUp; - delete m_buttonDown; -} - - -// Creates a new button. - -BOOL CEditValue::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CEdit* pe; - CButton* pc; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - CControl::Create(pos, dim, icon, eventMsg); - - GlintDelete(); - - m_edit = new CEdit(m_iMan); - pe = (CEdit*)m_edit; - pe->Create(pos, dim, 0, EVENT_NULL); - pe->SetMaxChar(4); - - m_buttonUp = new CButton(m_iMan); - pc = (CButton*)m_buttonUp; - pc->Create(pos, dim, 49, EVENT_NULL); // ^ - pc->SetRepeat(TRUE); - - m_buttonDown = new CButton(m_iMan); - pc = (CButton*)m_buttonDown; - pc->Create(pos, dim, 50, EVENT_NULL); // v - pc->SetRepeat(TRUE); - - MoveAdjust(); - return TRUE; -} - - -void CEditValue::SetPos(FPOINT pos) -{ - CControl::SetPos(pos); - MoveAdjust(); -} - -void CEditValue::SetDim(FPOINT dim) -{ - CControl::SetDim(dim); - MoveAdjust(); -} - -void CEditValue::MoveAdjust() -{ - FPOINT pos, dim; - - if ( m_edit != 0 ) - { - pos.x = m_pos.x; - pos.y = m_pos.y; - dim.x = m_dim.x-m_dim.y*0.6f; - dim.y = m_dim.y; - m_edit->SetPos(pos); - m_edit->SetDim(dim); - } - - if ( m_buttonUp != 0 ) - { - pos.x = m_pos.x+m_dim.x-m_dim.y*0.6f; - pos.y = m_pos.y+m_dim.y*0.5f; - dim.x = m_dim.y*0.6f; - dim.y = m_dim.y*0.5f; - m_buttonUp->SetPos(pos); - m_buttonUp->SetDim(dim); - } - - if ( m_buttonDown != 0 ) - { - pos.x = m_pos.x+m_dim.x-m_dim.y*0.6f; - pos.y = m_pos.y; - dim.x = m_dim.y*0.6f; - dim.y = m_dim.y*0.5f; - m_buttonDown->SetPos(pos); - m_buttonDown->SetDim(dim); - } -} - - -// Management of an event. - -BOOL CEditValue::EventProcess(const Event &event) -{ - float value; - - CControl::EventProcess(event); - - if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; - if ( (m_state & STATE_ENABLE) == 0 ) return TRUE; - - if ( m_edit != 0 ) - { - if ( m_edit->RetFocus() && - event.event == EVENT_KEYDOWN && - event.param == VK_RETURN ) - { - value = RetValue(); - if ( value > m_maxValue ) value = m_maxValue; - if ( value < m_minValue ) value = m_minValue; - SetValue(value, TRUE); - HiliteValue(event); - } - if ( !m_edit->EventProcess(event) ) return FALSE; - - if ( event.event == m_edit->RetEventMsg() ) - { - Event newEvent; - m_event->MakeEvent(newEvent, m_eventMsg); - m_event->AddEvent(newEvent); - } - } - - if ( m_buttonUp != 0 ) - { - if ( event.event == m_buttonUp->RetEventMsg() ) - { - value = RetValue()+m_stepValue; - if ( value > m_maxValue ) value = m_maxValue; - SetValue(value, TRUE); - HiliteValue(event); - } - if ( !m_buttonUp->EventProcess(event) ) return FALSE; - } - - if ( m_buttonDown != 0 ) - { - if ( event.event == m_buttonDown->RetEventMsg() ) - { - value = RetValue()-m_stepValue; - if ( value < m_minValue ) value = m_minValue; - SetValue(value, TRUE); - HiliteValue(event); - } - if ( !m_buttonDown->EventProcess(event) ) return FALSE; - } - - if ( event.event == EVENT_KEYDOWN && - event.param == VK_WHEELUP && - Detect(event.pos) ) - { - value = RetValue()+m_stepValue; - if ( value > m_maxValue ) value = m_maxValue; - SetValue(value, TRUE); - HiliteValue(event); - } - if ( event.event == EVENT_KEYDOWN && - event.param == VK_WHEELDOWN && - Detect(event.pos) ) - { - value = RetValue()-m_stepValue; - if ( value < m_minValue ) value = m_minValue; - SetValue(value, TRUE); - HiliteValue(event); - } - - return TRUE; -} - - -// Puts in evidence the edited value. - -void CEditValue::HiliteValue(const Event &event) -{ - int pos; - - if ( m_edit == 0 ) return; - - pos = m_edit->RetTextLength(); - if ( m_type == EVT_100 && pos > 0 ) - { - pos --; // not only selects the "%" - } - - m_edit->SetCursor(pos, 0); - m_edit->SetFocus(TRUE); - - Event newEvent = event; - newEvent.event = EVENT_FOCUS; - newEvent.param = m_edit->RetEventMsg(); - m_event->AddEvent(newEvent); // defocus the other objects -} - - -// Draw button. - -void CEditValue::Draw() -{ - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - if ( m_state & STATE_SHADOW ) - { - DrawShadow(m_pos, m_dim); - } - - if ( m_edit != 0 ) - { - m_edit->Draw(); - } - if ( m_buttonUp != 0 ) - { - m_buttonUp->Draw(); - } - if ( m_buttonDown != 0 ) - { - m_buttonDown->Draw(); - } -} - - -// Choosing the type of value. - -void CEditValue::SetType(EditValueType type) -{ - m_type = type; -} - -EditValueType CEditValue::RetType() -{ - return m_type; -} - - -// Changes the value. - -void CEditValue::SetValue(float value, BOOL bSendMessage) -{ - char text[100]; - - if ( m_edit == 0 ) return; - - text[0] = 0; - - if ( m_type == EVT_INT ) - { - sprintf(text, "%d", (int)value); - } - - if ( m_type == EVT_FLOAT ) - { - sprintf(text, "%.2f", value); - } - - if ( m_type == EVT_100 ) - { - sprintf(text, "%d%%", (int)(value*100.0f)); - } - - m_edit->SetText(text); - - if ( bSendMessage ) - { - Event newEvent; - m_event->MakeEvent(newEvent, m_eventMsg); - m_event->AddEvent(newEvent); - } -} - -// Return the edited value. - -float CEditValue::RetValue() -{ - char text[100]; - float value; - - if ( m_edit == 0 ) 0.0f; - - m_edit->GetText(text, 100); - sscanf(text, "%f", &value); - - if ( m_type == EVT_100 ) - { - value = (value+0.5f)/100.0f; - if ( value < 0.01f ) value = 0.0f; // less than 1%? - } - - return value; -} - - -// Management not for buttons. - -void CEditValue::SetStepValue(float value) -{ - m_stepValue = value; -} - -float CEditValue::RetStepValue() -{ - return m_stepValue; -} - - -// Management of the minimum value. - -void CEditValue::SetMinValue(float value) -{ - m_minValue = value; -} - -float CEditValue::RetMinValue() -{ - return m_minValue; -} - - -// Management of the maximum value. - -void CEditValue::SetMaxValue(float value) -{ - m_maxValue = value; -} - -float CEditValue::RetMaxValue() -{ - return m_maxValue; -} - diff --git a/src/editvalue.h b/src/editvalue.h deleted file mode 100644 index 3203b8b..0000000 --- a/src/editvalue.h +++ /dev/null @@ -1,85 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// editvalue.h - -#ifndef _EDITVALUE_H_ -#define _EDITVALUE_H_ - - -#include "control.h" - - -enum EditValueType -{ - EVT_INT = 1, // integer - EVT_FLOAT = 2, // float value - EVT_100 = 3, // percent (0 .. 1) -}; - - -class CD3DEngine; -class CEdit; -class CButton; - - - -class CEditValue : public CControl -{ -public: - CEditValue(CInstanceManager* iMan); - virtual ~CEditValue(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - - void SetPos(FPOINT pos); - void SetDim(FPOINT dim); - - BOOL EventProcess(const Event &event); - void Draw(); - - void SetType(EditValueType type); - EditValueType RetType(); - - void SetValue(float value, BOOL bSendMessage=FALSE); - float RetValue(); - - void SetStepValue(float value); - float RetStepValue(); - - void SetMinValue(float value); - float RetMinValue(); - - void SetMaxValue(float value); - float RetMaxValue(); - -protected: - void MoveAdjust(); - void HiliteValue(const Event &event); - -protected: - CEdit* m_edit; - CButton* m_buttonUp; - CButton* m_buttonDown; - - EditValueType m_type; - float m_stepValue; - float m_minValue; - float m_maxValue; -}; - - -#endif //_EDITVALUE_H_ diff --git a/src/event.cpp b/src/event.cpp deleted file mode 100644 index 2eeddb4..0000000 --- a/src/event.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// event.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include - -#include "struct.h" -#include "iman.h" -#include "event.h" - - - - -// Object's constructor. - -CEvent::CEvent(CInstanceManager* iMan) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_EVENT, this); - - Flush(); -} - -// Object's destructor. - -CEvent::~CEvent() -{ -} - - -// Empty the FIFO of events. - -void CEvent::Flush() -{ - m_head = 0; - m_tail = 0; - m_total = 0; -} - -// Produces an event. - -void CEvent::MakeEvent(Event &event, EventMsg msg) -{ - ZeroMemory(&event, sizeof(Event)); - event.event = msg; -} - -// Adds an event in the FIFO. - -BOOL CEvent::AddEvent(const Event &event) -{ - if ( m_total >= MAXEVENT ) return FALSE; - - m_fifo[m_head++] = event; - if ( m_head >= MAXEVENT ) m_head = 0; - m_total ++; - - return TRUE; -} - -// Removes an event from the FIFO. - -BOOL CEvent::GetEvent(Event &event) -{ - if ( m_head == m_tail ) return FALSE; - - event = m_fifo[m_tail++]; - if ( m_tail >= MAXEVENT ) m_tail = 0; - m_total --; - - return TRUE; -} - diff --git a/src/event.h b/src/event.h deleted file mode 100644 index 8da2600..0000000 --- a/src/event.h +++ /dev/null @@ -1,636 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// event.h - -#ifndef _EVENT_H_ -#define _EVENT_H_ - - -#include "struct.h" - - -#if !defined (WM_XBUTTONDOWN) -#define WM_XBUTTONDOWN 0x020B -#define WM_XBUTTONUP 0x020C -#define XBUTTON1 0x0001 -#define XBUTTON2 0x0002 -#endif - - - -class CInstanceManager; - - -#define MAXEVENT 100 - -// Events. - -enum EventMsg -{ - EVENT_NULL = 0, - - EVENT_QUIT = 1, - EVENT_FRAME = 2, - EVENT_LBUTTONDOWN = 3, - EVENT_RBUTTONDOWN = 4, - EVENT_LBUTTONUP = 5, - EVENT_RBUTTONUP = 6, - EVENT_MOUSEMOVE = 7, - EVENT_KEYDOWN = 8, - EVENT_KEYUP = 9, - EVENT_CHAR = 10, - EVENT_FOCUS = 11, - - EVENT_UPDINTERFACE = 20, - EVENT_WIN = 30, - EVENT_LOST = 31, - - EVENT_BUTTON_OK = 40, - EVENT_BUTTON_CANCEL = 41, - EVENT_BUTTON_NEXT = 42, - EVENT_BUTTON_PREV = 43, - EVENT_BUTTON_QUIT = 44, - - EVENT_BUTTON0 = 50, - EVENT_BUTTON1 = 51, - EVENT_BUTTON2 = 52, - EVENT_BUTTON3 = 53, - EVENT_BUTTON4 = 54, - EVENT_BUTTON5 = 55, - EVENT_BUTTON6 = 56, - EVENT_BUTTON7 = 57, - EVENT_BUTTON8 = 58, - EVENT_BUTTON9 = 59, - EVENT_BUTTON10 = 60, - EVENT_BUTTON11 = 61, - EVENT_BUTTON12 = 62, - EVENT_BUTTON13 = 63, - EVENT_BUTTON14 = 64, - EVENT_BUTTON15 = 65, - EVENT_BUTTON16 = 66, - EVENT_BUTTON17 = 67, - EVENT_BUTTON18 = 68, - EVENT_BUTTON19 = 69, - - EVENT_EDIT0 = 70, - EVENT_EDIT1 = 71, - EVENT_EDIT2 = 72, - EVENT_EDIT3 = 73, - EVENT_EDIT4 = 74, - EVENT_EDIT5 = 75, - EVENT_EDIT6 = 76, - EVENT_EDIT7 = 77, - EVENT_EDIT8 = 78, - EVENT_EDIT9 = 79, - - EVENT_WINDOW0 = 80, // the bottom panel - EVENT_WINDOW1 = 81, // map - EVENT_WINDOW2 = 82, // CDisplayText - EVENT_WINDOW3 = 83, // CStudio - EVENT_WINDOW4 = 84, // DisplayInfo - EVENT_WINDOW5 = 85, // setup - EVENT_WINDOW6 = 86, - EVENT_WINDOW7 = 87, - EVENT_WINDOW8 = 88, - EVENT_WINDOW9 = 89, // dialogue - - EVENT_LABEL0 = 90, - EVENT_LABEL1 = 91, - EVENT_LABEL2 = 92, - EVENT_LABEL3 = 93, - EVENT_LABEL4 = 94, - EVENT_LABEL5 = 95, - EVENT_LABEL6 = 96, - EVENT_LABEL7 = 97, - EVENT_LABEL8 = 98, - EVENT_LABEL9 = 99, - EVENT_LABEL10 = 100, - EVENT_LABEL11 = 101, - EVENT_LABEL12 = 102, - EVENT_LABEL13 = 103, - EVENT_LABEL14 = 104, - EVENT_LABEL15 = 105, - EVENT_LABEL16 = 106, - EVENT_LABEL17 = 107, - EVENT_LABEL18 = 108, - EVENT_LABEL19 = 109, - - EVENT_LIST0 = 110, - EVENT_LIST1 = 111, - EVENT_LIST2 = 112, - EVENT_LIST3 = 113, - EVENT_LIST4 = 114, - EVENT_LIST5 = 115, - EVENT_LIST6 = 116, - EVENT_LIST7 = 117, - EVENT_LIST8 = 118, - EVENT_LIST9 = 119, - - EVENT_TOOLTIP = 200, - - EVENT_DIALOG_OK = 300, - EVENT_DIALOG_CANCEL = 301, - EVENT_DIALOG_LABEL = 302, - EVENT_DIALOG_LABEL1 = 303, - EVENT_DIALOG_LABEL2 = 304, - EVENT_DIALOG_LABEL3 = 305, - EVENT_DIALOG_LIST = 306, - EVENT_DIALOG_EDIT = 307, - EVENT_DIALOG_CHECK1 = 308, - EVENT_DIALOG_CHECK2 = 309, - - EVENT_INTERFACE_TRAINER = 400, - EVENT_INTERFACE_DEFI = 401, - EVENT_INTERFACE_MISSION = 402, - EVENT_INTERFACE_FREE = 403, - EVENT_INTERFACE_PROTO = 404, - EVENT_INTERFACE_NAME = 405, - EVENT_INTERFACE_SETUP = 406, - EVENT_INTERFACE_QUIT = 407, - EVENT_INTERFACE_BACK = 408, - EVENT_INTERFACE_AGAIN = 409, - EVENT_INTERFACE_WRITE = 410, - EVENT_INTERFACE_READ = 411, - EVENT_INTERFACE_ABORT = 412, - EVENT_INTERFACE_USER = 413, - EVENT_INTERFACE_TEEN = 414, - - EVENT_INTERFACE_CHAP = 420, - EVENT_INTERFACE_LIST = 421, - EVENT_INTERFACE_RESUME = 422, - EVENT_INTERFACE_PLAY = 423, - - EVENT_INTERFACE_SETUPd = 430, - EVENT_INTERFACE_SETUPg = 431, - EVENT_INTERFACE_SETUPp = 432, - EVENT_INTERFACE_SETUPc = 433, - EVENT_INTERFACE_SETUPs = 434, - - EVENT_INTERFACE_DEVICE = 440, - EVENT_INTERFACE_RESOL = 441, - EVENT_INTERFACE_FULL = 442, - EVENT_INTERFACE_APPLY = 443, - - EVENT_INTERFACE_TOTO = 450, - EVENT_INTERFACE_SHADOW = 451, - EVENT_INTERFACE_DIRTY = 452, - EVENT_INTERFACE_LENS = 453, - EVENT_INTERFACE_SKY = 454, - EVENT_INTERFACE_PLANET = 456, - EVENT_INTERFACE_LIGHT = 457, - EVENT_INTERFACE_PARTI = 458, - EVENT_INTERFACE_CLIP = 459, - EVENT_INTERFACE_DETAIL = 460, - EVENT_INTERFACE_TEXTURE = 461, - EVENT_INTERFACE_RAIN = 462, - EVENT_INTERFACE_GLINT = 463, - EVENT_INTERFACE_TOOLTIP = 464, - EVENT_INTERFACE_MOVIES = 465, - EVENT_INTERFACE_NICERST = 466, - EVENT_INTERFACE_SCROLL = 467, - EVENT_INTERFACE_INVERTX = 468, - EVENT_INTERFACE_INVERTY = 469, - EVENT_INTERFACE_EFFECT = 470, - EVENT_INTERFACE_MOUSE = 471, - EVENT_INTERFACE_GROUND = 472, - EVENT_INTERFACE_GADGET = 473, - EVENT_INTERFACE_FOG = 474, - EVENT_INTERFACE_HIMSELF = 475, - EVENT_INTERFACE_EDITMODE= 476, - EVENT_INTERFACE_EDITVALUE= 477, - EVENT_INTERFACE_SOLUCE4 = 478, - - EVENT_INTERFACE_KINFO1 = 500, - EVENT_INTERFACE_KINFO2 = 501, - EVENT_INTERFACE_KGROUP = 502, - EVENT_INTERFACE_KSCROLL = 503, - EVENT_INTERFACE_KDEF = 504, - EVENT_INTERFACE_KLEFT = 505, - EVENT_INTERFACE_KRIGHT = 506, - EVENT_INTERFACE_KUP = 507, - EVENT_INTERFACE_KDOWN = 508, - EVENT_INTERFACE_KGUP = 509, - EVENT_INTERFACE_KGDOWN = 510, - EVENT_INTERFACE_KCAMERA = 511, - EVENT_INTERFACE_KDESEL = 512, - EVENT_INTERFACE_KACTION = 513, - EVENT_INTERFACE_KNEAR = 514, - EVENT_INTERFACE_KAWAY = 515, - EVENT_INTERFACE_KNEXT = 516, - EVENT_INTERFACE_KHUMAN = 517, - EVENT_INTERFACE_KQUIT = 518, - EVENT_INTERFACE_KHELP = 519, - EVENT_INTERFACE_KPROG = 520, - EVENT_INTERFACE_KCBOT = 521, - EVENT_INTERFACE_KVISIT = 522, - EVENT_INTERFACE_KSPEED10= 523, - EVENT_INTERFACE_KSPEED15= 524, - EVENT_INTERFACE_KSPEED20= 525, - EVENT_INTERFACE_KSPEED30= 526, - - EVENT_INTERFACE_VOLSOUND= 530, - EVENT_INTERFACE_VOLMUSIC= 531, - EVENT_INTERFACE_SOUND3D = 532, - - EVENT_INTERFACE_MIN = 540, - EVENT_INTERFACE_NORM = 541, - EVENT_INTERFACE_MAX = 542, - - EVENT_INTERFACE_SILENT = 550, - EVENT_INTERFACE_NOISY = 551, - - EVENT_INTERFACE_JOYSTICK= 560, - EVENT_INTERFACE_SOLUCE = 561, - - EVENT_INTERFACE_GLINTl = 570, - EVENT_INTERFACE_GLINTr = 571, - EVENT_INTERFACE_GLINTu = 572, - EVENT_INTERFACE_GLINTb = 573, - - EVENT_INTERFACE_NEDIT = 580, - EVENT_INTERFACE_NLIST = 581, - EVENT_INTERFACE_NOK = 582, - EVENT_INTERFACE_NCANCEL = 583, - EVENT_INTERFACE_NDELETE = 584, - EVENT_INTERFACE_NLABEL = 585, - - EVENT_INTERFACE_IOWRITE = 600, - EVENT_INTERFACE_IOREAD = 601, - EVENT_INTERFACE_IOLIST = 602, - EVENT_INTERFACE_IONAME = 603, - EVENT_INTERFACE_IOLABEL = 604, - EVENT_INTERFACE_IOIMAGE = 605, - EVENT_INTERFACE_IODELETE= 606, - - EVENT_INTERFACE_PERSO = 620, - EVENT_INTERFACE_POK = 621, - EVENT_INTERFACE_PCANCEL = 622, - EVENT_INTERFACE_PDEF = 623, - EVENT_INTERFACE_PHEAD = 624, - EVENT_INTERFACE_PBODY = 625, - EVENT_INTERFACE_PLROT = 626, - EVENT_INTERFACE_PRROT = 627, - EVENT_INTERFACE_PC0a = 640, - EVENT_INTERFACE_PC1a = 641, - EVENT_INTERFACE_PC2a = 642, - EVENT_INTERFACE_PC3a = 643, - EVENT_INTERFACE_PC4a = 644, - EVENT_INTERFACE_PC5a = 645, - EVENT_INTERFACE_PC6a = 646, - EVENT_INTERFACE_PC7a = 647, - EVENT_INTERFACE_PC8a = 648, - EVENT_INTERFACE_PC9a = 649, - EVENT_INTERFACE_PCRa = 650, - EVENT_INTERFACE_PCGa = 651, - EVENT_INTERFACE_PCBa = 652, - EVENT_INTERFACE_PC0b = 660, - EVENT_INTERFACE_PC1b = 661, - EVENT_INTERFACE_PC2b = 662, - EVENT_INTERFACE_PC3b = 663, - EVENT_INTERFACE_PC4b = 664, - EVENT_INTERFACE_PC5b = 665, - EVENT_INTERFACE_PC6b = 666, - EVENT_INTERFACE_PC7b = 667, - EVENT_INTERFACE_PC8b = 668, - EVENT_INTERFACE_PC9b = 669, - EVENT_INTERFACE_PCRb = 670, - EVENT_INTERFACE_PCGb = 671, - EVENT_INTERFACE_PCBb = 672, - EVENT_INTERFACE_PFACE1 = 680, - EVENT_INTERFACE_PFACE2 = 681, - EVENT_INTERFACE_PFACE3 = 682, - EVENT_INTERFACE_PFACE4 = 683, - EVENT_INTERFACE_PGLASS0 = 690, - EVENT_INTERFACE_PGLASS1 = 691, - EVENT_INTERFACE_PGLASS2 = 692, - EVENT_INTERFACE_PGLASS3 = 693, - EVENT_INTERFACE_PGLASS4 = 694, - EVENT_INTERFACE_PGLASS5 = 695, - EVENT_INTERFACE_PGLASS6 = 696, - EVENT_INTERFACE_PGLASS7 = 697, - EVENT_INTERFACE_PGLASS8 = 698, - EVENT_INTERFACE_PGLASS9 = 699, - - EVENT_DT_GROUP0 = 700, - EVENT_DT_GROUP1 = 701, - EVENT_DT_GROUP2 = 702, - EVENT_DT_GROUP3 = 703, - EVENT_DT_GROUP4 = 704, - EVENT_DT_LABEL0 = 710, - EVENT_DT_LABEL1 = 711, - EVENT_DT_LABEL2 = 712, - EVENT_DT_LABEL3 = 713, - EVENT_DT_LABEL4 = 714, - EVENT_DT_VISIT0 = 720, - EVENT_DT_VISIT1 = 721, - EVENT_DT_VISIT2 = 722, - EVENT_DT_VISIT3 = 723, - EVENT_DT_VISIT4 = 724, - EVENT_DT_END = 725, - - EVENT_CMD = 800, - EVENT_SPEED = 801, - - EVENT_HYPER_PREV = 900, - EVENT_HYPER_NEXT = 901, - EVENT_HYPER_HOME = 902, - EVENT_HYPER_COPY = 903, - EVENT_HYPER_SIZE1 = 904, - EVENT_HYPER_SIZE2 = 905, - EVENT_HYPER_SIZE3 = 906, - EVENT_HYPER_SIZE4 = 907, - EVENT_HYPER_SIZE5 = 908, - - EVENT_SATCOM_HUSTON = 920, - EVENT_SATCOM_SAT = 921, - EVENT_SATCOM_LOADING = 922, - EVENT_SATCOM_OBJECT = 923, - EVENT_SATCOM_PROG = 924, - EVENT_SATCOM_SOLUCE = 925, - - EVENT_OBJECT_DESELECT = 1000, - EVENT_OBJECT_LEFT = 1001, - EVENT_OBJECT_RIGHT = 1002, - EVENT_OBJECT_UP = 1003, - EVENT_OBJECT_DOWN = 1004, - EVENT_OBJECT_GASUP = 1005, - EVENT_OBJECT_GASDOWN = 1006, - EVENT_OBJECT_HTAKE = 1020, - EVENT_OBJECT_MTAKE = 1021, - EVENT_OBJECT_MFRONT = 1022, - EVENT_OBJECT_MBACK = 1023, - EVENT_OBJECT_MPOWER = 1024, - EVENT_OBJECT_BHELP = 1040, - EVENT_OBJECT_BTAKEOFF = 1041, - EVENT_OBJECT_BDERRICK = 1050, - EVENT_OBJECT_BSTATION = 1051, - EVENT_OBJECT_BFACTORY = 1052, - EVENT_OBJECT_BCONVERT = 1053, - EVENT_OBJECT_BTOWER = 1054, - EVENT_OBJECT_BREPAIR = 1055, - EVENT_OBJECT_BRESEARCH = 1056, - EVENT_OBJECT_BRADAR = 1057, - EVENT_OBJECT_BENERGY = 1058, - EVENT_OBJECT_BLABO = 1059, - EVENT_OBJECT_BNUCLEAR = 1060, - EVENT_OBJECT_BPARA = 1061, - EVENT_OBJECT_BINFO = 1062, - EVENT_OBJECT_BXXXX = 1063, - EVENT_OBJECT_GFLAT = 1070, - EVENT_OBJECT_FCREATE = 1071, - EVENT_OBJECT_FDELETE = 1072, - EVENT_OBJECT_FCOLORb = 1073, - EVENT_OBJECT_FCOLORr = 1074, - EVENT_OBJECT_FCOLORg = 1075, - EVENT_OBJECT_FCOLORy = 1076, - EVENT_OBJECT_FCOLORv = 1077, - EVENT_OBJECT_FACTORYwa = 1080, - EVENT_OBJECT_FACTORYta = 1081, - EVENT_OBJECT_FACTORYfa = 1082, - EVENT_OBJECT_FACTORYia = 1083, - EVENT_OBJECT_FACTORYwc = 1084, - EVENT_OBJECT_FACTORYtc = 1085, - EVENT_OBJECT_FACTORYfc = 1086, - EVENT_OBJECT_FACTORYic = 1087, - EVENT_OBJECT_FACTORYwi = 1088, - EVENT_OBJECT_FACTORYti = 1089, - EVENT_OBJECT_FACTORYfi = 1090, - EVENT_OBJECT_FACTORYii = 1091, - EVENT_OBJECT_FACTORYws = 1092, - EVENT_OBJECT_FACTORYts = 1093, - EVENT_OBJECT_FACTORYfs = 1094, - EVENT_OBJECT_FACTORYis = 1095, - EVENT_OBJECT_FACTORYrt = 1096, - EVENT_OBJECT_FACTORYrc = 1097, - EVENT_OBJECT_FACTORYrr = 1098, - EVENT_OBJECT_FACTORYrs = 1099, - EVENT_OBJECT_FACTORYsa = 1100, - EVENT_OBJECT_SEARCH = 1200, - EVENT_OBJECT_TERRAFORM = 1201, - EVENT_OBJECT_FIRE = 1202, - EVENT_OBJECT_FIREANT = 1203, - EVENT_OBJECT_RECOVER = 1220, - EVENT_OBJECT_BEGSHIELD = 1221, - EVENT_OBJECT_ENDSHIELD = 1222, - EVENT_OBJECT_RTANK = 1223, - EVENT_OBJECT_RFLY = 1224, - EVENT_OBJECT_RTHUMP = 1225, - EVENT_OBJECT_RCANON = 1226, - EVENT_OBJECT_RTOWER = 1227, - EVENT_OBJECT_RPHAZER = 1228, - EVENT_OBJECT_RSHIELD = 1229, - EVENT_OBJECT_RATOMIC = 1230, - EVENT_OBJECT_RiPAW = 1231, - EVENT_OBJECT_RiGUN = 1232, - EVENT_OBJECT_RESET = 1233, - EVENT_OBJECT_DIMSHIELD = 1234, - EVENT_OBJECT_TARGET = 1235, - EVENT_OBJECT_PROGLIST = 1310, - EVENT_OBJECT_PROGRUN = 1311, - EVENT_OBJECT_PROGEDIT = 1312, - EVENT_OBJECT_PROGSTART = 1313, - EVENT_OBJECT_PROGSTOP = 1314, - EVENT_OBJECT_INFOOK = 1340, - EVENT_OBJECT_DELETE = 1350, - EVENT_OBJECT_GENERGY = 1360, - EVENT_OBJECT_GSHIELD = 1361, - EVENT_OBJECT_GRANGE = 1362, - EVENT_OBJECT_COMPASS = 1363, - EVENT_OBJECT_MAP = 1364, - EVENT_OBJECT_MAPZOOM = 1365, - EVENT_OBJECT_GPROGRESS = 1366, - EVENT_OBJECT_GRADAR = 1367, - EVENT_OBJECT_GINFO = 1368, - EVENT_OBJECT_TYPE = 1369, - EVENT_OBJECT_CROSSHAIR = 1370, - EVENT_OBJECT_CORNERul = 1371, - EVENT_OBJECT_CORNERur = 1372, - EVENT_OBJECT_CORNERdl = 1373, - EVENT_OBJECT_CORNERdr = 1374, - EVENT_OBJECT_MAPi = 1375, - EVENT_OBJECT_MAPg = 1376, - EVENT_OBJECT_CAMERA = 1400, - EVENT_OBJECT_HELP = 1401, - EVENT_OBJECT_SOLUCE = 1402, - EVENT_OBJECT_CAMERAleft = 1403, - EVENT_OBJECT_CAMERAright= 1404, - EVENT_OBJECT_CAMERAnear = 1405, - EVENT_OBJECT_CAMERAaway = 1406, - EVENT_OBJECT_SHORTCUT00 = 1500, - EVENT_OBJECT_SHORTCUT01 = 1501, - EVENT_OBJECT_SHORTCUT02 = 1502, - EVENT_OBJECT_SHORTCUT03 = 1503, - EVENT_OBJECT_SHORTCUT04 = 1504, - EVENT_OBJECT_SHORTCUT05 = 1505, - EVENT_OBJECT_SHORTCUT06 = 1506, - EVENT_OBJECT_SHORTCUT07 = 1507, - EVENT_OBJECT_SHORTCUT08 = 1508, - EVENT_OBJECT_SHORTCUT09 = 1509, - EVENT_OBJECT_SHORTCUT10 = 1510, - EVENT_OBJECT_SHORTCUT11 = 1511, - EVENT_OBJECT_SHORTCUT12 = 1512, - EVENT_OBJECT_SHORTCUT13 = 1513, - EVENT_OBJECT_SHORTCUT14 = 1514, - EVENT_OBJECT_SHORTCUT15 = 1515, - EVENT_OBJECT_SHORTCUT16 = 1516, - EVENT_OBJECT_SHORTCUT17 = 1517, - EVENT_OBJECT_SHORTCUT18 = 1518, - EVENT_OBJECT_SHORTCUT19 = 1519, - EVENT_OBJECT_MOVIELOCK = 1550, - EVENT_OBJECT_EDITLOCK = 1551, - EVENT_OBJECT_LIMIT = 1560, - - EVENT_OBJECT_PEN0 = 1570, - EVENT_OBJECT_PEN1 = 1571, - EVENT_OBJECT_PEN2 = 1572, - EVENT_OBJECT_PEN3 = 1573, - EVENT_OBJECT_PEN4 = 1574, - EVENT_OBJECT_PEN5 = 1575, - EVENT_OBJECT_PEN6 = 1576, - EVENT_OBJECT_PEN7 = 1577, - EVENT_OBJECT_PEN8 = 1578, - EVENT_OBJECT_REC = 1580, - EVENT_OBJECT_STOP = 1581, - - EVENT_STUDIO_OK = 2000, - EVENT_STUDIO_CANCEL = 2001, - EVENT_STUDIO_EDIT = 2002, - EVENT_STUDIO_LIST = 2003, - EVENT_STUDIO_NEW = 2010, - EVENT_STUDIO_OPEN = 2011, - EVENT_STUDIO_SAVE = 2012, - EVENT_STUDIO_UNDO = 2013, - EVENT_STUDIO_CUT = 2014, - EVENT_STUDIO_COPY = 2015, - EVENT_STUDIO_PASTE = 2016, - EVENT_STUDIO_SIZE = 2017, - EVENT_STUDIO_TOOL = 2018, - EVENT_STUDIO_HELP = 2019, - EVENT_STUDIO_COMPILE = 2050, - EVENT_STUDIO_RUN = 2051, - EVENT_STUDIO_REALTIME = 2052, - EVENT_STUDIO_STEP = 2053, - - EVENT_USER = 10000, - EVENT_FORCE_DWORD = 0x7fffffff -}; - -typedef struct -{ - EventMsg event; // event (EVENT *) - long param; // parameter - FPOINT pos; // mouse position (0 .. 1) - float axeX; // control the X axis (-1 .. 1) - float axeY; // control of the Y axis (-1 .. 1) - float axeZ; // control the Z axis (-1 .. 1) - short keyState; // state of the keyboard (KS_ *) - float rTime; // relative time -} -Event; - - -#define VK_BUTTON1 (0x100+1) // joystick button 1 -#define VK_BUTTON2 (0x100+2) // joystick button 2 -#define VK_BUTTON3 (0x100+3) // joystick button 3 -#define VK_BUTTON4 (0x100+4) // joystick button 4 -#define VK_BUTTON5 (0x100+5) // joystick button 5 -#define VK_BUTTON6 (0x100+6) // joystick button 6 -#define VK_BUTTON7 (0x100+7) // joystick button 7 -#define VK_BUTTON8 (0x100+8) // joystick button 8 -#define VK_BUTTON9 (0x100+9) // joystick button 9 -#define VK_BUTTON10 (0x100+10) // joystick button 10 -#define VK_BUTTON11 (0x100+11) // joystick button 11 -#define VK_BUTTON12 (0x100+12) // joystick button 12 -#define VK_BUTTON13 (0x100+13) // joystick button 13 -#define VK_BUTTON14 (0x100+14) // joystick button 14 -#define VK_BUTTON15 (0x100+15) // joystick button 15 -#define VK_BUTTON16 (0x100+16) // joystick button 16 -#define VK_BUTTON17 (0x100+17) // joystick button 17 -#define VK_BUTTON18 (0x100+18) // joystick button 18 -#define VK_BUTTON19 (0x100+19) // joystick button 19 -#define VK_BUTTON20 (0x100+20) // joystick button 20 -#define VK_BUTTON21 (0x100+21) // joystick button 21 -#define VK_BUTTON22 (0x100+22) // joystick button 22 -#define VK_BUTTON23 (0x100+23) // joystick button 23 -#define VK_BUTTON24 (0x100+24) // joystick button 24 -#define VK_BUTTON25 (0x100+25) // joystick button 25 -#define VK_BUTTON26 (0x100+26) // joystick button 26 -#define VK_BUTTON27 (0x100+27) // joystick button 27 -#define VK_BUTTON28 (0x100+28) // joystick button 28 -#define VK_BUTTON29 (0x100+29) // joystick button 29 -#define VK_BUTTON30 (0x100+30) // joystick button 30 -#define VK_BUTTON31 (0x100+31) // joystick button 31 -#define VK_BUTTON32 (0x100+32) // joystick button 32 - -#define VK_WHEELUP (0x200+1) // Mousewheel up -#define VK_WHEELDOWN (0x200+2) // Mousewheel down - - -enum KeyRank -{ - KEYRANK_LEFT = 0, - KEYRANK_RIGHT = 1, - KEYRANK_UP = 2, - KEYRANK_DOWN = 3, - KEYRANK_GUP = 4, - KEYRANK_GDOWN = 5, - KEYRANK_CAMERA = 6, - KEYRANK_DESEL = 7, - KEYRANK_ACTION = 8, - KEYRANK_NEAR = 9, - KEYRANK_AWAY = 10, - KEYRANK_NEXT = 11, - KEYRANK_HUMAN = 12, - KEYRANK_QUIT = 13, - KEYRANK_HELP = 14, - KEYRANK_PROG = 15, - KEYRANK_VISIT = 16, - KEYRANK_SPEED10 = 17, - KEYRANK_SPEED15 = 18, - KEYRANK_SPEED20 = 19, - KEYRANK_SPEED30 = 20, - KEYRANK_AIMUP = 21, - KEYRANK_AIMDOWN = 22, - KEYRANK_CBOT = 23, -}; - - - -class CEvent -{ -public: - CEvent(CInstanceManager* iMan); - ~CEvent(); - - void Flush(); - void MakeEvent(Event &event, EventMsg msg); - BOOL AddEvent(const Event &event); - BOOL GetEvent(Event &event); - -protected: - -protected: - CInstanceManager* m_iMan; - - Event m_fifo[MAXEVENT]; - int m_head; - int m_tail; - int m_total; -}; - - -#endif //_EVENT_H_ diff --git a/src/gauge.cpp b/src/gauge.cpp deleted file mode 100644 index 420cebf..0000000 --- a/src/gauge.cpp +++ /dev/null @@ -1,159 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// gauge.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "gauge.h" - - - - -// Object's constructor. - -CGauge::CGauge(CInstanceManager* iMan) : CControl(iMan) -{ - m_level = 0.0f; -} - -// Object's destructor. - -CGauge::~CGauge() -{ -} - - -// Creates a new button. - -BOOL CGauge::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - CControl::Create(pos, dim, icon, eventMsg); - return TRUE; -} - - -// Management of an event. - -BOOL CGauge::EventProcess(const Event &event) -{ - CControl::EventProcess(event); - - if ( event.event == EVENT_LBUTTONDOWN ) - { - if ( CControl::Detect(event.pos) ) - { - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - return FALSE; - } - } - - return TRUE; -} - - -// Draw the gauge. - -void CGauge::Draw() -{ - FPOINT pos, dim, ddim, uv1, uv2, corner; - float dp; - - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - - dp = 0.5f/256.0f; - - pos = m_pos; - dim = m_dim; - - uv1.x = 32.0f/256.0f; - uv1.y = 32.0f/256.0f; - uv2.x = 64.0f/256.0f; - uv2.y = 64.0f/256.0f; - - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - corner.x = 10.0f/640.0f; - corner.y = 10.0f/480.0f; - - DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); - - - pos.x += 3.0f/640.0f; - pos.y += 3.0f/480.0f; - dim.x -= 6.0f/640.0f; - dim.y -= 6.0f/480.0f; - - if ( m_dim.x < m_dim.y ) // vertical gauge? - { - uv1.x = (0.0f+m_icon*16.0f)/256.0f; - uv2.x = uv1.x+16.0f/256.0f; - uv1.y = 128.0f/256.0f+m_level*(64.0f/256.0f); - uv2.y = uv1.y+64.0f/256.0f; - } - else // horizontal gauge? - { - uv1.x = 64.0f/256.0f+(1.0f-m_level)*(64.0f/256.0f); - uv2.x = uv1.x+64.0f/256.0f; - uv1.y = (128.0f+m_icon*16.0f)/256.0f; - uv2.y = uv1.y+16.0f/256.0f; - } - - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - DrawIcon(pos, dim, uv1, uv2); -} - - -// Management of level of the gauge. - -void CGauge::SetLevel(float level) -{ - if ( level < 0.0f ) level = 0.0f; - if ( level > 1.0f ) level = 1.0f; - m_level = level; -} - -float CGauge::RetLevel() -{ - return m_level; -} - - diff --git a/src/gauge.h b/src/gauge.h deleted file mode 100644 index 9895d75..0000000 --- a/src/gauge.h +++ /dev/null @@ -1,52 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// gauge.h - -#ifndef _GAUGE_H_ -#define _GAUGE_H_ - - -#include "control.h" - - -class CD3DEngine; - - - -class CGauge : public CControl -{ -public: - CGauge(CInstanceManager* iMan); - virtual ~CGauge(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - - BOOL EventProcess(const Event &event); - - void Draw(); - - void SetLevel(float level); - float RetLevel(); - -protected: - -protected: - float m_level; -}; - - -#endif //_GAUGE_H_ diff --git a/src/global.h b/src/global.h deleted file mode 100644 index 32aefdc..0000000 --- a/src/global.h +++ /dev/null @@ -1,64 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// global.h - -#ifndef _GLOBAL_H_ -#define _GLOBAL_H_ - - -#define BUILD_FACTORY (1<<0) // factory -#define BUILD_DERRICK (1<<1) // derrick -#define BUILD_CONVERT (1<<2) // converter -#define BUILD_RADAR (1<<3) // radar -#define BUILD_ENERGY (1<<4) // factory of cells -#define BUILD_NUCLEAR (1<<5) // nuclear power plant -#define BUILD_STATION (1<<6) // base station -#define BUILD_REPAIR (1<<7) // repair center -#define BUILD_TOWER (1<<8) // defense tower -#define BUILD_RESEARCH (1<<9) // research center -#define BUILD_LABO (1<<10) // laboratory -#define BUILD_PARA (1<<11) // lightning protection -#define BUILD_INFO (1<<12) // information terminal -#define BUILD_GFLAT (1<<16) // flat floor -#define BUILD_FLAG (1<<17) // puts / removes colored flag - - -// Do not change values ​​was because of backups (bits = ...). - -#define RESEARCH_TANK (1<<0) // caterpillars -#define RESEARCH_FLY (1<<1) // wings -#define RESEARCH_CANON (1<<2) // cannon -#define RESEARCH_TOWER (1<<3) // defense tower -#define RESEARCH_ATOMIC (1<<4) // nuclear -#define RESEARCH_THUMP (1<<5) // thumper -#define RESEARCH_SHIELD (1<<6) // shield -#define RESEARCH_PHAZER (1<<7) // phazer gun -#define RESEARCH_iPAW (1<<8) // legs of insects -#define RESEARCH_iGUN (1<<9) // cannon of insects -#define RESEARCH_RECYCLER (1<<10) // recycler -#define RESEARCH_SUBM (1<<11) // submarine -#define RESEARCH_SNIFFER (1<<12) // sniffer - -extern long g_id; // unique identifier -extern long g_build; // constructible buildings -extern long g_researchDone; // research done -extern long g_researchEnable; // research available -extern float g_unit; // conversion factor - - - -#endif //_GLOBAL_H_ diff --git a/src/graphics/README.txt b/src/graphics/README.txt new file mode 100644 index 0000000..57bba37 --- /dev/null +++ b/src/graphics/README.txt @@ -0,0 +1,5 @@ +src/graphics + +In the future, it will contain common interface to handling 3D graphics with concrete implementations for OpenGL and DirectX. + +Currently, there is only the D3D interface. diff --git a/src/graphics/common/blitz.cpp b/src/graphics/common/blitz.cpp new file mode 100644 index 0000000..cf88fe3 --- /dev/null +++ b/src/graphics/common/blitz.cpp @@ -0,0 +1,471 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "d3dutil.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "terrain.h" +#include "math3d.h" +#include "object.h" +#include "camera.h" +#include "auto.h" +#include "autopara.h" +#include "sound.h" +#include "blitz.h" + + + + +// Constructor of the terrain. + +CBlitz::CBlitz(CInstanceManager* iMan, CD3DEngine* engine) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_BLITZ, this); + + m_engine = engine; + m_terrain = 0; + m_camera = 0; + m_sound = 0; + Flush(); +} + +// Destructor of the terrain. + +CBlitz::~CBlitz() +{ +} + + +// Removes lightning. + +void CBlitz::Flush() +{ + int i; + + m_bBlitzExist = FALSE; + m_time = 0.0f; + m_phase = BPH_WAIT; + m_speed = 0.0f; + m_progress = 0.0f; + + for ( i=0 ; iRetPause() ) return TRUE; + if ( m_engine->RetMovieLock() ) return TRUE; + + m_time += event.rTime; + m_progress += event.rTime*m_speed; + + if ( m_phase == BPH_WAIT ) + { + if ( m_progress >= 1.0f ) + { +#if 1 + m_pos.x = (Rand()-0.5f)*(3200.0f-200.0f); + m_pos.z = (Rand()-0.5f)*(3200.0f-200.0f); +#else + m_pos.x = (Rand()-0.5f)*(3200.0f-2800.0f); + m_pos.z = (Rand()-0.5f)*(3200.0f-2800.0f); +#endif + m_pos.y = 0.0f; + + pObj = SearchObject(m_pos); + if ( pObj == 0 ) + { + m_terrain->MoveOnFloor(m_pos, TRUE); + } + else + { + m_pos = pObj->RetPosition(0); + m_terrain->MoveOnFloor(m_pos, TRUE); + + type = pObj->RetType(); + if ( type == OBJECT_BASE ) + { + m_pos.y += 120.0f; // top of the rocket + } + else if ( type == OBJECT_PARA ) + { + automat = (CAutoPara*)pObj->RetAuto(); + if ( automat != 0 ) + { + automat->StartBlitz(); + } + m_pos.y += 67.0f; // top of lightning rod + } + else + { + pObj->ExploObject(EXPLO_BOUM, 1.0f); + } + } + + eye = m_engine->RetEyePt(); + dist = Length(m_pos, eye); + deep = m_engine->RetDeepView(); + + if ( dist < deep ) + { + pos = eye+((m_pos-eye)*0.2f); // like so close! + m_sound->Play(SOUND_BLITZ, pos); + + m_camera->StartOver(OE_BLITZ, m_pos, 1.0f); + + m_phase = BPH_BLITZ; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + } + + if ( m_phase == BPH_BLITZ ) + { + if ( m_progress < 1.0f ) + { + max = 5.0f; + for ( i=0 ; i max ) m_shift[i].x = max; + + m_shift[i].y += (Rand()-0.5f)*max*2.0f; + if ( m_shift[i].y < -max ) m_shift[i].y = -max; + if ( m_shift[i].y > max ) m_shift[i].y = max; + + m_width[i] += (Rand()-0.5f)*2.0f; + if ( m_width[i] < 1.0f ) m_width[i] = 1.0f; + if ( m_width[i] > 6.0f ) m_width[i] = 6.0f; + } + m_shift[0].x = 0.0f; + m_shift[0].y = 0.0f; + m_width[0] = 0.0f; + } + else + { + m_phase = BPH_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/(1.0f+Rand()*m_delay); + } + } + + return TRUE; +} + + +// Draw lightning. + +void CBlitz::Draw() +{ + LPDIRECT3DDEVICE7 device; + D3DVERTEX2 vertex[4]; // 2 triangles + D3DVECTOR corner[4], eye, n, p, p1, p2; + D3DMATRIX matrix; + FPOINT texInf, texSup, rot; + float a; + int i; + + if ( !m_bBlitzExist ) return; + if ( m_phase != BPH_BLITZ ) return; + + device = m_engine->RetD3DDevice(); + device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + + D3DUtil_SetIdentityMatrix(matrix); + device->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); + + m_engine->SetTexture("effect00.tga"); + m_engine->SetState(D3DSTATETTb); + texInf.x = 64.5f/256.0f; + texInf.y = 33.0f/256.0f; + texSup.x = 95.5f/256.0f; + texSup.y = 34.0f/256.0f; // blank + + p1 = m_pos; + eye = m_engine->RetEyePt(); + a = RotateAngle(eye.x-p1.x, eye.z-p1.z); + n = Normalize(p1-eye); + + for ( i=0 ; iDrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); + + p1 = p2; + } + + device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE); +} + + +// Triggers lightning. + +BOOL CBlitz::Create(float sleep, float delay, float magnetic) +{ + m_bBlitzExist = TRUE; + if ( sleep < 1.0f ) sleep = 1.0f; + m_sleep = sleep; + m_delay = delay; + m_magnetic = magnetic; + + m_phase = BPH_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/m_sleep; + + if ( m_terrain == 0 ) + { + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + } + + if ( m_camera == 0 ) + { + m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); + } + + if ( m_sound == 0 ) + { + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + } + + return FALSE; +} + + +// Gives the status of lightning. + +BOOL CBlitz::GetStatus(float &sleep, float &delay, float &magnetic, float &progress) +{ + if ( !m_bBlitzExist ) return FALSE; + + sleep = m_sleep; + delay = m_delay; + magnetic = m_magnetic; + progress = m_progress; + + return TRUE; +} + +// Specifies the status of lightning. + +BOOL CBlitz::SetStatus(float sleep, float delay, float magnetic, float progress) +{ + m_bBlitzExist = TRUE; + + m_sleep = sleep; + m_delay = delay; + m_magnetic = magnetic; + m_progress = progress; + m_phase = BPH_WAIT; + m_speed = 1.0f/m_sleep; + + return TRUE; +} + + +// Seeking the object closest to the lightning. + +CObject* CBlitz::SearchObject(D3DVECTOR pos) +{ + CObject *pObj, *pBest, *pObjPara[100]; + D3DVECTOR oPos, pPos[100]; + ObjectType type; + float min, dist, detect; + int i, nbPara; + + // Seeking the object closest to the point of impact of lightning. + pBest = 0; + min = 100000.0f; + nbPara = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetActif() ) continue; // inactive object? + if ( pObj->RetTruck() != 0 ) continue; // object transported? + + type = pObj->RetType(); + if ( type == OBJECT_BASE || + type == OBJECT_PARA ) // building a lightning effect? + { + pObjPara[nbPara] = pObj; + pPos[nbPara] = pObj->RetPosition(0); + nbPara ++; + } + + detect = 0.0f; + if ( type == OBJECT_BASE || + type == OBJECT_DERRICK || + type == OBJECT_FACTORY || + type == OBJECT_REPAIR || + type == OBJECT_DESTROYER|| + type == OBJECT_STATION || + type == OBJECT_CONVERT || + type == OBJECT_TOWER || + type == OBJECT_RESEARCH || + type == OBJECT_RADAR || + type == OBJECT_INFO || + type == OBJECT_ENERGY || + type == OBJECT_LABO || + type == OBJECT_NUCLEAR || + type == OBJECT_PARA || + type == OBJECT_SAFE || + type == OBJECT_HUSTON ) + { + detect = m_magnetic; + } + if ( type == OBJECT_METAL || + type == OBJECT_POWER || + type == OBJECT_ATOMIC ) + { + detect = m_magnetic*0.3f; + } + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEft || + type == OBJECT_MOBILEtt || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEit || + type == OBJECT_MOBILEdr ) + { + detect = m_magnetic*0.5f; + } + if ( detect == 0.0f ) continue; + + oPos = pObj->RetPosition(0); + dist = Length2d(oPos, pos); + if ( dist > detect ) continue; + if ( dist < min ) + { + min = dist; + pBest = pObj; + } + } + if ( pBest == 0 ) return 0; // nothing found + + // Under the protection of a lightning conductor? + oPos = pBest->RetPosition(0); + for ( i=nbPara-1 ; i>=0 ; i-- ) + { + dist = Length2d(oPos, pPos[i]); + if ( dist <= BLITZPARA ) + { + return pObjPara[i]; + } + } + return pBest; +} + diff --git a/src/graphics/common/blitz.h b/src/graphics/common/blitz.h new file mode 100644 index 0000000..30a34ed --- /dev/null +++ b/src/graphics/common/blitz.h @@ -0,0 +1,84 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// blitz.h + +#ifndef _BLITZ_H_ +#define _BLITZ_H_ + + +#include "misc.h" +#include "struct.h" + + +class CInstanceManager; +class CD3DEngine; +class CTerrain; +class CCamera; +class CSound; + + + +#define BLITZPARA 200.0f // radius of lightning protection +#define BLITZMAX 50 + +enum BlitzPhase +{ + BPH_WAIT, + BPH_BLITZ, +}; + + + +class CBlitz +{ +public: + CBlitz(CInstanceManager* iMan, CD3DEngine* engine); + ~CBlitz(); + + void Flush(); + BOOL EventProcess(const Event &event); + BOOL Create(float sleep, float delay, float magnetic); + BOOL GetStatus(float &sleep, float &delay, float &magnetic, float &progress); + BOOL SetStatus(float sleep, float delay, float magnetic, float progress); + void Draw(); + +protected: + BOOL EventFrame(const Event &event); + CObject* SearchObject(D3DVECTOR pos); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CTerrain* m_terrain; + CCamera* m_camera; + CSound* m_sound; + + BOOL m_bBlitzExist; + float m_sleep; + float m_delay; + float m_magnetic; + BlitzPhase m_phase; + float m_time; + float m_speed; + float m_progress; + D3DVECTOR m_pos; + FPOINT m_shift[BLITZMAX]; + float m_width[BLITZMAX]; +}; + + +#endif //_BLITZ_H_ diff --git a/src/graphics/common/camera.cpp b/src/graphics/common/camera.cpp new file mode 100644 index 0000000..e526d6c --- /dev/null +++ b/src/graphics/common/camera.cpp @@ -0,0 +1,2109 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "language.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "terrain.h" +#include "water.h" +#include "object.h" +#include "physics.h" +#include "camera.h" + + + + +// Object's constructor. + +CCamera::CCamera(CInstanceManager* iMan) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_CAMERA, this); + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); + + m_type = CAMERA_FREE; + m_smooth = CS_NORM; + m_cameraObj = 0; + + m_eyeDistance = 10.0f; + m_initDelay = 0.0f; + + m_actualEye = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_actualLookat = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_finalEye = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_finalLookat = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_normEye = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_normLookat = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_focus = 1.0f; + + m_bRightDown = FALSE; + m_rightPosInit = FPOINT(0.5f, 0.5f); + m_rightPosCenter = FPOINT(0.5f, 0.5f); + m_rightPosMove = FPOINT(0.5f, 0.5f); + + m_eyePt = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_directionH = 0.0f; + m_directionV = 0.0f; + m_heightEye = 20.0f; + m_heightLookat = 0.0f; + m_speed = 2.0f; + + m_backDist = 0.0f; + m_backMin = 0.0f; + m_addDirectionH = 0.0f; + m_addDirectionV = 0.0f; + m_bTransparency = FALSE; + + m_fixDist = 0.0f; + m_fixDirectionH = 0.0f; + m_fixDirectionV = 0.0f; + + m_visitGoal = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_visitDist = 0.0f; + m_visitTime = 0.0f; + m_visitType = CAMERA_NULL; + m_visitDirectionH = 0.0f; + m_visitDirectionV = 0.0f; + + m_editHeight = 40.0f; + + m_remotePan = 0.0f; + m_remoteZoom = 0.0f; + + m_mouseDirH = 0.0f; + m_mouseDirV = 0.0f; + m_mouseMarging = 0.01f; + + m_motorTurn = 0.0f; + + m_centeringPhase = CP_NULL; + m_centeringAngleH = 0.0f; + m_centeringAngleV = 0.0f; + m_centeringDist = 0.0f; + m_centeringCurrentH = 0.0f; + m_centeringCurrentV = 0.0f; + m_centeringTime = 0.0f; + m_centeringProgress = 0.0f; + + m_effectType = CE_NULL; + m_effectPos = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_effectForce = 0.0f; + m_effectProgress = 0.0f; + m_effectOffset = D3DVECTOR(0.0f, 0.0f, 0.0f); + + m_scriptEye = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_scriptLookat = D3DVECTOR(0.0f, 0.0f, 0.0f); + + m_bEffect = TRUE; + m_bCameraScroll = TRUE; + m_bCameraInvertX = FALSE; + m_bCameraInvertY = FALSE; +} + +// Object's constructor. + +CCamera::~CCamera() +{ +} + + +void CCamera::SetEffect(BOOL bEnable) +{ + m_bEffect = bEnable; +} + +void CCamera::SetCameraScroll(BOOL bScroll) +{ + m_bCameraScroll = bScroll; +} + +void CCamera::SetCameraInvertX(BOOL bInvert) +{ + m_bCameraInvertX = bInvert; +} + +void CCamera::SetCameraInvertY(BOOL bInvert) +{ + m_bCameraInvertY = bInvert; +} + + +// Returns an additional force to turn. + +float CCamera::RetMotorTurn() +{ + if ( m_type == CAMERA_BACK ) return m_motorTurn; + return 0.0f; +} + + + +// Initializes the camera. + +void CCamera::Init(D3DVECTOR eye, D3DVECTOR lookat, float delay) +{ + D3DVECTOR vUpVec; + + m_initDelay = delay; + + eye.y += m_terrain->RetFloorLevel(eye, TRUE); + lookat.y += m_terrain->RetFloorLevel(lookat, TRUE); + + m_type = CAMERA_FREE; + m_eyePt = eye; + + m_directionH = RotateAngle(eye.x-lookat.x, eye.z-lookat.z)+PI/2.0f; + m_directionV = -RotateAngle(Length2d(eye, lookat), eye.y-lookat.y); + + m_eyeDistance = 10.0f; + m_heightLookat = 10.0f; + m_backDist = 30.0f; + m_backMin = 10.0f; + m_addDirectionH = 0.0f; + m_addDirectionV = -PI*0.05f; + m_fixDist = 50.0f; + m_fixDirectionH = PI*0.25f; + m_fixDirectionV = -PI*0.10f; + m_centeringPhase = CP_NULL; + m_actualEye = m_eyePt; + m_actualLookat = LookatPoint(m_eyePt, m_directionH, m_directionV, 50.0f); + m_finalEye = m_actualEye; + m_finalLookat = m_actualLookat; + m_scriptEye = m_actualEye; + m_scriptLookat = m_actualLookat; + m_focus = 1.00f; + m_remotePan = 0.0f; + m_remoteZoom = 0.0f; + + FlushEffect(); + FlushOver(); + SetType(CAMERA_FREE); +} + + +// Gives the object controlling the camera. + +void CCamera::SetObject(CObject* object) +{ + m_cameraObj = object; +} + +CObject* CCamera::RetObject() +{ + return m_cameraObj; +} + + +// Changes the level of transparency of an object and objects +// transported (battery & cargo). + +void SetTransparency(CObject* pObj, float value) +{ + CObject* pFret; + + pObj->SetTransparency(value); + + pFret = pObj->RetFret(); + if ( pFret != 0 ) + { + pFret->SetTransparency(value); + } + + pFret = pObj->RetPower(); + if ( pFret != 0 ) + { + pFret->SetTransparency(value); + } +} + +// Change the type of camera. + +void CCamera::SetType(CameraType type) +{ + CObject* pObj; + ObjectType oType; + D3DVECTOR vUpVec; + int i; + + m_remotePan = 0.0f; + m_remoteZoom = 0.0f; + + if ( m_type == CAMERA_BACK && m_bTransparency ) + { + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj->RetTruck() ) continue; // battery or cargo? + + SetTransparency(pObj, 0.0f); // opaque object + } + } + m_bTransparency = FALSE; + + if ( type == CAMERA_INFO || + type == CAMERA_VISIT ) // xx -> info ? + { + m_normEye = m_engine->RetEyePt(); + m_normLookat = m_engine->RetLookatPt(); + + m_engine->SetFocus(1.00f); // normal + m_type = type; + return; + } + + if ( m_type == CAMERA_INFO || + m_type == CAMERA_VISIT ) // info -> xx ? + { + m_engine->SetFocus(m_focus); // gives initial focus + m_type = type; + + vUpVec = D3DVECTOR(0.0f, 1.0f, 0.0f); + SetViewParams(m_normEye, m_normLookat, vUpVec); + return; + } + + if ( m_type == CAMERA_BACK && type == CAMERA_FREE ) // back -> free ? + { + m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, -50.0f); + } + + if ( m_type == CAMERA_BACK && type == CAMERA_EDIT ) // back -> edit ? + { + m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, -1.0f); + } + + if ( m_type == CAMERA_ONBOARD && type == CAMERA_FREE ) // onboard -> free ? + { + m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, -30.0f); + } + + if ( m_type == CAMERA_ONBOARD && type == CAMERA_EDIT ) // onboard -> edit ? + { + m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, -30.0f); + } + + if ( m_type == CAMERA_ONBOARD && type == CAMERA_EXPLO ) // onboard -> explo ? + { + m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, -50.0f); + } + + if ( m_type == CAMERA_BACK && type == CAMERA_EXPLO ) // back -> explo ? + { + m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, -20.0f); + } + + if ( type == CAMERA_FIX || + type == CAMERA_PLANE ) + { + AbortCentering(); // Special stops framing + } + + m_fixDist = 50.0f; + if ( type == CAMERA_PLANE ) + { + m_fixDist = 60.0f; + } + + if ( type == CAMERA_BACK ) + { + AbortCentering(); // Special stops framing + m_addDirectionH = 0.0f; + m_addDirectionV = -PI*0.05f; + + if ( m_cameraObj == 0 ) oType = OBJECT_NULL; + else oType = m_cameraObj->RetType(); + + m_backDist = 30.0f; + if ( oType == OBJECT_BASE ) m_backDist = 200.0f; + if ( oType == OBJECT_HUMAN ) m_backDist = 20.0f; + if ( oType == OBJECT_TECH ) m_backDist = 20.0f; + if ( oType == OBJECT_FACTORY ) m_backDist = 50.0f; + if ( oType == OBJECT_RESEARCH ) m_backDist = 40.0f; + if ( oType == OBJECT_DERRICK ) m_backDist = 40.0f; + if ( oType == OBJECT_REPAIR ) m_backDist = 35.0f; + if ( oType == OBJECT_DESTROYER) m_backDist = 35.0f; + if ( oType == OBJECT_TOWER ) m_backDist = 45.0f; + if ( oType == OBJECT_NUCLEAR ) m_backDist = 70.0f; + if ( oType == OBJECT_PARA ) m_backDist = 180.0f; + if ( oType == OBJECT_SAFE ) m_backDist = 50.0f; + if ( oType == OBJECT_HUSTON ) m_backDist = 120.0f; + + m_backMin = m_backDist/3.0f; + if ( oType == OBJECT_HUMAN ) m_backMin = 10.0f; + if ( oType == OBJECT_TECH ) m_backMin = 10.0f; + if ( oType == OBJECT_FACTORY ) m_backMin = 30.0f; + if ( oType == OBJECT_RESEARCH ) m_backMin = 20.0f; + if ( oType == OBJECT_NUCLEAR ) m_backMin = 32.0f; + if ( oType == OBJECT_PARA ) m_backMin = 40.0f; + if ( oType == OBJECT_SAFE ) m_backMin = 25.0f; + if ( oType == OBJECT_HUSTON ) m_backMin = 80.0f; + } + + if ( type != CAMERA_ONBOARD && m_cameraObj != 0 ) + { + m_cameraObj->SetGunGoalH(0.0f); // puts the cannon right + } + + if ( type == CAMERA_ONBOARD ) + { + m_focus = 1.50f; // Wide + } + else + { + m_focus = 1.00f; // normal + } + m_engine->SetFocus(m_focus); + + m_type = type; + + SetSmooth(CS_NORM); +} + +CameraType CCamera::RetType() +{ + return m_type; +} + + +// Management of the smoothing mode. + +void CCamera::SetSmooth(CameraSmooth type) +{ + m_smooth = type; +} + +CameraSmooth CCamera::RetSmoth() +{ + return m_smooth; +} + + +// Management of the setback distance. + +void CCamera::SetDist(float dist) +{ + m_fixDist = dist; +} + +float CCamera::RetDist() +{ + return m_fixDist; +} + + +// Manage angle mode CAMERA_FIX. + +void CCamera::SetFixDirection(float angle) +{ + m_fixDirectionH = angle; +} + +float CCamera::RetFixDirection() +{ + return m_fixDirectionH; +} + + +// Managing the triggering mode of the camera panning. + +void CCamera::SetRemotePan(float value) +{ + m_remotePan = value; +} + +float CCamera::RetRemotePan() +{ + return m_remotePan; +} + +// Management of the remote zoom (0 .. 1) of the camera. + +void CCamera::SetRemoteZoom(float value) +{ + value = Norm(value); + + if ( m_type == CAMERA_BACK ) + { + m_backDist = m_backMin+(200.0f-m_backMin)*value; + } + + if ( m_type == CAMERA_FIX || + m_type == CAMERA_PLANE ) + { + m_fixDist = 10.0f+(200.0f-10.0f)*value; + } +} + +float CCamera::RetRemoteZoom() +{ + if ( m_type == CAMERA_BACK ) + { + return (m_backDist-m_backMin)/(200.0f-m_backMin); + } + + if ( m_type == CAMERA_FIX || + m_type == CAMERA_PLANE ) + { + return (m_fixDist-10.0f)/(200.0f-10.0f); + } + return 0.0f; +} + + + +// Start with a tour round the camera. + +void CCamera::StartVisit(D3DVECTOR goal, float dist) +{ + m_visitType = m_type; + SetType(CAMERA_VISIT); + m_visitGoal = goal; + m_visitDist = dist; + m_visitTime = 0.0f; + m_visitDirectionH = 0.0f; + m_visitDirectionV = -PI*0.10f; +} + +// Circular end of a visit with the camera. + +void CCamera::StopVisit() +{ + SetType(m_visitType); // presents the initial type +} + + +// Returns the point of view of the camera. + +void CCamera::RetCamera(D3DVECTOR &eye, D3DVECTOR &lookat) +{ + eye = m_eyePt; + lookat = LookatPoint(m_eyePt, m_directionH, m_directionV, 50.0f); +} + + +// Specifies a special movement of camera to frame action. + +BOOL CCamera::StartCentering(CObject *object, float angleH, float angleV, + float dist, float time) +{ + if ( m_type != CAMERA_BACK ) return FALSE; + if ( object != m_cameraObj ) return FALSE; + + if ( m_centeringPhase != CP_NULL ) return FALSE; + + if ( m_addDirectionH > PI ) + { + angleH = PI*2.0f-angleH; + } + + m_centeringPhase = CP_START; + m_centeringAngleH = angleH; + m_centeringAngleV = angleV; + m_centeringDist = dist; + m_centeringCurrentH = 0.0f; + m_centeringCurrentV = 0.0f; + m_centeringTime = time; + m_centeringProgress = 0.0f; + + return TRUE; +} + +// Ends a special movement of camera to frame action. + +BOOL CCamera::StopCentering(CObject *object, float time) +{ + if ( m_type != CAMERA_BACK ) return FALSE; + if ( object != m_cameraObj ) return FALSE; + + if ( m_centeringPhase != CP_START && + m_centeringPhase != CP_WAIT ) return FALSE; + + m_centeringPhase = CP_STOP; + + if ( m_centeringAngleH != 99.9f ) + { + m_centeringAngleH = m_centeringCurrentH; + } + if ( m_centeringAngleV != 99.9f ) + { + m_centeringAngleV = m_centeringCurrentV; + } + + m_centeringTime = time; + m_centeringProgress = 0.0f; + + return TRUE; +} + +// Stop framing special in the current position. + +void CCamera::AbortCentering() +{ + if ( m_type == CAMERA_INFO || + m_type == CAMERA_VISIT ) return; + + if ( m_centeringPhase == CP_NULL ) return; + + m_centeringPhase = CP_NULL; + + if ( m_centeringAngleH != 99.9f ) + { + m_addDirectionH = m_centeringCurrentH; + } + if ( m_centeringAngleV != 99.9f ) + { + m_addDirectionV = m_centeringCurrentV; + } +} + + + +// Removes the special effect with the camera + +void CCamera::FlushEffect() +{ + m_effectType = CE_NULL; + m_effectForce = 0.0f; + m_effectProgress = 0.0f; + m_effectOffset = D3DVECTOR(0.0f, 0.0f, 0.0f); +} + +// Starts a special effect with the camera. + +void CCamera::StartEffect(CameraEffect effect, D3DVECTOR pos, float force) +{ + if ( !m_bEffect ) return; + + m_effectType = effect; + m_effectPos = pos; + m_effectForce = force; + m_effectProgress = 0.0f; +} + +// Advances the effect of the camera. + +void CCamera::EffectFrame(const Event &event) +{ + float dist, force; + + if ( m_type == CAMERA_INFO || + m_type == CAMERA_VISIT ) return; + + if ( m_effectType == CE_NULL ) return; + + m_effectOffset = D3DVECTOR(0.0f, 0.0f, 0.0f); + force = m_effectForce; + + if ( m_effectType == CE_TERRAFORM ) + { + m_effectProgress += event.rTime*0.7f; + m_effectOffset.x = (Rand()-0.5f)*10.0f; + m_effectOffset.y = (Rand()-0.5f)*10.0f; + m_effectOffset.z = (Rand()-0.5f)*10.0f; + + force *= 1.0f-m_effectProgress; + } + + if ( m_effectType == CE_EXPLO ) + { + m_effectProgress += event.rTime*1.0f; + m_effectOffset.x = (Rand()-0.5f)*5.0f; + m_effectOffset.y = (Rand()-0.5f)*5.0f; + m_effectOffset.z = (Rand()-0.5f)*5.0f; + + force *= 1.0f-m_effectProgress; + } + + if ( m_effectType == CE_SHOT ) + { + m_effectProgress += event.rTime*1.0f; + m_effectOffset.x = (Rand()-0.5f)*2.0f; + m_effectOffset.y = (Rand()-0.5f)*2.0f; + m_effectOffset.z = (Rand()-0.5f)*2.0f; + + force *= 1.0f-m_effectProgress; + } + + if ( m_effectType == CE_CRASH ) + { + m_effectProgress += event.rTime*5.0f; + m_effectOffset.y = sinf(m_effectProgress*PI)*1.5f; + m_effectOffset.x = (Rand()-0.5f)*1.0f*(1.0f-m_effectProgress); + m_effectOffset.z = (Rand()-0.5f)*1.0f*(1.0f-m_effectProgress); + } + + if ( m_effectType == CE_VIBRATION ) + { + m_effectProgress += event.rTime*0.1f; + m_effectOffset.y = (Rand()-0.5f)*1.0f*(1.0f-m_effectProgress); + m_effectOffset.x = (Rand()-0.5f)*1.0f*(1.0f-m_effectProgress); + m_effectOffset.z = (Rand()-0.5f)*1.0f*(1.0f-m_effectProgress); + } + + if ( m_effectType == CE_PET ) + { + m_effectProgress += event.rTime*5.0f; + m_effectOffset.x = (Rand()-0.5f)*0.2f; + m_effectOffset.y = (Rand()-0.5f)*2.0f; + m_effectOffset.z = (Rand()-0.5f)*0.2f; + } + + dist = Length(m_eyePt, m_effectPos); + dist = Norm((dist-100.f)/100.0f); + + force *= 1.0f-dist; +#if _TEEN + force *= 2.0f; +#endif + m_effectOffset *= force; + + if ( m_effectProgress >= 1.0f ) + { + FlushEffect(); + } +} + + +// Removes the effect of superposition in the foreground. + +void CCamera::FlushOver() +{ + m_overType = OE_NULL; + m_overColorBase.r = 0.0f; // black + m_overColorBase.g = 0.0f; + m_overColorBase.b = 0.0f; + m_overColorBase.a = 0.0f; + m_engine->SetOverColor(); // nothing +} + +// Specifies the base color. + +void CCamera::SetOverBaseColor(D3DCOLORVALUE color) +{ + m_overColorBase = color; +} + +// Starts a layering effect in the foreground. + +void CCamera::StartOver(OverEffect effect, D3DVECTOR pos, float force) +{ + D3DCOLOR color; + float dist, decay; + + m_overType = effect; + m_overTime = 0.0f; + + if ( m_overType == OE_BLITZ ) decay = 400.0f; + else decay = 100.0f; + dist = Length(m_eyePt, pos); + dist = (dist-decay)/decay; + if ( dist < 0.0f ) dist = 0.0f; + if ( dist > 1.0f ) dist = 1.0f; + + m_overForce = force * (1.0f-dist); + + if ( m_overType == OE_BLOOD ) + { + m_overColor.r = 0.8f; + m_overColor.g = 0.1f; + m_overColor.b = 0.1f; // red + m_overMode = D3DSTATETCb; + + m_overFadeIn = 0.4f; + m_overFadeOut = 0.8f; + m_overForce = 1.0f; + } + + if ( m_overType == OE_FADEINw ) + { + m_overColor.r = 1.0f; + m_overColor.g = 1.0f; + m_overColor.b = 1.0f; // white + m_overMode = D3DSTATETCb; + + m_overFadeIn = 0.0f; + m_overFadeOut =20.0f; + m_overForce = 1.0f; + } + + if ( m_overType == OE_FADEOUTw ) + { + m_overColor.r = 1.0f; + m_overColor.g = 1.0f; + m_overColor.b = 1.0f; // white + m_overMode = D3DSTATETCb; + + m_overFadeIn = 6.0f; + m_overFadeOut = 100000.0f; + m_overForce = 1.0f; + } + + if ( m_overType == OE_FADEOUTb ) + { + color = m_engine->RetFogColor(1); // fog color underwater + m_overColor = RetColor(color); + m_overMode = D3DSTATETCw; + + m_overFadeIn = 4.0f; + m_overFadeOut = 100000.0f; + m_overForce = 1.0f; + } + + if ( m_overType == OE_BLITZ ) + { + m_overColor.r = 0.9f; + m_overColor.g = 1.0f; + m_overColor.b = 1.0f; // white-cyan + m_overMode = D3DSTATETCb; + + m_overFadeIn = 0.0f; + m_overFadeOut = 1.0f; + } +} + +// Advanced overlay effect in the foreground. + +void CCamera::OverFrame(const Event &event) +{ + D3DCOLORVALUE color; + float intensity; + + if ( m_type == CAMERA_INFO || + m_type == CAMERA_VISIT ) return; + + if ( m_overType == OE_NULL ) + { + return; + } + + m_overTime += event.rTime; + + if ( m_overType == OE_BLITZ ) + { + if ( rand()%2 == 0 ) + { + color.r = m_overColor.r*m_overForce; + color.g = m_overColor.g*m_overForce; + color.b = m_overColor.b*m_overForce; + } + else + { + color.r = 0.0f; + color.g = 0.0f; + color.b = 0.0f; + } + color.a = 0.0f; + m_engine->SetOverColor(RetColor(color), m_overMode); + } + else + { + if ( m_overFadeIn > 0.0f && m_overTime < m_overFadeIn ) + { + intensity = m_overTime/m_overFadeIn; + intensity *= m_overForce; + + if ( m_overMode == D3DSTATETCw ) + { + color.r = 1.0f-(1.0f-m_overColor.r)*intensity; + color.g = 1.0f-(1.0f-m_overColor.g)*intensity; + color.b = 1.0f-(1.0f-m_overColor.b)*intensity; + } + else + { + color.r = m_overColor.r*intensity; + color.g = m_overColor.g*intensity; + color.b = m_overColor.b*intensity; + + color.r = 1.0f-(1.0f-color.r)*(1.0f-m_overColorBase.r); + color.g = 1.0f-(1.0f-color.g)*(1.0f-m_overColorBase.g); + color.b = 1.0f-(1.0f-color.b)*(1.0f-m_overColorBase.b); + } + color.a = 0.0f; + m_engine->SetOverColor(RetColor(color), m_overMode); + } + else if ( m_overFadeOut > 0.0f && m_overTime-m_overFadeIn < m_overFadeOut ) + { + intensity = 1.0f-(m_overTime-m_overFadeIn)/m_overFadeOut; + intensity *= m_overForce; + + if ( m_overMode == D3DSTATETCw ) + { + color.r = 1.0f-(1.0f-m_overColor.r)*intensity; + color.g = 1.0f-(1.0f-m_overColor.g)*intensity; + color.b = 1.0f-(1.0f-m_overColor.b)*intensity; + } + else + { + color.r = m_overColor.r*intensity; + color.g = m_overColor.g*intensity; + color.b = m_overColor.b*intensity; + + color.r = 1.0f-(1.0f-color.r)*(1.0f-m_overColorBase.r); + color.g = 1.0f-(1.0f-color.g)*(1.0f-m_overColorBase.g); + color.b = 1.0f-(1.0f-color.b)*(1.0f-m_overColorBase.b); + } + color.a = 0.0f; + m_engine->SetOverColor(RetColor(color), m_overMode); + } + } + + if ( m_overTime >= m_overFadeIn+m_overFadeOut ) + { + FlushOver(); + return; + } +} + + + +// Sets the soft movement of the camera. + +void CCamera::FixCamera() +{ + m_initDelay = 0.0f; + m_actualEye = m_finalEye = m_scriptEye; + m_actualLookat = m_finalLookat = m_scriptLookat; + SetViewTime(m_scriptEye, m_scriptLookat, 0.0f); +} + +// Specifies the location and direction of view to the 3D engine. + +void CCamera::SetViewTime(const D3DVECTOR &vEyePt, + const D3DVECTOR &vLookatPt, + float rTime) +{ + D3DVECTOR vUpVec, eye, lookat; + float prog, dist, h; + + if ( m_type == CAMERA_INFO ) + { + eye = vEyePt; + lookat = vLookatPt; + } + else + { + if ( m_initDelay > 0.0f ) + { + m_initDelay -= rTime; + if ( m_initDelay < 0.0f ) m_initDelay = 0.0f; + rTime /= 1.0f+m_initDelay; + } + + eye = vEyePt; + lookat = vLookatPt; + if ( !IsCollision(eye, lookat) ) + { + m_finalEye = eye; + m_finalLookat = lookat; + } + + dist = Length(m_finalEye, m_actualEye); + if ( m_smooth == CS_NONE ) prog = dist; + if ( m_smooth == CS_NORM ) prog = powf(dist, 1.5f)*rTime*0.5f; + if ( m_smooth == CS_HARD ) prog = powf(dist, 1.0f)*rTime*4.0f; + if ( m_smooth == CS_SPEC ) prog = powf(dist, 1.0f)*rTime*0.05f; + if ( dist == 0.0f ) + { + m_actualEye = m_finalEye; + } + else + { + if ( prog > dist ) prog = dist; + m_actualEye = (m_finalEye-m_actualEye)/dist*prog + m_actualEye; + } + + dist = Length(m_finalLookat, m_actualLookat); + if ( m_smooth == CS_NONE ) prog = dist; + if ( m_smooth == CS_NORM ) prog = powf(dist, 1.5f)*rTime*2.0f; + if ( m_smooth == CS_HARD ) prog = powf(dist, 1.0f)*rTime*4.0f; + if ( m_smooth == CS_SPEC ) prog = powf(dist, 1.0f)*rTime*4.0f; + if ( dist == 0.0f ) + { + m_actualLookat = m_finalLookat; + } + else + { + if ( prog > dist ) prog = dist; + m_actualLookat = (m_finalLookat-m_actualLookat)/dist*prog + m_actualLookat; + } + + eye = m_effectOffset+m_actualEye; + m_water->AdjustEye(eye); + + h = m_terrain->RetFloorLevel(eye); + if ( eye.y < h+4.0f ) + { + eye.y = h+4.0f; + } + + lookat = m_effectOffset+m_actualLookat; + } + + vUpVec = D3DVECTOR(0.0f, 1.0f, 0.0f); + SetViewParams(eye, lookat, vUpVec); +} + + +// Avoid the obstacles. + +BOOL CCamera::IsCollision(D3DVECTOR &eye, D3DVECTOR lookat) +{ + if ( m_type == CAMERA_BACK ) return IsCollisionBack(eye, lookat); + if ( m_type == CAMERA_FIX ) return IsCollisionFix(eye, lookat); + if ( m_type == CAMERA_PLANE ) return IsCollisionFix(eye, lookat); + return FALSE; +} + +// Avoid the obstacles. + +BOOL CCamera::IsCollisionBack(D3DVECTOR &eye, D3DVECTOR lookat) +{ +#if 0 + CObject *pObj; + D3DVECTOR oPos, min, max, proj; + ObjectType oType, iType; + float oRadius, dpp, dpl, del, dist, len, prox; + int i; + + if ( m_cameraObj == 0 ) + { + iType = OBJECT_NULL; + } + else + { + iType = m_cameraObj->RetType(); + } + + min.x = Min(eye.x, lookat.x); + min.y = Min(eye.y, lookat.y); + min.z = Min(eye.z, lookat.z); + + max.x = Max(eye.x, lookat.x); + max.y = Max(eye.y, lookat.y); + max.z = Max(eye.z, lookat.z); + + prox = 8.0f; // maximum proximity of the vehicle + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj == m_cameraObj ) continue; + + oType = pObj->RetType(); + if ( oType == OBJECT_TOTO || + oType == OBJECT_FIX || + oType == OBJECT_FRET || + oType == OBJECT_STONE || + oType == OBJECT_URANIUM || + oType == OBJECT_METAL || + oType == OBJECT_POWER || + oType == OBJECT_ATOMIC || + oType == OBJECT_BULLET || + oType == OBJECT_BBOX || + oType == OBJECT_TNT || + oType == OBJECT_BOMB || + oType == OBJECT_WAYPOINTb || + oType == OBJECT_WAYPOINTr || + oType == OBJECT_WAYPOINTg || + oType == OBJECT_WAYPOINTy || + oType == OBJECT_WAYPOINTv || + oType == OBJECT_FLAGb || + oType == OBJECT_FLAGr || + oType == OBJECT_FLAGg || + oType == OBJECT_FLAGy || + oType == OBJECT_FLAGv || + oType == OBJECT_ANT || + oType == OBJECT_SPIDER || + oType == OBJECT_BEE || + oType == OBJECT_WORM ) continue; + + pObj->GetGlobalSphere(oPos, oRadius); + if ( oRadius <= 0.0f ) continue; + + if ( oPos.x+oRadius < min.x || + oPos.y+oRadius < min.y || + oPos.z+oRadius < min.z || + oPos.x-oRadius > max.x || + oPos.y-oRadius > max.y || + oPos.z-oRadius > max.z ) continue; + + if ( iType == OBJECT_FACTORY ) + { + dpl = Length(oPos, lookat); + if ( dpl < oRadius ) continue; + } + + proj = Projection(eye, lookat, oPos); + dpp = Length(proj, oPos); + if ( dpp > oRadius ) continue; + + del = Length(eye, lookat); + len = Length(eye, proj); + if ( len > del ) continue; + + dist = sqrtf(oRadius*oRadius + dpp*dpp)-3.0f; + if ( dist < 0.0f ) dist = 0.0f; + proj = (lookat-eye)*dist/del + proj; + len = Length(eye, proj); + + if ( len < del-prox ) + { + eye = proj; + eye.y += len/5.0f; + return FALSE; + } + else + { + eye = (eye-lookat)*prox/del + lookat; + eye.y += (del-prox)/5.0f; + return FALSE; + } + } + return FALSE; +#else + CObject *pObj; + D3DVECTOR oPos, min, max, proj; + ObjectType oType, iType; + float oRadius, dpp, del, len, angle; + int i; + + if ( m_cameraObj == 0 ) + { + iType = OBJECT_NULL; + } + else + { + iType = m_cameraObj->RetType(); + } + + min.x = Min(m_actualEye.x, m_actualLookat.x); + min.y = Min(m_actualEye.y, m_actualLookat.y); + min.z = Min(m_actualEye.z, m_actualLookat.z); + + max.x = Max(m_actualEye.x, m_actualLookat.x); + max.y = Max(m_actualEye.y, m_actualLookat.y); + max.z = Max(m_actualEye.z, m_actualLookat.z); + + m_bTransparency = FALSE; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj->RetTruck() ) continue; // battery or cargo? + + SetTransparency(pObj, 0.0f); // opaque object + + if ( pObj == m_cameraObj ) continue; + + if ( iType == OBJECT_BASE || // building? + iType == OBJECT_DERRICK || + iType == OBJECT_FACTORY || + iType == OBJECT_STATION || + iType == OBJECT_CONVERT || + iType == OBJECT_REPAIR || + iType == OBJECT_DESTROYER|| + iType == OBJECT_TOWER || + iType == OBJECT_RESEARCH || + iType == OBJECT_RADAR || + iType == OBJECT_ENERGY || + iType == OBJECT_LABO || + iType == OBJECT_NUCLEAR || + iType == OBJECT_PARA || + iType == OBJECT_SAFE || + iType == OBJECT_HUSTON ) continue; + + oType = pObj->RetType(); + if ( oType == OBJECT_HUMAN || + oType == OBJECT_TECH || + oType == OBJECT_TOTO || + oType == OBJECT_FIX || + oType == OBJECT_FRET || + oType == OBJECT_ANT || + oType == OBJECT_SPIDER || + oType == OBJECT_BEE || + oType == OBJECT_WORM ) continue; + + pObj->GetGlobalSphere(oPos, oRadius); + if ( oRadius <= 2.0f ) continue; // ignores small objects + + if ( oPos.x+oRadius < min.x || + oPos.y+oRadius < min.y || + oPos.z+oRadius < min.z || + oPos.x-oRadius > max.x || + oPos.y-oRadius > max.y || + oPos.z-oRadius > max.z ) continue; + + proj = Projection(m_actualEye, m_actualLookat, oPos); + dpp = Length(proj, oPos); + if ( dpp > oRadius ) continue; + + if ( oType == OBJECT_FACTORY ) + { + angle = RotateAngle(m_actualEye.x-oPos.x, oPos.z-m_actualEye.z); // CW ! + angle = Direction(angle, pObj->RetAngleY(0)); + if ( Abs(angle) < 30.0f*PI/180.0f ) continue; // in the gate? + } + + del = Length(m_actualEye, m_actualLookat); + if ( oType == OBJECT_FACTORY ) + { + del += oRadius; + } + + len = Length(m_actualEye, proj); + if ( len > del ) continue; + + SetTransparency(pObj, 1.0f); // transparent object + m_bTransparency = TRUE; + } + return FALSE; +#endif +} + +// Avoid the obstacles. + +BOOL CCamera::IsCollisionFix(D3DVECTOR &eye, D3DVECTOR lookat) +{ + CObject *pObj; + D3DVECTOR oPos, proj; + ObjectType type; + float oRadius, dist; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj == m_cameraObj ) continue; + + type = pObj->RetType(); + if ( type == OBJECT_TOTO || + type == OBJECT_FRET || + type == OBJECT_STONE || + type == OBJECT_URANIUM || + type == OBJECT_METAL || + type == OBJECT_POWER || + type == OBJECT_ATOMIC || + type == OBJECT_BULLET || + type == OBJECT_BBOX || + type == OBJECT_KEYa || + type == OBJECT_KEYb || + type == OBJECT_KEYc || + type == OBJECT_KEYd || + type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_BEE || + type == OBJECT_WORM ) continue; + + pObj->GetGlobalSphere(oPos, oRadius); + if ( oRadius == 0.0f ) continue; + + dist = Length(eye, oPos); + if ( dist < oRadius ) + { + dist = Length(eye, lookat); + proj = Projection(eye, lookat, oPos); + eye = (lookat-eye)*oRadius/dist + proj; + return FALSE; + } + } + return FALSE; +} + + +// Management of an event. + +BOOL CCamera::EventProcess(const Event &event) +{ + switch( event.event ) + { + case EVENT_FRAME: + EventFrame(event); + break; + +#if 0 + case EVENT_RBUTTONDOWN: + m_bRightDown = TRUE; + m_rightPosInit = event.pos; + m_rightPosCenter = FPOINT(0.5f, 0.5f); + m_engine->MoveMousePos(m_rightPosCenter); +//? m_engine->SetMouseHide(TRUE); // cache la souris + break; + + case EVENT_RBUTTONUP: + m_bRightDown = FALSE; + m_engine->MoveMousePos(m_rightPosInit); +//? m_engine->SetMouseHide(FALSE); // remontre la souris + m_addDirectionH = 0.0f; + m_addDirectionV = -PI*0.05f; + break; +#endif + + case EVENT_MOUSEMOVE: + EventMouseMove(event); + break; + + case EVENT_KEYDOWN: + if ( event.param == VK_WHEELUP ) EventMouseWheel(+1); + if ( event.param == VK_WHEELDOWN ) EventMouseWheel(-1); + break; + } + return TRUE; +} + +// Changed the camera according to the mouse moved. + +BOOL CCamera::EventMouseMove(const Event &event) +{ + m_mousePos = event.pos; + return TRUE; +} + +// Mouse wheel operated. + +void CCamera::EventMouseWheel(int dir) +{ + if ( m_type == CAMERA_BACK ) + { + if ( dir > 0 ) + { + m_backDist -= 8.0f; + if ( m_backDist < m_backMin ) m_backDist = m_backMin; + } + if ( dir < 0 ) + { + m_backDist += 8.0f; + if ( m_backDist > 200.0f ) m_backDist = 200.0f; + } + } + + if ( m_type == CAMERA_FIX || + m_type == CAMERA_PLANE ) + { + if ( dir > 0 ) + { + m_fixDist -= 8.0f; + if ( m_fixDist < 10.0f ) m_fixDist = 10.0f; + } + if ( dir < 0 ) + { + m_fixDist += 8.0f; + if ( m_fixDist > 200.0f ) m_fixDist = 200.0f; + } + } + + if ( m_type == CAMERA_VISIT ) + { + if ( dir > 0 ) + { + m_visitDist -= 8.0f; + if ( m_visitDist < 20.0f ) m_visitDist = 20.0f; + } + if ( dir < 0 ) + { + m_visitDist += 8.0f; + if ( m_visitDist > 200.0f ) m_visitDist = 200.0f; + } + } +} + +// Changed the camera according to the time elapsed. + +BOOL CCamera::EventFrame(const Event &event) +{ + EffectFrame(event); + OverFrame(event); + + if ( m_type == CAMERA_FREE ) + { + return EventFrameFree(event); + } + if ( m_type == CAMERA_EDIT ) + { + return EventFrameEdit(event); + } + if ( m_type == CAMERA_DIALOG ) + { + return EventFrameDialog(event); + } + if ( m_type == CAMERA_BACK ) + { + return EventFrameBack(event); + } + if ( m_type == CAMERA_FIX || + m_type == CAMERA_PLANE ) + { + return EventFrameFix(event); + } + if ( m_type == CAMERA_EXPLO ) + { + return EventFrameExplo(event); + } + if ( m_type == CAMERA_ONBOARD ) + { + return EventFrameOnBoard(event); + } + if ( m_type == CAMERA_SCRIPT ) + { + return EventFrameScript(event); + } + if ( m_type == CAMERA_INFO ) + { + return EventFrameInfo(event); + } + if ( m_type == CAMERA_VISIT ) + { + return EventFrameVisit(event); + } + + return TRUE; +} + + +// Returns the default sprite to use for the mouse. + +D3DMouse CCamera::RetMouseDef(FPOINT pos) +{ + D3DMouse type; + + type = D3DMOUSENORM; + m_mousePos = pos; + + if ( m_type == CAMERA_INFO ) return type; + + if ( m_bRightDown ) // the right button pressed? + { + m_rightPosMove.x = pos.x - m_rightPosCenter.x; + m_rightPosMove.y = pos.y - m_rightPosCenter.y; + type = D3DMOUSEMOVE; + } + else + { + if ( !m_bCameraScroll ) return type; + + m_mouseDirH = 0.0f; + m_mouseDirV = 0.0f; + + if ( pos.x < m_mouseMarging ) + { + m_mouseDirH = pos.x/m_mouseMarging - 1.0f; + } + + if ( pos.x > 1.0f-m_mouseMarging ) + { + m_mouseDirH = 1.0f - (1.0f-pos.x)/m_mouseMarging; + } + + if ( pos.y < m_mouseMarging ) + { + m_mouseDirV = pos.y/m_mouseMarging - 1.0f; + } + + if ( pos.y > 1.0f-m_mouseMarging ) + { + m_mouseDirV = 1.0f - (1.0f-pos.y)/m_mouseMarging; + } + + if ( m_type == CAMERA_FREE || + m_type == CAMERA_EDIT || + m_type == CAMERA_BACK || + m_type == CAMERA_FIX || + m_type == CAMERA_PLANE || + m_type == CAMERA_EXPLO ) + { + if ( m_mouseDirH > 0.0f ) + { + type = D3DMOUSESCROLLR; + } + if ( m_mouseDirH < 0.0f ) + { + type = D3DMOUSESCROLLL; + } + } + + if ( m_type == CAMERA_FREE || + m_type == CAMERA_EDIT ) + { + if ( m_mouseDirV > 0.0f ) + { + type = D3DMOUSESCROLLU; + } + if ( m_mouseDirV < 0.0f ) + { + type = D3DMOUSESCROLLD; + } + } + + if ( m_bCameraInvertX ) + { + m_mouseDirH = -m_mouseDirH; + } + } + + return type; +} + + + +// Moves the point of view. + +BOOL CCamera::EventFrameFree(const Event &event) +{ + D3DVECTOR pos, vLookatPt; + float factor; + + factor = m_heightEye*0.5f+30.0f; + + if ( m_mouseDirH != 0.0f ) + { + m_directionH -= m_mouseDirH*event.rTime*0.7f*m_speed; + } + if ( m_mouseDirV != 0.0f ) + { + m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, m_mouseDirV*event.rTime*factor*m_speed); + } + + // Up/Down. + m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, event.axeY*event.rTime*factor*m_speed); + + // Left/Right. + if ( event.keyState & KS_CONTROL ) + { + if ( event.axeX < 0.0f ) + { + m_eyePt = LookatPoint(m_eyePt, m_directionH+PI/2.0f, m_directionV, -event.axeX*event.rTime*factor*m_speed); + } + if ( event.axeX > 0.0f ) + { + m_eyePt = LookatPoint(m_eyePt, m_directionH-PI/2.0f, m_directionV, event.axeX*event.rTime*factor*m_speed); + } + } + else + { + m_directionH -= event.axeX*event.rTime*0.7f*m_speed; + } + + // PageUp/PageDown. + if ( event.keyState & KS_NUMMINUS ) + { + if ( m_heightEye < 500.0f ) + { + m_heightEye += event.rTime*factor*m_speed; + } + } + if ( event.keyState & KS_NUMPLUS ) + { + if ( m_heightEye > -2.0f ) + { + m_heightEye -= event.rTime*factor*m_speed; + } + } + + m_terrain->ValidPosition(m_eyePt, 10.0f); + + if ( m_terrain->MoveOnFloor(m_eyePt, TRUE) ) + { + m_eyePt.y += m_heightEye; + + pos = m_eyePt; + if ( m_terrain->MoveOnFloor(pos, TRUE) ) + { + pos.y -= 2.0f; + if ( m_eyePt.y < pos.y ) + { + m_eyePt.y = pos.y; + } + } + + } + + vLookatPt = LookatPoint( m_eyePt, m_directionH, m_directionV, 50.0f ); + + if ( m_terrain->MoveOnFloor(vLookatPt, TRUE) ) + { + vLookatPt.y += m_heightLookat; + } + + SetViewTime(m_eyePt, vLookatPt, event.rTime); + + return TRUE; +} + +// Moves the point of view. + +BOOL CCamera::EventFrameEdit(const Event &event) +{ + D3DVECTOR pos, vLookatPt; + float factor; + + factor = m_editHeight*0.5f+30.0f; + + if ( m_mouseDirH != 0.0f ) + { + m_directionH -= m_mouseDirH*event.rTime*0.7f*m_speed; + } + if ( m_mouseDirV != 0.0f ) + { + m_eyePt = LookatPoint(m_eyePt, m_directionH, m_directionV, m_mouseDirV*event.rTime*factor*m_speed); + } + + if ( m_bCameraScroll ) + { + // Left/Right. + m_fixDirectionH += m_mouseDirH*event.rTime*1.0f*m_speed; + m_fixDirectionH = NormAngle(m_fixDirectionH); + + // Up/Down. +//? m_fixDirectionV -= m_mouseDirV*event.rTime*0.5f*m_speed; +//? if ( m_fixDirectionV < -PI*0.40f ) m_fixDirectionV = -PI*0.40f; +//? if ( m_fixDirectionV > PI*0.20f ) m_fixDirectionV = PI*0.20f; + } + + m_terrain->ValidPosition(m_eyePt, 10.0f); + + if ( m_terrain->MoveOnFloor(m_eyePt, FALSE) ) + { + m_eyePt.y += m_editHeight; + + pos = m_eyePt; + if ( m_terrain->MoveOnFloor(pos, FALSE) ) + { + pos.y += 2.0f; + if ( m_eyePt.y < pos.y ) + { + m_eyePt.y = pos.y; + } + } + + } + + vLookatPt = LookatPoint( m_eyePt, m_directionH, m_directionV, 50.0f ); + + if ( m_terrain->MoveOnFloor(vLookatPt, TRUE) ) + { + vLookatPt.y += m_heightLookat; + } + + SetViewTime(m_eyePt, vLookatPt, event.rTime); + + return TRUE; +} + +// Moves the point of view. + +BOOL CCamera::EventFrameDialog(const Event &event) +{ + return TRUE; +} + +// Moves the point of view. + +BOOL CCamera::EventFrameBack(const Event &event) +{ + CPhysics* physics; + ObjectType type; + D3DVECTOR pos, vLookatPt; + FPOINT mouse; + float centeringH, centeringV, centeringD, h, v, d, floor; + + if ( m_cameraObj == 0 ) + { + type = OBJECT_NULL; + } + else + { + type = m_cameraObj->RetType(); + } + + // +/-. + if ( event.keyState & KS_NUMPLUS ) + { + m_backDist -= event.rTime*30.0f*m_speed; + if ( m_backDist < m_backMin ) m_backDist = m_backMin; + } + if ( event.keyState & KS_NUMMINUS ) + { + m_backDist += event.rTime*30.0f*m_speed; + if ( m_backDist > 200.0f ) m_backDist = 200.0f; + } + + m_motorTurn = 0.0f; + + if ( m_bRightDown ) + { + m_addDirectionH = m_rightPosMove.x*6.0f; + m_addDirectionV = -m_rightPosMove.y*2.0f; + } + else + { + if ( m_bCameraScroll ) + { +#if 1 + // Left/Right. + m_addDirectionH += m_mouseDirH*event.rTime*1.0f*m_speed; + m_addDirectionH = NormAngle(m_addDirectionH); + + // Up/Down. +//? m_backDist -= m_mouseDirV*event.rTime*30.0f*m_speed; +//? if ( m_backDist < 10.0f ) m_backDist = 10.0f; +//? if ( m_backDist > 200.0f ) m_backDist = 200.0f; +#else + if ( m_mousePos.y >= 0.18f && m_mousePos.y <= 0.93f ) + { +//? m_addDirectionH = -(m_mousePos.x-0.5f)*4.0f; + m_addDirectionV = (m_mousePos.y-0.5f)*2.0f; +//? if ( m_bCameraInvertX ) m_addDirectionH = -m_addDirectionH; + if ( m_bCameraInvertY ) m_addDirectionV = -m_addDirectionV; + + if ( m_mousePos.x < 0.5f ) m_motorTurn = -1.0f; + if ( m_mousePos.x > 0.5f ) m_motorTurn = 1.0f; + + mouse = m_mousePos; + mouse.x = 0.5f; + m_engine->MoveMousePos(mouse); + } + else + { + m_addDirectionH = 0.0f; + m_addDirectionV = 0.0f; + } +#endif + } + } + + if ( m_mouseDirH != 0 || m_mouseDirV != 0 ) + { + AbortCentering(); // special stops framing + } + + // Increase the special framework. + centeringH = 0.0f; + centeringV = 0.0f; + centeringD = 0.0f; + + if ( m_centeringPhase == CP_START ) + { + m_centeringProgress += event.rTime/m_centeringTime; + if ( m_centeringProgress > 1.0f ) m_centeringProgress = 1.0f; + centeringH = m_centeringProgress; + centeringV = m_centeringProgress; + centeringD = m_centeringProgress; + if ( m_centeringProgress >= 1.0f ) + { + m_centeringPhase = CP_WAIT; + } + } + + if ( m_centeringPhase == CP_WAIT ) + { + centeringH = 1.0f; + centeringV = 1.0f; + centeringD = 1.0f; + } + + if ( m_centeringPhase == CP_STOP ) + { + m_centeringProgress += event.rTime/m_centeringTime; + if ( m_centeringProgress > 1.0f ) m_centeringProgress = 1.0f; + centeringH = 1.0f-m_centeringProgress; + centeringV = 1.0f-m_centeringProgress; + centeringD = 1.0f-m_centeringProgress; + if ( m_centeringProgress >= 1.0f ) + { + m_centeringPhase = CP_NULL; + } + } + + if ( m_centeringAngleH == 99.9f ) centeringH = 0.0f; + if ( m_centeringAngleV == 99.9f ) centeringV = 0.0f; + if ( m_centeringDist == 0.0f ) centeringD = 0.0f; + + if ( m_cameraObj != 0 ) + { + vLookatPt = m_cameraObj->RetPosition(0); + if ( type == OBJECT_BASE ) vLookatPt.y += 40.0f; + else if ( type == OBJECT_HUMAN ) vLookatPt.y += 1.0f; + else if ( type == OBJECT_TECH ) vLookatPt.y += 1.0f; + else vLookatPt.y += 4.0f; + + h = -m_cameraObj->RetAngleY(0); // angle vehicle / building + + if ( type == OBJECT_DERRICK || + type == OBJECT_FACTORY || + type == OBJECT_REPAIR || + type == OBJECT_DESTROYER|| + type == OBJECT_STATION || + type == OBJECT_CONVERT || + type == OBJECT_TOWER || + type == OBJECT_RESEARCH || + type == OBJECT_RADAR || + type == OBJECT_INFO || + type == OBJECT_ENERGY || + type == OBJECT_LABO || + type == OBJECT_NUCLEAR || + type == OBJECT_PARA || + type == OBJECT_SAFE || + type == OBJECT_HUSTON || + type == OBJECT_START || + type == OBJECT_END ) // building? + { + h += PI*0.20f; // nearly face + } + else // vehicle? + { + h += PI; // back + } + h = NormAngle(h)+m_remotePan; + v = 0.0f; //? + + h += m_centeringCurrentH; + h += m_addDirectionH*(1.0f-centeringH); + h = NormAngle(h); + + if ( type == OBJECT_MOBILEdr ) // designer? + { + v -= 0.3f; // Camera top + } + + v += m_centeringCurrentV; + v += m_addDirectionV*(1.0f-centeringV); + + d = m_backDist; + d += m_centeringDist*centeringD; + + m_centeringCurrentH = m_centeringAngleH*centeringH; + m_centeringCurrentV = m_centeringAngleV*centeringV; + + m_eyePt = RotateView(vLookatPt, h, v, d); + + physics = m_cameraObj->RetPhysics(); + if ( physics != 0 && physics->RetLand() ) // ground? + { + pos = vLookatPt+(vLookatPt-m_eyePt); + floor = m_terrain->RetFloorHeight(pos)-4.0f; + if ( floor > 0.0f ) + { + m_eyePt.y += floor; // shows the descent in front + } + } + + m_eyePt = ExcludeTerrain(m_eyePt, vLookatPt, h, v); + m_eyePt = ExcludeObject(m_eyePt, vLookatPt, h, v); + + SetViewTime(m_eyePt, vLookatPt, event.rTime); + + m_directionH = h+PI/2.0f; + m_directionV = v; + } + + return TRUE; +} + +// Moves the point of view. + +BOOL CCamera::EventFrameFix(const Event &event) +{ + D3DVECTOR pos, vLookatPt; + float h, v, d; + + // +/-. + if ( event.keyState & KS_NUMPLUS ) + { + m_fixDist -= event.rTime*30.0f*m_speed; + if ( m_fixDist < 10.0f ) m_fixDist = 10.0f; + } + if ( event.keyState & KS_NUMMINUS ) + { + m_fixDist += event.rTime*30.0f*m_speed; + if ( m_fixDist > 200.0f ) m_fixDist = 200.0f; + } + + if ( m_bCameraScroll ) + { + // Left/Right. + m_fixDirectionH += m_mouseDirH*event.rTime*1.0f*m_speed; + m_fixDirectionH = NormAngle(m_fixDirectionH); + + // Up/Down. +//? m_fixDist -= m_mouseDirV*event.rTime*30.0f*m_speed; +//? if ( m_fixDist < 10.0f ) m_fixDist = 10.0f; +//? if ( m_fixDist > 200.0f ) m_fixDist = 200.0f; + } + + if ( m_mouseDirH != 0 || m_mouseDirV != 0 ) + { + AbortCentering(); // special stops framing + } + + if ( m_cameraObj != 0 ) + { + vLookatPt = m_cameraObj->RetPosition(0); + + h = m_fixDirectionH+m_remotePan; + v = m_fixDirectionV; + + d = m_fixDist; +//- if ( m_type == CAMERA_PLANE ) d += 20.0f; + m_eyePt = RotateView(vLookatPt, h, v, d); +//- if ( m_type == CAMERA_PLANE ) m_eyePt.y += 50.0f; + if ( m_type == CAMERA_PLANE ) m_eyePt.y += m_fixDist/2.0f; + m_eyePt = ExcludeTerrain(m_eyePt, vLookatPt, h, v); + m_eyePt = ExcludeObject(m_eyePt, vLookatPt, h, v); + + SetViewTime(m_eyePt, vLookatPt, event.rTime); + + m_directionH = h+PI/2.0f; + m_directionV = v; + } + + return TRUE; +} + +// Moves the point of view. + +BOOL CCamera::EventFrameExplo(const Event &event) +{ + D3DVECTOR pos, vLookatPt; + float factor; + + factor = m_heightEye*0.5f+30.0f; + + if ( m_mouseDirH != 0.0f ) + { + m_directionH -= m_mouseDirH*event.rTime*0.7f*m_speed; + } + + m_terrain->ValidPosition(m_eyePt, 10.0f); + + if ( m_terrain->MoveOnFloor(m_eyePt, FALSE) ) + { + m_eyePt.y += m_heightEye; + + pos = m_eyePt; + if ( m_terrain->MoveOnFloor(pos, FALSE) ) + { + pos.y += 2.0f; + if ( m_eyePt.y < pos.y ) + { + m_eyePt.y = pos.y; + } + } + + } + + vLookatPt = LookatPoint( m_eyePt, m_directionH, m_directionV, 50.0f ); + + if ( m_terrain->MoveOnFloor(vLookatPt, TRUE) ) + { + vLookatPt.y += m_heightLookat; + } + + SetViewTime(m_eyePt, vLookatPt, event.rTime); + + return TRUE; +} + +// Moves the point of view. + +BOOL CCamera::EventFrameOnBoard(const Event &event) +{ + D3DVECTOR vLookatPt, vUpVec, eye, lookat, pos; + + if ( m_cameraObj != 0 ) + { + m_cameraObj->SetViewFromHere(m_eyePt, m_directionH, m_directionV, + vLookatPt, vUpVec, m_type); + eye = m_effectOffset*0.3f+m_eyePt; + lookat = m_effectOffset*0.3f+vLookatPt; + + SetViewParams(eye, lookat, vUpVec); + m_actualEye = eye; + m_actualLookat = lookat; + } + return TRUE; +} + +// Moves the point of view. + +BOOL CCamera::EventFrameInfo(const Event &event) +{ + SetViewTime(D3DVECTOR(0.0f, 0.0f, 0.0f), + D3DVECTOR(0.0f, 0.0f, 1.0f), + event.rTime); + return TRUE; +} + +// Moves the point of view. + +BOOL CCamera::EventFrameVisit(const Event &event) +{ + D3DVECTOR eye; + float angleH, angleV; + + m_visitTime += event.rTime; + + // +/-. + if ( event.keyState & KS_NUMPLUS ) + { + m_visitDist -= event.rTime*50.0f*m_speed; + if ( m_visitDist < 20.0f ) m_visitDist = 20.0f; + } + if ( event.keyState & KS_NUMMINUS ) + { + m_visitDist += event.rTime*50.0f*m_speed; + if ( m_visitDist > 200.0f ) m_visitDist = 200.0f; + } + + // PageUp/Down. + if ( event.keyState & KS_PAGEUP ) + { + m_visitDirectionV -= event.rTime*1.0f*m_speed; + if ( m_visitDirectionV < -PI*0.40f ) m_visitDirectionV = -PI*0.40f; + } + if ( event.keyState & KS_PAGEDOWN ) + { + m_visitDirectionV += event.rTime*1.0f*m_speed; + if ( m_visitDirectionV > 0.0f ) m_visitDirectionV = 0.0f; + } + + if ( m_bCameraScroll ) + { + m_visitDist -= m_mouseDirV*event.rTime*30.0f*m_speed; + if ( m_visitDist < 20.0f ) m_visitDist = 20.0f; + if ( m_visitDist > 200.0f ) m_visitDist = 200.0f; + } + + angleH = (m_visitTime/10.0f)*(PI*2.0f); + angleV = m_visitDirectionV; + eye = RotateView(m_visitGoal, angleH, angleV, m_visitDist); + eye = ExcludeTerrain(eye, m_visitGoal, angleH, angleV); + eye = ExcludeObject(eye, m_visitGoal, angleH, angleV); + SetViewTime(eye, m_visitGoal, event.rTime); + + return TRUE; +} + +// Moves the point of view. + +BOOL CCamera::EventFrameScript(const Event &event) +{ + SetViewTime(m_scriptEye+m_effectOffset, + m_scriptLookat+m_effectOffset, event.rTime); + return TRUE; +} + +void CCamera::SetScriptEye(D3DVECTOR eye) +{ + m_scriptEye = eye; +} + +void CCamera::SetScriptLookat(D3DVECTOR lookat) +{ + m_scriptLookat = lookat; +} + + +// Specifies the location and direction of view. + +void CCamera::SetViewParams(const D3DVECTOR &eye, const D3DVECTOR &lookat, + const D3DVECTOR &up) +{ + BOOL bUnder; + + m_engine->SetViewParams(eye, lookat, up, m_eyeDistance); + + bUnder = (eye.y < m_water->RetLevel()); // Is it underwater? + if ( m_type == CAMERA_INFO ) bUnder = FALSE; + m_engine->SetRankView(bUnder?1:0); +} + + +// Adjusts the camera not to enter the field. + +D3DVECTOR CCamera::ExcludeTerrain(D3DVECTOR eye, D3DVECTOR lookat, + float &angleH, float &angleV) +{ + D3DVECTOR pos; + float dist; + + pos = eye; + if ( m_terrain->MoveOnFloor(pos) ) + { + dist = Length2d(lookat, pos); + pos.y += 2.0f+dist*0.1f; + if ( pos.y > eye.y ) + { + angleV = -RotateAngle(dist, pos.y-lookat.y); + eye = RotateView(lookat, angleH, angleV, dist); + } + } + return eye; +} + +// Adjusts the camera not to enter an object. + +D3DVECTOR CCamera::ExcludeObject(D3DVECTOR eye, D3DVECTOR lookat, + float &angleH, float &angleV) +{ + CObject* pObj; + D3DVECTOR oPos; + float oRad, dist; + int i, j; + +return eye; +//? + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + j = 0; + while ( pObj->GetCrashSphere(j++, oPos, oRad) ) + { + dist = Length(oPos, eye); + if ( dist < oRad+2.0f ) + { + eye.y = oPos.y+oRad+2.0f; + } + } + } + + return eye; +} + + diff --git a/src/graphics/common/camera.h b/src/graphics/common/camera.h new file mode 100644 index 0000000..f38db1a --- /dev/null +++ b/src/graphics/common/camera.h @@ -0,0 +1,271 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// camera.h + +#ifndef _CAMERA_H_ +#define _CAMERA_H_ + + +#include "d3dengine.h" +#include "struct.h" + + +class CInstanceManager; +class CD3DEngine; +class CTerrain; +class CWater; +class CObject; + + +enum CameraType +{ + CAMERA_NULL = 0, // camera undefined + CAMERA_FREE = 1, // camera free (never in principle) + CAMERA_EDIT = 2, // camera while editing a program + CAMERA_ONBOARD = 3, // camera on board a robot + CAMERA_BACK = 4, // camera behind a robot + CAMERA_FIX = 5, // static camera following robot + CAMERA_EXPLO = 6, // camera steady after explosion + CAMERA_SCRIPT = 7, // camera during a film script + CAMERA_INFO = 8, // camera for displaying information + CAMERA_VISIT = 9, // visit instead of an error + CAMERA_DIALOG = 10, // camera for dialogue + CAMERA_PLANE = 11, // static camera height +}; + +enum CameraSmooth +{ + CS_NONE = 0, // sharp + CS_NORM = 1, // normal + CS_HARD = 2, // hard + CS_SPEC = 3, // special +}; + +enum CenteringPhase +{ + CP_NULL = 0, + CP_START = 1, + CP_WAIT = 2, + CP_STOP = 3, +}; + +enum CameraEffect +{ + CE_NULL = 0, // no effect + CE_TERRAFORM = 1, // digging in + CE_CRASH = 2, // Vehicle driving is severely + CE_EXPLO = 3, // explosion + CE_SHOT = 4, // not mortal shot + CE_VIBRATION = 5, // vibration during construction + CE_PET = 6, // spleen reactor +}; + +enum OverEffect +{ + OE_NULL = 0, // no effect + OE_BLOOD = 1, // flash red + OE_FADEINw = 2, // white -> nothing + OE_FADEOUTw = 3, // nothing -> white + OE_FADEOUTb = 4, // nothing -> blue + OE_BLITZ = 5, // lightning +}; + + + +class CCamera +{ +public: + CCamera(CInstanceManager* iMan); + ~CCamera(); + + BOOL EventProcess(const Event &event); + + void Init(D3DVECTOR eye, D3DVECTOR lookat, float delay); + + void SetObject(CObject* object); + CObject* RetObject(); + + void SetType(CameraType type); + CameraType RetType(); + + void SetSmooth(CameraSmooth type); + CameraSmooth RetSmoth(); + + void SetDist(float dist); + float RetDist(); + + void SetFixDirection(float angle); + float RetFixDirection(); + + void SetRemotePan(float value); + float RetRemotePan(); + + void SetRemoteZoom(float value); + float RetRemoteZoom(); + + void StartVisit(D3DVECTOR goal, float dist); + void StopVisit(); + + void RetCamera(D3DVECTOR &eye, D3DVECTOR &lookat); + + BOOL StartCentering(CObject *object, float angleH, float angleV, float dist, float time); + BOOL StopCentering(CObject *object, float time); + void AbortCentering(); + + void FlushEffect(); + void StartEffect(CameraEffect effect, D3DVECTOR pos, float force); + + void FlushOver(); + void SetOverBaseColor(D3DCOLORVALUE color); + void StartOver(OverEffect effect, D3DVECTOR pos, float force); + + void FixCamera(); + void SetScriptEye(D3DVECTOR eye); + void SetScriptLookat(D3DVECTOR lookat); + + void SetEffect(BOOL bEnable); + void SetCameraScroll(BOOL bScroll); + void SetCameraInvertX(BOOL bInvert); + void SetCameraInvertY(BOOL bInvert); + + float RetMotorTurn(); + D3DMouse RetMouseDef(FPOINT pos); + +protected: + BOOL EventMouseMove(const Event &event); + void EventMouseWheel(int dir); + BOOL EventFrame(const Event &event); + BOOL EventFrameFree(const Event &event); + BOOL EventFrameEdit(const Event &event); + BOOL EventFrameDialog(const Event &event); + BOOL EventFrameBack(const Event &event); + BOOL EventFrameFix(const Event &event); + BOOL EventFrameExplo(const Event &event); + BOOL EventFrameOnBoard(const Event &event); + BOOL EventFrameInfo(const Event &event); + BOOL EventFrameVisit(const Event &event); + BOOL EventFrameScript(const Event &event); + + void SetViewTime(const D3DVECTOR &vEyePt, const D3DVECTOR &vLookatPt, float rTime); + BOOL IsCollision(D3DVECTOR &eye, D3DVECTOR lookat); + BOOL IsCollisionBack(D3DVECTOR &eye, D3DVECTOR lookat); + BOOL IsCollisionFix(D3DVECTOR &eye, D3DVECTOR lookat); + + D3DVECTOR ExcludeTerrain(D3DVECTOR eye, D3DVECTOR lookat, float &angleH, float &angleV); + D3DVECTOR ExcludeObject(D3DVECTOR eye, D3DVECTOR lookat, float &angleH, float &angleV); + + void SetViewParams(const D3DVECTOR &eye, const D3DVECTOR &lookat, const D3DVECTOR &up); + void EffectFrame(const Event &event); + void OverFrame(const Event &event); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CTerrain* m_terrain; + CWater* m_water; + + CameraType m_type; // the type of camera (CAMERA *) + CameraSmooth m_smooth; // type of smoothing + CObject* m_cameraObj; // object linked to the camera + + float m_eyeDistance; // distance between the eyes + float m_initDelay; // time of initial centering + + D3DVECTOR m_actualEye; // current eye + D3DVECTOR m_actualLookat; // aim current + D3DVECTOR m_finalEye; // final eye + D3DVECTOR m_finalLookat; // aim final + D3DVECTOR m_normEye; // normal eye + D3DVECTOR m_normLookat; // aim normal + float m_focus; + + BOOL m_bRightDown; + FPOINT m_rightPosInit; + FPOINT m_rightPosCenter; + FPOINT m_rightPosMove; + + D3DVECTOR m_eyePt; // CAMERA_FREE: eye + float m_directionH; // CAMERA_FREE: horizontal direction + float m_directionV; // CAMERA_FREE: vertical direction + float m_heightEye; // CAMERA_FREE: height above the ground + float m_heightLookat; // CAMERA_FREE: height above the ground + float m_speed; // CAMERA_FREE: speed of movement + + float m_backDist; // CAMERA_BACK: distance + float m_backMin; // CAMERA_BACK: distance minimal + float m_addDirectionH; // CAMERA_BACK: additional direction + float m_addDirectionV; // CAMERA_BACK: additional direction + BOOL m_bTransparency; + + float m_fixDist; // CAMERA_FIX: distance + float m_fixDirectionH; // CAMERA_FIX: direction + float m_fixDirectionV; // CAMERA_FIX: direction + + D3DVECTOR m_visitGoal; // CAMERA_VISIT: target position + float m_visitDist; // CAMERA_VISIT: distance + float m_visitTime; // CAMERA_VISIT: relative time + CameraType m_visitType; // CAMERA_VISIT: initial type + float m_visitDirectionH; // CAMERA_VISIT: direction + float m_visitDirectionV; // CAMERA_VISIT: direction + + float m_editHeight; // CAMERA_EDIT: height + + float m_remotePan; + float m_remoteZoom; + + FPOINT m_mousePos; + float m_mouseDirH; + float m_mouseDirV; + float m_mouseMarging; + + float m_motorTurn; + + CenteringPhase m_centeringPhase; + float m_centeringAngleH; + float m_centeringAngleV; + float m_centeringDist; + float m_centeringCurrentH; + float m_centeringCurrentV; + float m_centeringTime; + float m_centeringProgress; + + CameraEffect m_effectType; + D3DVECTOR m_effectPos; + float m_effectForce; + float m_effectProgress; + D3DVECTOR m_effectOffset; + + OverEffect m_overType; + float m_overForce; + float m_overTime; + D3DCOLORVALUE m_overColorBase; + D3DCOLORVALUE m_overColor; + int m_overMode; + float m_overFadeIn; + float m_overFadeOut; + + D3DVECTOR m_scriptEye; + D3DVECTOR m_scriptLookat; + + BOOL m_bEffect; // shocks if explosion? + BOOL m_bCameraScroll; // scroll in the edges? + BOOL m_bCameraInvertX; // X inversion in the edges? + BOOL m_bCameraInvertY; // Y inversion in the edges? +}; + + +#endif //_CAMERA_H_ diff --git a/src/graphics/common/cloud.cpp b/src/graphics/common/cloud.cpp new file mode 100644 index 0000000..8d6aeae --- /dev/null +++ b/src/graphics/common/cloud.cpp @@ -0,0 +1,332 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "d3dutil.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "terrain.h" +#include "object.h" +#include "cloud.h" + + + +#define DIMEXPAND 4 // extension of the dimensions + + + +// Constructor of clouds. + +CCloud::CCloud(CInstanceManager* iMan, CD3DEngine* engine) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_CLOUD, this); + + m_engine = engine; + m_terrain = 0; + + m_level = 0.0f; + m_wind = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_subdiv = 8; + m_filename[0] = 0; + m_bEnable = TRUE; +} + +// Destructor of clouds. + +CCloud::~CCloud() +{ +} + + +BOOL CCloud::EventProcess(const Event &event) +{ + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + return TRUE; +} + +// Makes the clouds evolve. + +BOOL CCloud::EventFrame(const Event &event) +{ + if ( m_engine->RetPause() ) return TRUE; + + m_time += event.rTime; + + if ( m_level == 0.0f ) return TRUE; + + if ( m_time-m_lastTest < 0.2f ) return TRUE; + m_lastTest = m_time; + + return TRUE; +} + + +// Adjusts the position to normal, to imitate the clouds +// at movement. + +void CCloud::AdjustLevel(D3DVECTOR &pos, D3DVECTOR &eye, float deep, + FPOINT &uv1, FPOINT &uv2) +{ + float dist, factor; + + uv1.x = (pos.x+20000.0f)/1280.0f; + uv1.y = (pos.z+20000.0f)/1280.0f; + uv1.x -= m_time*(m_wind.x/100.0f); + uv1.y -= m_time*(m_wind.z/100.0f); + + uv2.x = 0.0f; + uv2.y = 0.0f; + + dist = Length2d(pos, eye); + factor = powf(dist/deep, 2.0f); + pos.y -= m_level*factor*10.0f; +} + +inline DWORD F2DW( FLOAT f ) +{ + return *((DWORD*)&f); +} + +// Draw the clouds. + +void CCloud::Draw() +{ + LPDIRECT3DDEVICE7 device; + D3DVERTEX2* vertex; + D3DMATRIX* matView; + D3DMATERIAL7 material; + D3DMATRIX matrix; + D3DVECTOR n, pos, p, eye; + FPOINT uv1, uv2; + float iDeep, deep, size, fogStart, fogEnd; + int i, j, u; + + if ( !m_bEnable ) return; + if ( m_level == 0.0f ) return; + if ( m_lineUsed == 0 ) return; + + vertex = (D3DVERTEX2*)malloc(sizeof(D3DVERTEX2)*(m_brick+2)*2); + + iDeep = m_engine->RetDeepView(); + deep = (m_brick*m_size)/2.0f; + m_engine->SetDeepView(deep); + m_engine->SetFocus(m_engine->RetFocus()); + m_engine->UpdateMatProj(); // increases the depth of view + +//? fogStart = deep*0.10f; +//? fogEnd = deep*0.16f; + fogStart = deep*0.15f; + fogEnd = deep*0.24f; + + device = m_engine->RetD3DDevice(); + device->SetRenderState(D3DRENDERSTATE_AMBIENT, 0x00000000); + device->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE); + device->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); +//? device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE); + device->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE); + device->SetRenderState(D3DRENDERSTATE_FOGSTART, F2DW(fogStart)); + device->SetRenderState(D3DRENDERSTATE_FOGEND, F2DW(fogEnd)); + + matView = m_engine->RetMatView(); + device->SetTransform(D3DTRANSFORMSTATE_VIEW, matView); + + ZeroMemory( &material, sizeof(D3DMATERIAL7) ); + material.diffuse = m_diffuse; + material.ambient = m_ambient; + m_engine->SetMaterial(material); + + m_engine->SetTexture(m_filename, 0); + m_engine->SetTexture(m_filename, 1); + +//? m_engine->SetState(D3DSTATETTb|D3DSTATEDUALw|D3DSTATEWRAP); + m_engine->SetState(D3DSTATETTb|D3DSTATEFOG|D3DSTATEWRAP); +//? m_engine->SetState(D3DSTATEWRAP); + + D3DUtil_SetIdentityMatrix(matrix); + device->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); + + size = m_size/2.0f; + eye = m_engine->RetEyePt(); + n = D3DVECTOR(0.0f, -1.0f, 0.0f); + + // Draws all the lines. + for ( i=0 ; iDrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, u, NULL); + m_engine->AddStatisticTriangle(u-2); + } + + m_engine->SetDeepView(iDeep); + m_engine->SetFocus(m_engine->RetFocus()); + m_engine->UpdateMatProj(); // gives depth to initial + + free(vertex); +} + + +// Updates the positions, relative to the ground. + +BOOL CCloud::CreateLine(int x, int y, int len) +{ + float offset; + + m_line[m_lineUsed].x = x; + m_line[m_lineUsed].y = y; + m_line[m_lineUsed].len = len; + + offset = m_brick*m_size/2.0f - m_size/2.0f; + + m_line[m_lineUsed].px1 = m_size* m_line[m_lineUsed].x - offset; + m_line[m_lineUsed].px2 = m_size*(m_line[m_lineUsed].x+m_line[m_lineUsed].len) - offset; + m_line[m_lineUsed].pz = m_size* m_line[m_lineUsed].y - offset; + + m_lineUsed ++; + + return ( m_lineUsed < MAXCLOUDLINE ); +} + +// Creates all areas of cloud. + +BOOL CCloud::Create(const char *filename, + D3DCOLORVALUE diffuse, D3DCOLORVALUE ambient, + float level) +{ + int y; + + m_diffuse = diffuse; + m_ambient = ambient; + m_level = level; + m_time = 0.0f; + m_lastTest = 0.0f; + strcpy(m_filename, filename); + + if ( m_filename[0] != 0 ) + { + m_engine->LoadTexture(m_filename, 0); + m_engine->LoadTexture(m_filename, 1); + } + + if ( m_terrain == 0 ) + { + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + } + + m_wind = m_terrain->RetWind(); + + m_brick = m_terrain->RetBrick()*m_terrain->RetMosaic()*DIMEXPAND; + m_size = m_terrain->RetSize(); + + m_brick /= m_subdiv*DIMEXPAND; + m_size *= m_subdiv*DIMEXPAND; + + if ( m_level == 0.0f ) return TRUE; + + m_lineUsed = 0; + for ( y=0 ; y +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "light.h" + + + + + +// Initializes a progression. + +void ProgInit(LightProg &p, float value) +{ + p.starting = value; + p.ending = value; + p.current = value; + p.progress = 0.0f; + p.speed = 100.0f; +} + +// Makes evolve a progression. + +void ProgFrame(LightProg &p, float rTime) +{ + if ( p.speed < 100.0f ) + { + if ( p.progress < 1.0f ) + { + p.progress += p.speed*rTime; + if ( p.progress > 1.0f ) + { + p.progress = 1.0f; + } + } + + p.current = (p.ending-p.starting)*p.progress + p.starting; + } + else + { + p.current = p.ending; + } +} + +// Change the current value. + +void ProgSet(LightProg &p, float value) +{ + p.starting = p.current; + p.ending = value; + p.progress = 0.0f; +} + + + + + +// Object's constructor. + +CLight::CLight(CInstanceManager* iMan, CD3DEngine* engine) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_LIGHT, this); + + m_pD3DDevice = 0; + m_engine = engine; + + m_lightUsed = 0; + m_lightTable = (Light*)malloc(sizeof(Light)*D3DMAXLIGHT); + ZeroMemory(m_lightTable, sizeof(Light)*D3DMAXLIGHT); + + m_time = 0.0f; +} + +// Object's destructor. + +CLight::~CLight() +{ + free(m_lightTable); + m_iMan->DeleteInstance(CLASS_LIGHT, this); +} + + +void CLight::SetD3DDevice(LPDIRECT3DDEVICE7 device) +{ + m_pD3DDevice = device; +} + + +// Removes all the lights. + +void CLight::FlushLight() +{ + int i; + + for ( i=0 ; iLightEnable(i, FALSE); + } + m_lightUsed = 0; +} + + +// Creates a new light. Returns its rank or -1 on error. + +int CLight::CreateLight() +{ + int i; + + for ( i=0 ; i= D3DMAXLIGHT ) return FALSE; + + m_lightTable[lightRank].bUsed = FALSE; + m_pD3DDevice->LightEnable(lightRank, FALSE); + + m_lightUsed = 0; + for ( i=0 ; i= D3DMAXLIGHT ) return FALSE; + + m_lightTable[lightRank].light = light; + + ProgInit(m_lightTable[lightRank].colorRed, m_lightTable[lightRank].light.dcvDiffuse.r); + ProgInit(m_lightTable[lightRank].colorGreen, m_lightTable[lightRank].light.dcvDiffuse.g); + ProgInit(m_lightTable[lightRank].colorBlue, m_lightTable[lightRank].light.dcvDiffuse.b); + + return TRUE; +} + +// Gives the specifications of a light. + +BOOL CLight::GetLight(int lightRank, D3DLIGHT7 &light) +{ + if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; + + light = m_lightTable[lightRank].light; + return TRUE; +} + + +// Lights up or put out a light. + +BOOL CLight::LightEnable(int lightRank, BOOL bEnable) +{ + if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; + + m_lightTable[lightRank].bEnable = bEnable; + return TRUE; +} + + +// Specifies the type (TYPE *) items included in this light. +// This light does not light up so that this type of objects. + +BOOL CLight::SetLightIncluType(int lightRank, D3DTypeObj type) +{ + if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; + + m_lightTable[lightRank].incluType = type; + return TRUE; +} + +// Specifies the type (TYPE *) items excluded by this light. +// This light does not illuminate then ever these objects. + +BOOL CLight::SetLightExcluType(int lightRank, D3DTypeObj type) +{ + if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; + + m_lightTable[lightRank].excluType = type; + return TRUE; +} + + +// Management of the position of the light. + +BOOL CLight::SetLightPos(int lightRank, D3DVECTOR pos) +{ + if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; + + m_lightTable[lightRank].light.dvPosition = pos; + return TRUE; +} + +D3DVECTOR CLight::RetLightPos(int lightRank) +{ + if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return D3DVECTOR(0.0f, 0.0f, 0.0f); + + return m_lightTable[lightRank].light.dvPosition; +} + + +// Management direction of the light. + +BOOL CLight::SetLightDir(int lightRank, D3DVECTOR dir) +{ + if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; + + m_lightTable[lightRank].light.dvDirection = dir; + return TRUE; +} + +D3DVECTOR CLight::RetLightDir(int lightRank) +{ + if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return D3DVECTOR(0.0f, 0.0f, 0.0f); + + return m_lightTable[lightRank].light.dvDirection; +} + + +// Specifies the rate of change. + +BOOL CLight::SetLightIntensitySpeed(int lightRank, float speed) +{ + if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; + + m_lightTable[lightRank].intensity.speed = speed; + return TRUE; +} + +// Management of the intensity of light. + +BOOL CLight::SetLightIntensity(int lightRank, float value) +{ + if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; + + ProgSet(m_lightTable[lightRank].intensity, value); + return TRUE; +} + +float CLight::RetLightIntensity(int lightRank) +{ + if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return 0.0f; + + return m_lightTable[lightRank].intensity.current; +} + + +// Specifies the rate of change. + +BOOL CLight::SetLightColorSpeed(int lightRank, float speed) +{ + if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; + + m_lightTable[lightRank].colorRed.speed = speed; + m_lightTable[lightRank].colorGreen.speed = speed; + m_lightTable[lightRank].colorBlue.speed = speed; + return TRUE; +} + +// Color management for light. + +BOOL CLight::SetLightColor(int lightRank, D3DCOLORVALUE color) +{ + if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; + + ProgSet(m_lightTable[lightRank].colorRed, color.r); + ProgSet(m_lightTable[lightRank].colorGreen, color.g); + ProgSet(m_lightTable[lightRank].colorBlue, color.b); + return TRUE; +} + +D3DCOLORVALUE CLight::RetLightColor(int lightRank) +{ + D3DCOLORVALUE color; + + if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) + { + color.r = 0.5f; + color.g = 0.5f; + color.b = 0.5f; + color.a = 0.5f; + return color; + } + + color.r = m_lightTable[lightRank].colorRed.current; + color.g = m_lightTable[lightRank].colorGreen.current; + color.b = m_lightTable[lightRank].colorBlue.current; + return color; +} + + +// Adjusts the color of all lights. + +void CLight::AdaptLightColor(D3DCOLORVALUE color, float factor) +{ + D3DCOLORVALUE value; + int i; + + for ( i=0 ; iRetPause() ) return; + + m_time += rTime; + + for ( i=0 ; iRetEyePt()-m_engine->RetLookatPt(); + angle = RotateAngle(dir.x, dir.z); + angle += PI*0.5f*i; + m_lightTable[i].light.dvDirection.x = sinf(angle*2.0f); + m_lightTable[i].light.dvDirection.z = cosf(angle*2.0f); + } + } +} + + +// Updates all the lights. + +void CLight::LightUpdate() +{ + BOOL bEnable; + float value; + int i; + + for ( i=0 ; iSetLight(i, &m_lightTable[i].light); + m_pD3DDevice->LightEnable(i, bEnable); + } + else + { + m_lightTable[i].light.dcvDiffuse.r = 0.0f; + m_lightTable[i].light.dcvDiffuse.g = 0.0f; + m_lightTable[i].light.dcvDiffuse.b = 0.0f; + + m_pD3DDevice->LightEnable(i, bEnable); + } + } +} + +// Updates the lights for a given type. + +void CLight::LightUpdate(D3DTypeObj type) +{ + BOOL bEnable; + int i; + + for ( i=0 ; iLightEnable(i, bEnable); + } + + if ( m_lightTable[i].excluType != TYPENULL ) + { + bEnable = (m_lightTable[i].excluType != type); + m_pD3DDevice->LightEnable(i, bEnable); + } + } +} + + diff --git a/src/graphics/common/light.h b/src/graphics/common/light.h new file mode 100644 index 0000000..ae2bcfb --- /dev/null +++ b/src/graphics/common/light.h @@ -0,0 +1,113 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// light.h + +#ifndef _LIGHT_H_ +#define _LIGHT_H_ + + +#include "d3dengine.h" + + +class CInstanceManager; +class CD3DEngine; + + +#define D3DMAXLIGHT 100 + + +typedef struct +{ + float starting; + float ending; + float current; + float progress; + float speed; +} +LightProg; + + +typedef struct +{ + char bUsed; // TRUE -> light exists + char bEnable; // TRUE -> light turned on + + D3DTypeObj incluType; // type of all objects included + D3DTypeObj excluType; // type of all objects excluded + + D3DLIGHT7 light; // configuration of the light + + LightProg intensity; // intensity (0 .. 1) + LightProg colorRed; + LightProg colorGreen; + LightProg colorBlue; +} +Light; + + + +class CLight +{ +public: + CLight(CInstanceManager *iMan, CD3DEngine* engine); + virtual ~CLight(); + + void SetD3DDevice(LPDIRECT3DDEVICE7 device); + + void FlushLight(); + int CreateLight(); + BOOL DeleteLight(int lightRank); + BOOL SetLight(int lightRank, const D3DLIGHT7 &light); + BOOL GetLight(int lightRank, D3DLIGHT7 &light); + BOOL LightEnable(int lightRank, BOOL bEnable); + + BOOL SetLightIncluType(int lightRank, D3DTypeObj type); + BOOL SetLightExcluType(int lightRank, D3DTypeObj type); + + BOOL SetLightPos(int lightRank, D3DVECTOR pos); + D3DVECTOR RetLightPos(int lightRank); + + BOOL SetLightDir(int lightRank, D3DVECTOR dir); + D3DVECTOR RetLightDir(int lightRank); + + BOOL SetLightIntensitySpeed(int lightRank, float speed); + BOOL SetLightIntensity(int lightRank, float value); + float RetLightIntensity(int lightRank); + void AdaptLightColor(D3DCOLORVALUE color, float factor); + + BOOL SetLightColorSpeed(int lightRank, float speed); + BOOL SetLightColor(int lightRank, D3DCOLORVALUE color); + D3DCOLORVALUE RetLightColor(int lightRank); + + void FrameLight(float rTime); + void LightUpdate(); + void LightUpdate(D3DTypeObj type); + +protected: + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + LPDIRECT3DDEVICE7 m_pD3DDevice; + + float m_time; + int m_lightUsed; + Light* m_lightTable; +}; + + +#endif //_LIGHT_H_ diff --git a/src/graphics/common/mainmovie.cpp b/src/graphics/common/mainmovie.cpp new file mode 100644 index 0000000..8205d16 --- /dev/null +++ b/src/graphics/common/mainmovie.cpp @@ -0,0 +1,249 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// mainmovie.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "global.h" +#include "event.h" +#include "iman.h" +#include "math3d.h" +#include "camera.h" +#include "object.h" +#include "motion.h" +#include "motionhuman.h" +#include "interface.h" +#include "robotmain.h" +#include "sound.h" +#include "mainmovie.h" + + + + +// Constructor of the application card. + +CMainMovie::CMainMovie(CInstanceManager* iMan) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_SHORT, this); + + m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); + m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + + Flush(); +} + +// Destructor of the application card. + +CMainMovie::~CMainMovie() +{ +} + + +// Stops the current movie. + +void CMainMovie::Flush() +{ + m_type = MM_NONE; +} + + +// Start of a film. + +BOOL CMainMovie::Start(MainMovieType type, float time) +{ + D3DMATRIX* mat; + D3DVECTOR pos; + CObject* pObj; + CMotion* motion; + + m_type = type; + m_speed = 1.0f/time; + m_progress = 0.0f; + + if ( m_type == MM_SATCOMopen ) + { + pObj = m_main->SearchHuman(); + if ( pObj == 0 ) + { + m_type = MM_NONE; // it's over! + return TRUE; + } + + motion = pObj->RetMotion(); + if ( motion != 0 ) + { + motion->SetAction(MHS_SATCOM, 0.5f); // reads the SatCom + } + + m_camera->RetCamera(m_initialEye, m_initialLookat); + m_camera->SetType(CAMERA_SCRIPT); + m_camera->SetSmooth(CS_HARD); + m_camera->SetScriptEye(m_initialEye); + m_camera->SetScriptLookat(m_initialLookat); + m_camera->FixCamera(); + + mat = pObj->RetWorldMatrix(0); + m_finalLookat[0] = Transform(*mat, D3DVECTOR( 1.6f, 1.0f, 1.2f)); + m_finalEye[0] = Transform(*mat, D3DVECTOR(-1.5f, 5.0f, 3.0f)); + m_finalLookat[1] = Transform(*mat, D3DVECTOR( 1.6f, 1.0f, 1.2f)); + m_finalEye[1] = Transform(*mat, D3DVECTOR( 0.8f, 3.0f, 0.8f)); + } + + if ( m_type == MM_SATCOMclose ) + { + pObj = m_main->SearchHuman(); + if ( pObj != 0 ) + { + motion = pObj->RetMotion(); + if ( motion != 0 ) + { + motion->SetAction(-1); // finishes reading SatCom + } + } + + m_camera->SetType(CAMERA_BACK); + m_type = MM_NONE; // it's already over! + } + + return TRUE; +} + +// Stop a current movie. + +BOOL CMainMovie::Stop() +{ + CObject* pObj; + CMotion* motion; + + if ( m_type == MM_SATCOMopen ) + { + pObj = m_main->SearchHuman(); + if ( pObj != 0 ) + { + motion = pObj->RetMotion(); + if ( motion != 0 ) + { + motion->SetAction(-1); // finishes reading SatCom + } + } + } + + m_type = MM_NONE; + return TRUE; +} + +// Indicates whether a film is in progress. + +BOOL CMainMovie::IsExist() +{ + return (m_type != MM_NONE); +} + + +// Processing an event. + +BOOL CMainMovie::EventProcess(const Event &event) +{ + D3DVECTOR initialEye, initialLookat, finalEye, finalLookat, eye, lookat; + float progress; + + if ( m_type == MM_NONE ) return TRUE; + + m_progress += event.rTime*m_speed; + + if ( m_type == MM_SATCOMopen ) + { + if ( m_progress < 1.0f ) + { + progress = 1.0f-powf(1.0f-m_progress, 3.0f); + + if ( progress < 0.6f ) + { + progress = progress/0.6f; + initialEye = m_initialEye; + initialLookat = m_initialLookat; + finalEye = m_finalEye[0]; + finalLookat = m_finalLookat[0]; + } + else + { + progress = (progress-0.6f)/0.3f; + initialEye = m_finalEye[0]; + initialLookat = m_finalLookat[0]; + finalEye = m_finalEye[1]; + finalLookat = m_finalLookat[1]; + } + if ( progress > 1.0f ) progress = 1.0f; + + eye = (finalEye-initialEye)*progress+initialEye; + lookat = (finalLookat-initialLookat)*progress+initialLookat; + m_camera->SetScriptEye(eye); + m_camera->SetScriptLookat(lookat); +// m_camera->FixCamera(); + } + else + { + m_stopType = m_type; + Flush(); + return FALSE; + } + } + + if ( m_type == MM_SATCOMclose ) + { + if ( m_progress < 1.0f ) + { + } + else + { + m_stopType = m_type; + Flush(); + return FALSE; + } + } + + return TRUE; +} + + +// Returns the type of the current movie. + +MainMovieType CMainMovie::RetType() +{ + return m_type; +} + +// Returns the type of movie stop. + +MainMovieType CMainMovie::RetStopType() +{ + return m_stopType; +} + + diff --git a/src/graphics/common/mainmovie.h b/src/graphics/common/mainmovie.h new file mode 100644 index 0000000..f31b3a9 --- /dev/null +++ b/src/graphics/common/mainmovie.h @@ -0,0 +1,80 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// mainmovie.h + +#ifndef _MAINMOVIE_H_ +#define _MAINMOVIE_H_ + + +class CInstanceManager; +class CEvent; +class CD3DEngine; +class CInterface; +class CRobotMain; +class CCamera; +class CSound; +class CObject; + + + + +enum MainMovieType +{ + MM_NONE, + MM_SATCOMopen, + MM_SATCOMclose, +}; + + + +class CMainMovie +{ +public: + CMainMovie(CInstanceManager* iMan); + ~CMainMovie(); + + void Flush(); + BOOL Start(MainMovieType type, float time); + BOOL Stop(); + BOOL IsExist(); + BOOL EventProcess(const Event &event); + MainMovieType RetType(); + MainMovieType RetStopType(); + +protected: + +protected: + CInstanceManager* m_iMan; + CEvent* m_event; + CD3DEngine* m_engine; + CInterface* m_interface; + CRobotMain* m_main; + CCamera* m_camera; + CSound* m_sound; + + MainMovieType m_type; + MainMovieType m_stopType; + float m_speed; + float m_progress; + D3DVECTOR m_initialEye; + D3DVECTOR m_initialLookat; + D3DVECTOR m_finalEye[2]; + D3DVECTOR m_finalLookat[2]; +}; + + +#endif //_MAINMOVIE_H_ diff --git a/src/graphics/common/model.cpp b/src/graphics/common/model.cpp new file mode 100644 index 0000000..80ce6b5 --- /dev/null +++ b/src/graphics/common/model.cpp @@ -0,0 +1,3228 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// model.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "water.h" +#include "robotmain.h" +#include "interface.h" +#include "edit.h" +#include "button.h" +#include "cmdtoken.h" +#include "modfile.h" +#include "model.h" + + + +#define MAX_COLORS 9 + +static float table_color[MAX_COLORS*3] = +{ + 1.0f, 1.0f, 1.0f, // white + 1.0f, 0.0f, 0.0f, // red + 0.0f, 1.0f, 0.0f, // green + 0.0f, 0.6f, 1.0f, // blue + 1.0f, 1.0f, 0.0f, // yellow + 0.0f, 1.0f, 1.0f, // cyan + 1.0f, 0.0f, 1.0f, // magenta + 0.3f, 0.3f, 0.3f, // grey + 0.0f, 0.0f, 0.0f, // black +}; + + +#define MAX_STATES 10 + +static int table_state[MAX_STATES] = +{ + D3DSTATENORMAL, + D3DSTATEPART1, + D3DSTATEPART2, + D3DSTATEPART3, + D3DSTATEPART4, + D3DSTATE2FACE, // #5 + D3DSTATETTw, + D3DSTATETTb, + D3DSTATETTw|D3DSTATE2FACE, // #8 + D3DSTATETTb|D3DSTATE2FACE, // #9 +}; + + +#define MAX_NAMES 23 + + + + +// Object's constructor. + +CModel::CModel(CInstanceManager* iMan) +{ + m_iMan = iMan; + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); + + m_modFile = new CModFile(m_iMan); + m_triangleTable = m_modFile->RetTriangleList(); + + m_textureRank = 0; + strcpy(m_textureName, "lemt.tga"); + m_color = 0; + m_state = 0; + m_textureMode = 0; + m_textureRotate = 0; + m_bTextureMirrorX = FALSE; + m_bTextureMirrorY = FALSE; + m_texturePart = 0; + TexturePartUpdate(); + + m_bDisplayTransparent = FALSE; + m_bDisplayOnlySelection = FALSE; + InitView(); + + m_triangleSel1 = 0; + m_triangleSel2 = 0; + + m_mode = 1; + m_oper = 'P'; + + m_secondTexNum = 0; + m_secondSubdiv = 1; + m_secondOffsetU = 0; + m_secondOffsetV = 0; + + m_min = 0.0f; + m_max = 1000000.0f; +} + +// Object's destructor. + +CModel::~CModel() +{ + delete m_modFile; +} + + +// You must call this procedure before changing the model interactively. + +void CModel::StartUserAction() +{ + Event event; + FPOINT pos, dim; + CButton* pb; + + dim.x = 105.0f/640.0f; + dim.y = 18.0f/480.0f; + pos.x = 10.0f/640.0f; + pos.y = 450.0f/480.0f; + m_interface->CreateEdit(pos, dim, 0, EVENT_EDIT1); + + dim.x = 50.0f/640.0f; + pos.x = 125.0f/640.0f; + pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON1); + pb->SetState(STATE_SIMPLY); + pb->SetName("Load"); + pos.x = 185.0f/640.0f; + pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON2); + pb->SetState(STATE_SIMPLY); + pb->SetName("Script"); + pos.x = 245.0f/640.0f; + pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON3); + pb->SetState(STATE_SIMPLY); + pb->SetName("Read"); + pos.x = 305.0f/640.0f; + pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON4); + pb->SetState(STATE_SIMPLY); + pb->SetName("Add"); + pos.x = 365.0f/640.0f; + pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON5); + pb->SetState(STATE_SIMPLY); + pb->SetName("Write"); + + dim.x = 50.0f/640.0f; + dim.y = 18.0f/480.0f; + pos.x = 10.0f/640.0f; + pos.y = 425.0f/480.0f; + m_interface->CreateEdit(pos, dim, 0, EVENT_EDIT2); + pos.x = 65.0f/640.0f; + pos.y = 425.0f/480.0f; + m_interface->CreateEdit(pos, dim, 0, EVENT_EDIT3); + pos.x = 10.0f/640.0f; + pos.y = 400.0f/480.0f; + m_interface->CreateEdit(pos, dim, 0, EVENT_EDIT4); + pos.x = 65.0f/640.0f; + pos.y = 400.0f/480.0f; + m_interface->CreateEdit(pos, dim, 0, EVENT_EDIT5); + + dim.x = 20.0f/640.0f; + dim.y = 20.0f/480.0f; + pos.y = 370.0f/480.0f; + pos.x = 10.0f/640.0f; + pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON10); + pb->SetState(STATE_SIMPLY); + pb->SetName("P"); + pos.x = 30.0f/640.0f; + pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON11); + pb->SetState(STATE_SIMPLY); + pb->SetName("R"); + pos.x = 50.0f/640.0f; + pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON12); + pb->SetState(STATE_SIMPLY); + pb->SetName("Z"); + pos.y = 350.0f/480.0f; + pos.x = 10.0f/640.0f; + pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON13); + pb->SetState(STATE_SIMPLY); + pb->SetName("+X"); + pos.x = 30.0f/640.0f; + pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON14); + pb->SetState(STATE_SIMPLY); + pb->SetName("+Y"); + pos.x = 50.0f/640.0f; + pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON15); + pb->SetState(STATE_SIMPLY); + pb->SetName("+Z"); + pos.y = 330.0f/480.0f; + pos.x = 10.0f/640.0f; + pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON16); + pb->SetState(STATE_SIMPLY); + pb->SetName("-X"); + pos.x = 30.0f/640.0f; + pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON17); + pb->SetState(STATE_SIMPLY); + pb->SetName("-Y"); + pos.x = 50.0f/640.0f; + pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON18); + pb->SetState(STATE_SIMPLY); + pb->SetName("-Z"); + +//? m_modFile->ReadModel("objects\\io.mod"); + DeselectAll(); + CurrentInit(); + + ZeroMemory(&event, sizeof(Event)); + EventFrame(event); + + m_engine->LoadAllTexture(); + UpdateInfoText(); +} + +// You must call this procedure after modifing the model interactively. + +void CModel::StopUserAction() +{ + m_interface->DeleteControl(EVENT_EDIT1); + m_interface->DeleteControl(EVENT_EDIT2); + m_interface->DeleteControl(EVENT_EDIT3); + m_interface->DeleteControl(EVENT_EDIT4); + m_interface->DeleteControl(EVENT_EDIT5); + m_interface->DeleteControl(EVENT_BUTTON1); + m_interface->DeleteControl(EVENT_BUTTON2); + m_interface->DeleteControl(EVENT_BUTTON3); + m_interface->DeleteControl(EVENT_BUTTON4); + m_interface->DeleteControl(EVENT_BUTTON5); + m_interface->DeleteControl(EVENT_BUTTON10); + m_interface->DeleteControl(EVENT_BUTTON11); + m_interface->DeleteControl(EVENT_BUTTON12); + m_interface->DeleteControl(EVENT_BUTTON13); + m_interface->DeleteControl(EVENT_BUTTON14); + m_interface->DeleteControl(EVENT_BUTTON15); + m_interface->DeleteControl(EVENT_BUTTON16); + m_interface->DeleteControl(EVENT_BUTTON17); + m_interface->DeleteControl(EVENT_BUTTON18); + + m_engine->SetInfoText(0, ""); + m_engine->SetInfoText(1, ""); +} + + +// Updates the​editable values for mapping textures. + +void CModel::PutTextureValues() +{ + CEdit* pe; + char s[100]; + int value; + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT2); + if ( pe != 0 ) + { + value = (int)(m_textureSup.x*256.0f+0.5f); + sprintf(s, "%d", value); + pe->SetText(s); + } + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT3); + if ( pe != 0 ) + { + value = (int)(m_textureSup.y*256.0f+0.5f); + sprintf(s, "%d", value); + pe->SetText(s); + } + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT4); + if ( pe != 0 ) + { + value = (int)(m_textureInf.x*256.0f-0.5f); + sprintf(s, "%d", value); + pe->SetText(s); + } + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT5); + if ( pe != 0 ) + { + value = (int)(m_textureInf.y*256.0f-0.5f); + sprintf(s, "%d", value); + pe->SetText(s); + } +} + +// Takes the editable values for mapping textures. + +void CModel::GetTextureValues() +{ + CEdit* pe; + char s[100]; + int value; + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT2); + if ( pe != 0 ) + { + pe->GetText(s, 100); + sscanf(s, "%d", &value); + m_textureSup.x = ((float)value-0.5f)/256.0f; + } + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT3); + if ( pe != 0 ) + { + pe->GetText(s, 100); + sscanf(s, "%d", &value); + m_textureSup.y = ((float)value-0.5f)/256.0f; + } + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT4); + if ( pe != 0 ) + { + pe->GetText(s, 100); + sscanf(s, "%d", &value); + m_textureInf.x = ((float)value+0.5f)/256.0f; + } + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT5); + if ( pe != 0 ) + { + pe->GetText(s, 100); + sscanf(s, "%d", &value); + m_textureInf.y = ((float)value+0.5f)/256.0f; + } +} + + +// Gives the model name. + +void CModel::GetModelName(char *buffer) +{ + CEdit* pe; + char s[100]; + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT1); + if ( pe == 0 ) + { + strcpy(buffer, "objects\\io.mod"); + } + else + { + pe->GetText(s, 100); + sprintf(buffer, "objects\\%s.mod", s); + } +} + +// Gives the model name. + +void CModel::GetDXFName(char *buffer) +{ + CEdit* pe; + char s[100]; + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT1); + if ( pe == 0 ) + { + strcpy(buffer, "models\\import.dxf"); + } + else + { + pe->GetText(s, 100); + sprintf(buffer, "models\\%s.dxf", s); + } +} + +// Gives the model name. + +void CModel::GetScriptName(char *buffer) +{ + CEdit* pe; + char s[100]; + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT1); + if ( pe == 0 ) + { + strcpy(buffer, "objects\\script.txt"); + } + else + { + pe->GetText(s, 100); + sprintf(buffer, "objects\\%s.txt", s); + } +} + +// Indicates whether the edition name has focus. + +BOOL CModel::IsEditFocus() +{ + CEdit* pe; + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT1); + if ( pe != 0 ) + { + if ( pe->RetFocus() ) return TRUE; + } + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT2); + if ( pe != 0 ) + { + if ( pe->RetFocus() ) return TRUE; + } + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT3); + if ( pe != 0 ) + { + if ( pe->RetFocus() ) return TRUE; + } + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT4); + if ( pe != 0 ) + { + if ( pe->RetFocus() ) return TRUE; + } + + pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT5); + if ( pe != 0 ) + { + if ( pe->RetFocus() ) return TRUE; + } + + return FALSE; +} + + +// Management of an event. + +BOOL CModel::EventProcess(const Event &event) +{ + char s[100]; + int first, last; + + switch( event.event ) + { + case EVENT_FRAME: + EventFrame(event); + break; + + case EVENT_KEYDOWN: + if ( IsEditFocus() ) + break; + + if ( event.param == '1' ) + { + m_mode = 1; + UpdateInfoText(); + } + if ( event.param == '2' ) + { + m_mode = 2; + UpdateInfoText(); + } + if ( event.param == '3' ) + { + m_mode = 3; + UpdateInfoText(); + } + if ( event.param == VK_ADD ) // numpad? + { + if ( event.keyState & KS_SHIFT ) CurrentSelect(TRUE); + CurrentSearchNext(+1, (event.keyState & KS_CONTROL)); + } + if ( event.param == VK_SUBTRACT ) // least numpad? + { + if ( event.keyState & KS_SHIFT ) CurrentSelect(TRUE); + CurrentSearchNext(-1, (event.keyState & KS_CONTROL)); + } + if ( event.param == VK_NUMPAD0 ) + { + CurrentSelect(FALSE); + } + if ( event.param == VK_DECIMAL ) + { + CurrentSelect(TRUE); + } + if ( event.param == VK_END ) + { + DeselectAll(); + } + if ( event.param == VK_INSERT ) + { + SelectAll(); + } + if ( event.param == VK_BACK ) // Delete normal ? + { + SelectDelete(); + } + if ( event.param == VK_SPACE ) + { + m_bDisplayTransparent = !m_bDisplayTransparent; + m_bDisplayOnlySelection = FALSE; + } + if ( event.param == 'H' ) + { + m_bDisplayOnlySelection = !m_bDisplayOnlySelection; + m_bDisplayTransparent = FALSE; + } + if ( m_mode == 1 ) + { + if ( event.param == 'S' ) + { + SmoothSelect(); + } + if ( event.param == 'N' ) + { + PlaneSelect(); + } + if ( event.param == 'C' ) + { + ColorSelect(); + } + if ( event.param == 'V' ) + { + m_color ++; + if ( m_color >= MAX_COLORS ) m_color = 0; + UpdateInfoText(); + ColorSelect(); + } + if ( event.param == 'J' ) + { + StateSelect(); + } + if ( event.param == 'K' ) + { + m_state ++; + if ( m_state >= MAX_STATES ) m_state = 0; + UpdateInfoText(); + StateSelect(); + } + if ( event.param == 'M' ) + { + m_textureMode ++; + if ( m_textureMode > 3 ) m_textureMode = 0; + UpdateInfoText(); + GetTextureValues(); + MappingSelect(m_textureMode, m_textureRotate, + m_bTextureMirrorX, m_bTextureMirrorY, + m_textureInf, m_textureSup, m_textureName); + } + if ( event.param == 'Z' ) + { + m_textureRotate ++; + if ( m_textureRotate > 2 ) m_textureRotate = 0; + UpdateInfoText(); + GetTextureValues(); + MappingSelect(m_textureMode, m_textureRotate, + m_bTextureMirrorX, m_bTextureMirrorY, + m_textureInf, m_textureSup, m_textureName); + } + if ( event.param == 'X' ) + { + m_bTextureMirrorX = !m_bTextureMirrorX; + UpdateInfoText(); + GetTextureValues(); + MappingSelect(m_textureMode, m_textureRotate, + m_bTextureMirrorX, m_bTextureMirrorY, + m_textureInf, m_textureSup, m_textureName); + } + if ( event.param == 'Y' ) + { + m_bTextureMirrorY = !m_bTextureMirrorY; + UpdateInfoText(); + GetTextureValues(); + MappingSelect(m_textureMode, m_textureRotate, + m_bTextureMirrorX, m_bTextureMirrorY, + m_textureInf, m_textureSup, m_textureName); + } + if ( event.param == 'O' ) + { + TextureRankChange(+1); + UpdateInfoText(); + } + if ( event.param == 'P' ) + { + TexturePartChange(+1); + UpdateInfoText(); + GetTextureValues(); + MappingSelect(m_textureMode, m_textureRotate, + m_bTextureMirrorX, m_bTextureMirrorY, + m_textureInf, m_textureSup, m_textureName); + } + if ( event.param == 'T' ) + { + GetTextureValues(); + MappingSelect(m_textureMode, m_textureRotate, + m_bTextureMirrorX, m_bTextureMirrorY, + m_textureInf, m_textureSup, m_textureName); + } + if ( event.param == 'E' ) + { + FPOINT ti, ts; + ti.x = 0.00f; + ti.y = 0.00f; + ts.x = 0.00f; + ts.y = 0.00f; + MappingSelect(m_textureMode, m_textureRotate, + m_bTextureMirrorX, m_bTextureMirrorY, + ti, ts, ""); + } + } + if ( m_mode == 2 ) + { + if ( event.param == 'E' ) + { + m_secondTexNum = 0; + UpdateInfoText(); + MappingSelect2(m_secondTexNum, m_secondSubdiv, m_secondOffsetU, m_secondOffsetV, m_bTextureMirrorX, m_bTextureMirrorY); + } + if ( event.param == 'O' ) + { + m_secondTexNum ++; + if ( m_secondTexNum > 10 ) m_secondTexNum = 1; + UpdateInfoText(); + } + if ( event.param == 'T' ) + { + MappingSelect2(m_secondTexNum, m_secondSubdiv, m_secondOffsetU, m_secondOffsetV, m_bTextureMirrorX, m_bTextureMirrorY); + m_engine->LoadAllTexture(); + } + if ( event.param == 'U' ) + { + m_secondOffsetU += 45; + if ( m_secondOffsetU >= 360 ) m_secondOffsetU = 0; + MappingSelect2(m_secondTexNum, m_secondSubdiv, m_secondOffsetU, m_secondOffsetV, m_bTextureMirrorX, m_bTextureMirrorY); + UpdateInfoText(); + } + if ( event.param == 'V' ) + { + m_secondOffsetV += 45; + if ( m_secondOffsetV >= 360 ) m_secondOffsetV = 0; + MappingSelect2(m_secondTexNum, m_secondSubdiv, m_secondOffsetU, m_secondOffsetV, m_bTextureMirrorX, m_bTextureMirrorY); + UpdateInfoText(); + } + if ( event.param == 'X' ) + { + m_bTextureMirrorX = !m_bTextureMirrorX; + MappingSelect2(m_secondTexNum, m_secondSubdiv, m_secondOffsetU, m_secondOffsetV, m_bTextureMirrorX, m_bTextureMirrorY); + UpdateInfoText(); + } + if ( event.param == 'Y' ) + { + m_bTextureMirrorY = !m_bTextureMirrorY; + MappingSelect2(m_secondTexNum, m_secondSubdiv, m_secondOffsetU, m_secondOffsetV, m_bTextureMirrorX, m_bTextureMirrorY); + UpdateInfoText(); + } + if ( event.param == 'S' ) + { + m_secondSubdiv ++; + if ( m_secondSubdiv > 7 ) m_secondSubdiv = 1; + MappingSelect2(m_secondTexNum, m_secondSubdiv, m_secondOffsetU, m_secondOffsetV, m_bTextureMirrorX, m_bTextureMirrorY); + UpdateInfoText(); + } + } + if ( m_mode == 3 ) + { + if ( event.param == 'M' ) + { + if ( m_min == 0.0f && m_max == 1000000.0f ) + { + m_min = 0.0f; m_max = 100.0f; + } + else if ( m_min == 0.0f && m_max == 100.0f ) + { + m_min = 100.0f; m_max = 200.0f; + } + else if ( m_min == 100.0f && m_max == 200.0f ) + { + m_min = 200.0f; m_max = 1000000.0f; + } + else if ( m_min == 200.0f && m_max == 1000000.0f ) + { + m_min = 0.0f; m_max = 1000000.0f; + } + UpdateInfoText(); + } + if ( event.param == 'C' ) + { + MinMaxChange(); + } + } + break; + + case EVENT_BUTTON1: // import ? + GetDXFName(s); + m_modFile->ReadDXF(s, m_min, m_max); + DeselectAll(); + CurrentInit(); + EventFrame(event); + m_engine->LoadAllTexture(); + break; + + case EVENT_BUTTON2: // script ? + GetScriptName(s); + ReadScript(s); + DeselectAll(); + CurrentInit(); + EventFrame(event); + m_engine->LoadAllTexture(); + break; + + case EVENT_BUTTON3: // read ? + GetModelName(s); + m_modFile->ReadModel(s, TRUE, FALSE); // standard read with borders + DeselectAll(); + CurrentInit(); + EventFrame(event); + m_engine->LoadAllTexture(); + break; + + case EVENT_BUTTON4: // add ? + GetModelName(s); + first = m_modFile->RetTriangleUsed(); + m_modFile->AddModel(s, first, TRUE, FALSE); // standard read with borders + last = m_modFile->RetTriangleUsed(); + SelectZone(first, last); + EventFrame(event); + break; + + case EVENT_BUTTON5: // write ? + GetModelName(s); + DeselectAll(); + m_modFile->WriteModel(s); + break; + + case EVENT_BUTTON10: // pos ? + m_oper = 'P'; + break; + case EVENT_BUTTON11: // rotate ? + m_oper = 'R'; + break; + case EVENT_BUTTON12: // zoom ? + m_oper = 'Z'; + break; + + case EVENT_BUTTON13: // +X ? + MoveSelect(D3DVECTOR(1.0f, 0.0f, 0.0f)); + break; + case EVENT_BUTTON16: // -X ? + MoveSelect(D3DVECTOR(-1.0f, 0.0f, 0.0f)); + break; + case EVENT_BUTTON14: // +Y ? + MoveSelect(D3DVECTOR(0.0f, 1.0f, 0.0f)); + break; + case EVENT_BUTTON17: // -Y ? + MoveSelect(D3DVECTOR(0.0f, -1.0f, 0.0f)); + break; + case EVENT_BUTTON15: // +Z ? + MoveSelect(D3DVECTOR(0.0f, 0.0f, 1.0f)); + break; + case EVENT_BUTTON18: // -Z ? + MoveSelect(D3DVECTOR(0.0f, 0.0f, -1.0f)); + break; + } + + return 0; +} + + +// Drives the model. + +BOOL CModel::EventFrame(const Event &event) +{ + D3DMATERIAL7 matCurrent, matCurrenti, matCurrents, matTrans; + D3DMATERIAL7* pMat; + D3DVERTEX2 vertex[3]; + char texName2[20]; + int i, used, objRank, state; + + m_time += event.rTime; + + m_engine->FlushObject(); + objRank = m_engine->CreateObject(); + + ZeroMemory(&matCurrent, sizeof(D3DMATERIAL7)); + matCurrent.diffuse.r = 1.0f; + matCurrent.diffuse.g = 0.0f; + matCurrent.diffuse.b = 0.0f; // red + matCurrent.ambient.r = 0.5f; + matCurrent.ambient.g = 0.5f; + matCurrent.ambient.b = 0.5f; + + ZeroMemory(&matCurrents, sizeof(D3DMATERIAL7)); + matCurrents.diffuse.r = 1.0f; + matCurrents.diffuse.g = 1.0f; + matCurrents.diffuse.b = 0.0f; // yellow + matCurrents.ambient.r = 0.5f; + matCurrents.ambient.g = 0.5f; + matCurrents.ambient.b = 0.5f; + + ZeroMemory(&matCurrenti, sizeof(D3DMATERIAL7)); + matCurrenti.diffuse.r = 0.0f; + matCurrenti.diffuse.g = 0.0f; + matCurrenti.diffuse.b = 1.0f; // blue + matCurrenti.ambient.r = 0.5f; + matCurrenti.ambient.g = 0.5f; + matCurrenti.ambient.b = 0.5f; + + used = m_modFile->RetTriangleUsed(); + for ( i=0 ; i= m_triangleSel1 && + i <= m_triangleSel2 && + (int)(m_time*10.0f)%2 == 0 ) + { + pMat = &matCurrent; + } + else if ( m_triangleTable[i].bSelect && + (int)(m_time*10.0f)%2 == 0 ) + { + pMat = &matCurrents; + } + else + { + if ( m_bDisplayOnlySelection ) continue; + if ( m_bDisplayTransparent ) + { + matTrans = m_triangleTable[i].material; + matTrans.diffuse.a = 0.1f; // very transparent + pMat = &matTrans; + state = D3DSTATETD; + } + } + + if ( m_triangleTable[i].texNum2 == 0 ) + { + m_engine->AddTriangle(objRank, &m_triangleTable[i].p1, 3, + *pMat, state, + m_triangleTable[i].texName, "", + 0.0f, 1000000.0f, FALSE); + } + else + { + sprintf(texName2, "dirty%.2d.tga", m_triangleTable[i].texNum2); + m_engine->AddTriangle(objRank, &m_triangleTable[i].p1, 3, + *pMat, state|D3DSTATEDUALb, + m_triangleTable[i].texName, texName2, + 0.0f, 1000000.0f, FALSE); + } + + if ( m_bDisplayTransparent && // draws inside? + i >= m_triangleSel1 && + i <= m_triangleSel2 ) + { + vertex[0] = m_triangleTable[i].p3; + vertex[1] = m_triangleTable[i].p2; + vertex[2] = m_triangleTable[i].p1; + + m_engine->AddTriangle(objRank, vertex, 3, + matCurrenti, D3DSTATENORMAL, + m_triangleTable[i].texName, "", + 0.0f, 1000000.0f, FALSE); + } + } + + return TRUE; +} + + +// Gives a vertex. + +BOOL CModel::GetVertex(int rank, D3DVERTEX2 &vertex) +{ + if ( rank < 0 || rank/3 >= m_modFile->RetTriangleUsed() ) return FALSE; + if ( !m_triangleTable[rank/3].bUsed ) return FALSE; + + if ( !m_triangleTable[rank/3].bSelect ) return FALSE; + + if ( rank%3 == 0 ) + { + vertex = m_triangleTable[rank/3].p1; + return TRUE; + } + if ( rank%3 == 1 ) + { + vertex = m_triangleTable[rank/3].p2; + return TRUE; + } + if ( rank%3 == 2 ) + { + vertex = m_triangleTable[rank/3].p3; + return TRUE; + } + return FALSE; +} + +// Modifies a vertex. + +BOOL CModel::SetVertex(int rank, D3DVERTEX2 &vertex) +{ + if ( rank < 0 || rank/3 >= m_modFile->RetTriangleUsed() ) return FALSE; + if ( !m_triangleTable[rank/3].bUsed ) return FALSE; + + if ( !m_triangleTable[rank/3].bSelect ) return FALSE; + + if ( rank%3 == 0 ) + { + m_triangleTable[rank/3].p1 = vertex; + return TRUE; + } + if ( rank%3 == 1 ) + { + m_triangleTable[rank/3].p2 = vertex; + return TRUE; + } + if ( rank%3 == 2 ) + { + m_triangleTable[rank/3].p3 = vertex; + return TRUE; + } + return FALSE; +} + +// Smoothed normals selected triangles. + +void CModel::SmoothSelect() +{ + char* bDone; + int index[100]; + int used, i, j, rank; + D3DVERTEX2 vi, vj; + D3DVECTOR sum; + + used = m_modFile->RetTriangleUsed(); + + bDone = (char*)malloc(used*3*sizeof(char)); + for ( i=0 ; i= 100 ) break; + } + } + + sum.x = 0; + sum.y = 0; + sum.z = 0; + for ( j=0 ; jRetTriangleUsed(); + + for ( i=0 ; iRetTriangleUsed(); + for ( i=0 ; iRetTriangleUsed(); + for ( i=0 ; iRetTriangleUsed(); + for ( i=0 ; iReadModel(buffer, TRUE, TRUE); + last = m_modFile->RetTriangleUsed(); + SelectZone(0, last); + } + else + { + first = m_modFile->RetTriangleUsed(); + m_modFile->AddModel(buffer, first, TRUE, FALSE); + last = m_modFile->RetTriangleUsed(); + SelectZone(first, last); + } + bFirst = FALSE; + + move = OpDir(line, "zoom"); + OperSelect(move, 'Z'); + + move = OpDir(line, "rot"); + move *= PI/180.0f; // degrees -> radians + OperSelect(move, 'R'); + + move = OpDir(line, "pos"); + OperSelect(move, 'P'); + } + } + + fclose(file); +} + + + +// Computes the bbox of selected triangles. + +void CModel::BBoxCompute(D3DVECTOR &min, D3DVECTOR &max) +{ + D3DVERTEX2 vertex; + int used, i; + + min.x = 1000000.0f; + min.y = 1000000.0f; + min.z = 1000000.0f; + max.x = -1000000.0f; + max.y = -1000000.0f; + max.z = -1000000.0f; + + used = m_modFile->RetTriangleUsed(); + + for ( i=0 ; i max.x ) max.x = vertex.x; + if ( vertex.y > max.y ) max.y = vertex.y; + if ( vertex.z > max.z ) max.z = vertex.z; + } +} + +// Returns the gravity center of the selection. + +D3DVECTOR CModel::RetSelectCDG() +{ + D3DVECTOR min, max, cdg; + + BBoxCompute(min, max); + + cdg.x = (min.x+max.x)/2.0f; + cdg.y = (min.y+max.y)/2.0f; + cdg.z = (min.z+max.z)/2.0f; + + return cdg; +} + +// Returns the normal vector of the selection. + +D3DVECTOR CModel::RetSelectNormal() +{ + D3DVECTOR p1, p2, p3, n; + + p1.x = m_triangleTable[m_triangleSel1].p1.nx; + p1.y = m_triangleTable[m_triangleSel1].p1.ny; + p1.z = m_triangleTable[m_triangleSel1].p1.nz; + + p2.x = m_triangleTable[m_triangleSel1].p2.nx; + p2.y = m_triangleTable[m_triangleSel1].p2.ny; + p2.z = m_triangleTable[m_triangleSel1].p2.nz; + + p3.x = m_triangleTable[m_triangleSel1].p3.nx; + p3.y = m_triangleTable[m_triangleSel1].p3.ny; + p3.z = m_triangleTable[m_triangleSel1].p3.nz; + + n = Normalize(p1+p2+p3); + + return n; +} + +// Maps a texture onto the selected triangles. + +BOOL CModel::IsMappingSelectPlausible(D3DMaping D3Dmode) +{ + D3DVERTEX2 vertex[3]; + D3DVECTOR min, max; + FPOINT a, b, ti, ts; + float au, bu, av, bv; + int used, i, j; + + ti.x = 0.0f; + ti.y = 0.0f; + ts.x = 1.0f; + ts.y = 1.0f; + + BBoxCompute(min, max); + + if ( D3Dmode == D3DMAPPINGX ) + { + a.x = min.z; + a.y = min.y; + b.x = max.z; + b.y = max.y; + } + if ( D3Dmode == D3DMAPPINGY ) + { + a.x = min.x; + a.y = min.z; + b.x = max.x; + b.y = max.z; + } + if ( D3Dmode == D3DMAPPINGZ ) + { + a.x = min.x; + a.y = min.y; + b.x = max.x; + b.y = max.y; + } + + au = (ts.x-ti.x)/(b.x-a.x); + bu = ts.x-b.x*(ts.x-ti.x)/(b.x-a.x); + + av = (ts.y-ti.y)/(b.y-a.y); + bv = ts.y-b.y*(ts.y-ti.y)/(b.y-a.y); + + used = m_modFile->RetTriangleUsed(); + for ( i=0 ; iRetTriangleUsed(); + for ( i=0 ; iRetTriangleUsed(); + for ( i=0 ; iRetTriangleUsed(); + for ( i=0 ; iRetTriangleUsed(); + for ( i=0 ; iRetTriangleUsed(); + for ( i=0 ; i 1.0f ) u[j] -= 1.0f; +#else + u[j] = RotateAngle(p.x, p.z)/PI; +//? if ( u[j] > 1.0f ) u[j] = 2.0f-u[j]; + if ( u[j] > 1.0f ) u[j] -= 1.0f; +#endif + + v[j] = p.y/dim.y/2.0f + 0.5f; + + if ( u[j] < 0.5f ) m[j] = u[j]; + else m[j] = u[j]-1.0f; + } + + avg = (m[0]+m[1]+m[2])/3.0f; + + for ( j=0 ; j<3 ; j++ ) + { + if ( u[j] < 0.05f || u[j] > 0.95f ) + { + if ( avg > 0.0f ) u[j] = 0.0f; + else u[j] = 1.0f; + } + + vertex[j].tu = ti.x+(ts.x-ti.x)*u[j]; + vertex[j].tv = ti.y+(ts.y-ti.y)*v[j]; + + SetVertex(i*3+j, vertex[j]); + } + } + + SelectTerm(); +} + + +// Maps a secondary texture on selected triangles. + +void CModel::MappingSelect2(int texNum2, int subdiv, + int offsetU, int offsetV, + BOOL bMirrorX, BOOL bMirrorY) +{ + D3DVERTEX2 vertex; + D3DVECTOR min, max, center, p; + float u ,v; + int used, i; + + DefaultSelect(); + + used = m_modFile->RetTriangleUsed(); + for ( i=0 ; i 2 ) + { + MappingSelectPlane2(subdiv-3, bMirrorX, bMirrorY); + return; + } + + BBoxCompute(min, max); + center = (min+max)/2.0f; + + for ( i=0 ; iRetTriangleUsed(); + for ( i=0 ; iRetTriangleUsed(); + for ( i=0 ; iRetTriangleUsed(); + for ( i=0 ; i= Max(n.y, n.z) ) mode = 0; + if ( n.y >= Max(n.x, n.z) ) mode = 1; + if ( n.z >= Max(n.x, n.y) ) mode = 2; + } + + if ( !GetVertex(i, vertex) ) continue; + + if ( mode == 0 ) + { + vertex.tu2 = vertex.z*au.z+bu.z; + vertex.tv2 = vertex.y*av.y+bv.y; + } + if ( mode == 1 ) + { + vertex.tu2 = vertex.x*au.x+bu.x; + vertex.tv2 = vertex.z*av.z+bv.z; + } + if ( mode == 2 ) + { + vertex.tu2 = vertex.x*au.x+bu.x; + vertex.tv2 = vertex.y*av.y+bv.y; + } + + SetVertex(i, vertex); + } + + SelectTerm(); +} + + +// Seeks the next triangle. + +int CModel::SearchNext(int rank, int step) +{ + int max, i; + + max = m_modFile->RetTriangleUsed(); + + for ( i=0 ; i= max ) rank = 0; + + if ( m_triangleTable[rank].min != m_min || + m_triangleTable[rank].max != m_max ) continue; + + if ( m_triangleTable[rank].bUsed ) break; + } + return rank; +} + +// Seeks all the triangles belonging to the same plane. + +int CModel::SearchSamePlane(int first, int step) +{ + D3DVECTOR vFirst[3], vNext[3]; + int last, i; + + vFirst[0].x = m_triangleTable[first].p1.x; + vFirst[0].y = m_triangleTable[first].p1.y; + vFirst[0].z = m_triangleTable[first].p1.z; + vFirst[1].x = m_triangleTable[first].p2.x; + vFirst[1].y = m_triangleTable[first].p2.y; + vFirst[1].z = m_triangleTable[first].p2.z; + vFirst[2].x = m_triangleTable[first].p3.x; + vFirst[2].y = m_triangleTable[first].p3.y; + vFirst[2].z = m_triangleTable[first].p3.z; + + for ( i=0 ; i<1000 ; i++ ) + { + last = first; + first = SearchNext(first, step); + + vNext[0].x = m_triangleTable[first].p1.x; + vNext[0].y = m_triangleTable[first].p1.y; + vNext[0].z = m_triangleTable[first].p1.z; + vNext[1].x = m_triangleTable[first].p2.x; + vNext[1].y = m_triangleTable[first].p2.y; + vNext[1].z = m_triangleTable[first].p2.z; + vNext[2].x = m_triangleTable[first].p3.x; + vNext[2].y = m_triangleTable[first].p3.y; + vNext[2].z = m_triangleTable[first].p3.z; + + if ( !IsSamePlane(vFirst, vNext) ) // other plan? + { + return last; + } + } + return first; +} + +// Seeks the next triangle. + +void CModel::CurrentSearchNext(int step, BOOL bControl) +{ + if ( step > 0 ) // forward? + { + m_triangleSel1 = SearchNext(m_triangleSel2, step); + if ( bControl ) + { + m_triangleSel2 = m_triangleSel1; + } + else + { + m_triangleSel2 = SearchSamePlane(m_triangleSel1, step); + } + } + if ( step < 0 ) // back? + { + m_triangleSel2 = SearchNext(m_triangleSel1, step); + if ( bControl ) + { + m_triangleSel1 = m_triangleSel2; + } + else + { + m_triangleSel1 = SearchSamePlane(m_triangleSel2, step); + } + } + +#if 0 + char s[100]; + sprintf(s, "(%.2f;%.2f;%.2f) (%.2f;%.2f;%.2f) (%.2f;%.2f;%.2f)", + m_triangleTable[m_triangleSel1].p1.x, + m_triangleTable[m_triangleSel1].p1.y, + m_triangleTable[m_triangleSel1].p1.z, + m_triangleTable[m_triangleSel1].p2.x, + m_triangleTable[m_triangleSel1].p2.y, + m_triangleTable[m_triangleSel1].p2.z, + m_triangleTable[m_triangleSel1].p3.x, + m_triangleTable[m_triangleSel1].p3.y, + m_triangleTable[m_triangleSel1].p3.z); + m_engine->SetInfoText(2, s); + sprintf(s, "(%.2f;%.2f) (%.2f;%.2f) (%.2f;%.2f)", + m_triangleTable[m_triangleSel1].p1.tu2, + m_triangleTable[m_triangleSel1].p1.tv2, + m_triangleTable[m_triangleSel1].p2.tu2, + m_triangleTable[m_triangleSel1].p2.tv2, + m_triangleTable[m_triangleSel1].p3.tu2, + m_triangleTable[m_triangleSel1].p3.tv2); + m_engine->SetInfoText(3, s); +#endif + + InitViewFromSelect(); + UpdateInfoText(); +} + +// Initializes the current triangles. + +void CModel::CurrentInit() +{ + m_triangleSel1 = 0; + m_triangleSel2 = SearchSamePlane(m_triangleSel1, +1); + + InitViewFromSelect(); + UpdateInfoText(); +} + +// Selects the current triangles. + +void CModel::CurrentSelect(BOOL bSelect) +{ + int i; + + for ( i=m_triangleSel1 ; i<=m_triangleSel2 ; i++ ) + { + m_triangleTable[i].bSelect = bSelect; + } +} + + +// Deselects all triangles. + +void CModel::DeselectAll() +{ + int used, i; + + used = m_modFile->RetTriangleUsed(); + for ( i=0 ; iRetTriangleUsed(); + for ( i=0 ; i= first && i < last ) + { + m_triangleTable[i].bSelect = TRUE; + } + } + m_triangleSel1 = first; + m_triangleSel2 = last-1; +} + +// Selects all triangles. + +void CModel::SelectAll() +{ + int used, i; + + used = m_modFile->RetTriangleUsed(); + for ( i=0 ; iRetTriangleUsed(); + for ( i=0 ; i= m_triangleSel1 && i <= m_triangleSel2 ) + { + if ( !m_triangleTable[i].bSelect ) return; + } + else + { + if ( m_triangleTable[i].bSelect ) return; + } + } + + DeselectAll(); +} + +// Selects the triangles currents. + +void CModel::DefaultSelect() +{ + int used, i; + + used = m_modFile->RetTriangleUsed(); + for ( i=m_triangleSel1 ; i<=m_triangleSel2 ; i++ ) + { + m_triangleTable[i].bSelect = TRUE; + } +} + + + +// Removes all selected triangles. + +void CModel::SelectDelete() +{ + int used ,i; + + DefaultSelect(); + + used = m_modFile->RetTriangleUsed(); + for ( i=0 ; iRetTriangleUsed(); + for ( i=0 ; iSetTriangleUsed(j); + CurrentInit(); +} + + +// Change the min / max of all selected triangles. + +void CModel::MinMaxChange() +{ + int used, i; + + DefaultSelect(); + + used = m_modFile->RetTriangleUsed(); + for ( i=0 ; i= PI ) + { + m_viewAngleV -= PI; + m_viewAngleH -= PI; + } + m_viewAngleV *= 0.75f; + + char s[100]; + sprintf(s, "angle=%f %f -> %f %f\n", h,v, m_viewAngleH, m_viewAngleV); + OutputDebugString(s); +#endif +} + +// Updates the parameters for the point of view. + +void CModel::UpdateView() +{ + D3DVECTOR eye, lookat, vUpVec; + +//? lookat = RetSelectCDG(); + lookat = D3DVECTOR(0.0f, m_viewHeight, 0.0f); + eye = RotateView(lookat, m_viewAngleH, m_viewAngleV, m_viewDist); + + vUpVec = D3DVECTOR(0.0f, 1.0f, 0.0f); + m_engine->SetViewParams(eye, lookat, vUpVec, 10.0f); + m_engine->SetRankView(0); +} + +// Moves the point of view. + +void CModel::ViewMove(const Event &event, float speed) +{ + if ( IsEditFocus() ) return; + + // Up/Down. + if ( event.axeY > 0.5f ) + { + if ( event.keyState & KS_CONTROL ) + { + m_viewHeight += event.rTime*10.0f*speed; + if ( m_viewHeight > 100.0f ) m_viewHeight = 100.0f; + } + else + { + m_viewAngleV -= event.rTime*1.0f*speed; + if ( m_viewAngleV < -PI*0.49f ) m_viewAngleV = -PI*0.49f; + } + } + if ( event.axeY < -0.5f ) + { + if ( event.keyState & KS_CONTROL ) + { + m_viewHeight -= event.rTime*10.0f*speed; + if ( m_viewHeight < -100.0f ) m_viewHeight = -100.0f; + } + else + { + m_viewAngleV += event.rTime*1.0f*speed; + if ( m_viewAngleV > PI*0.49f ) m_viewAngleV = PI*0.49f; + } + } + + // Left/Right. + if ( event.axeX < -0.5f ) + { + m_viewAngleH -= event.rTime*1.0f*speed; + } + if ( event.axeX > 0.5f ) + { + m_viewAngleH += event.rTime*1.0f*speed; + } + + // PageUp/PageDown. + if ( event.keyState & KS_PAGEUP ) + { + m_viewDist -= event.rTime*30.0f*speed; + if ( m_viewDist < 1.0f ) m_viewDist = 1.0f; + } + if ( event.keyState & KS_PAGEDOWN ) + { + m_viewDist += event.rTime*30.0f*speed; + if ( m_viewDist > 300.0f ) m_viewDist = 300.0f; + } +} + + + +// Updates the text information. + +void CModel::UpdateInfoText() +{ + char info[100]; + + if ( m_mode == 1 ) + { + sprintf(info, "[1] V:color=%d K:state=%d Sel=%d..%d (T=%d)", + m_color, m_state, + m_triangleSel1, m_triangleSel2, + m_triangleSel2-m_triangleSel1+1); + m_engine->SetInfoText(0, info); + + sprintf(info, "M:mode=%d Z:rot=%d XY:mir=%d;%d P:part=%d O:name=%s", + m_textureMode, m_textureRotate, + m_bTextureMirrorX, m_bTextureMirrorY, + m_texturePart, m_textureName); + m_engine->SetInfoText(1, info); + } + + if ( m_mode == 2 ) + { + sprintf(info, "[2] Sel=%d..%d (T=%d)", + m_triangleSel1, m_triangleSel2, + m_triangleSel2-m_triangleSel1+1); + m_engine->SetInfoText(0, info); + + sprintf(info, "O:dirty=%d UV:offset=%d;%d XY:mir=%d;%d S:subdiv=%d", + m_secondTexNum, + m_secondOffsetU, m_secondOffsetV, + m_bTextureMirrorX, m_bTextureMirrorY, + m_secondSubdiv); + m_engine->SetInfoText(1, info); + } + + if ( m_mode == 3 ) + { + sprintf(info, "[3] LOD Min/max=%d..%d Sel=%d..%d (T=%d)", + (int)m_min, (int)m_max, + m_triangleSel1, m_triangleSel2, + m_triangleSel2-m_triangleSel1+1); + m_engine->SetInfoText(0, info); + + sprintf(info, "[Change]"); + m_engine->SetInfoText(1, info); + } +} + + + +static int tablePartT[] = // lemt.tga +{ + 192, 0, 256, 32, // track profile + 0, 64, 128, 128, // wheels for track + 0, 0, 128, 64, // profile + 90, 0, 128, 28, // pivot trainer + 128, 0, 192, 44, // chest front + 128, 44, 192, 58, // shell + 128, 58, 192, 87, // back chest + 128, 87, 192, 128, // back shell + 128, 128, 192, 144, // sub back shell + 0, 128, 32, 152, // rear fender + 0, 152, 32, 182, // fender middle + 0, 182, 32, 256, // front fender + 32, 128, 112, 176, // wing + 224, 48, 232, 64, // thrust tunnel + 192, 32, 224, 64, // fire under reactor + 224, 32, 256, 48, // foot + 192, 64, 256, 128, // sensor + 192, 128, 224, 176, // battery holder + 192, 216, 248, 248, // cannon board + 220, 216, 222, 245, // cannon board + 64, 176, 128, 224, // top cannon + 128, 152, 192, 160, // external cannon + 128, 144, 192, 152, // interior cannon + 192, 176, 224, 192, // small cannon + 128, 236, 192, 256, // cannon organic + 214, 192, 224, 216, // crosshair + 224, 128, 248, 152, // articulation + 128, 192, 192, 214, // piston board + 128, 214, 192, 236, // piston front + 192, 192, 214, 214, // piston edge + 128, 192, 161, 214, // small piston board + 32, 176, 64, 198, // radar piston + 128, 160, 160, 192, // wheel + 232, 48, 255, 56, // tire profile + 240, 152, 248, 216, // vertical hatching + 248, 192, 256, 256, // battery + 224, 152, 240, 168, // rock + 144, 80, 176, 112, // nuclear + 140, 76, 180, 116, // large nuclear + 144, 80, 152, 88, // yellow nuclear + 224, 168, 240, 192, // cap resolution C + 224, 192, 240, 210, // back resolution C + 32, 224, 96, 235, // arm resolution C + 32, 235, 96, 246, // arm resolution C + 161, 1, 164, 4, // blank + 168, 1, 171, 4, // medium gray + 154, 1, 157, 4, // dark gray uniform + 147, 1, 150, 4, // blue unifrom + 114, 130, 118, 134, // red unifrom + 121, 130, 125, 134, // green uniform + 114, 137, 118, 141, // yellow uniform + 121, 137, 125, 141, // violet uniform + -1 +}; + +static int tablePartR[] = // roller.tga +{ + 0, 0, 128, 52, // wheels for track + 48, 137, 128, 201, // catalytic radiator + 0, 52, 32, 84, // front radiator + 32, 52, 43, 84, // back radiator + 0, 84, 96, 137, // large catalytic + 128, 0, 192, 85, // front + 128, 173, 192, 256, // back + 192, 0, 256, 42, // over + 128, 85, 192, 109, // catalytic pillon + 128, 109, 192, 173, // top pillon + 192, 85, 240, 109, // catalytic gate pillon + 0, 137, 24, 256, // catalytic verrin + 24, 137, 48, 256, // catalytic verrin + 48, 201, 128, 233, // medium cannon + 192, 109, 256, 173, // bottom cannon + 192, 173, 240, 205, // cannon 1 + 192, 173, 240, 177, // cannon 2 + 43, 52, 75, 84, // front cannon + 48, 233, 128, 247, // piston + 96, 105, 128, 137, // front phazer + 96, 97, 128, 105, // phazer cannon + 75, 52, 107, 84, // exhaust pipe + 192, 205, 243, 256, // nuclear power plant instruction + 192, 42, 256, 85, // reflection glass + -1 +}; + +static int tablePartW[] = // subm.tga +{ + 0, 0, 128, 26, // chenilles + 0, 26, 22, 114, // portique 1 + 0, 114, 22, 202, // portique 2 + 22, 26, 82, 56, // c�t� hublot + 22, 56, 82, 86, // c�t� ligne rouge + 22, 86, 82, 116, // c�t� simple + 22, 116, 82, 146, // avant/arri�re + 22, 146, 82, 176, // avant/arri�re + phare + 132, 82, 196, 166, // capot trainer + 132, 166, 196, 177, // capot trainer + 132, 177, 196, 188, // capot trainer + 0, 224, 96, 256, // c�t� trainer + 30, 224, 48, 256, // arri�re trainer + 136, 240, 216, 256, // barri�re courte + 96, 240, 256, 256, // barri�re longue + 128, 0, 160, 32, // black-box 1 + 160, 0, 192, 32, // black-box 2 + 192, 0, 224, 32, // black-box 3 + 224, 105, 256, 137, // TNT 1 + 224, 137, 256, 169, // TNT 2 + 82, 32, 146, 82, // factory r�solution C + 146, 32, 210, 82, // factory r�solution C + 224, 0, 256, 105, // tower r�solution C + 82, 82, 132, 150, // research r�solution C + 199, 169, 256, 233, // sac r�solution C + 106, 150, 130, 214, // cl� A + 82, 150, 106, 214, // cl� B + 132, 188, 196, 212, // cl� C + 132, 212, 196, 236, // cl� D + 210, 32, 224, 46, // gris + 56, 176, 82, 224, // sol coffre-fort + -1 +}; + +static int tablePartDr[] = // drawer.tga +{ + 128, 0, 134, 6, // bleu + 128, 6, 134, 12, // gris fonc� + 128, 12, 134, 18, // gris clair + 0, 0, 128, 32, // roues chenille + 192, 0, 256, 32, // profil chenille + 140, 0, 160, 8, // profil phare + 160, 0, 192, 32, // face phare + 0, 32, 160, 48, // hachure + 160, 32, 192, 48, // c�t� + 0, 48, 96, 96, // tableau de bord + 96, 48, 192, 112, // radiateur + 192, 32, 256, 112, // grille lat�rale + 192, 112, 256, 128, // capot + 0, 96, 8, 160, // chassis + 8, 96, 96, 104, // axe chenilles + 8, 104, 16, 160, // axe carrousel + 16, 128, 24, 160, // flan support + 224, 128, 256, 160, // rotule + 24, 104, 32, 160, // bocal (18) + 32, 104, 40, 160, // bocal + 40, 104, 48, 160, // bocal + 24, 152, 48, 160, // bocal fond + 0, 240, 32, 256, // crayon 1: couleur (22) + 0, 160, 32, 192, // crayon 1: dessus + 0, 192, 32, 256, // crayon 1: pointe + 32, 240, 64, 256, // crayon 2: couleur + 32, 160, 64, 192, // crayon 2: dessus + 32, 192, 64, 256, // crayon 2: pointe + 64, 240, 96, 256, // crayon 3: couleur + 64, 160, 96, 192, // crayon 3: dessus + 64, 192, 96, 256, // crayon 3: pointe + 96, 240, 128, 256, // crayon 4: couleur + 96, 160, 128, 192, // crayon 4: dessus + 96, 192, 128, 256, // crayon 4: pointe + 128, 240, 160, 256, // crayon 5: couleur + 128, 160, 160, 192, // crayon 5: dessus + 128, 192, 160, 256, // crayon 5: pointe + 160, 240, 192, 256, // crayon 6: couleur + 160, 160, 192, 192, // crayon 6: dessus + 160, 192, 192, 256, // crayon 6: pointe + 192, 240, 224, 256, // crayon 7: couleur + 192, 160, 224, 192, // crayon 7: dessus + 192, 192, 224, 256, // crayon 7: pointe + 224, 240, 256, 256, // crayon 8: couleur + 224, 160, 256, 192, // crayon 8: dessus + 224, 192, 256, 256, // crayon 8: pointe + -1 +}; + +static int tablePartKi[] = // kid.tga +{ + 0, 0, 128, 53, // ciseaux + 128, 0, 256, 128, // CD + 0, 0, 8, 8, // livre 1: fond + 8, 0, 16, 8, // livre 2: fond + 16, 0, 24, 8, // livre: fond + 24, 0, 32, 8, // livre: fond + 32, 0, 40, 8, // livre: fond + 40, 0, 48, 8, // livre: fond + 0, 53, 22, 138, // livre 1: tranche + 22, 53, 86, 138, // livre 1: face + 0, 138, 22, 224, // livre 2: tranche + 22, 138, 86, 224, // livre 2: face + 86, 53, 94, 85, // livre: pages + 94, 53, 110, 139, // livre: tranche + 110, 53, 126, 139, // livre: tranche + 86, 139, 102, 225, // livre: tranche + 102, 139, 118, 225, // livre: tranche + 118, 139, 134, 225, // livre: tranche + 64, 0, 72, 8, // fauille: fond + 155, 155, 256, 256, // feuille: carreaux + 72, 0, 80, 8, // lampe + 80, 0, 88, 8, // lampe + 80, 8, 88, 16, // ampoule + 72, 8, 80, 16, // rayons (23) + 86, 85, 94, 139, // lampe + 0, 224, 32, 256, // lampe rotule + 64, 8, 72, 16, // arrosoir: fond + 134, 128, 142, 256, // arrosoir: corps + 142, 128, 150, 256, // arrosoir: tuyau + 128, 225, 134, 256, // arrosoir: int�rieur + 32, 224, 64, 256, // arrosoir: ponneau + 56, 8, 64, 16, // skate: roues (31) + 48, 8, 56, 16, // skate: axes + 40, 8, 48, 16, // skate: grip + 32, 8, 40, 16, // skate: tranche + 24, 8, 32, 16, // skate: dessous + 150, 128, 200, 256, // skate: motif 1 + 200, 128, 250, 256, // skate: motif 2 + 64, 224, 96, 256, // skate: roue (38) + 96, 225, 104, 256, // skate: amortisseur + -1 +}; + +static int tablePartKi2[] = // kid2.tga +{ + 2, 2, 62, 62, // coca: dessus + 0, 64, 8, 192, // coca: flan + 8, 64, 96, 192, // coca: logo + 128, 0, 256, 85, // carton + 128, 85, 256, 91, // carton tranche + 128, 128, 256, 256, // roue + 192, 96, 256, 128, // pneu + 184, 96, 192, 128, // jante + 128, 96, 160, 128, // int�rieur + 160, 96, 168, 104, // porte bois + 160, 104, 168, 112, // porte m�tal + 160, 112, 184, 128, // vitre + 96, 0, 128, 256, // bouteille: corps (12) + 64, 0, 96, 32, // bouteille: bouchon + 168, 96, 176, 104, // bouteille: vert + 0, 192, 96, 224, // bois clair + 0, 224, 96, 256, // bois fonc� + 64, 32, 96, 64, // bateau + 168, 104, 176, 112, // ballon (18) + 176, 104, 184, 112, // ballon + 176, 96, 184, 104, // int�rieur caisse + -1 +}; + +static int tablePartKi3[] = // kid3.tga +{ + 0, 0, 32, 28, // �crou: flan + 0, 28, 32, 44, // �crou: profil + 0, 44, 32, 60, // �crou: pas de vis + 0, 60, 32, 64, // tuyau + 0, 64, 32, 68, // tuyau + 0, 68, 8, 76, // tuyau + 0, 76, 32, 108, // plastic + 8, 68, 16, 76, // saut: gris clair (7) + 16, 68, 24, 76, // saut: gris fonc� + 24, 68, 32, 76, // saut: gris bois + 0, 108, 32, 140, // saut: rotule + 0, 140, 32, 144, // saut: axe + 128, 0, 256, 128, // saut: flan + 0, 144, 8, 152, // basket: gris fonc� (13) + 8, 144, 16, 152, // basket: gris clair + 16, 144, 24, 152, // basket: gris lacets + 24, 144, 32, 152, // basket: gris semelle + 0, 152, 8, 181, // basket: int�rieur + 0, 181, 192, 256, // basket: c�t� + 192, 181, 226, 256, // basket: arri�re + 32, 135, 96, 181, // basket: dessus (20) + 96, 168, 128, 181, // basket: avant + 8, 152, 16, 160, // chaise: plastique + 16, 152, 24, 160, // chaise: m�tal + 32, 0, 64, 32, // chaise: roue + 8, 177, 24, 181, // chaise: roue + 226, 181, 234, 256, // chaise: piston (26) + 64, 96, 128, 128, // chaise: relief + 96, 135, 128, 167, // chaise: dessous + 32, 128, 250, 135, // paille 1 + 38, 128, 256, 135, // paille 2 + 234, 181, 242, 256, // allumette + 8, 160, 16, 168, // allumette (dessus) + 128, 135, 224, 181, // panneau + 242, 135, 256, 256, // poteau (34) + 24, 152, 32, 160, // clou + 16, 160, 24, 168, // tuyau m�talique + 112, 181, 192, 185, // tuyau int�rieur + 32, 32, 48, 80, // pas de vis + 24, 160, 32, 168, // ventillateur: plastique (39) + 40, 80, 56, 96, // ventillateur: plastique d�grad� + 8, 168, 16, 176, // ventillateur: m�tal + 32, 80, 40, 112, // ventillateur: socle 1 + 64, 0, 96, 16, // ventillateur: socle 2 + 48, 32, 56, 80, // ventillateur: socle 3 + 64, 16, 96, 32, // ventillateur: moteur flan + 96, 0, 128, 32, // ventillateur: moteur face + 102, 6, 122, 26, // ventillateur: socle dessus + 16, 168, 24, 176, // pot: uni (48) + 56, 32, 64, 64, // pot: haut + 56, 64, 64, 96, // pot: bas + 64, 32, 128, 96, // pot: terre + -1 +}; + +static int tablePartF[] = // factory.tga +{ + 0, 0, 152, 152, // plancher octogonal fabrique + 50, 50, 102, 102, // dessus pile + 0, 152, 128, 252, // avant + 128, 152, 256, 252, // arri�re + 152, 28, 225, 128, // c�t� + 152, 28, 176, 128, // c�t� partiel + 152, 0, 216, 16, // hachures + 236, 0, 256, 40, // axe + 152, 128, 224, 152, // support cible + -1 +}; + +static int tablePartD[] = // derrick.tga +{ + 0, 0, 64, 32, // grand c�t� + 64, 0, 96, 24, // petit c�t� + 96, 0, 136, 24, // attention + 0, 32, 8, 160, // tube 1 + 8, 32, 16, 96, // tube 2 + 16, 32, 24, 160, // pilier + 24, 32, 32, 160, // tige foret + 32, 32, 40, 160, // tige destructeur + 8, 96, 16, 128, // foret + 136, 0, 256, 120, // plancher octogonal station de recharge + 40, 32, 64, 56, // cube m�tal + 64, 24, 128, 48, // c�t� tour haut + 64, 48, 128, 229, // c�t� tour bas + 136, 120, 256, 240, // int�rieur usine + 0, 160, 64, 224, // to�t usine + -1 +}; + +static int tablePartC[] = // convert.tga +{ + 0, 0, 120, 120, // plancher octogonal convertisseur + 0, 120, 128, 176, // grand c�t� + 128, 120, 192, 176, // petit c�t� + 192, 120, 256, 184, // couvercle convertisseur + 120, 0, 216, 64, // face trianble + 216, 0, 248, 64, // c�t� triangle + 120, 64, 160, 84, // axe + 0, 141, 128, 176, // recherche: base + 0, 176, 128, 214, // recherche: haut + 0, 214, 128, 252, // recherche: haut (!) + 174, 64, 190, 120, // recherche: montant + 190, 64, 206, 120, // recherche: montant + 206, 64, 254, 85, // radar + 192, 168, 256, 232, // hachures carr�es + 248, 0, 256, 64, // c�ne fabrique de piles + 128, 176, 192, 240, // dessus centrale nucl�aire + 120, 85, 174, 120, // technicien, visage + 206, 106, 256, 120, // technicien, casquette + 160, 64, 174, 78, // technicien, visi�re + -1 +}; + +static int tablePartS[] = // search.tga +{ + 0, 0, 128, 128, // usine 1 + 128, 0, 256, 128, // usine 2 + 0, 128, 128, 256, // pile + 128, 128, 228, 240, // support pile + 228, 128, 256, 184, // antenne + 128, 128, 192, 160, // contr�le 1 + 128, 160, 192, 192, // contr�le 2 + 128, 192, 192, 224, // contr�le 3 + 128, 224, 192, 256, // contr�le 4 + -1 +}; + +static int tablePartP[] = // plant.tga +{ + 0, 160, 48, 256, // feuille 1 + 0, 0, 94, 100, // feuille 2 + 48, 156, 108, 256, // feuille 3 + 94, 0, 104, 100, // tige 1 + 185, 0, 195, 100, // tige 2 + 108, 100, 182, 256, // foug�re + 104, 0, 144, 100, // courge + 203, 0, 256, 83, // armature derrick r�solution C + -1 +}; + +static int tablePartV[] = // vegetal.tga +{ + 0, 0, 94, 100, // racine + 186, 0, 256, 256, // tronc + 162, 0, 168, 128, // mat drapeau bleu + 168, 0, 174, 128, // mat drapeau rouge + 174, 0, 180, 128, // mat drapeau vert + 180, 0, 186, 128, // mat drapeau jaune + 180, 128, 186, 256, // mat drapeau violet + 94, 0, 107, 32, // drapeau bleu + 107, 0, 120, 32, // drapeau rouge + 120, 0, 133, 32, // drapeau vert + 133, 0, 146, 32, // drapeau jaune + 146, 0, 159, 32, // drapeau violet + 94, 64, 126, 96, // verre 1 + 126, 64, 158, 86, // verre 2 + 128, 128, 180, 144, // verre 3a + 128, 144, 180, 160, // verre 3b + 128, 94, 162, 128, // verre 4 + 0, 100, 32, 228, // champignon 1 + 32, 100, 48, 228, // champignon 1 + 48, 100, 112, 228, // champignon 2 + 112, 100, 128, 228, // champignon 2 + 128, 160, 180, 212, // tronc (21) + -1 +}; + +static int tablePartM[] = // mother.tga +{ + 0, 0, 128, 128, // corps arri�re + 128, 0, 192, 128, // corps avant + 0, 128, 64, 192, // t�te + 64, 128, 192, 160, // pince ext. + 64, 160, 192, 192, // pince int. + 0, 192, 64, 256, // mire + -1 +}; + +static int tablePartA[] = // ant.tga +{ + 0, 0, 64, 64, // queue + 0, 96, 128, 160, // queue abeille + 64, 0, 128, 64, // corps + 128, 0, 192, 64, // t�te + 0, 64, 64, 72, // patte + 0, 72, 64, 80, // antenne + 64, 64, 150, 96, // queue ver + 150, 64, 182, 96, // corps ver + 182, 64, 256, 96, // t�te ver + 224, 32, 256, 64, // articulation ver + 128, 96, 220, 160, // aile + 0, 80, 16, 96, // oeil + 200, 0, 208, 8, // vert clair + 200, 8, 208, 16, // vert fonc� + 0, 160, 64, 224, // corps araign�e + 64, 160, 128, 192, // t�te araign�e + 208, 0, 216, 64, // patte araign�e + 216, 0, 224, 32, // patte araign�e + 224, 0, 256, 8, // antenne araign�e + 192, 0, 200, 8, // brun clair + 192, 8, 200, 16, // brun fonc� + 128, 160, 256, 256, // SatCom + -1 +}; + +static int tablePartH[] = // human.tga +{ + 0, 0, 64, 64, // vissi�re + 64, 0, 96, 64, // cuisse + 96, 0, 128, 64, // jambe + 128, 0, 192, 32, // bras + 128, 32, 192, 64, // avant-bras + 0, 64, 128, 224, // ventre + 128, 64, 256, 224, // dos + 64, 224, 112, 256, // dessus pied + 144, 224, 168, 240, // dessous pied + 112, 224, 144, 240, // c�t� pied + 112, 224, 128, 240, // c�t� pied + 0, 224, 64, 256, // gant + 168, 224, 200, 256, // oreille + 112, 240, 144, 256, // ligne casque + 200, 224, 208, 256, // int�rieur coup + 240, 0, 244, 64, // bombone orange + 244, 0, 248, 64, // bombone orange (reflet) + 248, 0, 252, 64, // bombone bleu + 252, 0, 256, 64, // bombone bleu (reflet) + 144, 240, 156, 256, // gris habit + 156, 240, 168, 256, // gris articulation +//? 208, 224, 256, 256, // SatCom + 192, 0, 240, 64, // quartz + -1 +}; + +static int tablePartG[] = // apollo.tga +{ + 0, 0, 64, 64, // rev�tement LEM + 64, 0, 128, 64, // rev�tement LEM + 128, 8, 136, 128, // pied + 0, 64, 64, 128, // roue + 136, 24, 152, 44, // profil pneu + 136, 8, 160, 24, // garde boue + 64, 64, 128, 128, // si�ge + 64, 128, 128, 192, // si�ge + 64, 192, 128, 212, // si�ge + 128, 128, 240, 192, // moteur + 0, 192, 28, 256, // moteur + 32, 128, 60, 256, // moteur + 224, 0, 256, 128, // avant + 206, 0, 224, 128, // avant + 136, 44, 168, 62, // avant + 64, 212, 108, 256, // panneau de commande + 198, 0, 206, 128, // mat + 190, 64, 198, 128, // mat + 160, 8, 176, 24, // cam�ra + 176, 8, 192, 24, // moyeu + 136, 64, 168, 96, // module + 168, 64, 190, 96, // module + 136, 96, 168, 128, // module + 128, 192, 230, 252, // drapeau + 0, 128, 32, 192, // antenne + 128, 0, 136, 8, // jaune + 136, 0, 144, 8, // beige + 144, 0, 152, 8, // brun + 168, 0, 176, 8, // gris tr�s clair + 152, 0, 160, 8, // gris clair + 160, 0, 168, 8, // gris fonc� + -1 +}; + +static int tablePartB[] = // base1.tga +{ + 0, 0, 80, 256, // int�rieur porte + 80, 0, 88, 256, // tranche porte + 116, 0, 180, 64, // coiffe 1 + 116, 64, 180, 102, // coiffe 2 + 180, 0, 244, 37, // base + 180, 37, 196, 101, // support + 88, 0, 116, 256, // colonne + 212, 37, 256, 128, // suppl�ment + 128, 128, 256, 256, // 1/4 du sol + 196, 37, 212, 53, // gris fonc� + 196, 53, 212, 69, // gris clair + -1 +}; + +static int tablePartCe[] = // cellar01.tga +{ + 0, 128, 64, 192, // briques + 64, 128, 128, 192, // briques + 128, 128, 192, 192, // briques + 192, 128, 256, 192, // briques + -1 +}; + +static int tablePartFa[] = // face01.tga +{ + 0, 0, 256, 256, // visage + -1 +}; + +// Retourne le pointeur la table. + +int* CModel::RetTextureTable() +{ + if ( m_textureRank == 0 ) return tablePartT; + if ( m_textureRank == 1 ) return tablePartR; + if ( m_textureRank == 2 ) return tablePartW; + if ( m_textureRank == 3 ) return tablePartDr; + if ( m_textureRank == 4 ) return tablePartKi; + if ( m_textureRank == 5 ) return tablePartKi2; + if ( m_textureRank == 6 ) return tablePartKi3; + if ( m_textureRank == 7 ) return tablePartF; + if ( m_textureRank == 8 ) return tablePartD; + if ( m_textureRank == 9 ) return tablePartC; + if ( m_textureRank == 10 ) return tablePartS; + if ( m_textureRank == 11 ) return tablePartP; + if ( m_textureRank == 12 ) return tablePartV; + if ( m_textureRank == 13 ) return tablePartM; + if ( m_textureRank == 14 ) return tablePartA; + if ( m_textureRank == 15 ) return tablePartH; + if ( m_textureRank == 16 ) return tablePartG; + if ( m_textureRank == 17 ) return tablePartB; + if ( m_textureRank == 18 ) return tablePartCe; + if ( m_textureRank == 19 ) return tablePartFa; + if ( m_textureRank == 20 ) return tablePartFa; + if ( m_textureRank == 21 ) return tablePartFa; + if ( m_textureRank == 22 ) return tablePartFa; + return 0; +} + +// Updates the part of texture. + +void CModel::TexturePartUpdate() +{ + int *table; + + table = RetTextureTable(); + if ( table == 0 ) return; + + m_textureInf.x = (table[m_texturePart*4+0]+0.5f)/256.0f; + m_textureInf.y = (table[m_texturePart*4+1]+0.5f)/256.0f; + m_textureSup.x = (table[m_texturePart*4+2]-0.5f)/256.0f; + m_textureSup.y = (table[m_texturePart*4+3]-0.5f)/256.0f; + + PutTextureValues(); +} + +// Changes the texture. + +void CModel::TextureRankChange(int step) +{ + m_textureRank += step; + + if ( m_textureRank >= MAX_NAMES ) m_textureRank = 0; + if ( m_textureRank < 0 ) m_textureRank = MAX_NAMES-1; + + if ( m_textureRank == 0 ) strcpy(m_textureName, "lemt.tga"); + if ( m_textureRank == 1 ) strcpy(m_textureName, "roller.tga"); + if ( m_textureRank == 2 ) strcpy(m_textureName, "subm.tga"); + if ( m_textureRank == 3 ) strcpy(m_textureName, "drawer.tga"); + if ( m_textureRank == 4 ) strcpy(m_textureName, "kid.tga"); + if ( m_textureRank == 5 ) strcpy(m_textureName, "kid2.tga"); + if ( m_textureRank == 6 ) strcpy(m_textureName, "kid3.tga"); + if ( m_textureRank == 7 ) strcpy(m_textureName, "factory.tga"); + if ( m_textureRank == 8 ) strcpy(m_textureName, "derrick.tga"); + if ( m_textureRank == 9 ) strcpy(m_textureName, "convert.tga"); + if ( m_textureRank == 10 ) strcpy(m_textureName, "search.tga"); + if ( m_textureRank == 11 ) strcpy(m_textureName, "plant.tga"); + if ( m_textureRank == 12 ) strcpy(m_textureName, "vegetal.tga"); + if ( m_textureRank == 13 ) strcpy(m_textureName, "mother.tga"); + if ( m_textureRank == 14 ) strcpy(m_textureName, "ant.tga"); + if ( m_textureRank == 15 ) strcpy(m_textureName, "human.tga"); + if ( m_textureRank == 16 ) strcpy(m_textureName, "apollo.tga"); + if ( m_textureRank == 17 ) strcpy(m_textureName, "base1.tga"); + if ( m_textureRank == 18 ) strcpy(m_textureName, "cellar01.tga"); + if ( m_textureRank == 19 ) strcpy(m_textureName, "face01.tga"); + if ( m_textureRank == 20 ) strcpy(m_textureName, "face02.tga"); + if ( m_textureRank == 21 ) strcpy(m_textureName, "face03.tga"); + if ( m_textureRank == 22 ) strcpy(m_textureName, "face04.tga"); + + m_texturePart = 0; +} + +// Changes the part of texture. + +void CModel::TexturePartChange(int step) +{ + int *table; + + table = RetTextureTable(); + if ( table == 0 ) return; + + m_texturePart ++; + + if ( table[m_texturePart*4] == -1 ) + { + m_texturePart = 0; + } + + TexturePartUpdate(); +} + + diff --git a/src/graphics/common/model.h b/src/graphics/common/model.h new file mode 100644 index 0000000..35b48b6 --- /dev/null +++ b/src/graphics/common/model.h @@ -0,0 +1,137 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// model.h + +#ifndef _MODEL_H_ +#define _MODEL_H_ + + +#include "struct.h" + + +class CInstanceManager; +class CD3DEngine; +class CModFile; +class CInterface; + + + +class CModel +{ +public: + CModel(CInstanceManager* iMan); + ~CModel(); + + void StartUserAction(); + void StopUserAction(); + + BOOL EventProcess(const Event &event); + + void InitView(); + void InitViewFromSelect(); + void UpdateView(); + void ViewMove(const Event &event, float speed); + +protected: + BOOL EventFrame(const Event &event); + BOOL GetVertex(int rank, D3DVERTEX2 &vertex); + BOOL SetVertex(int rank, D3DVERTEX2 &vertex); + D3DVECTOR RetSelectCDG(); + D3DVECTOR RetSelectNormal(); + void SmoothSelect(); + void PlaneSelect(); + void ColorSelect(); + void StateSelect(); + void MoveSelect(D3DVECTOR move); + void OperSelect(D3DVECTOR move, char oper); + void ReadScript(char *filename); + void BBoxCompute(D3DVECTOR &min, D3DVECTOR &max); + BOOL IsMappingSelectPlausible(D3DMaping D3Dmode); + void MappingSelect(int mode, int rotate, BOOL bMirrorX, BOOL bMirrorY, FPOINT ti, FPOINT ts, char *texName); + void MappingSelectSpherical(int mode, int rotate, BOOL bMirrorX, BOOL bMirrorY, FPOINT ti, FPOINT ts, char *texName); + D3DVECTOR RetMappingCenter(D3DVECTOR pos, D3DVECTOR min); + void MappingSelectCylindrical(int mode, int rotate, BOOL bMirrorX, BOOL bMirrorY, FPOINT ti, FPOINT ts, char *texName); + void MappingSelectFace(int mode, int rotate, BOOL bMirrorX, BOOL bMirrorY, FPOINT ti, FPOINT ts, char *texName); + void MappingSelect2(int texNum2, int subdiv, int offsetU, int offsetV, BOOL bMirrorX, BOOL bMirrorY); + void MappingSelectPlane2(int mode, BOOL bMirrorX, BOOL bMirrorY); + void MappingSelectSpherical2(BOOL bMirrorX, BOOL bMirrorY); + void MappingSelectMagic2(BOOL bMirrorX, BOOL bMirrorY); + int SearchNext(int rank, int step); + int SearchSamePlane(int first, int step); + void CurrentSearchNext(int step, BOOL bControl); + void CurrentInit(); + void CurrentSelect(BOOL bSelect); + void DeselectAll(); + void SelectAll(); + void SelectZone(int first, int last); + void SelectTerm(); + void DefaultSelect(); + void SelectDelete(); + void Compress(); + void MinMaxSelect(); + void MinMaxChange(); + void UpdateInfoText(); + int* RetTextureTable(); + void TexturePartUpdate(); + void TextureRankChange(int step); + void TexturePartChange(int step); + void PutTextureValues(); + void GetTextureValues(); + void GetModelName(char *buffer); + void GetDXFName(char *buffer); + void GetScriptName(char *buffer); + BOOL IsEditFocus(); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CModFile* m_modFile; + CInterface* m_interface; + + float m_time; + ModelTriangle* m_triangleTable; + int m_triangleSel1; + int m_triangleSel2; + int m_mode; + int m_textureMode; + int m_textureRotate; + BOOL m_bTextureMirrorX; + BOOL m_bTextureMirrorY; + FPOINT m_textureInf; + FPOINT m_textureSup; + int m_texturePart; + int m_textureRank; + char m_textureName[20]; + BOOL m_bDisplayTransparent; + BOOL m_bDisplayOnlySelection; + float m_viewHeight; + float m_viewDist; + float m_viewAngleH; + float m_viewAngleV; + int m_color; + int m_state; + int m_secondTexNum; + int m_secondSubdiv; + int m_secondOffsetU; + int m_secondOffsetV; + char m_oper; + float m_min; + float m_max; +}; + + +#endif //_MODEL_H_ diff --git a/src/graphics/common/particule.cpp b/src/graphics/common/particule.cpp new file mode 100644 index 0000000..0a8c27d --- /dev/null +++ b/src/graphics/common/particule.cpp @@ -0,0 +1,4373 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// particule.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dmath.h" +#include "d3dtextr.h" +#include "d3dengine.h" +#include "d3dutil.h" +#include "language.h" +#include "iman.h" +#include "math3d.h" +#include "event.h" +#include "object.h" +#include "physics.h" +#include "auto.h" +#include "robotmain.h" +#include "terrain.h" +#include "sound.h" +#include "water.h" +#include "particule.h" + + + +#define FOG_HSUP 10.0f +#define FOG_HINF 100.0f + + + + +// Check if an object can be destroyed, but is not an enemy. + +BOOL IsSoft(ObjectType type) +{ + return ( type == OBJECT_HUMAN || + type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEft || + type == OBJECT_MOBILEtt || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEit || + type == OBJECT_MOBILEdr || // robot? + type == OBJECT_METAL || + type == OBJECT_POWER || + type == OBJECT_ATOMIC || // cargo? + type == OBJECT_DERRICK || + type == OBJECT_STATION || + type == OBJECT_FACTORY || + type == OBJECT_REPAIR || + type == OBJECT_DESTROYER|| + type == OBJECT_CONVERT || + type == OBJECT_TOWER || + type == OBJECT_RESEARCH || + type == OBJECT_RADAR || + type == OBJECT_INFO || + type == OBJECT_ENERGY || + type == OBJECT_LABO || + type == OBJECT_NUCLEAR || + type == OBJECT_PARA ); // building? +} + +// Check if an object is a destroyable enemy. + +BOOL IsAlien(ObjectType type) +{ + return ( type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_BEE || + type == OBJECT_WORM || + type == OBJECT_MOTHER || + type == OBJECT_NEST || + type == OBJECT_BULLET || + type == OBJECT_EGG || + type == OBJECT_MOBILEtg || + type == OBJECT_TEEN28 || + type == OBJECT_TEEN31 ); +} + +// Returns the damping factor for friendly fire. + +float RetDecay(ObjectType type) +{ + if ( IsSoft(type) ) return 0.2f; + return 1.0f; +} + + + +// Application constructor. + +CParticule::CParticule(CInstanceManager *iMan, CD3DEngine* engine) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_PARTICULE, this); + + m_pD3DDevice = 0; + m_engine = engine; + m_main = 0; + m_terrain = 0; + m_water = 0; + m_sound = 0; + m_uniqueStamp = 0; + m_exploGunCounter = 0; + m_lastTimeGunDel = 0.0f; + m_absTime = 0.0f; + + FlushParticule(); +} + +// Application destructor. Free memory. + +CParticule::~CParticule() +{ + m_iMan->DeleteInstance(CLASS_PARTICULE, this); +} + + +void CParticule::SetD3DDevice(LPDIRECT3DDEVICE7 device) +{ + m_pD3DDevice = device; +} + + +// Removes all particles. + +void CParticule::FlushParticule() +{ + int i, j; + + for ( i=0 ; iSearchInstance(CLASS_MAIN); + } + +#if 0 + if ( sheet == SH_WORLD && + type != PARTISELY && + type != PARTISELR && + type != PARTIGUN1 && + type != PARTIGUN2 && + type != PARTIGUN3 && + type != PARTIGUN4 && + type != PARTIQUARTZ && + !m_main->RetMovieLock() ) + { + dist = Length(pos, m_engine->RetEyePt()); + if ( dist > 300.0f ) return -1; + } +#endif + + t = -1; + if ( type == PARTIEXPLOT || + type == PARTIEXPLOO || + type == PARTIMOTOR || + type == PARTIBLITZ || + type == PARTICRASH || + type == PARTIVAPOR || + type == PARTIGAS || + type == PARTIBASE || + type == PARTIFIRE || + type == PARTIFIREZ || + type == PARTIBLUE || + type == PARTIROOT || + type == PARTIRECOVER || + type == PARTIEJECT || + type == PARTISCRAPS || + type == PARTIGUN2 || + type == PARTIGUN3 || + type == PARTIGUN4 || + type == PARTIQUEUE || + type == PARTIORGANIC1 || + type == PARTIORGANIC2 || + type == PARTIFLAME || + type == PARTIBUBBLE || + type == PARTIERROR || + type == PARTIWARNING || + type == PARTIINFO || + type == PARTISPHERE1 || + type == PARTISPHERE2 || + type == PARTISPHERE4 || + type == PARTISPHERE5 || + type == PARTISPHERE6 || + type == PARTIPLOUF0 || + type == PARTITRACK1 || + type == PARTITRACK2 || + type == PARTITRACK3 || + type == PARTITRACK4 || + type == PARTITRACK5 || + type == PARTITRACK6 || + type == PARTITRACK7 || + type == PARTITRACK8 || + type == PARTITRACK9 || + type == PARTITRACK10 || + type == PARTITRACK11 || + type == PARTITRACK12 || + type == PARTILENS1 || + type == PARTILENS2 || + type == PARTILENS3 || + type == PARTILENS4 || + type == PARTIGFLAT || + type == PARTIDROP || + type == PARTIWATER || + type == PARTILIMIT1 || + type == PARTILIMIT2 || + type == PARTILIMIT3 || + type == PARTILIMIT4 || + type == PARTIEXPLOG1 || + type == PARTIEXPLOG2 ) + { + t = 1; // effect00 + } + if ( type == PARTIGLINT || + type == PARTIGLINTb || + type == PARTIGLINTr || + type == PARTITOTO || + type == PARTISELY || + type == PARTISELR || + type == PARTIQUARTZ || + type == PARTIGUNDEL || + type == PARTICONTROL || + type == PARTISHOW || + type == PARTICHOC || + type == PARTIFOG4 || + type == PARTIFOG5 || + type == PARTIFOG6 || + type == PARTIFOG7 ) + { + t = 2; // effect01 + } + if ( type == PARTIGUN1 || + type == PARTIFLIC || + type == PARTISPHERE0 || + type == PARTISPHERE3 || + type == PARTIFOG0 || + type == PARTIFOG1 || + type == PARTIFOG2 || + type == PARTIFOG3 ) + { + t = 3; // effect02 + } + if ( type == PARTISMOKE1 || + type == PARTISMOKE2 || + type == PARTISMOKE3 || + type == PARTIBLOOD || + type == PARTIBLOODM || + type == PARTIVIRUS1 || + type == PARTIVIRUS2 || + type == PARTIVIRUS3 || + type == PARTIVIRUS4 || + type == PARTIVIRUS5 || + type == PARTIVIRUS6 || + type == PARTIVIRUS7 || + type == PARTIVIRUS8 || + type == PARTIVIRUS9 || + type == PARTIVIRUS10 ) + { + t = 4; // text (D3DSTATETTw) + } + if ( t >= MAXPARTITYPE ) return -1; + if ( t == -1 ) return -1; + + for ( j=0 ; j= PARTIFOG0 && + type <= PARTIFOG9 ) + { + if ( m_fogTotal < MAXPARTIFOG ) + m_fog[m_fogTotal++] = i; + } + + return i | ((m_particule[i].uniqueStamp&0xffff)<<16); + } + } + + return -1; +} + +// Creates a new triangular particle (debris). +// Returns the channel of the particle created or -1 on error. + +int CParticule::CreateFrag(D3DVECTOR pos, D3DVECTOR speed, + D3DTriangle *triangle, + ParticuleType type, + float duration, float mass, + float windSensitivity, int sheet) +{ + D3DVECTOR p1, p2, p3, n; + float l1, l2, l3, dx, dy; + int i, j, t; + + t = 0; + for ( j=0 ; j= MAXPARTITYPE ) return -1; + if ( t == -1 ) return -1; + + for ( j=0 ; jRetWheelTraceQuantity()*MAXWHEELTRACE); + max = MAXWHEELTRACE; + i = m_wheelTraceIndex++; + if ( m_wheelTraceIndex > max ) m_wheelTraceIndex = 0; + + m_wheelTrace[i].type = type; + m_wheelTrace[i].pos[0] = p1; // ul + m_wheelTrace[i].pos[1] = p2; // dl + m_wheelTrace[i].pos[2] = p3; // ur + m_wheelTrace[i].pos[3] = p4; // dr + m_wheelTrace[i].startTime = m_absTime; + + if ( m_terrain == 0 ) + { + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + } + + m_terrain->MoveOnFloor(m_wheelTrace[i].pos[0]); + m_wheelTrace[i].pos[0].y += 0.2f; // just above the ground + + m_terrain->MoveOnFloor(m_wheelTrace[i].pos[1]); + m_wheelTrace[i].pos[1].y += 0.2f; // just above the ground + + m_terrain->MoveOnFloor(m_wheelTrace[i].pos[2]); + m_wheelTrace[i].pos[2].y += 0.2f; // just above the ground + + m_terrain->MoveOnFloor(m_wheelTrace[i].pos[3]); + m_wheelTrace[i].pos[3].y += 0.2f; // just above the ground + + if ( m_wheelTraceTotal < max ) + { + m_wheelTraceTotal ++; + } + else + { + m_wheelTraceTotal = max; + } +} + + +// Check a channel number. +// Adapts the channel so it can be used as an offset in m_particule. + +BOOL CParticule::CheckChannel(int &channel) +{ + int uniqueStamp; + + uniqueStamp = (channel>>16)&0xffff; + channel &= 0xffff; + + if ( channel < 0 ) return FALSE; + if ( channel >= MAXPARTICULE*MAXPARTITYPE ) return FALSE; +#if 0 + if ( !m_particule[channel].bUsed ) return FALSE; + + if ( m_particule[channel].uniqueStamp != uniqueStamp ) return FALSE; +#else + if ( !m_particule[channel].bUsed ) + { + OutputDebugString("CheckChannel bUsed=FALSE !\n"); + return FALSE; + } + + if ( m_particule[channel].uniqueStamp != uniqueStamp ) + { + OutputDebugString("CheckChannel uniqueStamp !\n"); + return FALSE; + } +#endif + + return TRUE; +} + +// Removes a particle after his rank. + +void CParticule::DeleteRank(int rank) +{ + int i; + + if ( m_totalInterface[rank/MAXPARTICULE][m_particule[rank].sheet] > 0 ) + { + m_totalInterface[rank/MAXPARTICULE][m_particule[rank].sheet] --; + } + + i = m_particule[rank].trackRank; + if ( i != -1 ) // drag associated? + { + m_track[i].bUsed = FALSE; // frees the drag + } + + m_particule[rank].bUsed = FALSE; +} + +// Removes all particles of a given type. + +void CParticule::DeleteParticule(ParticuleType type) +{ + int i; + + for ( i=0 ; i 0 ) + { + m_totalInterface[channel/MAXPARTICULE][m_particule[channel].sheet] --; + } + + i = m_particule[channel].trackRank; + if ( i != -1 ) // drag associated? + { + m_track[i].bUsed = FALSE; // frees the drag + } + + m_particule[channel].bUsed = FALSE; +} + + +// Specifies the object to which the particle is bound. + +void CParticule::SetObjectLink(int channel, CObject *object) +{ + if ( !CheckChannel(channel) ) return; + m_particule[channel].objLink = object; +} + +// Specifies the parent object that created the particle. + +void CParticule::SetObjectFather(int channel, CObject *object) +{ + if ( !CheckChannel(channel) ) return; + m_particule[channel].objFather = object; +} + +void CParticule::SetPosition(int channel, D3DVECTOR pos) +{ + if ( !CheckChannel(channel) ) return; + m_particule[channel].pos = pos; +} + +void CParticule::SetDimension(int channel, FPOINT dim) +{ + if ( !CheckChannel(channel) ) return; + m_particule[channel].dim = dim; +} + +void CParticule::SetZoom(int channel, float zoom) +{ + if ( !CheckChannel(channel) ) return; + m_particule[channel].zoom = zoom; +} + +void CParticule::SetAngle(int channel, float angle) +{ + if ( !CheckChannel(channel) ) return; + m_particule[channel].angle = angle; +} + +void CParticule::SetIntensity(int channel, float intensity) +{ + if ( !CheckChannel(channel) ) return; + m_particule[channel].intensity = intensity; +} + +void CParticule::SetParam(int channel, D3DVECTOR pos, FPOINT dim, float zoom, + float angle, float intensity) +{ + if ( !CheckChannel(channel) ) return; + m_particule[channel].pos = pos; + m_particule[channel].dim = dim; + m_particule[channel].zoom = zoom; + m_particule[channel].angle = angle; + m_particule[channel].intensity = intensity; +} + +void CParticule::SetPhase(int channel, ParticulePhase phase, float duration) +{ + if ( !CheckChannel(channel) ) return; + m_particule[channel].phase = phase; + m_particule[channel].duration = duration; + m_particule[channel].phaseTime = m_particule[channel].time; +} + +// Returns the position of the particle. + +BOOL CParticule::GetPosition(int channel, D3DVECTOR &pos) +{ + if ( !CheckChannel(channel) ) return FALSE; + pos = m_particule[channel].pos; + return TRUE; +} + + +// Indicates whether a sheet evolves or not. + +void CParticule::SetFrameUpdate(int sheet, BOOL bUpdate) +{ + m_bFrameUpdate[sheet] = bUpdate; +} + +// Makes evolve all the particles. + +void CParticule::FrameParticule(float rTime) +{ + CObject* object; + D3DVECTOR eye, pos, speed, wind; + FPOINT ts, ti, dim; + BOOL bPause; + float progress, dp, h, duration, mass, amplitude; + int i, j, r, total; + + if ( m_main == 0 ) + { + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + } + + bPause = ( m_engine->RetPause() && !m_main->RetInfoLock() ); + + if ( m_terrain == 0 ) + { + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + } + if ( m_water == 0 ) + { + m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); + } + + if ( !bPause ) + { + m_lastTimeGunDel += rTime; + m_absTime += rTime; + } + + wind = m_terrain->RetWind(); + eye = m_engine->RetEyePt(); + + for ( i=0 ; iRetFloorLevel(m_particule[i].pos, TRUE); + } + h += m_particule[i].dim.y*0.75f; + if ( m_particule[i].pos.y < h ) // impact with the ground? + { + if ( m_particule[i].type == PARTIPART && + m_particule[i].weight > 3.0f && // heavy enough? + m_particule[i].bounce < 3 ) + { + amplitude = m_particule[i].weight*0.1f; + amplitude *= 1.0f-0.3f*m_particule[i].bounce; + if ( amplitude > 1.0f ) amplitude = 1.0f; + if ( amplitude > 0.0f ) + { + Play(SOUND_BOUM, m_particule[i].pos, amplitude); + } + } + + if ( m_particule[i].bounce < 3 ) + { + m_particule[i].pos.y = h; + m_particule[i].speed.y *= -0.4f; + m_particule[i].speed.x *= 0.4f; + m_particule[i].speed.z *= 0.4f; + m_particule[i].bounce ++; // more impact + } + else // disappears after 3 bounces? + { + if ( m_particule[i].pos.y < h-10.0f || + m_particule[i].time >= 20.0f ) + { + DeleteRank(i); + continue; + } + } + } + } + + // Manages drag associated. + r = m_particule[i].trackRank; + if ( r != -1 ) // drag exists? + { + if ( TrackMove(r, m_particule[i].pos, progress) ) + { + DeleteRank(i); + continue; + } + + m_track[r].bDrawParticule = (progress < 1.0f); + } + + if ( m_particule[i].type == PARTITRACK1 ) // explosion technique? + { + m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); + + ts.x = 0.375f; + ts.y = 0.000f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTITRACK2 ) // spray blue? + { + m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); + + ts.x = 0.500f; + ts.y = 0.000f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTITRACK3 ) // spider? + { + m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); + + ts.x = 0.500f; + ts.y = 0.750f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTITRACK4 ) // insect explosion? + { + m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); + + ts.x = 0.625f; + ts.y = 0.000f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTITRACK5 ) // derrick? + { + m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); + + ts.x = 0.750f; + ts.y = 0.000f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTITRACK6 ) // reset in/out? + { + ts.x = 0.0f; + ts.y = 0.0f; + ti.x = 0.0f; + ti.y = 0.0f; + } + + if ( m_particule[i].type == PARTITRACK7 || // win-1 ? + m_particule[i].type == PARTITRACK8 || // win-2 ? + m_particule[i].type == PARTITRACK9 || // win-3 ? + m_particule[i].type == PARTITRACK10 ) // win-4 ? + { + m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); + + ts.x = 0.25f*(m_particule[i].type-PARTITRACK7); + ts.y = 0.25f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTITRACK11 ) // phazer shot? + { + object = SearchObjectGun(m_particule[i].goal, m_particule[i].pos, m_particule[i].type, m_particule[i].objFather); + m_particule[i].goal = m_particule[i].pos; + if ( object != 0 ) + { + if ( object->RetType() == OBJECT_MOTHER ) + { + object->ExploObject(EXPLO_BOUM, 0.1f); + } + else + { + object->ExploObject(EXPLO_BOUM, 0.0f, RetDecay(object->RetType())); + } + } + + m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); + + ts.x = 0.375f; + ts.y = 0.000f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTITRACK12 ) // drag reactor? + { + m_particule[i].zoom = 1.0f; + + ts.x = 0.375f; + ts.y = 0.000f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIMOTOR ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f-progress; + m_particule[i].intensity = 1.0f-progress; + + ts.x = 0.000f; + ts.y = 0.750f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIBLITZ ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f-progress; + m_particule[i].angle = Rand()*PI*2.0f; + + ts.x = 0.125f; + ts.y = 0.750f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTICRASH ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + +//? m_particule[i].intensity = 1.0f-progress; + if ( progress < 0.25f ) + { + m_particule[i].zoom = progress/0.25f; + } + else + { + m_particule[i].intensity = 1.0f-(progress-0.25f)/0.75f; + } + +//? ts.x = 0.250f; + ts.x = 0.000f; +//? ts.x = 0.375f; + ts.y = 0.750f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIVAPOR ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].intensity = 1.0f-progress; + m_particule[i].zoom = 1.0f+progress*3.0f; + + ts.x = 0.000f; + ts.y = 0.750f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIGAS ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f-progress; + + ts.x = 0.375f; + ts.y = 0.750f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIBASE ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f+progress*7.0f; + m_particule[i].intensity = powf(1.0f-progress, 3.0f); + + ts.x = 0.375f; + ts.y = 0.750f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIFIRE || + m_particule[i].type == PARTIFIREZ ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( m_particule[i].type == PARTIFIRE ) + { + m_particule[i].zoom = 1.0f-progress; + } + else + { + m_particule[i].zoom = progress; + } + + ts.x = 0.500f; + ts.y = 0.750f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIGUN1 ) // fireball shot? + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( m_particule[i].testTime >= 0.1f ) + { + m_particule[i].testTime = 0.0f; + + if ( m_terrain->RetFloorHeight(m_particule[i].pos, TRUE) < -2.0f ) + { + m_exploGunCounter ++; + + if ( m_exploGunCounter%2 == 0 ) + { + pos = m_particule[i].goal; + m_terrain->MoveOnFloor(pos, TRUE); + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 0.0f; + dim.x = Rand()*6.0f+6.0f; + dim.y = dim.x; + duration = Rand()*1.0f+1.0f; + mass = 0.0f; + CreateParticule(pos, speed, dim, PARTIEXPLOG1, duration, mass, 1.0f); + + pos.y += 1.0f; + total = (int)(2.0f*m_engine->RetParticuleDensity()); + for ( j=0 ; jExploObject(EXPLO_BURN, 0.0f, RetDecay(object->RetType())); + + m_exploGunCounter ++; + + if ( m_exploGunCounter%2 == 0 ) + { + pos = m_particule[i].pos; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 0.0f; + dim.x = Rand()*6.0f+6.0f; + dim.y = dim.x; + duration = Rand()*1.0f+1.0f; + mass = 0.0f; + CreateParticule(pos, speed, dim, PARTIEXPLOG1, duration, mass, 1.0f); + + pos.y += 1.0f; + total = (int)(2.0f*m_engine->RetParticuleDensity()); + for ( j=0 ; j= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( m_particule[i].testTime >= 0.2f ) + { + m_particule[i].testTime = 0.0f; + object = SearchObjectGun(m_particule[i].goal, m_particule[i].pos, m_particule[i].type, m_particule[i].objFather); + m_particule[i].goal = m_particule[i].pos; + if ( object != 0 ) + { + if ( object->RetShieldRadius() > 0.0f ) // protected by shield? + { + CreateParticule(m_particule[i].pos, D3DVECTOR(0.0f, 0.0f, 0.0f), FPOINT(6.0f, 6.0f), PARTIGUNDEL, 2.0f); + if ( m_lastTimeGunDel > 0.2f ) + { + m_lastTimeGunDel = 0.0f; + Play(SOUND_GUNDEL, m_particule[i].pos, 1.0f); + } + DeleteRank(i); + continue; + } + else + { + if ( object->RetType() != OBJECT_HUMAN ) + { + Play(SOUND_TOUCH, m_particule[i].pos, 1.0f); + } + object->ExploObject(EXPLO_BOUM, 0.0f); // starts explosion + } + } + } + + m_particule[i].angle = Rand()*PI*2.0f; + m_particule[i].zoom = 1.0f-progress; + + ts.x = 0.125f; + ts.y = 0.875f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIGUN3 ) // spider suicides? + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( m_particule[i].testTime >= 0.2f ) + { + m_particule[i].testTime = 0.0f; + object = SearchObjectGun(m_particule[i].goal, m_particule[i].pos, m_particule[i].type, m_particule[i].objFather); + m_particule[i].goal = m_particule[i].pos; + if ( object != 0 ) + { + if ( object->RetShieldRadius() > 0.0f ) + { + CreateParticule(m_particule[i].pos, D3DVECTOR(0.0f, 0.0f, 0.0f), FPOINT(6.0f, 6.0f), PARTIGUNDEL, 2.0f); + if ( m_lastTimeGunDel > 0.2f ) + { + m_lastTimeGunDel = 0.0f; + Play(SOUND_GUNDEL, m_particule[i].pos, 1.0f); + } + DeleteRank(i); + continue; + } + else + { + object->ExploObject(EXPLO_BURN, 1.0f); // starts explosion + } + } + } + +//? ts.x = 0.875f; +//? ts.y = 0.750f; + ts.x = 0.500f; + ts.y = 0.750f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIGUN4 ) // orgaball shot? + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( m_particule[i].testTime >= 0.1f ) + { + m_particule[i].testTime = 0.0f; + + if ( m_terrain->RetFloorHeight(m_particule[i].pos, TRUE) < -2.0f ) + { + m_exploGunCounter ++; + + if ( m_exploGunCounter%2 == 0 ) + { + pos = m_particule[i].goal; + m_terrain->MoveOnFloor(pos, TRUE); + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 0.0f; + dim.x = Rand()*4.0f+2.0f; + dim.y = dim.x; + duration = Rand()*0.7f+0.7f; + mass = 0.0f; + CreateParticule(pos, speed, dim, PARTIEXPLOG2, duration, mass, 1.0f); + } + + if ( m_exploGunCounter%4 == 0 ) + { + Play(SOUND_EXPLOg2, pos, 0.5f); + } + + DeleteRank(i); + continue; + } + + object = SearchObjectGun(m_particule[i].goal, m_particule[i].pos, m_particule[i].type, m_particule[i].objFather); + m_particule[i].goal = m_particule[i].pos; + if ( object != 0 ) + { + object->ExploObject(EXPLO_BOUM, 0.0f, RetDecay(object->RetType())); + + m_exploGunCounter ++; + + if ( m_exploGunCounter%2 == 0 ) + { + pos = m_particule[i].pos; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 0.0f; + dim.x = Rand()*4.0f+2.0f; + dim.y = dim.x; + duration = Rand()*0.7f+0.7f; + mass = 0.0f; + CreateParticule(pos, speed, dim, PARTIEXPLOG2, duration, mass, 1.0f); + } + + if ( m_exploGunCounter%4 == 0 ) + { + Play(SOUND_EXPLOg2, pos, 0.5f); + } + + DeleteRank(i); + continue; + } + } + + m_particule[i].angle = Rand()*PI*2.0f; + m_particule[i].zoom = 1.0f-progress; + + ts.x = 0.125f; + ts.y = 0.875f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIFLIC ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 0.1f+progress; + m_particule[i].intensity = 1.0f-progress; + + ts.x = 0.00f; + ts.y = 0.75f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTISHOW ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( progress < 0.5f ) m_particule[i].intensity = progress/0.5f; + else m_particule[i].intensity = 2.0f-progress/0.5f; + m_particule[i].zoom = 1.0f-progress*0.8f; + m_particule[i].angle -= rTime*PI*0.5f; + + ts.x = 0.50f; + ts.y = 0.00f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTICHOC ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 0.1f+progress; + m_particule[i].intensity = 1.0f-progress; + + ts.x = 0.50f; + ts.y = 0.50f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTIGFLAT ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 0.1f+progress; + m_particule[i].intensity = 1.0f-progress; + m_particule[i].angle -= rTime*PI*2.0f; + + ts.x = 0.00f; + ts.y = 0.50f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTILIMIT1 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f; + m_particule[i].intensity = 1.0f; + + ts.x = 0.000f; + ts.y = 0.125f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + if ( m_particule[i].type == PARTILIMIT2 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f; + m_particule[i].intensity = 1.0f; + + ts.x = 0.375f; + ts.y = 0.125f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + if ( m_particule[i].type == PARTILIMIT3 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f; + m_particule[i].intensity = 1.0f; + + ts.x = 0.500f; + ts.y = 0.125f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIFOG0 ) + { + m_particule[i].zoom = progress; + m_particule[i].intensity = 0.3f+sinf(progress)*0.15f; + m_particule[i].angle += rTime*0.05f; + + ts.x = 0.25f; + ts.y = 0.75f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + if ( m_particule[i].type == PARTIFOG1 ) + { + m_particule[i].zoom = progress; + m_particule[i].intensity = 0.3f+sinf(progress)*0.15f; + m_particule[i].angle -= rTime*0.07f; + + ts.x = 0.25f; + ts.y = 0.75f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTIFOG2 ) + { + m_particule[i].zoom = progress; + m_particule[i].intensity = 0.6f+sinf(progress)*0.15f; + m_particule[i].angle += rTime*0.05f; + + ts.x = 0.75f; + ts.y = 0.75f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + if ( m_particule[i].type == PARTIFOG3 ) + { + m_particule[i].zoom = progress; + m_particule[i].intensity = 0.6f+sinf(progress)*0.15f; + m_particule[i].angle -= rTime*0.07f; + + ts.x = 0.75f; + ts.y = 0.75f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTIFOG4 ) + { + m_particule[i].zoom = progress; + m_particule[i].intensity = 0.5f+sinf(progress)*0.2f; + m_particule[i].angle += rTime*0.05f; + + ts.x = 0.00f; + ts.y = 0.25f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + if ( m_particule[i].type == PARTIFOG5 ) + { + m_particule[i].zoom = progress; + m_particule[i].intensity = 0.5f+sinf(progress)*0.2f; + m_particule[i].angle -= rTime*0.07f; + + ts.x = 0.00f; + ts.y = 0.25f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTIFOG6 ) + { + m_particule[i].zoom = progress; + m_particule[i].intensity = 0.5f+sinf(progress)*0.2f; + m_particule[i].angle += rTime*0.05f; + + ts.x = 0.50f; + ts.y = 0.25f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + if ( m_particule[i].type == PARTIFOG7 ) + { + m_particule[i].zoom = progress; + m_particule[i].intensity = 0.5f+sinf(progress)*0.2f; + m_particule[i].angle -= rTime*0.07f; + + ts.x = 0.50f; + ts.y = 0.25f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + // Decreases the intensity if the camera + // is almost at the same height (fog was eye level). + if ( m_particule[i].type >= PARTIFOG0 && + m_particule[i].type <= PARTIFOG9 ) + { + h = 10.0f; + + if ( m_particule[i].pos.y >= eye.y && + m_particule[i].pos.y < eye.y+h ) + { + m_particule[i].intensity *= (m_particule[i].pos.y-eye.y)/h; + } + if ( m_particule[i].pos.y > eye.y-h && + m_particule[i].pos.y < eye.y ) + { + m_particule[i].intensity *= (eye.y-m_particule[i].pos.y)/h; + } + } + + if ( m_particule[i].type == PARTIEXPLOT || + m_particule[i].type == PARTIEXPLOO ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f-progress/2.0f; + m_particule[i].intensity = 1.0f-progress; + + if ( m_particule[i].type == PARTIEXPLOT ) ts.x = 0.750f; + else ts.x = 0.875f; + ts.y = 0.750f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIEXPLOG1 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].intensity = 1.0f-progress; + + ts.x = 0.375f; + ts.y = 0.000f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + if ( m_particule[i].type == PARTIEXPLOG2 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].intensity = 1.0f-progress; + + ts.x = 0.625f; + ts.y = 0.000f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIFLAME ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f-progress/2.0f; + if ( progress < 0.5f ) + { + m_particule[i].intensity = progress/0.5f; + } + else + { + m_particule[i].intensity = 2.0f-progress/0.5f; + } + + ts.x = 0.750f; + ts.y = 0.750f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIBUBBLE ) + { + if ( progress >= 1.0f || + m_particule[i].pos.y >= m_water->RetLevel() ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f-progress/2.0f; + m_particule[i].intensity = 1.0f-progress; + + ts.x = 0.250f; + ts.y = 0.875f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTISMOKE1 || + m_particule[i].type == PARTISMOKE2 || + m_particule[i].type == PARTISMOKE3 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( progress < 0.25f ) + { + m_particule[i].zoom = progress/0.25f; + } + else + { + m_particule[i].intensity = 1.0f-(progress-0.25f)/0.75f; + } + + ts.x = 0.500f+0.125f*(m_particule[i].type-PARTISMOKE1); + ts.y = 0.750f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIBLOOD ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].intensity = 1.0f-progress; + + ts.x = 0.750f+(rand()%2)*0.125f; + ts.y = 0.875f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIBLOODM ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].intensity = 1.0f-progress; + + ts.x = 0.875f; + ts.y = 0.750f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIVIRUS1 || + m_particule[i].type == PARTIVIRUS2 || + m_particule[i].type == PARTIVIRUS3 || + m_particule[i].type == PARTIVIRUS4 || + m_particule[i].type == PARTIVIRUS5 || + m_particule[i].type == PARTIVIRUS6 || + m_particule[i].type == PARTIVIRUS7 || + m_particule[i].type == PARTIVIRUS8 || + m_particule[i].type == PARTIVIRUS9 || + m_particule[i].type == PARTIVIRUS10 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( progress < 0.25f ) + { + m_particule[i].zoom = progress/0.25f; + } + else + { + m_particule[i].intensity = 1.0f-(progress-0.25f)/0.75f; + } + m_particule[i].angle += rTime*PI*1.0f; + + if ( m_particule[i].type == PARTIVIRUS1 ) // A ? + { + ts.x = 0.0f/256.0f; ts.y = 19.0f/256.0f; + ti.x = 10.0f/256.0f; ti.y = 30.0f/256.0f; + } + if ( m_particule[i].type == PARTIVIRUS2 ) // C ? + { + ts.x = 19.0f/256.0f; ts.y = 19.0f/256.0f; + ti.x = 28.0f/256.0f; ti.y = 30.0f/256.0f; + } + if ( m_particule[i].type == PARTIVIRUS3 ) // E ? + { + ts.x = 36.0f/256.0f; ts.y = 19.0f/256.0f; + ti.x = 45.0f/256.0f; ti.y = 30.0f/256.0f; + } + if ( m_particule[i].type == PARTIVIRUS4 ) // N ? + { + ts.x = 110.0f/256.0f; ts.y = 19.0f/256.0f; + ti.x = 120.0f/256.0f; ti.y = 30.0f/256.0f; + } + if ( m_particule[i].type == PARTIVIRUS5 ) // R ? + { + ts.x = 148.0f/256.0f; ts.y = 19.0f/256.0f; + ti.x = 158.0f/256.0f; ti.y = 30.0f/256.0f; + } + if ( m_particule[i].type == PARTIVIRUS6 ) // T ? + { + ts.x = 166.0f/256.0f; ts.y = 19.0f/256.0f; + ti.x = 175.0f/256.0f; ti.y = 30.0f/256.0f; + } + if ( m_particule[i].type == PARTIVIRUS7 ) // 0 ? + { + ts.x = 90.0f/256.0f; ts.y = 2.0f/256.0f; + ti.x = 98.0f/256.0f; ti.y = 13.0f/256.0f; + } + if ( m_particule[i].type == PARTIVIRUS8 ) // 2 ? + { + ts.x = 103.0f/256.0f; ts.y = 2.0f/256.0f; + ti.x = 111.0f/256.0f; ti.y = 13.0f/256.0f; + } + if ( m_particule[i].type == PARTIVIRUS9 ) // 5 ? + { + ts.x = 125.0f/256.0f; ts.y = 2.0f/256.0f; + ti.x = 132.0f/256.0f; ti.y = 13.0f/256.0f; + } + if ( m_particule[i].type == PARTIVIRUS10 ) // 9 ? + { + ts.x = 153.0f/256.0f; ts.y = 2.0f/256.0f; + ti.x = 161.0f/256.0f; ti.y = 13.0f/256.0f; + } + } + + if ( m_particule[i].type == PARTIBLUE ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f-progress; + + ts.x = 0.625f; + ts.y = 0.750f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIROOT ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( progress < 0.25f ) + { + m_particule[i].zoom = progress/0.25f; + } + else + { + m_particule[i].intensity = 1.0f-(progress-0.25f)/0.75f; + } + + ts.x = 0.000f; + ts.y = 0.000f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIRECOVER ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( progress < 0.25f ) + { + m_particule[i].zoom = progress/0.25f; + } + else + { + m_particule[i].intensity = 1.0f-(progress-0.25f)/0.75f; + } + + ts.x = 0.875f; + ts.y = 0.000f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIEJECT ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f+powf(progress, 2.0f)*5.0f; + m_particule[i].intensity = 1.0f-progress; + + ts.x = 0.625f; + ts.y = 0.875f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTISCRAPS ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f-progress; + + ts.x = 0.625f; + ts.y = 0.875f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIFRAG ) + { + m_particule[i].angle += rTime*PI*0.5f; + + ts.x = 0.0f; + ts.y = 0.0f; + ti.x = 0.0f; + ti.y = 0.0f; + } + + if ( m_particule[i].type == PARTIPART ) + { + ts.x = 0.0f; + ts.y = 0.0f; + ti.x = 0.0f; + ti.y = 0.0f; + } + + if ( m_particule[i].type == PARTIQUEUE ) + { + if ( m_particule[i].testTime >= 0.05f ) + { + m_particule[i].testTime = 0.0f; + + D3DVECTOR pos, speed; + FPOINT dim; + + pos = m_particule[i].pos; +//? speed = -m_particule[i].speed*0.5f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 1.0f*(Rand()*0.8f+0.6f); + dim.y = dim.x; + CreateParticule(pos, speed, dim, PARTIGAS, 0.5f); + } + + ts.x = 0.375f; + ts.y = 0.750f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIORGANIC1 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + + pos = m_particule[i].pos; + dim.x = m_particule[i].dim.x/4.0f; + dim.y = dim.x; + duration = m_particule[i].duration; + mass = m_particule[i].mass; + total = (int)(10.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; iRetParticuleDensity()); + for ( i=0 ; i= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); + + ts.x = 0.125f; + ts.y = 0.875f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIGLINT ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( progress > 0.5f ) + { +//? m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration/2.0f); + m_particule[i].zoom = 1.0f-(progress-0.5f)*2.0f; + } + m_particule[i].angle = m_particule[i].time*PI; + + ts.x = 0.75f; + ts.y = 0.25f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTIGLINTb ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( progress > 0.5f ) + { + m_particule[i].zoom = 1.0f-(progress-0.5f)*2.0f; + } + m_particule[i].angle = m_particule[i].time*PI; + + ts.x = 0.75f; + ts.y = 0.50f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTIGLINTr ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( progress > 0.5f ) + { + m_particule[i].zoom = 1.0f-(progress-0.5f)*2.0f; + } + m_particule[i].angle = m_particule[i].time*PI; + + ts.x = 0.75f; + ts.y = 0.00f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type >= PARTILENS1 && + m_particule[i].type <= PARTILENS4 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( progress < 0.5f ) + { + m_particule[i].zoom = progress*2.0f; + } + else + { + m_particule[i].intensity = 1.0f-(progress-0.5f)*2.0f; + } +//? m_particule[i].angle = m_particule[i].time*PI; + + ts.x = 0.25f*(m_particule[i].type-PARTILENS1); + ts.y = 0.25f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTICONTROL ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( progress < 0.3f ) + { + m_particule[i].zoom = progress/0.3f; + } + else + { + m_particule[i].zoom = 1.0f; + m_particule[i].intensity = 1.0f-(progress-0.3f)/0.7f; + } + + ts.x = 0.00f; + ts.y = 0.00f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTIGUNDEL ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( progress > 0.5f ) + { + m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration/2.0f); + } + m_particule[i].angle = m_particule[i].time*PI; + + ts.x = 0.75f; + ts.y = 0.50f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTIQUARTZ ) + { + if ( progress >= 1.0f ) + { + m_particule[i].time = 0.0f; + m_particule[i].duration = 0.5f+Rand()*2.0f; + m_particule[i].pos.x = m_particule[i].speed.x + (Rand()-0.5f)*m_particule[i].mass; + m_particule[i].pos.y = m_particule[i].speed.y + (Rand()-0.5f)*m_particule[i].mass; + m_particule[i].pos.z = m_particule[i].speed.z + (Rand()-0.5f)*m_particule[i].mass; + m_particule[i].dim.x = 0.5f+Rand()*1.5f; + m_particule[i].dim.y = m_particule[i].dim.x; + progress = 0.0f; + } + + if ( progress < 0.2f ) + { + m_particule[i].zoom = progress/0.2f; + m_particule[i].intensity = 1.0f; + } + else + { + m_particule[i].zoom = 1.0f; + m_particule[i].intensity = 1.0f-(progress-0.2f)/0.8f; + } + + ts.x = 0.25f; + ts.y = 0.25f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTITOTO ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f-progress; + if ( progress < 0.15f ) + { + m_particule[i].intensity = progress/0.15f; + } + else + { + m_particule[i].intensity = 1.0f-(progress-0.15f)/0.85f; + } + m_particule[i].intensity *= 0.5f; + + ts.x = 0.25f; + ts.y = 0.50f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTIERROR ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = progress*1.0f; + m_particule[i].intensity = 1.0f-progress; + + ts.x = 0.500f; + ts.y = 0.875f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIWARNING ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = progress*1.0f; + m_particule[i].intensity = 1.0f-progress; + + ts.x = 0.875f; + ts.y = 0.875f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIINFO ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = progress*1.0f; + m_particule[i].intensity = 1.0f-progress; + + ts.x = 0.750f; + ts.y = 0.875f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTISELY ) + { + ts.x = 0.75f; + ts.y = 0.25f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + if ( m_particule[i].type == PARTISELR ) + { + ts.x = 0.75f; + ts.y = 0.00f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTISPHERE0 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = progress*m_particule[i].dim.x; +//? m_particule[i].intensity = 1.0f-progress; + if ( progress < 0.65f ) + { + m_particule[i].intensity = progress/0.65f; + } + else + { + m_particule[i].intensity = 1.0f-(progress-0.65f)/0.35f; + } + m_particule[i].intensity *= 0.5f; + + ts.x = 0.50f; + ts.y = 0.75f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTISPHERE1 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( progress < 0.30f ) + { + m_particule[i].intensity = progress/0.30f; + } + else + { + m_particule[i].intensity = 1.0f-(progress-0.30f)/0.70f; + } + m_particule[i].zoom = progress*m_particule[i].dim.x; + m_particule[i].angle = m_particule[i].time*PI*2.0f; + + ts.x = 0.000f; + ts.y = 0.000f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTISPHERE2 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( progress < 0.20f ) + { + m_particule[i].intensity = 1.0f; + } + else + { + m_particule[i].intensity = 1.0f-(progress-0.20f)/0.80f; + } + m_particule[i].zoom = progress*m_particule[i].dim.x; + m_particule[i].angle = m_particule[i].time*PI*2.0f; + + ts.x = 0.125f; + ts.y = 0.000f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTISPHERE3 ) + { + if ( m_particule[i].phase == PARPHEND && + progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( m_particule[i].phase == PARPHSTART ) + { + m_particule[i].intensity = progress; + if ( m_particule[i].intensity > 1.0f ) + { + m_particule[i].intensity = 1.0f; + } + } + + if ( m_particule[i].phase == PARPHEND ) + { + m_particule[i].intensity = 1.0f-progress; + } + + m_particule[i].zoom = m_particule[i].dim.x; + m_particule[i].angle = m_particule[i].time*PI*0.2f; + + ts.x = 0.25f; + ts.y = 0.75f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTISPHERE4 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = progress*m_particule[i].dim.x; + if ( progress < 0.65f ) + { + m_particule[i].intensity = progress/0.65f; + } + else + { + m_particule[i].intensity = 1.0f-(progress-0.65f)/0.35f; + } + m_particule[i].intensity *= 0.5f; + + ts.x = 0.125f; + ts.y = 0.000f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTISPHERE5 ) + { + m_particule[i].intensity = 0.7f+sinf(progress)*0.3f; + m_particule[i].zoom = m_particule[i].dim.x*(1.0f+sinf(progress*0.7f)*0.01f); + m_particule[i].angle = m_particule[i].time*PI*0.2f; + + ts.x = 0.25f; + ts.y = 0.50f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTISPHERE6 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = (1.0f-progress)*m_particule[i].dim.x; + m_particule[i].intensity = progress*0.5f; + + ts.x = 0.125f; + ts.y = 0.000f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIPLOUF0 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = progress; +#if 0 + if ( progress <= 0.5f ) + { + m_particule[i].intensity = 1.0f; + } + else + { + m_particule[i].intensity = 1.0f-(progress-0.5f)/0.5f; + } +#else +//? m_particule[i].intensity = 1.0f; + m_particule[i].intensity = 1.0f-progress; +#endif + + ts.x = 0.50f; + ts.y = 0.50f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTIDROP ) + { + if ( progress >= 1.0f || + m_particule[i].pos.y < m_water->RetLevel() ) + { + DeleteRank(i); + continue; + } + + m_particule[i].zoom = 1.0f-progress; + m_particule[i].intensity = 1.0f-progress; + + ts.x = 0.750f; + ts.y = 0.500f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIWATER ) + { + if ( progress >= 1.0f || + m_particule[i].pos.y < m_water->RetLevel() ) + { + DeleteRank(i); + continue; + } + + m_particule[i].intensity = 1.0f-progress; + + ts.x = 0.125f; + ts.y = 0.125f; + ti.x = ts.x+0.125f; + ti.y = ts.y+0.125f; + } + + if ( m_particule[i].type == PARTIRAY1 ) // rayon tour ? + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + if ( m_particule[i].testTime >= 0.2f ) + { + m_particule[i].testTime = 0.0f; + object = SearchObjectRay(m_particule[i].pos, m_particule[i].goal, + m_particule[i].type, m_particule[i].objFather); + if ( object != 0 ) + { + object->ExploObject(EXPLO_BOUM, 0.0f); + } + } + + ts.x = 0.00f; + ts.y = 0.00f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + if ( m_particule[i].type == PARTIRAY2 || + m_particule[i].type == PARTIRAY3 ) + { + if ( progress >= 1.0f ) + { + DeleteRank(i); + continue; + } + + ts.x = 0.00f; + ts.y = 0.25f; + ti.x = ts.x+0.25f; + ti.y = ts.y+0.25f; + } + + dp = (1.0f/256.0f)/2.0f; + m_particule[i].texSup.x = ts.x+dp; + m_particule[i].texSup.y = ts.y+dp; + m_particule[i].texInf.x = ti.x-dp; + m_particule[i].texInf.y = ti.y-dp; + m_particule[i].time += rTime; + m_particule[i].testTime += rTime; + } +} + + +// Moves a drag. +// Returns true if the drag is finished. + +BOOL CParticule::TrackMove(int i, D3DVECTOR pos, float progress) +{ + D3DVECTOR last; + int h, hh; + + if ( i < 0 || i >= MAXTRACK ) return TRUE; + if ( m_track[i].bUsed == FALSE ) return TRUE; + + if ( progress < 1.0f ) // particle exists? + { + h = m_track[i].head; + + if ( m_track[i].used == 1 || + m_track[i].last+m_track[i].step <= progress ) + { + m_track[i].last = progress; + last = m_track[i].pos[h]; + h ++; + if ( h == MAXTRACKLEN ) h = 0; + if ( m_track[i].used < MAXTRACKLEN ) m_track[i].used ++; + } + else + { + hh = h-1; + if ( hh < 0 ) hh = MAXTRACKLEN-1; + last = m_track[i].pos[hh]; + } + m_track[i].pos[h] = pos; + m_track[i].len[h] = Length(pos, last); + + m_track[i].head = h; + +//? m_track[i].intensity = 1.0f; + m_track[i].intensity = 1.0f-progress; + } + else // mort lente de la tra�n�e ? + { +//? m_track[i].intensity = 1.0f-(progress-1.0f)/(m_track[i].step*MAXTRACKLEN); + m_track[i].intensity = 0.0f; + } + + return (m_track[i].intensity <= 0.0f); +} + +// Draws a drag. + +void CParticule::TrackDraw(int i, ParticuleType type) +{ + D3DVERTEX2 vertex[4]; // 2 triangles + D3DVECTOR corner[4], p1, p2, p, n, eye; + D3DMATRIX matrix; + FPOINT texInf, texSup, rot; + float lTotal, f1, f2, a; + int counter, h; + + // Calculates the total length memorized. + lTotal = 0.0f; + h = m_track[i].head; + for ( counter=0 ; counterSetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); + + if ( type == PARTITRACK1 ) // explosion technique? + { + texInf.x = 64.5f/256.0f; + texInf.y = 21.0f/256.0f; + texSup.x = 95.5f/256.0f; + texSup.y = 22.0f/256.0f; // orange + } + if ( type == PARTITRACK2 ) // blue spray? + { + texInf.x = 64.5f/256.0f; + texInf.y = 13.0f/256.0f; + texSup.x = 95.5f/256.0f; + texSup.y = 14.0f/256.0f; // blue + } + if ( type == PARTITRACK3 ) // spider? + { + texInf.x = 64.5f/256.0f; + texInf.y = 5.0f/256.0f; + texSup.x = 95.5f/256.0f; + texSup.y = 6.0f/256.0f; // brown + } + if ( type == PARTITRACK4 ) // insect explosion? + { + texInf.x = 64.5f/256.0f; + texInf.y = 9.0f/256.0f; + texSup.x = 95.5f/256.0f; + texSup.y = 10.0f/256.0f; // dark green + } + if ( type == PARTITRACK5 ) // derrick? + { + texInf.x = 64.5f/256.0f; + texInf.y = 29.0f/256.0f; + texSup.x = 95.5f/256.0f; + texSup.y = 30.0f/256.0f; // dark brown + } + if ( type == PARTITRACK6 ) // reset in/out? + { + texInf.x = 64.5f/256.0f; + texInf.y = 17.0f/256.0f; + texSup.x = 95.5f/256.0f; + texSup.y = 18.0f/256.0f; // cyan + } + if ( type == PARTITRACK7 ) // win-1? + { + texInf.x = 64.5f/256.0f; + texInf.y = 41.0f/256.0f; + texSup.x = 95.5f/256.0f; + texSup.y = 42.0f/256.0f; // orange + } + if ( type == PARTITRACK8 ) // win-2? + { + texInf.x = 64.5f/256.0f; + texInf.y = 45.0f/256.0f; + texSup.x = 95.5f/256.0f; + texSup.y = 46.0f/256.0f; // yellow + } + if ( type == PARTITRACK9 ) // win-3? + { + texInf.x = 64.5f/256.0f; + texInf.y = 49.0f/256.0f; + texSup.x = 95.5f/256.0f; + texSup.y = 50.0f/256.0f; // red + } + if ( type == PARTITRACK10 ) // win-4? + { + texInf.x = 64.5f/256.0f; + texInf.y = 53.0f/256.0f; + texSup.x = 95.5f/256.0f; + texSup.y = 54.0f/256.0f; // violet + } + if ( type == PARTITRACK11 ) // phazer shot? + { + texInf.x = 64.5f/256.0f; + texInf.y = 21.0f/256.0f; + texSup.x = 95.5f/256.0f; + texSup.y = 22.0f/256.0f; // orange + } + if ( type == PARTITRACK12 ) // drag reactor? + { + texInf.x = 64.5f/256.0f; + texInf.y = 21.0f/256.0f; + texSup.x = 95.5f/256.0f; + texSup.y = 22.0f/256.0f; // orange + } + + h = m_track[i].head; + p1 = m_track[i].pos[h]; + f1 = m_track[i].intensity; + + eye = m_engine->RetEyePt(); + a = RotateAngle(eye.x-p1.x, eye.z-p1.z); + + for ( counter=0 ; counterDrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); + + if ( f2 < 0.0f ) break; + f1 = f2; + p1 = p2; + } +} + +// Draws a triangular particle. + +void CParticule::DrawParticuleTriangle(int i) +{ + CObject* object; + D3DMATRIX matrix; + D3DVECTOR eye, pos, angle; + + if ( m_particule[i].zoom == 0.0f ) return; + + eye = m_engine->RetEyePt(); + pos = m_particule[i].pos; + + object = m_particule[i].objLink; + if ( object != 0 ) + { + pos += object->RetPosition(0); + } + + angle.x = -RotateAngle(Length2d(pos, eye), pos.y-eye.y); + angle.y = RotateAngle(pos.z-eye.z, pos.x-eye.x); + angle.z = m_particule[i].angle; + + MatRotateXZY(matrix, angle); + matrix._41 = pos.x; + matrix._42 = pos.y; + matrix._43 = pos.z; + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_VERTEX2, + m_triangle[i].triangle, 3, NULL); + m_engine->AddStatisticTriangle(1); +} + +// Draw a normal particle. + +void CParticule::DrawParticuleNorm(int i) +{ + CObject* object; + D3DVERTEX2 vertex[4]; // 2 triangles + D3DMATRIX matrix; + D3DVECTOR corner[4], eye, pos, n, angle; + FPOINT dim; + float zoom; + + zoom = m_particule[i].zoom; + if ( !m_engine->RetStateColor() && m_particule[i].intensity < 0.5f ) + { + zoom *= m_particule[i].intensity/0.5f; + } + + if ( zoom == 0.0f ) return; + if ( m_particule[i].intensity == 0.0f ) return; + + if ( m_particule[i].sheet == SH_INTERFACE ) + { + pos = m_particule[i].pos; + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); + + dim.x = m_particule[i].dim.x * zoom; + dim.y = m_particule[i].dim.y * zoom; + + corner[0].x = pos.x+dim.x; + corner[0].y = pos.y+dim.y; + corner[0].z = 0.0f; + + corner[1].x = pos.x-dim.x; + corner[1].y = pos.y+dim.y; + corner[1].z = 0.0f; + + corner[2].x = pos.x+dim.x; + corner[2].y = pos.y-dim.y; + corner[2].z = 0.0f; + + corner[3].x = pos.x-dim.x; + corner[3].y = pos.y-dim.y; + corner[3].z = 0.0f; + + vertex[0] = D3DVERTEX2(corner[1], n, m_particule[i].texSup.x, m_particule[i].texSup.y); + vertex[1] = D3DVERTEX2(corner[0], n, m_particule[i].texInf.x, m_particule[i].texSup.y); + vertex[2] = D3DVERTEX2(corner[3], n, m_particule[i].texSup.x, m_particule[i].texInf.y); + vertex[3] = D3DVERTEX2(corner[2], n, m_particule[i].texInf.x, m_particule[i].texInf.y); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); + } + else + { + eye = m_engine->RetEyePt(); + pos = m_particule[i].pos; + + object = m_particule[i].objLink; + if ( object != 0 ) + { + pos += object->RetPosition(0); + } + + angle.x = -RotateAngle(Length2d(pos, eye), pos.y-eye.y); + angle.y = RotateAngle(pos.z-eye.z, pos.x-eye.x); + angle.z = m_particule[i].angle; + + MatRotateXZY(matrix, angle); + matrix._41 = pos.x; + matrix._42 = pos.y; + matrix._43 = pos.z; + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); + + dim.x = m_particule[i].dim.x * zoom; + dim.y = m_particule[i].dim.y * zoom; + + corner[0].x = dim.x; + corner[0].y = dim.y; + corner[0].z = 0.0f; + + corner[1].x = -dim.x; + corner[1].y = dim.y; + corner[1].z = 0.0f; + + corner[2].x = dim.x; + corner[2].y = -dim.y; + corner[2].z = 0.0f; + + corner[3].x = -dim.x; + corner[3].y = -dim.y; + corner[3].z = 0.0f; + + vertex[0] = D3DVERTEX2(corner[1], n, m_particule[i].texSup.x, m_particule[i].texSup.y); + vertex[1] = D3DVERTEX2(corner[0], n, m_particule[i].texInf.x, m_particule[i].texSup.y); + vertex[2] = D3DVERTEX2(corner[3], n, m_particule[i].texSup.x, m_particule[i].texInf.y); + vertex[3] = D3DVERTEX2(corner[2], n, m_particule[i].texInf.x, m_particule[i].texInf.y); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); + } +} + +// Draw a particle flat (horizontal). + +void CParticule::DrawParticuleFlat(int i) +{ + CObject* object; + D3DVERTEX2 vertex[4]; // 2 triangles + D3DMATRIX matrix; + D3DVECTOR corner[4], pos, n, angle, eye; + FPOINT dim; + + if ( m_particule[i].zoom == 0.0f ) return; + if ( m_particule[i].intensity == 0.0f ) return; + + pos = m_particule[i].pos; + + object = m_particule[i].objLink; + if ( object != 0 ) + { + pos += object->RetPosition(0); + } + + angle.x = PI/2.0f; + angle.y = 0.0f; + angle.z = m_particule[i].angle; + +#if 0 + if ( m_engine->RetRankView() == 1 ) // underwater? + { + angle.x = -PI/2.0f; + pos.y -= 1.0f; + } +#else + if ( m_engine->RetRankView() == 1 ) // underwater? + { + pos.y -= 1.0f; + } + + eye = m_engine->RetEyePt(); + if ( pos.y > eye.y ) // seen from below? + { + angle.x = -PI/2.0f; + } +#endif + + MatRotateXZY(matrix, angle); + matrix._41 = pos.x; + matrix._42 = pos.y; + matrix._43 = pos.z; + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); + + dim.x = m_particule[i].dim.x * m_particule[i].zoom; + dim.y = m_particule[i].dim.y * m_particule[i].zoom; + + corner[0].x = dim.x; + corner[0].y = dim.y; + corner[0].z = 0.0f; + + corner[1].x = -dim.x; + corner[1].y = dim.y; + corner[1].z = 0.0f; + + corner[2].x = dim.x; + corner[2].y = -dim.y; + corner[2].z = 0.0f; + + corner[3].x = -dim.x; + corner[3].y = -dim.y; + corner[3].z = 0.0f; + + vertex[0] = D3DVERTEX2(corner[1], n, m_particule[i].texSup.x, m_particule[i].texSup.y); + vertex[1] = D3DVERTEX2(corner[0], n, m_particule[i].texInf.x, m_particule[i].texSup.y); + vertex[2] = D3DVERTEX2(corner[3], n, m_particule[i].texSup.x, m_particule[i].texInf.y); + vertex[3] = D3DVERTEX2(corner[2], n, m_particule[i].texInf.x, m_particule[i].texInf.y); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); +} + +// Draw a particle to a flat sheet of fog. + +void CParticule::DrawParticuleFog(int i) +{ + CObject* object; + D3DVERTEX2 vertex[4]; // 2 triangles + D3DMATRIX matrix; + D3DVECTOR corner[4], pos, n, angle, eye; + FPOINT dim, zoom; + + if ( !m_engine->RetFog() ) return; + if ( m_particule[i].intensity == 0.0f ) return; + + pos = m_particule[i].pos; + + dim.x = m_particule[i].dim.x; + dim.y = m_particule[i].dim.y; + + if ( m_particule[i].type == PARTIFOG0 || + m_particule[i].type == PARTIFOG2 || + m_particule[i].type == PARTIFOG4 || + m_particule[i].type == PARTIFOG6 ) + { +//? pos.x += sinf(m_particule[i].zoom*1.2f)*dim.x*0.1f; +//? pos.y += cosf(m_particule[i].zoom*1.5f)*dim.y*0.1f; + zoom.x = 1.0f+sinf(m_particule[i].zoom*2.0f)/6.0f; + zoom.y = 1.0f+cosf(m_particule[i].zoom*2.7f)/6.0f; + } + if ( m_particule[i].type == PARTIFOG1 || + m_particule[i].type == PARTIFOG3 || + m_particule[i].type == PARTIFOG5 || + m_particule[i].type == PARTIFOG7 ) + { +//? pos.x += sinf(m_particule[i].zoom*1.0f)*dim.x*0.1f; +//? pos.y += cosf(m_particule[i].zoom*1.3f)*dim.y*0.1f; + zoom.x = 1.0f+sinf(m_particule[i].zoom*3.0f)/6.0f; + zoom.y = 1.0f+cosf(m_particule[i].zoom*3.7f)/6.0f; + } + + dim.x *= zoom.x; + dim.y *= zoom.y; + + object = m_particule[i].objLink; + if ( object != 0 ) + { + pos += object->RetPosition(0); + } + + angle.x = PI/2.0f; + angle.y = 0.0f; + angle.z = m_particule[i].angle; + + if ( m_engine->RetRankView() == 1 ) // underwater? + { + pos.y -= 1.0f; + } + + eye = m_engine->RetEyePt(); + if ( pos.y > eye.y ) // seen from below? + { + angle.x = -PI/2.0f; + } + + MatRotateXZY(matrix, angle); + matrix._41 = pos.x; + matrix._42 = pos.y; + matrix._43 = pos.z; + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); + + corner[0].x = dim.x; + corner[0].y = dim.y; + corner[0].z = 0.0f; + + corner[1].x = -dim.x; + corner[1].y = dim.y; + corner[1].z = 0.0f; + + corner[2].x = dim.x; + corner[2].y = -dim.y; + corner[2].z = 0.0f; + + corner[3].x = -dim.x; + corner[3].y = -dim.y; + corner[3].z = 0.0f; + + vertex[0] = D3DVERTEX2(corner[1], n, m_particule[i].texSup.x, m_particule[i].texSup.y); + vertex[1] = D3DVERTEX2(corner[0], n, m_particule[i].texInf.x, m_particule[i].texSup.y); + vertex[2] = D3DVERTEX2(corner[3], n, m_particule[i].texSup.x, m_particule[i].texInf.y); + vertex[3] = D3DVERTEX2(corner[2], n, m_particule[i].texInf.x, m_particule[i].texInf.y); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); +} + +// Draw a particle in the form of radius. + +void CParticule::DrawParticuleRay(int i) +{ + CObject* object; + D3DVERTEX2 vertex[4]; // 2 triangles + D3DMATRIX matrix; + D3DVECTOR corner[4], eye, pos, goal, n, angle, proj; + FPOINT dim, texInf, texSup; + BOOL bLeft; + float a, len, adv, prop, vario1, vario2; + int r, rank, step, first, last; + + if ( m_particule[i].zoom == 0.0f ) return; + if ( m_particule[i].intensity == 0.0f ) return; + + eye = m_engine->RetEyePt(); + pos = m_particule[i].pos; + goal = m_particule[i].goal; + + object = m_particule[i].objLink; + if ( object != 0 ) + { + pos += object->RetPosition(0); + } + + a = RotateAngle(FPOINT(pos.x,pos.z), FPOINT(goal.x,goal.z), FPOINT(eye.x,eye.z)); + bLeft = (a < PI); + + proj = Projection(pos, goal, eye); + angle.x = -RotateAngle(Length2d(proj, eye), proj.y-eye.y); + angle.y = RotateAngle(pos.z-goal.z, pos.x-goal.x)+PI/2.0f; + angle.z = -RotateAngle(Length2d(pos, goal), pos.y-goal.y); + if ( bLeft ) angle.x = -angle.x; + + MatRotateZXY(matrix, angle); + matrix._41 = pos.x; + matrix._42 = pos.y; + matrix._43 = pos.z; + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); + + n = D3DVECTOR(0.0f, 0.0f, bLeft?1.0f:-1.0f); + + dim.x = m_particule[i].dim.x * m_particule[i].zoom; + dim.y = m_particule[i].dim.y * m_particule[i].zoom; + + if ( bLeft ) dim.y = -dim.y; + + len = Length(pos, goal); + adv = 0.0f; + + step = (int)(len/(dim.x*2.0f))+1; + + if ( step == 1 ) + { + vario1 = 1.0f; + vario2 = 1.0f; + } + else + { + vario1 = 0.0f; + vario2 = 2.0f; + } + + if ( m_particule[i].type == PARTIRAY2 ) + { + first = 0; + last = step; + vario1 = 0.0f; + vario2 = 0.0f; + } + else if ( m_particule[i].type == PARTIRAY3 ) + { + if ( m_particule[i].time < m_particule[i].duration*0.40f ) + { + prop = m_particule[i].time / (m_particule[i].duration*0.40f); + first = 0; + last = (int)(prop*step); + } + else if ( m_particule[i].time < m_particule[i].duration*0.60f ) + { + first = 0; + last = step; + } + else + { + prop = (m_particule[i].time-m_particule[i].duration*0.60f) / (m_particule[i].duration*0.40f); + first = (int)(prop*step); + last = step; + } + } + else + { + if ( m_particule[i].time < m_particule[i].duration*0.50f ) + { + prop = m_particule[i].time / (m_particule[i].duration*0.50f); + first = 0; + last = (int)(prop*step); + } + else if ( m_particule[i].time < m_particule[i].duration*0.75f ) + { + first = 0; + last = step; + } + else + { + prop = (m_particule[i].time-m_particule[i].duration*0.75f) / (m_particule[i].duration*0.25f); + first = (int)(prop*step); + last = step; + } + } + + corner[0].x = adv; + corner[2].x = adv; + corner[0].y = dim.y; + corner[2].y = -dim.y; + corner[0].z = (Rand()-0.5f)*vario1; + corner[1].z = (Rand()-0.5f)*vario1; + corner[2].z = (Rand()-0.5f)*vario1; + corner[3].z = (Rand()-0.5f)*vario1; + + for ( rank=0 ; rank= first && rank <= last ) + { +#if 1 + texInf = m_particule[i].texInf; + texSup = m_particule[i].texSup; + + r = rand()%16; + texInf.x += 0.25f*(r/4); + texSup.x += 0.25f*(r/4); + if ( r%2 < 1 && adv > 0.0f && m_particule[i].type != PARTIRAY1 ) + { + Swap(texInf.x, texSup.x); + } + if ( r%4 < 2 ) + { + Swap(texInf.y, texSup.y); + } +#else + texInf.x = Mod(texInf.x+0.25f, 1.0f); + texSup.x = Mod(texSup.x+0.25f, 1.0f); +#endif + + vertex[0] = D3DVERTEX2(corner[1], n, texSup.x, texSup.y); + vertex[1] = D3DVERTEX2(corner[0], n, texInf.x, texSup.y); + vertex[2] = D3DVERTEX2(corner[3], n, texSup.x, texInf.y); + vertex[3] = D3DVERTEX2(corner[2], n, texInf.x, texInf.y); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); + } + adv += dim.x*2.0f; + } +} + +// Draws a spherical particle. + +void CParticule::DrawParticuleSphere(int i) +{ + D3DVERTEX2 vertex[2*16*(16+1)]; // triangles + D3DMATRIX matrix, rot; + D3DVECTOR angle, v0, v1; + FPOINT ts, ti; + float zoom, deltaRingAngle, deltaSegAngle; + float r0,r1, tu0,tv0, tu1,tv1; + int j, ring, seg, numRings, numSegments; + + zoom = m_particule[i].zoom; +#if 0 + if ( !m_engine->RetStateColor() && m_particule[i].intensity < 0.5f ) + { + zoom *= m_particule[i].intensity/0.5f; + } +#endif + + if ( zoom == 0.0f ) return; + + m_engine->SetState(D3DSTATETTb|D3DSTATE2FACE|D3DSTATEWRAP, RetColor(m_particule[i].intensity)); + + D3DUtil_SetIdentityMatrix(matrix); + matrix._11 = zoom; + matrix._22 = zoom; + matrix._33 = zoom; + matrix._41 = m_particule[i].pos.x; + matrix._42 = m_particule[i].pos.y; + matrix._43 = m_particule[i].pos.z; + + if ( m_particule[i].angle != 0.0f ) + { + angle.x = m_particule[i].angle*0.4f; + angle.y = m_particule[i].angle*1.0f; + angle.z = m_particule[i].angle*0.7f; + MatRotateZXY(rot, angle); + matrix = rot*matrix; + } + + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); + + ts.x = m_particule[i].texSup.x; + ts.y = m_particule[i].texSup.y; + ti.x = m_particule[i].texInf.x; + ti.y = m_particule[i].texInf.y; + + // Choose a tesselation level. + if ( m_particule[i].type == PARTISPHERE3 || + m_particule[i].type == PARTISPHERE5 ) + { + numRings = 16; + numSegments = 16; + } + else + { + numRings = 8; + numSegments = 10; + } + + // Establish constants used in sphere generation. + deltaRingAngle = PI/numRings; + deltaSegAngle = 2.0f*PI/numSegments; + + // Generate the group of rings for the sphere. + j = 0; + for ( ring=0 ; ringDrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, j, NULL); + m_engine->AddStatisticTriangle(j); + + m_engine->SetState(D3DSTATETTb, RetColor(m_particule[i].intensity)); +} + +// Returns the height depending on the progress. + +float ProgressCylinder(float progress) +{ + if ( progress < 0.5f ) + { + return 1.0f - (powf(1.0f-progress*2.0f, 2.0f)); + } + else + { + return 1.0f - (powf(progress*2.0f-1.0f, 2.0f)); + } +} + +// Draws a cylindrical particle. + +void CParticule::DrawParticuleCylinder(int i) +{ + D3DVERTEX2 vertex[2*5*(10+1)]; // triangles + D3DMATRIX matrix, rot; + D3DVECTOR angle, v0, v1; + FPOINT ts, ti; + float progress, zoom, diam, deltaSegAngle, h[6], d[6]; + float r0,r1, tu0,tv0, tu1,tv1, p1, p2, pp; + int j, ring, seg, numRings, numSegments; + + progress = m_particule[i].zoom; + zoom = m_particule[i].dim.x; + diam = m_particule[i].dim.y; + if ( progress >= 1.0f || zoom == 0.0f ) return; + + m_engine->SetState(D3DSTATETTb|D3DSTATE2FACE|D3DSTATEWRAP, RetColor(m_particule[i].intensity)); + + D3DUtil_SetIdentityMatrix(matrix); + matrix._11 = zoom; + matrix._22 = zoom; + matrix._33 = zoom; + matrix._41 = m_particule[i].pos.x; + matrix._42 = m_particule[i].pos.y; + matrix._43 = m_particule[i].pos.z; + + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); + + ts.x = m_particule[i].texSup.x; + ts.y = m_particule[i].texSup.y; + ti.x = m_particule[i].texInf.x; + ti.y = m_particule[i].texInf.y; + + numRings = 5; + numSegments = 10; + deltaSegAngle = 2.0f*PI/numSegments; + + if ( m_particule[i].type == PARTIPLOUF0 ) + { +#if 0 + if ( progress <= 0.5f ) + { + p1 = progress/0.5f; // front + p2 = 0.0f; // back + } + else + { + p1 = 1.0f; // front + p2 = (progress-0.5f)/0.5f; // back + ts.y += (ti.y-ts.y)*p2; + } +#else + p1 = progress; // front + p2 = powf(progress, 5.0f); // back +#endif + + for ( ring=0 ; ring<=numRings ; ring++ ) + { + pp = p2+(p1-p2)*((float)ring/numRings); + d[ring] = diam/zoom+pp*2.0f; + h[ring] = ProgressCylinder(pp); + } + } + + j = 0; + for ( ring=0 ; ringDrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, j, NULL); + m_engine->AddStatisticTriangle(j); + + m_engine->SetState(D3DSTATETTb, RetColor(m_particule[i].intensity)); +} + +// Draws a tire mark. + +void CParticule::DrawParticuleWheel(int i) +{ + D3DVECTOR pos[4], center; + D3DVERTEX2 vertex[4]; // 2 triangles + D3DVECTOR n; + FPOINT ts, ti; + float dist, dp; + + dist = Length2d(m_engine->RetEyePt(), m_wheelTrace[i].pos[0]); + if ( dist > 300.0f ) return; + + pos[0] = m_wheelTrace[i].pos[0]; + pos[1] = m_wheelTrace[i].pos[1]; + pos[2] = m_wheelTrace[i].pos[2]; + pos[3] = m_wheelTrace[i].pos[3]; + + if ( m_wheelTrace[i].type == PARTITRACE0 ) // white ground track? + { + ts.x = 8.0f/256.0f; + ts.y = 224.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE1 ) // black ground track? + { + ts.x = 0.0f/256.0f; + ts.y = 224.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE2 ) // gray ground track? + { + ts.x = 0.0f/256.0f; + ts.y = 232.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE3 ) // light gray ground track? + { + ts.x = 8.0f/256.0f; + ts.y = 232.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE4 ) // red ground track? + { + ts.x = 32.0f/256.0f; + ts.y = 224.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE5 ) // pink ground track? + { + ts.x = 40.0f/256.0f; + ts.y = 224.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE6 ) // violet ground track? + { + ts.x = 32.0f/256.0f; + ts.y = 232.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE7 ) // orange ground track? + { + ts.x = 40.0f/256.0f; + ts.y = 232.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE8 ) // yellow ground track? + { + ts.x = 16.0f/256.0f; + ts.y = 224.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE9 ) // beige ground track? + { + ts.x = 24.0f/256.0f; + ts.y = 224.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE10 ) // brown ground track? + { + ts.x = 16.0f/256.0f; + ts.y = 232.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE11 ) // skin ground track? + { + ts.x = 24.0f/256.0f; + ts.y = 232.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE12 ) // green ground track? + { + ts.x = 48.0f/256.0f; + ts.y = 224.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE13 ) // light green ground track? + { + ts.x = 56.0f/256.0f; + ts.y = 224.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE14 ) // blue ground track? + { + ts.x = 48.0f/256.0f; + ts.y = 232.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE15 ) // light blue ground track? + { + ts.x = 56.0f/256.0f; + ts.y = 232.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE16 ) // black arrow ground track? + { + ts.x = 160.0f/256.0f; + ts.y = 224.0f/256.0f; + } + else if ( m_wheelTrace[i].type == PARTITRACE17 ) // red arrow ground track? + { + ts.x = 176.0f/256.0f; + ts.y = 224.0f/256.0f; + } + else + { + return; + } + + if ( m_wheelTrace[i].type == PARTITRACE16 || + m_wheelTrace[i].type == PARTITRACE17 ) + { + ti.x = ts.x+16.0f/256.0f; + ti.y = ts.y+16.0f/256.0f; + } + else + { + ti.x = ts.x+8.0f/256.0f; + ti.y = ts.y+8.0f/256.0f; + } + + dp = (1.0f/256.0f)/2.0f; + ts.x = ts.x+dp; + ts.y = ts.y+dp; + ti.x = ti.x-dp; + ti.y = ti.y-dp; + + n = D3DVECTOR(0.0f, 1.0f, 0.0f); + + vertex[0] = D3DVERTEX2(pos[0], n, ts.x, ts.y); + vertex[1] = D3DVERTEX2(pos[1], n, ti.x, ts.y); + vertex[2] = D3DVERTEX2(pos[2], n, ts.x, ti.y); + vertex[3] = D3DVERTEX2(pos[3], n, ti.x, ti.y); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); +} + +// Draws all the particles. + +void CParticule::DrawParticule(int sheet) +{ + D3DMATERIAL7 mat; + D3DMATRIX matrix; + BOOL bLoadTexture; + char name[20]; + int state, t, i, j, r; + + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE); +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + + // Draw the basic particles of triangles. + if ( m_totalInterface[0][sheet] > 0 ) + { + for ( i=0 ; iSetTexture(m_triangle[i].texName1); + m_engine->SetMaterial(m_triangle[i].material); + m_engine->SetState(m_triangle[i].state); + DrawParticuleTriangle(i); + } + } + + // Draw the particles was calculated based on edge. + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE); + + ZeroMemory( &mat, sizeof(D3DMATERIAL7) ); + mat.diffuse.r = 1.0f; + mat.diffuse.g = 1.0f; + mat.diffuse.b = 1.0f; // white + mat.ambient.r = 0.5f; + mat.ambient.g = 0.5f; + mat.ambient.b = 0.5f; + m_engine->SetMaterial(mat); + + // Draw tire marks. + if ( m_wheelTraceTotal > 0 && sheet == SH_WORLD ) + { +#if _POLISH + m_engine->SetTexture("textp.tga"); +#else + m_engine->SetTexture("text.tga"); +#endif + m_engine->SetState(D3DSTATETTw); +//? m_engine->SetState(D3DSTATENORMAL); + D3DUtil_SetIdentityMatrix(matrix); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); + for ( i=0 ; i=1 ; t-- ) // black behind! + { + if ( m_totalInterface[t][sheet] == 0 ) continue; + + bLoadTexture = FALSE; + + if ( t == 4 ) state = D3DSTATETTw; // text.tga + else state = D3DSTATETTb; // effect[00..02].tga + m_engine->SetState(state); + + for ( j=0 ; jSetTexture(name); + bLoadTexture = TRUE; + } + + r = m_particule[i].trackRank; + if ( r != -1 ) + { + m_engine->SetState(state); + TrackDraw(r, m_particule[i].type); // draws the drag + if ( !m_track[r].bDrawParticule ) continue; + } + + m_engine->SetState(state, RetColor(m_particule[i].intensity)); + + if ( m_particule[i].bRay ) // ray? + { + DrawParticuleRay(i); + } + else if ( m_particule[i].type == PARTIFLIC || // circle in the water? + m_particule[i].type == PARTISHOW || + m_particule[i].type == PARTICHOC || + m_particule[i].type == PARTIGFLAT ) + { + DrawParticuleFlat(i); + } + else if ( m_particule[i].type >= PARTIFOG0 && + m_particule[i].type <= PARTIFOG9 ) + { + DrawParticuleFog(i); + } + else if ( m_particule[i].type >= PARTISPHERE0 && + m_particule[i].type <= PARTISPHERE9 ) // sphere? + { + DrawParticuleSphere(i); + } + else if ( m_particule[i].type >= PARTIPLOUF0 && + m_particule[i].type <= PARTIPLOUF4 ) // cylinder? + { + DrawParticuleCylinder(i); + } + else // normal? + { + DrawParticuleNorm(i); + } + } + } + +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE); +} + + +// Seeks if an object collided with a bullet. + +CObject* CParticule::SearchObjectGun(D3DVECTOR old, D3DVECTOR pos, + ParticuleType type, CObject *father) +{ + CObject *pObj, *pBest; + D3DVECTOR box1, box2, oPos, p; + ObjectType oType; + BOOL bShield; + float min, oRadius, dist, shieldRadius; + int i, j; + BOOL bHimself; + + if ( m_main->RetMovieLock() ) return 0; // current movie? + + bHimself = m_main->RetHimselfDamage(); + + min = 5.0f; + if ( type == PARTIGUN2 ) min = 2.0f; // shooting insect? + if ( type == PARTIGUN3 ) min = 3.0f; // suiciding spider? + + box1 = old; + box2 = pos; + if ( box1.x > box2.x ) Swap(box1.x, box2.x); // box1 < box2 + if ( box1.y > box2.y ) Swap(box1.y, box2.y); + if ( box1.z > box2.z ) Swap(box1.z, box2.z); + box1.x -= min; + box1.y -= min; + box1.z -= min; + box2.x += min; + box2.y += min; + box2.z += min; + + pBest = 0; + bShield = FALSE; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetActif() ) continue; // inactive? + if ( pObj == father ) continue; + + oType = pObj->RetType(); + + if ( oType == OBJECT_TOTO ) continue; + + if ( type == PARTIGUN1 ) // fireball shooting? + { + if ( oType == OBJECT_MOTHER ) continue; + if ( bHimself ) // damage is oneself? + { + if ( !IsAlien(oType) && + !IsSoft(oType) ) continue; + } + else // damage only to enemies? + { + if ( !IsAlien(oType) ) continue; + } + } + else if ( type == PARTIGUN2 ) // shooting insect? + { + if ( !IsSoft(oType) ) continue; + } + else if ( type == PARTIGUN3 ) // suiciding spider? + { + if ( !IsSoft(oType) ) continue; + } + else if ( type == PARTIGUN4 ) // orgaball shooting? + { + if ( oType == OBJECT_MOTHER ) continue; + if ( bHimself ) // damage is oneself? + { + if ( !IsAlien(oType) && + !IsSoft(oType) ) continue; + } + else // damage only to enemies? + { + if ( !IsAlien(oType) ) continue; + } + } + else if ( type == PARTITRACK11 ) // phazer shooting? + { + if ( bHimself ) // damage is oneself? + { + if ( !IsAlien(oType) && + !IsSoft(oType) ) continue; + } + else // damage only to enemies? + { + if ( !IsAlien(oType) ) continue; + } + } + else + { + continue; + } + + oPos = pObj->RetPosition(0); + + if ( type == PARTIGUN2 || // shooting insect? + type == PARTIGUN3 ) // suiciding spider? + { + // Test if the ball is entered into the sphere of a shield. + shieldRadius = pObj->RetShieldRadius(); + if ( shieldRadius > 0.0f ) + { + dist = Length(oPos, pos); + if ( dist <= shieldRadius ) + { + pBest = pObj; + bShield = TRUE; + } + } + } + if ( bShield ) continue; + + // Test the center of the object, which is necessary for objects + // that have no sphere in the center (station). + dist = Length(oPos, pos)-4.0f; + if ( dist < min ) + { + pBest = pObj; + } + + // Test with all spheres of the object. + j = 0; + while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) + { + if ( oPos.x+oRadius < box1.x || oPos.x-oRadius > box2.x || // outside the box? + oPos.y+oRadius < box1.y || oPos.y-oRadius > box2.y || + oPos.z+oRadius < box1.z || oPos.z-oRadius > box2.z ) continue; + + p = Projection(old, pos, oPos); + dist = Length(p, oPos)-oRadius; + if ( dist < min ) + { + pBest = pObj; + } + } + } + + return pBest; +} + +// Seeks if an object collided with a ray. + +CObject* CParticule::SearchObjectRay(D3DVECTOR pos, D3DVECTOR goal, + ParticuleType type, CObject *father) +{ + CObject* pObj; + D3DVECTOR box1, box2, oPos, p; + ObjectType oType; + float min, dist; + int i; + + if ( m_main->RetMovieLock() ) return 0; // current movie? + + min = 10.0f; + + box1 = pos; + box2 = goal; + if ( box1.x > box2.x ) Swap(box1.x, box2.x); // box1 < box2 + if ( box1.y > box2.y ) Swap(box1.y, box2.y); + if ( box1.z > box2.z ) Swap(box1.z, box2.z); + box1.x -= min; + box1.y -= min; + box1.z -= min; + box2.x += min; + box2.y += min; + box2.z += min; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetActif() ) continue; // inactive? + if ( pObj == father ) continue; + + oType = pObj->RetType(); + + if ( oType == OBJECT_TOTO ) continue; + + if ( type == PARTIRAY1 && + oType != OBJECT_MOBILEtg && + oType != OBJECT_TEEN28 && + oType != OBJECT_TEEN31 && + oType != OBJECT_ANT && + oType != OBJECT_SPIDER && + oType != OBJECT_BEE && + oType != OBJECT_WORM && + oType != OBJECT_MOTHER && + oType != OBJECT_NEST ) continue; + + oPos = pObj->RetPosition(0); + + if ( oPos.x < box1.x || oPos.x > box2.x || // outside the box? + oPos.y < box1.y || oPos.y > box2.y || + oPos.z < box1.z || oPos.z > box2.z ) continue; + + p = Projection(pos, goal, oPos); + dist = Length(p, oPos); + if ( dist < min ) return pObj; + } + + return 0; +} + + +// Sounded one. + +void CParticule::Play(Sound sound, D3DVECTOR pos, float amplitude) +{ + if ( m_sound == 0 ) + { + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + } + + m_sound->Play(sound, pos, amplitude); +} + + + +// Seeks the color if you're in the fog. +// Returns black if you're not in the fog. + +D3DCOLORVALUE CParticule::RetFogColor(D3DVECTOR pos) +{ + D3DCOLORVALUE result, color; + float dist, factor; + int fog, i; + + result.r = 0.0f; + result.g = 0.0f; + result.b = 0.0f; + result.a = 0.0f; + + for ( fog=0 ; fog= m_particule[i].pos.y+FOG_HSUP ) continue; + if ( pos.y <= m_particule[i].pos.y-FOG_HINF ) continue; + + dist = Length2d(pos, m_particule[i].pos); + if ( dist >= m_particule[i].dim.x*1.5f ) continue; + + // Calculates the horizontal distance. + factor = 1.0f-powf(dist/(m_particule[i].dim.x*1.5f), 4.0f); + + // Calculates the vertical distance. + if ( pos.y > m_particule[i].pos.y ) + { + factor *= 1.0f-(pos.y-m_particule[i].pos.y)/FOG_HSUP; + } + else + { + factor *= 1.0f-(m_particule[i].pos.y-pos.y)/FOG_HINF; + } + + factor *= 0.3f; + + if ( m_particule[i].type == PARTIFOG0 || + m_particule[i].type == PARTIFOG1 ) // blue? + { + color.r = 0.0f; + color.g = 0.5f; + color.b = 1.0f; + } + else if ( m_particule[i].type == PARTIFOG2 || + m_particule[i].type == PARTIFOG3 ) // red? + { + color.r = 2.0f; + color.g = 1.0f; + color.b = 0.0f; + } + else if ( m_particule[i].type == PARTIFOG4 || + m_particule[i].type == PARTIFOG5 ) // white? + { + color.r = 1.0f; + color.g = 1.0f; + color.b = 1.0f; + } + else if ( m_particule[i].type == PARTIFOG6 || + m_particule[i].type == PARTIFOG7 ) // yellow? + { + color.r = 0.8f; + color.g = 1.0f; + color.b = 0.4f; + } + else + { + color.r = 0.0f; + color.g = 0.0f; + color.b = 0.0f; + } + + result.r += color.r*factor; + result.g += color.g*factor; + result.b += color.b*factor; + } + + if ( result.r > 0.6f ) result.r = 0.6f; + if ( result.g > 0.6f ) result.g = 0.6f; + if ( result.b > 0.6f ) result.b = 0.6f; + + return result; +} + + +// Writes a file. BMP containing all the tire tracks. + +BOOL CParticule::WriteWheelTrace(char *filename, int width, int height, + D3DVECTOR dl, D3DVECTOR ur) +{ + HDC hDC; + HDC hDCImage; + HBITMAP hb; + PBITMAPINFO info; + HBRUSH hBrush; + HPEN hPen; + HGDIOBJ old; + RECT rect; + COLORREF color; + FPOINT pos[4]; + POINT list[4]; + int i; + + if ( !m_engine->GetRenderDC(hDC) ) return FALSE; + + hDCImage = CreateCompatibleDC(hDC); + if ( hDCImage == 0 ) + { + m_engine->ReleaseRenderDC(hDC); + return FALSE; + } + + hb = CreateCompatibleBitmap(hDC, width, height); + if ( hb == 0 ) + { + DeleteDC(hDCImage); + m_engine->ReleaseRenderDC(hDC); + return FALSE; + } + + SelectObject(hDCImage, hb); + + rect.left = 0; + rect.right = width; + rect.top = 0; + rect.bottom = height; + FillRect(hDCImage, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + hPen = CreatePen(PS_NULL, 1, 0); + SelectObject(hDCImage, hPen); + + for ( i=0 ; iCreateBitmapInfoStruct(hb); + if ( info == 0 ) + { + DeleteObject(hb); + DeleteDC(hDCImage); + m_engine->ReleaseRenderDC(hDC); + return FALSE; + } + + m_engine->CreateBMPFile(filename, info, hb, hDCImage); + + DeleteObject(hb); + DeleteDC(hDCImage); + m_engine->ReleaseRenderDC(hDC); + return TRUE; +} + diff --git a/src/graphics/common/particule.h b/src/graphics/common/particule.h new file mode 100644 index 0000000..67abad3 --- /dev/null +++ b/src/graphics/common/particule.h @@ -0,0 +1,339 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// particule.h + +#ifndef _PARTICULE_H_ +#define _PARTICULE_H_ + + +#include "d3dengine.h" +#include "sound.h" + + +class CInstanceManager; +class CRobotMain; +class CTerrain; +class CWater; +class CObject; + + +#define MAXPARTICULE 500 +#define MAXPARTITYPE 5 +#define MAXTRACK 100 +#define MAXTRACKLEN 10 +#define MAXPARTIFOG 100 +#define MAXWHEELTRACE 1000 + +#define SH_WORLD 0 // particle in the world in the interface +#define SH_FRONT 1 // particle in the world on the interface +#define SH_INTERFACE 2 // particle in the interface +#define SH_MAX 3 + +// type == 0 -> triangles +// type == 1 -> effect00 (black background) +// type == 2 -> effect01 (black background) +// type == 3 -> effect02 (black background) +// type == 4 -> text (white background) + + +enum ParticuleType +{ + PARTIEXPLOT = 1, // technology explosion + PARTIEXPLOO = 2, // organic explosion + PARTIMOTOR = 3, // the engine exhaust gas + PARTIGLINT = 4, // reflection + PARTIBLITZ = 5, // lightning recharging battery + PARTICRASH = 6, // dust after fall + PARTIGAS = 7, // gas from the reactor + PARTIFIRE = 9, // fireball shrinks + PARTIFIREZ = 10, // fireball grows + PARTIBLUE = 11, // blue ball + PARTISELY = 12, // yellow selection + PARTISELR = 13, // red selection + PARTIGUN1 = 18, // a bullet (fireball) + PARTIGUN2 = 19, // bullet 2 (ant) + PARTIGUN3 = 20, // bullet 3 (spider) + PARTIGUN4 = 21, // bullet 4 (orgaball) + PARTIFRAG = 22, // triangular fragment + PARTIQUEUE = 23, // inflamed tail + PARTIORGANIC1 = 24, // organic ball mother + PARTIORGANIC2 = 25, // organic ball daughter + PARTISMOKE1 = 26, // black smoke + PARTISMOKE2 = 27, // black smoke + PARTISMOKE3 = 28, // black smoke + PARTISMOKE4 = 29, // black smoke + PARTIBLOOD = 30, // human blood + PARTIBLOODM = 31, // blood laying + PARTIVAPOR = 32, // steam + PARTIVIRUS1 = 33, // virus 1 + PARTIVIRUS2 = 34, // virus 2 + PARTIVIRUS3 = 35, // virus 3 + PARTIVIRUS4 = 36, // virus 4 + PARTIVIRUS5 = 37, // virus 5 + PARTIVIRUS6 = 38, // virus 6 + PARTIVIRUS7 = 39, // virus 7 + PARTIVIRUS8 = 40, // virus 8 + PARTIVIRUS9 = 41, // virus 9 + PARTIVIRUS10 = 42, // virus 10 + PARTIRAY1 = 43, // ray 1 (turn) + PARTIRAY2 = 44, // ray 2 (electric arc) + PARTIRAY3 = 45, // ray 3 + PARTIRAY4 = 46, // ray 4 + PARTIFLAME = 47, // flame + PARTIBUBBLE = 48, // bubble + PARTIFLIC = 49, // circles in the water + PARTIEJECT = 50, // ejection from the reactor + PARTISCRAPS = 51, // waste from the reactor + PARTITOTO = 52, // reactor of tot + PARTIERROR = 53, // toto says no + PARTIWARNING = 54, // foo says blah + PARTIINFO = 54, // toto says yes + PARTIQUARTZ = 55, // reflection crystal + PARTISPHERE0 = 56, // explosion sphere + PARTISPHERE1 = 57, // energy sphere + PARTISPHERE2 = 58, // analysis sphere + PARTISPHERE3 = 59, // shield sphere + PARTISPHERE4 = 60, // information sphere (emit) + PARTISPHERE5 = 61, // botanical sphere (gravity root) + PARTISPHERE6 = 62, // information sphere (receive) + PARTISPHERE7 = 63, // sphere + PARTISPHERE8 = 64, // sphere + PARTISPHERE9 = 65, // sphere + PARTIGUNDEL = 66, // bullet destroyed by shield + PARTIPART = 67, // object part + PARTITRACK1 = 68, // drag 1 + PARTITRACK2 = 69, // drag 2 + PARTITRACK3 = 70, // drag 3 + PARTITRACK4 = 71, // drag 4 + PARTITRACK5 = 72, // drag 5 + PARTITRACK6 = 73, // drag 6 + PARTITRACK7 = 74, // drag 7 + PARTITRACK8 = 75, // drag 8 + PARTITRACK9 = 76, // drag 9 + PARTITRACK10 = 77, // drag 10 + PARTITRACK11 = 78, // drag 11 + PARTITRACK12 = 79, // drag 12 + PARTITRACK13 = 80, // drag 13 + PARTITRACK14 = 81, // drag 14 + PARTITRACK15 = 82, // drag 15 + PARTITRACK16 = 83, // drag 16 + PARTITRACK17 = 84, // drag 17 + PARTITRACK18 = 85, // drag 18 + PARTITRACK19 = 86, // drag 19 + PARTITRACK20 = 87, // drag 20 + PARTIGLINTb = 88, // blue reflection + PARTIGLINTr = 89, // red reflection + PARTILENS1 = 90, // brilliance 1 (orange) + PARTILENS2 = 91, // brilliance 2 (yellow) + PARTILENS3 = 92, // brilliance 3 (red) + PARTILENS4 = 93, // brilliance 4 (violet) + PARTICONTROL = 94, // reflection on button + PARTISHOW = 95, // shows a place + PARTICHOC = 96, // shock wave + PARTIGFLAT = 97, // shows if the ground is flat + PARTIRECOVER = 98, // blue ball recycler + PARTIROOT = 100, // gravity root smoke + PARTIPLOUF0 = 101, // splash + PARTIPLOUF1 = 102, // splash + PARTIPLOUF2 = 103, // splash + PARTIPLOUF3 = 104, // splash + PARTIPLOUF4 = 105, // splash + PARTIDROP = 106, // drop + PARTIFOG0 = 107, // fog 0 + PARTIFOG1 = 108, // fog 1 + PARTIFOG2 = 109, // fog 2 + PARTIFOG3 = 110, // fog 3 + PARTIFOG4 = 111, // fog 4 + PARTIFOG5 = 112, // fog 5 + PARTIFOG6 = 113, // fog 6 + PARTIFOG7 = 114, // fog 7 + PARTIFOG8 = 115, // fog 8 + PARTIFOG9 = 116, // fog 9 + PARTILIMIT1 = 117, // shows the limits 1 + PARTILIMIT2 = 118, // shows the limits 2 + PARTILIMIT3 = 119, // shows the limits 3 + PARTILIMIT4 = 120, // shows the limits 4 + PARTIWATER = 121, // drop of water + PARTIEXPLOG1 = 122, // ball explosion 1 + PARTIEXPLOG2 = 123, // ball explosion 2 + PARTIBASE = 124, // gases of spaceship + PARTITRACE0 = 140, // trace + PARTITRACE1 = 141, // trace + PARTITRACE2 = 142, // trace + PARTITRACE3 = 143, // trace + PARTITRACE4 = 144, // trace + PARTITRACE5 = 145, // trace + PARTITRACE6 = 146, // trace + PARTITRACE7 = 147, // trace + PARTITRACE8 = 148, // trace + PARTITRACE9 = 149, // trace + PARTITRACE10 = 150, // trace + PARTITRACE11 = 151, // trace + PARTITRACE12 = 152, // trace + PARTITRACE13 = 153, // trace + PARTITRACE14 = 154, // trace + PARTITRACE15 = 155, // trace + PARTITRACE16 = 156, // trace + PARTITRACE17 = 157, // trace + PARTITRACE18 = 158, // trace + PARTITRACE19 = 159, // trace +}; + +enum ParticulePhase +{ + PARPHSTART = 0, + PARPHEND = 1, +}; + +typedef struct +{ + char bUsed; // TRUE -> particle used + char bRay; // TRUE -> ray with goal + unsigned short uniqueStamp; // unique mark + short sheet; // sheet (0..n) + ParticuleType type; // type PARTI* + ParticulePhase phase; // phase PARPH* + float mass; // mass of the particle (in rebounding) + float weight; // weight of the particle (for noise) + float duration; // length of life + D3DVECTOR pos; // absolute position (relative if object links) + D3DVECTOR goal; // goal position (if bRay) + D3DVECTOR speed; // speed of displacement + float windSensitivity; + short bounce; // number of rebounds + FPOINT dim; // dimensions of the rectangle + float zoom; // zoom (0..1) + float angle; // angle of rotation + float intensity; // intensity + FPOINT texSup; // coordinated upper texture + FPOINT texInf; // coordinated lower texture + float time; // age of the particle (0..n) + float phaseTime; // age at the beginning of phase + float testTime; // time since last test + CObject* objLink; // father object (for example reactor) + CObject* objFather; // father object (for example reactor) + short objRank; // rank of the object, or -1 + short trackRank; // rank of the drag +} +Particule; + +typedef struct +{ + char bUsed; // TRUE -> drag used + char bDrawParticule; + float step; // duration of not + float last; // increase last not memorized + float intensity; // intensity at starting (0..1) + float width; // tail width + int used; // number of positions in "pos" + int head; // head to write index + D3DVECTOR pos[MAXTRACKLEN]; + float len[MAXTRACKLEN]; +} +Track; + +typedef struct +{ + ParticuleType type; // type PARTI* + D3DVECTOR pos[4]; // rectangle positions + float startTime; // beginning of life +} +WheelTrace; + + + +class CParticule +{ +public: + CParticule(CInstanceManager* iMan, CD3DEngine* engine); + ~CParticule(); + + void SetD3DDevice(LPDIRECT3DDEVICE7 device); + + void FlushParticule(); + void FlushParticule(int sheet); + int CreateParticule(D3DVECTOR pos, D3DVECTOR speed, FPOINT dim, ParticuleType type, float duration=1.0f, float mass=0.0f, float windSensitivity=1.0f, int sheet=0); + int CreateFrag(D3DVECTOR pos, D3DVECTOR speed, D3DTriangle *triangle, ParticuleType type, float duration=1.0f, float mass=0.0f, float windSensitivity=1.0f, int sheet=0); + int CreatePart(D3DVECTOR pos, D3DVECTOR speed, ParticuleType type, float duration=1.0f, float mass=0.0f, float weight=0.0f, float windSensitivity=1.0f, int sheet=0); + int CreateRay(D3DVECTOR pos, D3DVECTOR goal, ParticuleType type, FPOINT dim, float duration=1.0f, int sheet=0); + int CreateTrack(D3DVECTOR pos, D3DVECTOR speed, FPOINT dim, ParticuleType type, float duration=1.0f, float mass=0.0f, float length=10.0f, float width=1.0f); + void CreateWheelTrace(const D3DVECTOR &p1, const D3DVECTOR &p2, const D3DVECTOR &p3, const D3DVECTOR &p4, ParticuleType type); + void DeleteParticule(ParticuleType type); + void DeleteParticule(int channel); + void SetObjectLink(int channel, CObject *object); + void SetObjectFather(int channel, CObject *object); + void SetPosition(int channel, D3DVECTOR pos); + void SetDimension(int channel, FPOINT dim); + void SetZoom(int channel, float zoom); + void SetAngle(int channel, float angle); + void SetIntensity(int channel, float intensity); + void SetParam(int channel, D3DVECTOR pos, FPOINT dim, float zoom, float angle, float intensity); + void SetPhase(int channel, ParticulePhase phase, float duration); + BOOL GetPosition(int channel, D3DVECTOR &pos); + + D3DCOLORVALUE RetFogColor(D3DVECTOR pos); + + void SetFrameUpdate(int sheet, BOOL bUpdate); + void FrameParticule(float rTime); + void DrawParticule(int sheet); + + BOOL WriteWheelTrace(char *filename, int width, int height, D3DVECTOR dl, D3DVECTOR ur); + +protected: + void DeleteRank(int rank); + BOOL CheckChannel(int &channel); + void DrawParticuleTriangle(int i); + void DrawParticuleNorm(int i); + void DrawParticuleFlat(int i); + void DrawParticuleFog(int i); + void DrawParticuleRay(int i); + void DrawParticuleSphere(int i); + void DrawParticuleCylinder(int i); + void DrawParticuleWheel(int i); + CObject* SearchObjectGun(D3DVECTOR old, D3DVECTOR pos, ParticuleType type, CObject *father); + CObject* SearchObjectRay(D3DVECTOR pos, D3DVECTOR goal, ParticuleType type, CObject *father); + void Play(Sound sound, D3DVECTOR pos, float amplitude); + BOOL TrackMove(int i, D3DVECTOR pos, float progress); + void TrackDraw(int i, ParticuleType type); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + LPDIRECT3DDEVICE7 m_pD3DDevice; + CRobotMain* m_main; + CTerrain* m_terrain; + CWater* m_water; + CSound* m_sound; + + Particule m_particule[MAXPARTICULE*MAXPARTITYPE]; + D3DTriangle m_triangle[MAXPARTICULE]; // triangle if PartiType == 0 + Track m_track[MAXTRACK]; + int m_wheelTraceTotal; + int m_wheelTraceIndex; + WheelTrace m_wheelTrace[MAXWHEELTRACE]; + int m_totalInterface[MAXPARTITYPE][SH_MAX]; + BOOL m_bFrameUpdate[SH_MAX]; + int m_fogTotal; + int m_fog[MAXPARTIFOG]; + int m_uniqueStamp; + int m_exploGunCounter; + float m_lastTimeGunDel; + float m_absTime; +}; + + +#endif //_PARTICULE_H_ diff --git a/src/graphics/common/planet.cpp b/src/graphics/common/planet.cpp new file mode 100644 index 0000000..925b2e9 --- /dev/null +++ b/src/graphics/common/planet.cpp @@ -0,0 +1,248 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// planet.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "planet.h" + + + + +// Constructor of the terrain. + +CPlanet::CPlanet(CInstanceManager* iMan, CD3DEngine* engine) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_PLANET, this); + + m_engine = engine; + Flush(); + +} + +// Destructor of the terrain. + +CPlanet::~CPlanet() +{ +} + + +// Removes all the planets. + +void CPlanet::Flush() +{ + int i, j; + + for ( j=0 ; j<2 ; j++ ) + { + for ( i=0 ; iRetPause() ) return TRUE; + + m_time += event.rTime; + + for ( i=0 ; iLoadTexture(m_planet[j][i].name); + } + } +} + +// Draws all the planets. + +void CPlanet::Draw() +{ + LPDIRECT3DDEVICE7 device; + D3DVERTEX2 vertex[4]; // 2 triangles + D3DVECTOR n; + FPOINT p1, p2; + float eyeDirH, eyeDirV, dp, u1, u2, v1, v2, a; + int i; + + device = m_engine->RetD3DDevice(); + eyeDirH = m_engine->RetEyeDirH(); + eyeDirV = m_engine->RetEyeDirV(); + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal + dp = 0.5f/256.0f; + + for ( i=0 ; iSetTexture(m_planet[m_mode][i].name); + + if ( m_planet[m_mode][i].bTGA ) + { + m_engine->SetState(D3DSTATEWRAP|D3DSTATEALPHA); + } + else + { + m_engine->SetState(D3DSTATEWRAP|D3DSTATETTb); + } + + a = eyeDirH + m_planet[m_mode][i].angle.x; + p1.x = Mod(a, PI*2.0f)-0.5f; + + a = eyeDirV + m_planet[m_mode][i].angle.y; + p1.y = 0.4f+(Mod(a+PI, PI*2.0f)-PI)*(2.0f/PI); + + p1.x -= m_planet[m_mode][i].dim/2.0f*0.75f; + p1.y -= m_planet[m_mode][i].dim/2.0f; + p2.x = p1.x+m_planet[m_mode][i].dim*0.75f; + p2.y = p1.y+m_planet[m_mode][i].dim; + + u1 = m_planet[m_mode][i].uv1.x + dp; + v1 = m_planet[m_mode][i].uv1.y + dp; + u2 = m_planet[m_mode][i].uv2.x - dp; + v2 = m_planet[m_mode][i].uv2.y - dp; + + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); + vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); + vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); + + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); + } +} + + +// Creates a new planet. + +BOOL CPlanet::Create(int mode, FPOINT start, float dim, float speed, + float dir, char *name, FPOINT uv1, FPOINT uv2) +{ + int i; + + if ( mode < 0 ) mode = 0; + if ( mode > 1 ) mode = 1; + + for ( i=0 ; i 1 ) mode = 1; + m_mode = mode; +} + +int CPlanet::RetMode() +{ + return m_mode; +} + diff --git a/src/graphics/common/planet.h b/src/graphics/common/planet.h new file mode 100644 index 0000000..9a6ba52 --- /dev/null +++ b/src/graphics/common/planet.h @@ -0,0 +1,79 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// planet.h + +#ifndef _PLANET_H_ +#define _PLANET_H_ + + +#include "struct.h" + + +class CInstanceManager; +class CD3DEngine; + + + +#define MAXPLANET 10 + +typedef struct +{ + char bUsed; // TRUE -> planet exists + FPOINT start; // initial position in degrees + FPOINT angle; // current position in degrees + float dim; // dimensions (0..1) + float speed; // speed + float dir; // direction in the sky + char name[20]; // name of the texture + FPOINT uv1, uv2; // texture mapping + char bTGA; // texture .TGA +} +Planet; + + + + +class CPlanet +{ +public: + CPlanet(CInstanceManager* iMan, CD3DEngine* engine); + ~CPlanet(); + + void Flush(); + BOOL EventProcess(const Event &event); + BOOL Create(int mode, FPOINT start, float dim, float speed, float dir, char *name, FPOINT uv1, FPOINT uv2); + BOOL PlanetExist(); + void LoadTexture(); + void Draw(); + void SetMode(int mode); + int RetMode(); + +protected: + BOOL EventFrame(const Event &event); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + + float m_time; + int m_mode; + Planet m_planet[2][MAXPLANET]; + BOOL m_bPlanetExist; +}; + + +#endif //_PLANET_H_ diff --git a/src/graphics/common/pyro.cpp b/src/graphics/common/pyro.cpp new file mode 100644 index 0000000..3588585 --- /dev/null +++ b/src/graphics/common/pyro.cpp @@ -0,0 +1,2486 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// pyro.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "D3DEngine.h" +#include "D3DMath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "robotmain.h" +#include "terrain.h" +#include "camera.h" +#include "particule.h" +#include "light.h" +#include "object.h" +#include "motion.h" +#include "motionhuman.h" +#include "displaytext.h" +#include "sound.h" +#include "pyro.h" + + + + +// Object's constructor. + +CPyro::CPyro(CInstanceManager* iMan) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_PYRO, this, 100); + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); + m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); + m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + m_object = 0; + + m_progress = 0.0f; + m_speed = 0.0f; + m_lightRank = -1; + m_soundChannel = -1; + LightOperFlush(); +} + +// Object's destructor. + +CPyro::~CPyro() +{ + m_iMan->DeleteInstance(CLASS_PYRO, this); +} + + +// Destroys the object. + +void CPyro::DeleteObject(BOOL bAll) +{ + if ( m_lightRank != -1 ) + { + m_light->DeleteLight(m_lightRank); + m_lightRank = -1; + } +} + + +// Creates pyrotechnic effect. + +BOOL CPyro::Create(PyroType type, CObject* pObj, float force) +{ + D3DMATRIX* mat; + CObject* power; + CMotion* motion; + D3DVECTOR min, max, pos, speed; + FPOINT dim; + ObjectType oType; + Sound sound; + float duration, mass, h, limit; + int part, objRank, total, i, channel; + + m_object = pObj; + m_force = force; + + oType = pObj->RetType(); + objRank = pObj->RetObjectRank(0); + if ( objRank == -1 ) return FALSE; + m_engine->GetBBox(objRank, min, max); + pos = pObj->RetPosition(0); + + DisplayError(type, pObj); // displays eventual messages + + // Copies all spheres of the object. + for ( i=0 ; i<50 ; i++ ) + { + if ( !pObj->GetCrashSphere(i, m_crashSpherePos[i], m_crashSphereRadius[i]) ) break; + } + m_crashSphereUsed = i; + + // Calculates the size of the effect. + if ( oType == OBJECT_ANT || + oType == OBJECT_BEE || + oType == OBJECT_WORM || + oType == OBJECT_SPIDER ) + { + m_size = 40.0f; + } + else + { + m_size = Length(min, max)*2.0f; + if ( m_size < 4.0f ) m_size = 4.0f; + if ( m_size > 80.0f ) m_size = 80.0f; + } + if ( oType == OBJECT_TNT || + oType == OBJECT_BOMB ) + { + m_size *= 2.0f; + } + + m_pos = pos+(min+max)/2.0f; + m_type = type; + m_progress = 0.0f; + m_speed = 1.0f/20.0f; + m_time = 0.0f; + m_lastParticule = 0.0f; + m_lastParticuleSmoke = 0.0f; + m_lightRank = -1; + + if ( oType == OBJECT_TEEN28 || + oType == OBJECT_TEEN31 ) + { + m_pos.y = pos.y+1.0f; + } + + // Seeking the position of the battery. + power = pObj->RetPower(); + if ( power == 0 ) + { + m_bPower = FALSE; + } + else + { + m_bPower = TRUE; + pos = power->RetPosition(0); + pos.y += 1.0f; + mat = pObj->RetWorldMatrix(0); + m_posPower = Transform(*mat, pos); + } + if ( oType == OBJECT_POWER || + oType == OBJECT_ATOMIC || + oType == OBJECT_URANIUM || + oType == OBJECT_TNT || + oType == OBJECT_BOMB ) + { + m_bPower = TRUE; + m_posPower = m_pos; + m_posPower.y += 1.0f; + m_pos = m_posPower; + } + if ( oType == OBJECT_STATION ) + { + m_bPower = TRUE; + mat = pObj->RetWorldMatrix(0); + m_posPower = Transform(*mat, D3DVECTOR(-15.0f, 7.0f, 0.0f)); + m_pos = m_posPower; + } + if ( oType == OBJECT_ENERGY ) + { + m_bPower = TRUE; + mat = pObj->RetWorldMatrix(0); + m_posPower = Transform(*mat, D3DVECTOR(-7.0f, 6.0f, 0.0f)); + m_pos = m_posPower; + } + if ( oType == OBJECT_NUCLEAR ) + { + m_bPower = TRUE; + m_posPower = m_pos; + } + if ( oType == OBJECT_PARA ) + { + m_bPower = TRUE; + m_posPower = m_pos; + } + if ( oType == OBJECT_SCRAP4 || + oType == OBJECT_SCRAP5 ) // plastic material? + { + m_bPower = TRUE; + m_posPower = m_pos; + } + + // Plays the sound of a pyrotechnic effect. + if ( type == PT_FRAGT || + type == PT_FRAGW || + type == PT_EXPLOT || + type == PT_EXPLOW ) + { + if ( m_bPower ) + { + sound = SOUND_EXPLOp; + } + else + { + sound = SOUND_EXPLO; + } + if ( oType == OBJECT_STONE || + oType == OBJECT_METAL || + oType == OBJECT_BULLET || + oType == OBJECT_BBOX || + oType == OBJECT_KEYa || + oType == OBJECT_KEYb || + oType == OBJECT_KEYc || + oType == OBJECT_KEYd ) + { + sound = SOUND_EXPLOl; + } + if ( oType == OBJECT_URANIUM || + oType == OBJECT_POWER || + oType == OBJECT_ATOMIC || + oType == OBJECT_TNT || + oType == OBJECT_BOMB ) + { + sound = SOUND_EXPLOlp; + } + m_sound->Play(sound, m_pos); + } + if ( type == PT_FRAGO || + type == PT_EXPLOO || + type == PT_SPIDER || + type == PT_SHOTM ) + { + m_sound->Play(SOUND_EXPLOi, m_pos); + } + if ( type == PT_BURNT || + type == PT_BURNO ) + { + m_soundChannel = m_sound->Play(SOUND_BURN, m_pos, 1.0f, 1.0f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 12.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 5.0f, SOPER_STOP); + } + if ( type == PT_BURNO ) + { + m_sound->Play(SOUND_DEADi, m_pos); + m_sound->Play(SOUND_DEADi, m_engine->RetEyePt()); + } + if ( type == PT_EGG ) + { + m_sound->Play(SOUND_EGG, m_pos); + } + if ( type == PT_WPCHECK || + type == PT_FLCREATE || + type == PT_FLDELETE ) + { + m_sound->Play(SOUND_WAYPOINT, m_pos); + } + if ( oType == OBJECT_HUMAN ) + { + if ( type == PT_DEADG ) + { + m_sound->Play(SOUND_DEADg, m_pos); + } + if ( type == PT_DEADW ) + { + m_sound->Play(SOUND_DEADw, m_pos); + } + if ( type == PT_SHOTH && m_object->RetSelect() ) + { + m_sound->Play(SOUND_AIE, m_pos); + m_sound->Play(SOUND_AIE, m_engine->RetEyePt()); + } + } + + if ( m_type == PT_FRAGT || + m_type == PT_FRAGO || + m_type == PT_FRAGW ) + { + m_engine->ShadowDelete(m_object->RetObjectRank(0)); + } + + if ( m_type == PT_DEADG ) + { + m_object->SetDead(TRUE); + + motion = m_object->RetMotion(); + if ( motion != 0 ) + { + motion->SetAction(MHS_DEADg, 1.0f); + } + m_camera->StartCentering(m_object, PI*0.5f, 99.9f, 0.0f, 1.5f); + m_camera->StartOver(OE_FADEOUTw, m_pos, 1.0f); + m_speed = 1.0f/10.0f; + return TRUE; + } + if ( m_type == PT_DEADW ) + { + m_object->SetDead(TRUE); + + motion = m_object->RetMotion(); + if ( motion != 0 ) + { + motion->SetAction(MHS_DEADw, 4.0f); + } + m_camera->StartCentering(m_object, PI*0.5f, 99.9f, 0.0f, 3.0f); + m_camera->StartOver(OE_FADEOUTb, m_pos, 1.0f); + m_speed = 1.0f/10.0f; + return TRUE; + } + + if ( m_type == PT_SHOTT || + m_type == PT_SHOTM ) + { + m_camera->StartEffect(CE_SHOT, m_pos, force); + m_speed = 1.0f/1.0f; + return TRUE; + } + if ( m_type == PT_SHOTH ) + { + if ( m_object->RetSelect() ) + { + m_camera->StartOver(OE_BLOOD, m_pos, force); + } + m_speed = 1.0f/0.2f; + return TRUE; + } + + if ( m_type == PT_SHOTW ) + { + m_speed = 1.0f/1.0f; + } + + if ( m_type == PT_BURNT ) + { + BurnStart(); + } + + if ( m_type == PT_WPCHECK ) + { + m_speed = 1.0f/8.0f; + m_object->SetEnable(FALSE); // object more functional + } + if ( m_type == PT_FLCREATE ) + { + m_speed = 1.0f/2.0f; + } + if ( m_type == PT_FLDELETE ) + { + m_speed = 1.0f/2.0f; + m_object->SetEnable(FALSE); // object more functional + } + if ( m_type == PT_RESET ) + { + m_speed = 1.0f/2.0f; + m_object->SetPosition(0, m_object->RetResetPosition()); + m_object->SetAngle(0, m_object->RetResetAngle()); + m_object->SetZoom(0, 0.0f); + } + if ( m_type == PT_FINDING ) + { + limit = (m_size-1.0f)/4.0f; + if ( limit > 8.0f ) limit = 8.0f; + if ( oType == OBJECT_APOLLO2 ) limit = 2.0f; + m_speed = 1.0f/limit; + } + + if ( m_type == PT_EXPLOT || + m_type == PT_EXPLOO || + m_type == PT_EXPLOW ) + { + CreateTriangle(pObj, oType, 0); + m_engine->ShadowDelete(m_object->RetObjectRank(0)); + ExploStart(); + } + + if ( m_type == PT_FALL ) + { + FallStart(); + return TRUE; + } + + if ( m_type == PT_BURNT || + m_type == PT_BURNO ) + { + m_speed = 1.0f/15.0f; + + LightOperAdd(0.00f, 0.0f, 2.0f, 1.0f, 0.0f); // red-orange + LightOperAdd(0.30f, 1.0f, -0.8f, -0.8f, -0.8f); // dark gray + LightOperAdd(0.80f, 1.0f, -0.8f, -0.8f, -0.8f); // dark gray + LightOperAdd(1.00f, 0.0f, -0.8f, -0.8f, -0.8f); // dark gray + CreateLight(m_pos, 40.0f); + return TRUE; + } + + if ( m_type == PT_SPIDER ) + { + m_speed = 1.0f/15.0f; + + pos = D3DVECTOR(-3.0f, 2.0f, 0.0f); + mat = pObj->RetWorldMatrix(0); + m_pos = Transform(*mat, pos); + + m_engine->ShadowDelete(m_object->RetObjectRank(0)); + } + + if ( m_type != PT_EGG && + m_type != PT_WIN && + m_type != PT_LOST ) + { + h = 40.0f; + if ( m_type == PT_FRAGO || + m_type == PT_EXPLOO ) + { + LightOperAdd(0.00f, 0.0f, -1.0f, -0.5f, -1.0f); // dark green + LightOperAdd(0.05f, 1.0f, -1.0f, -0.5f, -1.0f); // dark green + LightOperAdd(1.00f, 0.0f, -1.0f, -0.5f, -1.0f); // dark green + } + else if ( m_type == PT_FRAGT || + m_type == PT_EXPLOT ) + { + LightOperAdd(0.00f, 1.0f, 4.0f, 4.0f, 2.0f); // yellow + LightOperAdd(0.02f, 1.0f, 4.0f, 2.0f, 0.0f); // red-orange + LightOperAdd(0.16f, 1.0f, -0.8f, -0.8f, -0.8f); // dark gray + LightOperAdd(1.00f, 0.0f, -0.8f, -0.8f, -0.8f); // dark gray + h = m_size*2.0f; + } + else if ( m_type == PT_SPIDER ) + { + LightOperAdd(0.00f, 0.0f, -0.5f, -1.0f, -1.0f); // dark red + LightOperAdd(0.05f, 1.0f, -0.5f, -1.0f, -1.0f); // dark red + LightOperAdd(1.00f, 0.0f, -0.5f, -1.0f, -1.0f); // dark red + } + else if ( m_type == PT_FRAGW || + m_type == PT_EXPLOW || + m_type == PT_SHOTW ) + { + LightOperAdd(0.00f, 0.0f, -0.5f, -0.5f, -1.0f); // dark yellow + LightOperAdd(0.05f, 1.0f, -0.5f, -0.5f, -1.0f); // dark yellow + LightOperAdd(1.00f, 0.0f, -0.5f, -0.5f, -1.0f); // dark yellow + } + else if ( m_type == PT_WPCHECK || + m_type == PT_FLCREATE || + m_type == PT_FLDELETE || + m_type == PT_RESET || + m_type == PT_FINDING ) + { + LightOperAdd(0.00f, 1.0f, 4.0f, 4.0f, 2.0f); // yellow + LightOperAdd(1.00f, 0.0f, 4.0f, 4.0f, 2.0f); // yellow + } + else + { + LightOperAdd(0.00f, 0.0f, -0.8f, -0.8f, -0.8f); // dark gray + LightOperAdd(0.05f, 1.0f, -0.8f, -0.8f, -0.8f); // dark gray + LightOperAdd(1.00f, 0.0f, -0.8f, -0.8f, -0.8f); // dark gray + } + CreateLight(m_pos, h); + + if ( m_type != PT_SHOTW && + m_type != PT_WPCHECK && + m_type != PT_FLCREATE && + m_type != PT_FLDELETE && + m_type != PT_RESET && + m_type != PT_FINDING ) + { + m_camera->StartEffect(CE_EXPLO, m_pos, force); + } + } + + if ( m_type == PT_SHOTW ) return TRUE; + + // Generates the triangles of the explosion. + if ( m_type == PT_FRAGT || + m_type == PT_FRAGO || + m_type == PT_FRAGW || + m_type == PT_SPIDER || + m_type == PT_EGG || + (m_type == PT_EXPLOT && oType == OBJECT_MOBILEtg) || + (m_type == PT_EXPLOT && oType == OBJECT_TEEN28 ) || + (m_type == PT_EXPLOT && oType == OBJECT_TEEN31 ) ) + { + for ( part=0 ; partRetParticuleDensity()); + if ( oType == OBJECT_TNT || + oType == OBJECT_BOMB ) total *= 3; + for ( i=0 ; iCreateTrack(pos, speed, dim, PARTITRACK1, + duration, mass, Rand()+0.7f, 1.0f); + } + } + + if ( m_size > 10.0f ) // large enough (freight excluded)? + { + if ( m_bPower ) + { + pos = m_posPower; + } + else + { + pos = m_pos; + m_terrain->MoveOnFloor(pos); + pos.y += 1.0f; + } + dim.x = m_size*0.4f; + dim.y = dim.x; + m_particule->CreateParticule(pos, D3DVECTOR(0.0f,0.0f,0.0f), dim, PARTISPHERE0, 2.0f, 0.0f, 0.0f); + } + } + + if ( m_type == PT_FRAGO || + m_type == PT_EXPLOO ) + { + total = (int)(10.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; iCreateParticule(pos, speed, dim, PARTIORGANIC1, + duration, mass); + } + total = (int)(5.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; iCreateTrack(pos, speed, dim, PARTITRACK4, + duration, mass, duration*0.5f, dim.x*2.0f); + } + } + + if ( m_type == PT_SPIDER ) + { + for ( i=0 ; i<50 ; i++ ) + { + pos = m_pos; + pos.x += (Rand()-0.5f)*3.0f; + pos.z += (Rand()-0.5f)*3.0f; + pos.y += (Rand()-0.5f)*2.0f; + speed.x = (Rand()-0.5f)*24.0f; + speed.z = (Rand()-0.5f)*24.0f; + speed.y = 10.0f+Rand()*10.0f; + dim.x = 1.0f; + dim.y = dim.x; + channel = m_particule->CreateParticule(pos, speed, dim, PARTIGUN3, 2.0f+Rand()*2.0f, 10.0f); + m_particule->SetObjectFather(channel, pObj); + } + total = (int)(10.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; iCreateTrack(pos, speed, dim, PARTITRACK3, + 2.0f+Rand()*2.0f, 10.0f, 2.0f, 0.6f); + } + } + + if ( type == PT_FRAGT || + type == PT_FRAGW || + type == PT_EXPLOT || + type == PT_EXPLOW ) + { + if ( m_size > 10.0f || m_bPower ) + { + pos = m_pos; +//? m_terrain->MoveOnFloor(pos); +//? pos.y += 2.0f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = m_size; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICHOC, 2.0f); + } + } + + return TRUE; +} + +// Creates an explosion with triangular form of particles. + +void CPyro::CreateTriangle(CObject* pObj, ObjectType oType, int part) +{ + D3DTriangle buffer[100]; + D3DMATRIX* mat; + D3DVECTOR offset, pos, speed; + float percent, min, max, h, duration, mass; + int objRank, total, i; + + objRank = pObj->RetObjectRank(part); + if ( objRank == -1 ) return; + + min = 0.0f; + max = m_engine->RetLimitLOD(0); + total = m_engine->RetTotalTriangles(objRank); + percent = 0.10f; + if ( total < 50 ) percent = 0.25f; + if ( total < 20 ) percent = 0.50f; + if ( m_type == PT_EGG ) percent = 0.30f; + if ( oType == OBJECT_POWER || + oType == OBJECT_ATOMIC || + oType == OBJECT_URANIUM || + oType == OBJECT_TNT || + oType == OBJECT_BOMB ) percent = 0.75f; + if ( oType == OBJECT_MOBILEtg ) percent = 0.50f; + if ( oType == OBJECT_TEEN28 ) percent = 0.75f; + if ( oType == OBJECT_MOTHER ) max = 1000000.0f; + if ( oType == OBJECT_TEEN28 ) max = 1000000.0f; + if ( oType == OBJECT_TEEN31 ) max = 1000000.0f; + total = m_engine->GetTriangles(objRank, min, max, buffer, 100, percent); + + for ( i=0 ; i 5.0f ) + { + p2.x = p1.x+((p2.x-p1.x)*5.0f/h); + p2.y = p1.y+((p2.y-p1.y)*5.0f/h); + p2.z = p1.z+((p2.z-p1.z)*5.0f/h); + } + + h = Length(p2, p3); + if ( h > 5.0f ) + { + p3.x = p2.x+((p3.x-p2.x)*5.0f/h); + p3.y = p2.y+((p3.y-p2.y)*5.0f/h); + p3.z = p2.z+((p3.z-p2.z)*5.0f/h); + } + + h = Length(p3, p1); + if ( h > 5.0f ) + { + p1.x = p3.x+((p1.x-p3.x)*5.0f/h); + p1.y = p3.y+((p1.y-p3.y)*5.0f/h); + p1.z = p3.z+((p1.z-p3.z)*5.0f/h); + } + + buffer[i].triangle[0].x = p1.x; + buffer[i].triangle[0].y = p1.y; + buffer[i].triangle[0].z = p1.z; + buffer[i].triangle[1].x = p2.x; + buffer[i].triangle[1].y = p2.y; + buffer[i].triangle[1].z = p2.z; + buffer[i].triangle[2].x = p3.x; + buffer[i].triangle[2].y = p3.y; + buffer[i].triangle[2].z = p3.z; + + offset.x = (buffer[i].triangle[0].x+buffer[i].triangle[1].x+buffer[i].triangle[2].x)/3.0f; + offset.y = (buffer[i].triangle[0].y+buffer[i].triangle[1].y+buffer[i].triangle[2].y)/3.0f; + offset.z = (buffer[i].triangle[0].z+buffer[i].triangle[1].z+buffer[i].triangle[2].z)/3.0f; + + buffer[i].triangle[0].x -= offset.x; + buffer[i].triangle[1].x -= offset.x; + buffer[i].triangle[2].x -= offset.x; + + buffer[i].triangle[0].y -= offset.y; + buffer[i].triangle[1].y -= offset.y; + buffer[i].triangle[2].y -= offset.y; + + buffer[i].triangle[0].z -= offset.z; + buffer[i].triangle[1].z -= offset.z; + buffer[i].triangle[2].z -= offset.z; + + mat = pObj->RetWorldMatrix(part); + pos = Transform(*mat, offset); + if ( m_type == PT_EGG ) + { + speed.x = (Rand()-0.5f)*10.0f; + speed.z = (Rand()-0.5f)*10.0f; + speed.y = Rand()*15.0f; + mass = Rand()*20.0f+20.0f; + } + else if ( m_type == PT_SPIDER ) + { + speed.x = (Rand()-0.5f)*10.0f; + speed.z = (Rand()-0.5f)*10.0f; + speed.y = Rand()*20.0f; + mass = Rand()*10.0f+15.0f; + } + else + { + speed.x = (Rand()-0.5f)*30.0f; + speed.z = (Rand()-0.5f)*30.0f; + speed.y = Rand()*30.0f; + mass = Rand()*10.0f+15.0f; + } + if ( oType == OBJECT_STONE ) speed *= 0.5f; + if ( oType == OBJECT_URANIUM ) speed *= 0.4f; + duration = Rand()*3.0f+3.0f; + m_particule->CreateFrag(pos, speed, &buffer[i], PARTIFRAG, + duration, mass, 0.5f); + } +} + +// Displays the error or eventual information, +// linked to the destruction of an insect, a vehicle or building. + +void CPyro::DisplayError(PyroType type, CObject* pObj) +{ + ObjectType oType; + Error err; + + oType = pObj->RetType(); + + if ( type == PT_FRAGT || + type == PT_FRAGO || + type == PT_FRAGW || + type == PT_EXPLOT || + type == PT_EXPLOO || + type == PT_EXPLOW || + type == PT_BURNT || + type == PT_BURNO ) + { + err = ERR_OK; + if ( oType == OBJECT_MOTHER ) err = INFO_DELETEMOTHER; + if ( oType == OBJECT_ANT ) err = INFO_DELETEANT; + if ( oType == OBJECT_BEE ) err = INFO_DELETEBEE; + if ( oType == OBJECT_WORM ) err = INFO_DELETEWORM; + if ( oType == OBJECT_SPIDER ) err = INFO_DELETESPIDER; + + if ( oType == OBJECT_MOBILEwa || + oType == OBJECT_MOBILEta || + oType == OBJECT_MOBILEfa || + oType == OBJECT_MOBILEia || + oType == OBJECT_MOBILEwc || + oType == OBJECT_MOBILEtc || + oType == OBJECT_MOBILEfc || + oType == OBJECT_MOBILEic || + oType == OBJECT_MOBILEwi || + oType == OBJECT_MOBILEti || + oType == OBJECT_MOBILEfi || + oType == OBJECT_MOBILEii || + oType == OBJECT_MOBILEws || + oType == OBJECT_MOBILEts || + oType == OBJECT_MOBILEfs || + oType == OBJECT_MOBILEis || + oType == OBJECT_MOBILErt || + oType == OBJECT_MOBILErc || + oType == OBJECT_MOBILErr || + oType == OBJECT_MOBILErs || + oType == OBJECT_MOBILEsa || + oType == OBJECT_MOBILEwt || + oType == OBJECT_MOBILEtt || + oType == OBJECT_MOBILEft || + oType == OBJECT_MOBILEit || + oType == OBJECT_MOBILEdr ) + { + err = ERR_DELETEMOBILE; + } + + if ( oType == OBJECT_DERRICK || + oType == OBJECT_FACTORY || + oType == OBJECT_STATION || + oType == OBJECT_CONVERT || + oType == OBJECT_REPAIR || + oType == OBJECT_DESTROYER|| + oType == OBJECT_TOWER || + oType == OBJECT_RESEARCH || + oType == OBJECT_RADAR || + oType == OBJECT_INFO || + oType == OBJECT_ENERGY || + oType == OBJECT_LABO || + oType == OBJECT_NUCLEAR || + oType == OBJECT_PARA || + oType == OBJECT_SAFE || + oType == OBJECT_HUSTON || + oType == OBJECT_START || + oType == OBJECT_END ) + { + err = ERR_DELETEBUILDING; + m_displayText->DisplayError(err, pObj->RetPosition(0), 5.0f); + return; + } + + if ( err != ERR_OK ) + { + m_displayText->DisplayError(err, pObj); + } + } +} + + +// Management of an event. + +BOOL CPyro::EventProcess(const Event &event) +{ + ParticuleType type; + D3DVECTOR pos, speed, angle; + FPOINT dim; + float prog, factor, duration; + int i, r; + + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_engine->RetPause() ) return TRUE; + + m_time += event.rTime; + m_progress += event.rTime*m_speed; + + if ( m_soundChannel != -1 && m_object != 0 ) + { + pos = m_object->RetPosition(0); + m_sound->Position(m_soundChannel, pos); + + if ( m_lightRank != -1 ) + { + pos.y += m_lightHeight; + m_light->SetLightPos(m_lightRank, pos); + } + } + + if ( m_type == PT_SHOTT && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + if ( m_crashSphereUsed > 0 ) + { + i = rand()%m_crashSphereUsed; + pos = m_crashSpherePos[i]; + pos.x += (Rand()-0.5f)*m_crashSphereRadius[i]*2.0f; + pos.z += (Rand()-0.5f)*m_crashSphereRadius[i]*2.0f; + speed.x = (Rand()-0.5f)*m_crashSphereRadius[i]*0.5f; + speed.z = (Rand()-0.5f)*m_crashSphereRadius[i]*0.5f; + speed.y = Rand()*m_crashSphereRadius[i]*1.0f; + dim.x = Rand()*m_crashSphereRadius[i]*0.5f+m_crashSphereRadius[i]*0.75f*m_force; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 3.0f); + } + else + { + pos = m_pos; + pos.x += (Rand()-0.5f)*m_size*0.3f; + pos.z += (Rand()-0.5f)*m_size*0.3f; + speed.x = (Rand()-0.5f)*m_size*0.1f; + speed.z = (Rand()-0.5f)*m_size*0.1f; + speed.y = Rand()*m_size*0.2f; + dim.x = Rand()*m_size/10.0f+m_size/10.0f*m_force; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 3.0f); + } + } + + if ( m_type == PT_SHOTH && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + for ( i=0 ; i<10 ; i++ ) + { + pos = m_pos; + pos.x += (Rand()-0.5f)*m_size*0.2f; + pos.z += (Rand()-0.5f)*m_size*0.2f; + pos.y += (Rand()-0.5f)*m_size*0.5f; + speed.x = (Rand()-0.5f)*5.0f; + speed.z = (Rand()-0.5f)*5.0f; + speed.y = Rand()*1.0f; + dim.x = 1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLOOD, Rand()*3.0f+3.0f, Rand()*10.0f+15.0f, 0.5f); + } + } + + if ( m_type == PT_SHOTM && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + r = (int)(10.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; iCreateParticule(pos, speed, dim, PARTIBLOODM, 2.0f, 50.0f, 0.0f); + } + } + + if ( m_type == PT_SHOTW && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + if ( m_crashSphereUsed > 0 ) + { + i = rand()%m_crashSphereUsed; + pos = m_crashSpherePos[i]; + pos.x += (Rand()-0.5f)*m_crashSphereRadius[i]*2.0f; + pos.z += (Rand()-0.5f)*m_crashSphereRadius[i]*2.0f; + speed.x = (Rand()-0.5f)*m_crashSphereRadius[i]*0.5f; + speed.z = (Rand()-0.5f)*m_crashSphereRadius[i]*0.5f; + speed.y = Rand()*m_crashSphereRadius[i]*1.0f; + dim.x = 1.0f*m_force; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 0.5f, 0.0f, 0.0f); + } + else + { + pos = m_pos; + pos.x += (Rand()-0.5f)*m_size*0.3f; + pos.z += (Rand()-0.5f)*m_size*0.3f; + speed.x = (Rand()-0.5f)*m_size*0.1f; + speed.z = (Rand()-0.5f)*m_size*0.1f; + speed.y = Rand()*m_size*0.2f; + dim.x = 1.0f*m_force; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 0.5f, 0.0f, 0.0f); + } + } + + if ( m_type == PT_SHOTW && + m_lastParticuleSmoke+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticuleSmoke = m_time; + + pos = m_pos; + pos.y -= 2.0f; + pos.x += (Rand()-0.5f)*4.0f; + pos.z += (Rand()-0.5f)*4.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 10.0f+Rand()*10.0f; + dim.x = Rand()*2.5f+2.0f*m_force; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 4.0f); + } + + if ( (m_type == PT_FRAGT || m_type == PT_EXPLOT) && + m_progress < 0.05f && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_pos; + speed.x = (Rand()-0.5f)*m_size*1.0f; + speed.z = (Rand()-0.5f)*m_size*1.0f; + speed.y = Rand()*m_size*0.50f; + dim.x = Rand()*m_size/5.0f+m_size/5.0f; + dim.y = dim.x; + + m_particule->CreateParticule(pos, speed, dim, PARTIEXPLOT); + } + + if ( (m_type == PT_FRAGT || m_type == PT_EXPLOT) && + m_progress < 0.10f && + m_lastParticuleSmoke+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticuleSmoke = m_time; + + dim.x = Rand()*m_size/3.0f+m_size/3.0f; + dim.y = dim.x; + pos = m_pos; + pos.x += (Rand()-0.5f)*m_size*0.5f; + pos.z += (Rand()-0.5f)*m_size*0.5f; + m_terrain->MoveOnFloor(pos); + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = -dim.x/2.0f/4.0f; + pos.y += dim.x/2.0f; + + r = rand()%2; + if ( r == 0 ) type = PARTISMOKE1; + if ( r == 1 ) type = PARTISMOKE2; + m_particule->CreateParticule(pos, speed, dim, type, 6.0f); + } + + if ( (m_type == PT_FRAGO || m_type == PT_EXPLOO) && + m_progress < 0.03f && + m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_pos; + speed.x = (Rand()-0.5f)*m_size*2.0f; + speed.z = (Rand()-0.5f)*m_size*2.0f; + speed.y = Rand()*m_size*1.0f; + dim.x = Rand()*m_size/2.0f+m_size/2.0f; + dim.y = dim.x; + + m_particule->CreateParticule(pos, speed, dim, PARTIEXPLOO); + } + + if ( (m_type == PT_FRAGW || m_type == PT_EXPLOW) && + m_progress < 0.05f && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_pos; + speed.x = (Rand()-0.5f)*m_size*1.0f; + speed.z = (Rand()-0.5f)*m_size*1.0f; + speed.y = Rand()*m_size*0.50f; + dim.x = 1.0f; + dim.y = dim.x; + + m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 0.5f, 0.0f, 0.0f); + } + + if ( (m_type == PT_FRAGW || m_type == PT_EXPLOW) && + m_progress < 0.25f && + m_lastParticuleSmoke+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticuleSmoke = m_time; + + pos = m_pos; + pos.y -= 2.0f; + pos.x += (Rand()-0.5f)*4.0f; + pos.z += (Rand()-0.5f)*4.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 4.0f+Rand()*4.0f; + dim.x = Rand()*2.5f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 4.0f); + } + + if ( m_type == PT_WPCHECK ) + { + if ( m_progress < 0.25f ) + { + factor = 0.0f; + } + else + { + factor = powf((m_progress-0.25f)/0.75f, 2.0f)*30.0f; + } + + if ( m_progress < 0.85f && + m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_pos; + pos.y += factor; + pos.x += (Rand()-0.5f)*3.0f; + pos.z += (Rand()-0.5f)*3.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 5.0f+Rand()*5.0f; + dim.x = Rand()*1.5f+1.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f); +//? m_particule->CreateParticule(pos, speed, dim, (ParticuleType)(PARTILENS1+rand()%4), 2.0f); + } + + angle = m_object->RetAngle(0); + angle.y = m_progress*20.0f; + angle.x = sinf(m_progress*49.0f)*0.3f; + angle.z = sinf(m_progress*47.0f)*0.2f; + m_object->SetAngle(0, angle); + + pos = m_pos; + pos.y += factor; + m_object->SetPosition(0, pos); + + if ( m_progress > 0.85f ) + { + m_object->SetZoom(0, 1.0f-(m_progress-0.85f)/0.15f); + } + } + + if ( m_type == PT_FLCREATE ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_pos; + m_terrain->MoveOnFloor(pos); + pos.x += (Rand()-0.5f)*1.0f; + pos.z += (Rand()-0.5f)*1.0f; + speed.x = (Rand()-0.5f)*2.0f; + speed.z = (Rand()-0.5f)*2.0f; + speed.y = 2.0f+Rand()*2.0f; + dim.x = (Rand()*1.0f+1.0f)*(0.2f+m_progress*0.8f); + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f); + } + + angle = m_object->RetAngle(0); +//? angle.y = powf(m_progress, 0.2f)*20.0f; + angle.x = sinf(m_progress*49.0f)*0.3f*(1.0f-m_progress); + angle.z = sinf(m_progress*47.0f)*0.2f*(1.0f-m_progress); + m_object->SetAngle(0, angle); + + m_object->SetZoom(0, m_progress); + } + + if ( m_type == PT_FLDELETE ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_pos; + m_terrain->MoveOnFloor(pos); + pos.x += (Rand()-0.5f)*1.0f; + pos.z += (Rand()-0.5f)*1.0f; + speed.x = (Rand()-0.5f)*2.0f; + speed.z = (Rand()-0.5f)*2.0f; + speed.y = 2.0f+Rand()*2.0f; + dim.x = (Rand()*1.0f+1.0f)*(0.2f+m_progress*0.8f); + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.5f); + } + + angle = m_object->RetAngle(0); + angle.y = m_progress*20.0f; + angle.x = sinf(m_progress*49.0f)*0.3f; + angle.z = sinf(m_progress*47.0f)*0.2f; + m_object->SetAngle(0, angle); + + m_object->SetZoom(0, 1.0f-m_progress); + } + + if ( m_type == PT_RESET ) + { +#if 0 + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_pos; + speed.x = (Rand()-0.5f)*6.0f; + speed.z = (Rand()-0.5f)*6.0f; + speed.y = Rand()*12.0f; + dim.x = (Rand()*2.5f+2.5f)*(1.0f-m_progress*0.9f); + dim.y = dim.x; + pos.y += dim.y; + m_particule->CreateParticule(pos, speed, dim, + (ParticuleType)(PARTILENS1+rand()%4), + Rand()*2.5f+2.5f, + Rand()*5.0f+5.0f, 0.0f); + } +#else + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_pos; + pos.x += (Rand()-0.5f)*5.0f; + pos.z += (Rand()-0.5f)*5.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 5.0f+Rand()*5.0f; + dim.x = Rand()*2.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINTb, 2.0f); + + pos = m_pos; + speed.x = (Rand()-0.5f)*20.0f; + speed.z = (Rand()-0.5f)*20.0f; + speed.y = Rand()*10.0f; + speed *= 0.5f+m_progress*0.5f; + dim.x = 0.6f; + dim.y = dim.x; + pos.y += dim.y; + duration = Rand()*1.5f+1.5f; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK6, + duration, 0.0f, + duration*0.9f, 0.7f); + } +#endif + + angle = m_object->RetResetAngle(); + m_object->SetAngleY(0, angle.y-powf((1.0f-m_progress)*5.0f, 2.0f)); + m_object->SetZoom(0, m_progress); + } + + if ( m_type == PT_FINDING ) + { + if ( m_object != 0 && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + factor = m_size*0.3f; + if ( m_object->RetType() == OBJECT_SAFE ) factor *= 1.3f; + if ( factor > 40.0f ) factor = 40.0f; + pos = m_pos; + m_terrain->MoveOnFloor(pos); + pos.x += (Rand()-0.5f)*factor; + pos.z += (Rand()-0.5f)*factor; + speed.x = (Rand()-0.5f)*2.0f; + speed.z = (Rand()-0.5f)*2.0f; + speed.y = 4.0f+Rand()*4.0f; + dim.x = (Rand()*3.0f+3.0f)*(1.0f-m_progress*0.9f); + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.5f); + } + } + + if ( (m_type == PT_BURNT || m_type == PT_BURNO) && + m_object != 0 ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + factor = m_size/25.0f; // 1 = standard size + + pos = m_object->RetPosition(0); + pos.y -= m_object->RetCharacter()->height; + pos.x += (Rand()-0.5f)*(4.0f+8.0f*m_progress)*factor; + pos.z += (Rand()-0.5f)*(4.0f+8.0f*m_progress)*factor; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 0.0f; + dim.x = (Rand()*2.5f+1.0f)*factor; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFLAME, 2.0f, 0.0f, 0.2f); + + pos = m_object->RetPosition(0); + pos.y -= m_object->RetCharacter()->height; + pos.x += (Rand()-0.5f)*(2.0f+4.0f*m_progress)*factor; + pos.z += (Rand()-0.5f)*(2.0f+4.0f*m_progress)*factor; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = (Rand()*5.0f*m_progress+3.0f)*factor; + dim.x = (Rand()*2.0f+1.0f)*factor; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFLAME, 2.0f, 0.0f, 0.2f); + + pos = m_object->RetPosition(0); + pos.y -= 2.0f; + pos.x += (Rand()-0.5f)*5.0f*factor; + pos.z += (Rand()-0.5f)*5.0f*factor; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = (6.0f+Rand()*6.0f+m_progress*6.0f)*factor; + dim.x = (Rand()*1.5f+1.0f+m_progress*3.0f)*factor; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); + } + + if ( m_type == PT_BURNT ) + { + BurnProgress(); + } + else + { + speed.y = 0.0f; + speed.x = (Rand()-0.5f)*m_progress*1.0f; + speed.z = (Rand()-0.5f)*m_progress*1.0f; + if ( m_progress > 0.8f ) + { + prog = (m_progress-0.8f)/0.2f; // 0..1 + speed.y = -prog*6.0f; // sinks into the ground + m_object->SetZoom(0, 1.0f-prog*0.5f); + } + m_object->SetLinVibration(speed); + } + } + + if ( m_type == PT_WIN ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.y += 1.5f; + speed.x = (Rand()-0.5f)*10.0f; + speed.z = (Rand()-0.5f)*10.0f; + speed.y = 8.0f+Rand()*8.0f; + dim.x = Rand()*0.2f+0.2f; + dim.y = dim.x; + m_particule->CreateTrack(pos, speed, dim, + (ParticuleType)(PARTITRACK7+rand()%4), + 3.0f, 20.0f, 1.0f, 0.4f); + } + } + + if ( m_type == PT_LOST ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.y -= 2.0f; + pos.x += (Rand()-0.5f)*10.0f; + pos.z += (Rand()-0.5f)*10.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 1.0f+Rand()*1.0f; + dim.x = Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 8.0f, 0.0f, 0.0f); + } + } + + if ( m_type == PT_FALL ) + { + FallProgress(event.rTime); + } + + if ( m_lightRank != -1 ) + { + LightOperFrame(event.rTime); + } + + return TRUE; +} + +// Indicates that the object binds to the effect no longer exists, without deleting it. + +void CPyro::CutObjectLink(CObject* pObj) +{ + if ( m_object == pObj ) + { + m_object = 0; + } +} + +// Indicates whether the pyrotechnic effect is complete. + +Error CPyro::IsEnded() +{ + // Destroys the object that exploded. + //It should not be destroyed at the end of the Create, + //because it is sometimes the object itself that makes the Create: + // pyro->Create(PT_FRAGT, this); + if ( m_type == PT_FRAGT || + m_type == PT_FRAGO || + m_type == PT_FRAGW || + m_type == PT_SPIDER || + m_type == PT_EGG ) + { + DeleteObject(TRUE, TRUE); + } + + if ( m_type == PT_FALL ) // freight which grave? + { + return FallIsEnded(); + } + + if ( m_type == PT_WIN || + m_type == PT_LOST ) + { + return ERR_CONTINUE; + } + + // End of the pyrotechnic effect? + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + if ( m_type == PT_EXPLOT || + m_type == PT_EXPLOO || + m_type == PT_EXPLOW ) // explosion? + { + ExploTerminate(); + } + + if ( m_type == PT_BURNT || + m_type == PT_BURNO ) // burning? + { + BurnTerminate(); + } + + if ( m_type == PT_WPCHECK || + m_type == PT_FLDELETE ) + { + DeleteObject(TRUE, TRUE); + } + + if ( m_type == PT_FLCREATE ) + { + m_object->SetAngleX(0, 0.0f); + m_object->SetAngleZ(0, 0.0f); + m_object->SetZoom(0, 1.0f); + } + + if ( m_type == PT_RESET ) + { + m_object->SetPosition(0, m_object->RetResetPosition()); + m_object->SetAngle(0, m_object->RetResetAngle()); + m_object->SetZoom(0, 1.0f); + } + + if ( m_lightRank != -1 ) + { + m_light->DeleteLight(m_lightRank); + m_lightRank = -1; + } + + return ERR_STOP; +} + +// Removes the binding to a pyrotechnic effect. + +void CPyro::DeleteObject(BOOL bPrimary, BOOL bSecondary) +{ + CObject *sub, *truck; + D3DVECTOR pos; + ObjectType type; + + if ( m_object == 0 ) return; + + if ( m_object->RetResetCap() == RESET_MOVE ) // resettable object? + { + m_object->SetEnable(FALSE); // object cache and inactive + pos = m_object->RetPosition(0); + pos.y = -100.0f; + m_object->SetPosition(0, pos); + return; + } + + type = m_object->RetType(); + if ( bSecondary && + type != OBJECT_FACTORY && + type != OBJECT_NUCLEAR && + type != OBJECT_ENERGY ) + { + sub = m_object->RetPower(); + if ( sub != 0 ) + { + sub->DeleteObject(); // removes the battery + delete sub; + m_object->SetPower(0); + } + + sub = m_object->RetFret(); + if ( sub != 0 ) + { + sub->DeleteObject(); // removes the object transported + delete sub; + m_object->SetFret(0); + } + } + + if ( bPrimary ) + { + truck = m_object->RetTruck(); + if ( truck != 0 ) // object carries? + { + if ( truck->RetPower() == m_object ) + { + truck->SetPower(0); + } + if ( truck->RetFret() == m_object ) + { + truck->SetFret(0); + } + } + + sub = m_object; + sub->DeleteObject(); // removes the object (*) + delete sub; + m_object = 0; + } +} + +// (*) CObject :: DeleteObject can reset m_object through CPyro :: CutObjectLink! + + +// Empty the table of operations of animation of light. + +void CPyro::LightOperFlush() +{ + m_lightOperTotal = 0; +} + +// Adds an animation operation of the light. + +void CPyro::LightOperAdd(float progress, float intensity, + float r, float g, float b) +{ + int i; + + i = m_lightOperTotal; + + m_lightOper[i].progress = progress; + m_lightOper[i].intensity = intensity; + m_lightOper[i].color.r = r; + m_lightOper[i].color.g = g; + m_lightOper[i].color.b = b; + + m_lightOperTotal ++; +} + +// Makes evolve the associated light. + +void CPyro::LightOperFrame(float rTime) +{ + D3DCOLORVALUE color; + float progress, intensity; + int i; + + for ( i=0 ; iSetLightIntensity(m_lightRank, intensity); + m_light->SetLightColor(m_lightRank, color); + break; + } + } +} + + +// Creates light to accompany a pyrotechnic effect. + +BOOL CPyro::CreateLight(D3DVECTOR pos, float height) +{ + D3DLIGHT7 light; + + if ( !m_engine->RetLightMode() ) return TRUE; + + m_lightHeight = height; + + ZeroMemory( &light, sizeof(light) ); + light.dltType = D3DLIGHT_SPOT; + light.dvPosition.x = pos.x; + light.dvPosition.y = pos.y+height; + light.dvPosition.z = pos.z; + light.dvDirection.x = 0.0f; + light.dvDirection.y = -1.0f; // against the bottom + light.dvDirection.z = 0.0f; + light.dvRange = D3DLIGHT_RANGE_MAX; + light.dvFalloff = 1.0f; + light.dvAttenuation0 = 1.0f; + light.dvAttenuation1 = 0.0f; + light.dvAttenuation2 = 0.0f; + light.dvTheta = 0.0f; + light.dvPhi = PI/4.0f; + + m_lightRank = m_light->CreateLight(); + if ( m_lightRank == -1 ) return FALSE; + + m_light->SetLight(m_lightRank, light); + m_light->SetLightIntensity(m_lightRank, 0.0f); + + // Only illuminates the objects on the ground. + m_light->SetLightIncluType(m_lightRank, TYPETERRAIN); + + return TRUE; +} + + +// Starts the explosion of a vehicle. + +void CPyro::ExploStart() +{ + D3DVECTOR pos, angle, speed, min, max; + float weight; + int i, objRank, channel; + + m_burnType = m_object->RetType(); + + pos = m_object->RetPosition(0); + m_burnFall = m_terrain->RetFloorHeight(pos, TRUE); + + m_object->Simplify(); + m_object->SetLock(TRUE); // ruin not usable yet + m_object->SetExplo(TRUE); // being destroyed + m_object->FlatParent(); + + if ( m_object->RetSelect() ) + { + m_object->SetSelect(FALSE); // deselects the object + m_camera->SetType(CAMERA_EXPLO); + m_main->DeselectAll(); + } + m_object->DeleteDeselList(m_object); + + for ( i=0 ; iRetObjectRank(i); + if ( objRank == -1 ) continue; + m_engine->ChangeSecondTexture(objRank, "dirty04.tga"); + + pos = m_object->RetPosition(i); + + if ( i == 0 ) // main part? + { + weight = 0.0f; + + speed.y = -1.0f; + speed.x = 0.0f; + speed.z = 0.0f; + } + else + { + m_engine->GetBBox(objRank, min, max); + weight = Length(min, max); // weight according to size! + + speed.y = 10.0f+Rand()*20.0f; + speed.x = (Rand()-0.5f)*20.0f; + speed.z = (Rand()-0.5f)*20.0f; + } + + channel = m_particule->CreatePart(pos, speed, PARTIPART, 10.0f, 20.0f, weight, 0.5f); + if ( channel != -1 ) + { + m_object->SetMasterParticule(i, channel); + } + } + m_engine->LoadTexture("dirty04.tga", 1); + + DeleteObject(FALSE, TRUE); // destroys the object transported + the battery +} + +// Ends the explosion of a vehicle. + +void CPyro::ExploTerminate() +{ + DeleteObject(TRUE, FALSE); // removes the main object +} + + +// Starts a vehicle fire. + +void CPyro::BurnStart() +{ + D3DVECTOR pos, angle; + int i, objRank; + + m_burnType = m_object->RetType(); + + pos = m_object->RetPosition(0); + m_burnFall = m_terrain->RetFloorHeight(pos, TRUE); + + m_object->Simplify(); + m_object->SetLock(TRUE); // ruin not usable yet + + if ( m_object->RetSelect() ) + { + m_object->SetSelect(FALSE); // deselects the object + m_camera->SetType(CAMERA_EXPLO); + m_main->DeselectAll(); + } + m_object->DeleteDeselList(m_object); + + for ( i=0 ; iRetObjectRank(i); + if ( objRank == -1 ) continue; + m_engine->ChangeSecondTexture(objRank, "dirty04.tga"); + } + m_engine->LoadTexture("dirty04.tga", 1); + + m_burnPartTotal = 0; + + if ( m_burnType == OBJECT_DERRICK || + m_burnType == OBJECT_FACTORY || + m_burnType == OBJECT_REPAIR || + m_burnType == OBJECT_DESTROYER|| + m_burnType == OBJECT_CONVERT || + m_burnType == OBJECT_TOWER || + m_burnType == OBJECT_RESEARCH || + m_burnType == OBJECT_ENERGY || + m_burnType == OBJECT_LABO ) + { + pos.x = 0.0f; + pos.y = -(4.0f+Rand()*4.0f); + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.4f; + angle.y = 0.0f; + angle.z = (Rand()-0.5f)*0.4f; + } + else if ( m_burnType == OBJECT_STATION || + m_burnType == OBJECT_RADAR || + m_burnType == OBJECT_INFO ) + { + pos.x = 0.0f; + pos.y = -(1.0f+Rand()*1.0f); + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.2f; + angle.y = 0.0f; + angle.z = (Rand()-0.5f)*0.2f; + } + else if ( m_burnType == OBJECT_NUCLEAR ) + { + pos.x = 0.0f; + pos.y = -(10.0f+Rand()*10.0f); + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.4f; + angle.y = 0.0f; + angle.z = (Rand()-0.5f)*0.4f; + } + else if ( m_burnType == OBJECT_PARA ) + { + pos.x = 0.0f; + pos.y = -(10.0f+Rand()*10.0f); + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.4f; + angle.y = 0.0f; + angle.z = (Rand()-0.5f)*0.4f; + } + else if ( m_burnType == OBJECT_SAFE ) + { + pos.x = 0.0f; + pos.y = -(10.0f+Rand()*10.0f); + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.4f; + angle.y = 0.0f; + angle.z = (Rand()-0.5f)*0.4f; + } + else if ( m_burnType == OBJECT_HUSTON ) + { + pos.x = 0.0f; + pos.y = -(10.0f+Rand()*10.0f); + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.4f; + angle.y = 0.0f; + angle.z = (Rand()-0.5f)*0.4f; + } + else if ( m_burnType == OBJECT_MOBILEwa || + m_burnType == OBJECT_MOBILEwc || + m_burnType == OBJECT_MOBILEwi || + m_burnType == OBJECT_MOBILEws || + m_burnType == OBJECT_MOBILEwt ) + { + pos.x = 0.0f; + pos.y = -(0.5f+Rand()*1.0f); + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.8f; + angle.y = 0.0f; + angle.z = (Rand()-0.5f)*0.4f; + } + else if ( m_burnType == OBJECT_TEEN31 ) // basket? + { + pos.x = 0.0f; + pos.y = 0.0f; + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.8f; + angle.y = 0.0f; + angle.z = (Rand()-0.5f)*0.2f; + } + else + { + pos.x = 0.0f; + pos.y = -(2.0f+Rand()*2.0f); + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.8f; + angle.y = 0.0f; + angle.z = (Rand()-0.5f)*0.8f; + } + BurnAddPart(0, pos, angle); // movement of the main part + + m_burnKeepPart[0] = -1; // nothing to keep + + if ( m_burnType == OBJECT_DERRICK ) + { + pos.x = 0.0f; + pos.y = -40.0f; + pos.z = 0.0f; + angle.x = 0.0f; + angle.y = 0.0f; + angle.z = 0.0f; + BurnAddPart(1, pos, angle); // down the drill + } + + if ( m_burnType == OBJECT_REPAIR ) + { + pos.x = 0.0f; + pos.y = -12.0f; + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.2f; + angle.y = (Rand()-0.5f)*0.2f; + angle.z = -90.0f*PI/180.0f; + BurnAddPart(1, pos, angle); // down the sensor + } + + if ( m_burnType == OBJECT_DESTROYER ) + { + pos.x = 0.0f; + pos.y = -12.0f; + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.2f; + angle.y = (Rand()-0.5f)*0.2f; + angle.z = -90.0f*PI/180.0f; + BurnAddPart(1, pos, angle); // down the sensor + } + + if ( m_burnType == OBJECT_CONVERT ) + { + pos.x = 0.0f; + pos.y = -200.0f; + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.5f; + angle.y = (Rand()-0.5f)*0.5f; + angle.z = 0.0f; + BurnAddPart(1, pos, angle); // down the cover + BurnAddPart(2, pos, angle); + BurnAddPart(3, pos, angle); + } + + if ( m_burnType == OBJECT_TOWER ) + { + pos.x = 0.0f; + pos.y = -7.0f; + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.4f; + angle.y = (Rand()-0.5f)*0.4f; + angle.z = 0.0f; + BurnAddPart(1, pos, angle); // down the cannon + } + + if ( m_burnType == OBJECT_RESEARCH ) + { + pos.x = 0.0f; + pos.y = -7.0f; + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.2f; + angle.y = (Rand()-0.5f)*0.2f; + angle.z = 0.0f; + BurnAddPart(1, pos, angle); // down the anemometer + } + + if ( m_burnType == OBJECT_RADAR ) + { + pos.x = 0.0f; + pos.y = -14.0f; + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.4f; + angle.y = (Rand()-0.5f)*0.4f; + angle.z = 0.0f; + BurnAddPart(1, pos, angle); // down the radar + BurnAddPart(2, pos, angle); + } + + if ( m_burnType == OBJECT_INFO ) + { + pos.x = 0.0f; + pos.y = -14.0f; + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.4f; + angle.y = (Rand()-0.5f)*0.4f; + angle.z = 0.0f; + BurnAddPart(1, pos, angle); // down the information terminal + BurnAddPart(2, pos, angle); + } + + if ( m_burnType == OBJECT_LABO ) + { + pos.x = 0.0f; + pos.y = -12.0f; + pos.z = 0.0f; + angle.x = 0.0f; + angle.y = 0.0f; + angle.z = 0.0f; + BurnAddPart(1, pos, angle); // down the arm + } + + if ( m_burnType == OBJECT_NUCLEAR ) + { + pos.x = 0.0f; + pos.y = 0.0f; + pos.z = 0.0f; + angle.x = 0.0f; + angle.y = 0.0f; + angle.z = -135.0f*PI/180.0f; + BurnAddPart(1, pos, angle); // down the cover + } + + if ( m_burnType == OBJECT_MOBILEfa || + m_burnType == OBJECT_MOBILEta || + m_burnType == OBJECT_MOBILEwa || + m_burnType == OBJECT_MOBILEia ) + { + pos.x = 2.0f; + pos.y = -5.0f; + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.2f; + angle.y = (Rand()-0.5f)*0.2f; + angle.z = 40.0f*PI/180.0f; + BurnAddPart(1, pos, angle); // down the arm + } + + if ( m_burnType == OBJECT_MOBILEfs || + m_burnType == OBJECT_MOBILEts || + m_burnType == OBJECT_MOBILEws || + m_burnType == OBJECT_MOBILEis ) + { + pos.x = 0.0f; + pos.y = -7.0f; + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.2f; + angle.y = (Rand()-0.5f)*0.2f; + angle.z = 50.0f*PI/180.0f; + BurnAddPart(1, pos, angle); // down the sensor + } + + if ( m_burnType == OBJECT_MOBILEfc || + m_burnType == OBJECT_MOBILEtc || + m_burnType == OBJECT_MOBILEwc || + m_burnType == OBJECT_MOBILEic ) + { + pos.x = -1.5f; + pos.y = -5.0f; + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.2f; + angle.y = (Rand()-0.5f)*0.2f; + angle.z = -25.0f*PI/180.0f; + BurnAddPart(1, pos, angle); // down the cannon + } + + if ( m_burnType == OBJECT_MOBILEfi || + m_burnType == OBJECT_MOBILEti || + m_burnType == OBJECT_MOBILEwi || + m_burnType == OBJECT_MOBILEii ) + { + pos.x = -1.5f; + pos.y = -5.0f; + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*0.2f; + angle.y = (Rand()-0.5f)*0.2f; + angle.z = -25.0f*PI/180.0f; + BurnAddPart(1, pos, angle); // down the insect-cannon + } + + if ( m_burnType == OBJECT_MOBILErt || + m_burnType == OBJECT_MOBILErc ) + { + pos.x = 0.0f; + pos.y = -10.0f; + pos.z = 0.0f; + angle.x = 0.0f; + angle.y = 0.0f; + angle.z = 0.0f; + BurnAddPart(1, pos, angle); // down the holder + + pos.x = 0.0f; + pos.y = -10.0f; + pos.z = 0.0f; + angle.x = 0.0f; + angle.y = 0.0f; + angle.z = 0.0f; + BurnAddPart(2, pos, angle); // down the pestle/cannon + } + + if ( m_burnType == OBJECT_MOBILErr ) + { + pos.x = 0.0f; + pos.y = -10.0f; + pos.z = 0.0f; + angle.x = 0.0f; + angle.y = 0.0f; + angle.z = 0.0f; + BurnAddPart(1, pos, angle); // down the holder + + pos.x = 0.0f; + pos.y = 0.0f; + pos.z = 0.0f; + angle.x = 0.0f; + angle.y = 0.0f; + angle.z = -PI/2.0f; + BurnAddPart(4, pos, angle); + + pos.x = 0.0f; + pos.y = 0.0f; + pos.z = 0.0f; + angle.x = 0.0f; + angle.y = 0.0f; + angle.z = PI/2.5f; + BurnAddPart(2, pos, angle); + } + + if ( m_burnType == OBJECT_MOBILErs ) + { + pos.x = 0.0f; + pos.y = -10.0f; + pos.z = 0.0f; + angle.x = 0.0f; + angle.y = 0.0f; + angle.z = 0.0f; + BurnAddPart(1, pos, angle); // down the holder + + pos.x = 0.0f; + pos.y = -5.0f; + pos.z = 0.0f; + angle.x = 0.0f; + angle.y = 0.0f; + angle.z = 0.0f; + BurnAddPart(2, pos, angle); + + pos.x = 0.0f; + pos.y = -5.0f; + pos.z = 0.0f; + angle.x = 0.0f; + angle.y = 0.0f; + angle.z = 0.0f; + BurnAddPart(3, pos, angle); + } + + if ( m_burnType == OBJECT_MOBILEsa ) + { + pos.x = 0.0f; + pos.y = -10.0f; + pos.z = 0.0f; + angle.x = 0.0f; + angle.y = 0.0f; + angle.z = 0.0f; + BurnAddPart(1, pos, angle); // down the holder + } + + if ( m_burnType == OBJECT_MOBILEwa || + m_burnType == OBJECT_MOBILEwc || + m_burnType == OBJECT_MOBILEwi || + m_burnType == OBJECT_MOBILEws || + m_burnType == OBJECT_MOBILEwt ) // wheels? + { + for ( i=0 ; i<4 ; i++ ) + { + pos.x = 0.0f; + pos.y = Rand()*0.5f; + pos.z = 0.0f; + angle.x = (Rand()-0.5f)*PI/2.0f; + angle.y = (Rand()-0.5f)*PI/2.0f; + angle.z = 0.0f; + BurnAddPart(6+i, pos, angle); // wheel + + m_burnKeepPart[i] = 6+i; // we keep the wheels + } + m_burnKeepPart[i] = -1; + } + + if ( m_burnType == OBJECT_MOBILEta || + m_burnType == OBJECT_MOBILEtc || + m_burnType == OBJECT_MOBILEti || + m_burnType == OBJECT_MOBILEts || + m_burnType == OBJECT_MOBILErt || + m_burnType == OBJECT_MOBILErc || + m_burnType == OBJECT_MOBILErr || + m_burnType == OBJECT_MOBILErs || + m_burnType == OBJECT_MOBILEsa || + m_burnType == OBJECT_MOBILEdr ) // caterpillars? + { + pos.x = 0.0f; + pos.y = -4.0f; + pos.z = 2.0f; + angle.x = (Rand()-0.5f)*20.0f*PI/180.0f; + angle.y = (Rand()-0.5f)*10.0f*PI/180.0f; + angle.z = (Rand()-0.5f)*30.0f*PI/180.0f; + BurnAddPart(6, pos, angle); // down the right caterpillar + + pos.x = 0.0f; + pos.y = -4.0f; + pos.z = -2.0f; + angle.x = (Rand()-0.5f)*20.0f*PI/180.0f; + angle.y = (Rand()-0.5f)*10.0f*PI/180.0f; + angle.z = (Rand()-0.5f)*30.0f*PI/180.0f; + BurnAddPart(7, pos, angle); // down the left caterpillar + } + + if ( m_burnType == OBJECT_MOBILEfa || + m_burnType == OBJECT_MOBILEfc || + m_burnType == OBJECT_MOBILEfi || + m_burnType == OBJECT_MOBILEfs || + m_burnType == OBJECT_MOBILEft ) // flying? + { + for ( i=0 ; i<3 ; i++ ) + { + pos.x = 0.0f; + pos.y = -3.0f; + pos.z = 0.0f; + angle.x = 0.0f; + angle.y = 0.0f; + angle.z = (Rand()-0.5f)*PI/2.0f; + BurnAddPart(6+i, pos, angle); // foot + } + m_burnKeepPart[i] = -1; + } + + if ( m_burnType == OBJECT_MOBILEia || + m_burnType == OBJECT_MOBILEic || + m_burnType == OBJECT_MOBILEii || + m_burnType == OBJECT_MOBILEis ) // legs? + { + for ( i=0 ; i<6; i++ ) + { + pos.x = 0.0f; + pos.y = -3.0f; + pos.z = 0.0f; + angle.x = 0.0f; + angle.y = (Rand()-0.5f)*PI/4.0f; + angle.z = (Rand()-0.5f)*PI/4.0f; + BurnAddPart(6+i, pos, angle); // leg + } + } +} + +// Adds a part move. + +void CPyro::BurnAddPart(int part, D3DVECTOR pos, D3DVECTOR angle) +{ + int i; + + i = m_burnPartTotal; + m_burnPart[i].part = part; + m_burnPart[i].initialPos = m_object->RetPosition(part); + m_burnPart[i].finalPos = m_burnPart[i].initialPos+pos; + m_burnPart[i].initialAngle = m_object->RetAngle(part); + m_burnPart[i].finalAngle = m_burnPart[i].initialAngle+angle; + + m_burnPartTotal ++; +} + +// Advances of a vehicle fire. + +void CPyro::BurnProgress() +{ + CObject* sub; + D3DVECTOR pos; + float h; + int i; + + if ( m_burnType == OBJECT_TEEN31 ) // basket? + { + m_object->SetZoomY(0, 1.0f-m_progress*0.5f); // slight flattening + } + + for ( i=0 ; i 0.0f ) + { + h = powf(m_progress, 2.0f)*1000.0f; + if ( h > m_burnFall ) h = m_burnFall; + pos.y -= h; + } + m_object->SetPosition(m_burnPart[i].part, pos); + + pos = m_burnPart[i].initialAngle + m_progress*(m_burnPart[i].finalAngle-m_burnPart[i].initialAngle); + m_object->SetAngle(m_burnPart[i].part, pos); + } + + sub = m_object->RetPower(); + if ( sub != 0 ) // is there a battery? + { + sub->SetZoomY(0, 1.0f-m_progress); // complete flattening + } +} + +// Indicates whether a part should be retained. + +BOOL CPyro::BurnIsKeepPart(int part) +{ + int i; + + i = 0; + while ( m_burnKeepPart[i] != -1 ) + { + if ( part == m_burnKeepPart[i++] ) return TRUE; // must keep + } + return FALSE; // must destroy +} + +// Ends the fire of an insect or a vehicle. + +void CPyro::BurnTerminate() +{ + int i, objRank; + + if ( m_type == PT_BURNO ) // organic object is burning? + { + DeleteObject(TRUE, TRUE); // removes the insect + return; + } + + for ( i=1 ; iRetObjectRank(i); + if ( objRank == -1 ) continue; + if ( BurnIsKeepPart(i) ) continue; + + m_object->DeletePart(i); + } + + DeleteObject(FALSE, TRUE); // destroys the object transported + the battery + + if ( m_burnType == OBJECT_DERRICK || + m_burnType == OBJECT_STATION || + m_burnType == OBJECT_FACTORY || + m_burnType == OBJECT_REPAIR || + m_burnType == OBJECT_DESTROYER|| + m_burnType == OBJECT_CONVERT || + m_burnType == OBJECT_TOWER || + m_burnType == OBJECT_RESEARCH || + m_burnType == OBJECT_RADAR || + m_burnType == OBJECT_INFO || + m_burnType == OBJECT_ENERGY || + m_burnType == OBJECT_LABO || + m_burnType == OBJECT_NUCLEAR || + m_burnType == OBJECT_PARA || + m_burnType == OBJECT_SAFE || + m_burnType == OBJECT_HUSTON || + m_burnType == OBJECT_START || + m_burnType == OBJECT_END ) + { + m_object->SetType(OBJECT_RUINfactory); // others become a ruin + m_object->SetLock(FALSE); + } + else + { + m_object->SetType(OBJECT_RUINmobilew1); // others become a ruin + m_object->SetLock(FALSE); + } + + m_object->SetBurn(FALSE); // ruin usable (c-e-d. recoverable) +} + + +// Start of an object freight falling. + +void CPyro::FallStart() +{ + D3DVECTOR pos; + + m_object->SetBurn(TRUE); // usable + + pos = m_object->RetPosition(0); + m_fallFloor = m_terrain->RetFloorLevel(pos); + m_fallSpeed = 0.0f; + m_fallBulletTime = 0.0f; + m_bFallEnding = FALSE; +} + +// Seeking an object explode by the falling ball of bees. + +CObject* CPyro::FallSearchBeeExplo() +{ + CObject* pObj; + D3DVECTOR iPos, oPos; + ObjectType oType; + float iRadius, oRadius, distance, shieldRadius; + int i, j; + + m_object->GetCrashSphere(0, iPos, iRadius); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( oType != OBJECT_HUMAN && + oType != OBJECT_MOBILEfa && + oType != OBJECT_MOBILEta && + oType != OBJECT_MOBILEwa && + oType != OBJECT_MOBILEia && + oType != OBJECT_MOBILEfc && + oType != OBJECT_MOBILEtc && + oType != OBJECT_MOBILEwc && + oType != OBJECT_MOBILEic && + oType != OBJECT_MOBILEfi && + oType != OBJECT_MOBILEti && + oType != OBJECT_MOBILEwi && + oType != OBJECT_MOBILEii && + oType != OBJECT_MOBILEfs && + oType != OBJECT_MOBILEts && + oType != OBJECT_MOBILEws && + oType != OBJECT_MOBILEis && + oType != OBJECT_MOBILErt && + oType != OBJECT_MOBILErc && + oType != OBJECT_MOBILErr && + oType != OBJECT_MOBILErs && + oType != OBJECT_MOBILEsa && + oType != OBJECT_MOBILEtg && + oType != OBJECT_MOBILEft && + oType != OBJECT_MOBILEtt && + oType != OBJECT_MOBILEwt && + oType != OBJECT_MOBILEit && + oType != OBJECT_MOBILEdr && + oType != OBJECT_BASE && + oType != OBJECT_DERRICK && + oType != OBJECT_STATION && + oType != OBJECT_FACTORY && + oType != OBJECT_REPAIR && + oType != OBJECT_DESTROYER&& + oType != OBJECT_CONVERT && + oType != OBJECT_TOWER && + oType != OBJECT_RESEARCH && + oType != OBJECT_RADAR && + oType != OBJECT_INFO && + oType != OBJECT_ENERGY && + oType != OBJECT_LABO && + oType != OBJECT_NUCLEAR && + oType != OBJECT_PARA && + oType != OBJECT_SAFE && + oType != OBJECT_HUSTON && + oType != OBJECT_METAL && + oType != OBJECT_POWER && + oType != OBJECT_ATOMIC ) continue; + + if ( pObj->RetTruck() != 0 ) continue; // object transported? + + oPos = pObj->RetPosition(0); + + shieldRadius = pObj->RetShieldRadius(); + if ( shieldRadius > 0.0f ) + { + distance = Length(oPos, iPos); + if ( distance <= shieldRadius ) return pObj; + } + + if ( oType == OBJECT_BASE ) + { + distance = Length(oPos, iPos); + if ( distance < 25.0f ) return pObj; + } + + // Test the center of the object, which is necessary for objects + // that have no sphere in the center (station). + distance = Length(oPos, iPos)-4.0f; + if ( distance < 5.0f ) return pObj; + + // Test with all spheres of the object. + j = 0; + while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) + { + distance = Length(oPos, iPos); + if ( distance <= iRadius+oRadius ) + { + return pObj; + } + } + } + return 0; +} + +// Fall of an object's freight. + +void CPyro::FallProgress(float rTime) +{ + CObject* pObj; + D3DVECTOR pos; + BOOL bFloor = FALSE; + + if ( m_object == 0 ) return; + + m_fallSpeed += rTime*50.0f; // v2 = v1 + a*dt + pos = m_object->RetPosition(0); + pos.y -= m_fallSpeed*rTime; // dd -= v2*dt + + if ( pos.y <= m_fallFloor ) // below the ground level? + { + pos.y = m_fallFloor; + bFloor = TRUE; + } + m_object->SetPosition(0, pos); + + if ( m_object->RetType() == OBJECT_BULLET ) + { + m_fallBulletTime += rTime; + + if ( m_fallBulletTime > 0.2f || bFloor ) + { + m_fallBulletTime = 0.0f; + + pObj = FallSearchBeeExplo(); + if ( pObj == 0 ) + { + if ( bFloor ) // reaches the ground? + { + m_object->ExploObject(EXPLO_BOUM, 0.0f); // start explosion + } + } + else + { + if ( pObj->RetShieldRadius() > 0.0f ) // protected by shield? + { + m_particule->CreateParticule(pos, D3DVECTOR(0.0f, 0.0f, 0.0f), FPOINT(6.0f, 6.0f), PARTIGUNDEL, 2.0f, 0.0f, 0.0f); + m_sound->Play(SOUND_GUNDEL); + + DeleteObject(TRUE, TRUE); // removes the ball + } + else + { + if ( pObj->ExploObject(EXPLO_BOUM, 1.0f) ) // start explosion + { + DeleteObject(TRUE, TRUE); // removes the ball + } + else + { + m_object->ExploObject(EXPLO_BOUM, 0.0f); // start explosion + } + } + } + + if ( bFloor || pObj != 0 ) + { + m_bFallEnding = TRUE; + } + } + } +} + +// Indicates whether the fall is over. + +Error CPyro::FallIsEnded() +{ + D3DVECTOR pos; + + if ( m_bFallEnding || m_object == 0 ) return ERR_STOP; + + pos = m_object->RetPosition(0); + if ( pos.y > m_fallFloor ) return ERR_CONTINUE; + + m_sound->Play(SOUND_BOUM, pos); + m_object->SetBurn(FALSE); // usable again + + return ERR_STOP; +} + diff --git a/src/graphics/common/pyro.h b/src/graphics/common/pyro.h new file mode 100644 index 0000000..5eac0c9 --- /dev/null +++ b/src/graphics/common/pyro.h @@ -0,0 +1,175 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// pyro.h + +#ifndef _PYRO_H_ +#define _PYRO_H_ + + +#include "d3dengine.h" +#include "object.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CTerrain; +class CCamera; +class CParticule; +class CLight; +class CObject; +class CDisplayText; +class CRobotMain; +class CSound; + + + +enum PyroType +{ + PT_NULL = 0, + PT_FRAGT = 1, // fragmentation of technical object + PT_FRAGO = 2, // fragmentation of organic object + PT_FRAGW = 4, // fragmentation of object under water + PT_EXPLOT = 5, // explosion of technical object + PT_EXPLOO = 6, // explosion of organic object + PT_EXPLOW = 8, // explosion of object under water + PT_SHOTT = 9, // hit technical object + PT_SHOTH = 10, // hit human + PT_SHOTM = 11, // hit queen + PT_SHOTW = 12, // hit under water + PT_EGG = 13, // break the egg + PT_BURNT = 14, // burning of technical object + PT_BURNO = 15, // burning of organic object + PT_SPIDER = 16, // spider explosion + PT_FALL = 17, // cargo falling + PT_WPCHECK = 18, // indicator reaches + PT_FLCREATE = 19, // flag create + PT_FLDELETE = 20, // flag destroy + PT_RESET = 21, // reset position of the object + PT_WIN = 22, // fireworks + PT_LOST = 23, // black smoke + PT_DEADG = 24, // shooting death + PT_DEADW = 25, // drowning death + PT_FINDING = 26, // object discovered +}; + + +typedef struct +{ + int part; + D3DVECTOR initialPos; + D3DVECTOR finalPos; + D3DVECTOR initialAngle; + D3DVECTOR finalAngle; +} +PyroBurnPart; + +typedef struct +{ + float progress; + float intensity; + D3DCOLORVALUE color; +} +PyroLightOper; + + + +class CPyro +{ +public: + CPyro(CInstanceManager* iMan); + ~CPyro(); + + void DeleteObject(BOOL bAll=FALSE); + BOOL Create(PyroType type, CObject* pObj, float force=1.0f); + BOOL EventProcess(const Event &event); + Error IsEnded(); + void CutObjectLink(CObject* pObj); + +protected: + void DisplayError(PyroType type, CObject* pObj); + BOOL CreateLight(D3DVECTOR pos, float height); + void DeleteObject(BOOL bPrimary, BOOL bSecondary); + + void CreateTriangle(CObject* pObj, ObjectType oType, int part); + + void ExploStart(); + void ExploTerminate(); + + void BurnStart(); + void BurnAddPart(int part, D3DVECTOR pos, D3DVECTOR angle); + void BurnProgress(); + BOOL BurnIsKeepPart(int part); + void BurnTerminate(); + + void FallStart(); + CObject* FallSearchBeeExplo(); + void FallProgress(float rTime); + Error FallIsEnded(); + + void LightOperFlush(); + void LightOperAdd(float progress, float intensity, float r, float g, float b); + void LightOperFrame(float rTime); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CTerrain* m_terrain; + CCamera* m_camera; + CParticule* m_particule; + CLight* m_light; + CObject* m_object; + CDisplayText* m_displayText; + CRobotMain* m_main; + CSound* m_sound; + + D3DVECTOR m_pos; // center of the effect + D3DVECTOR m_posPower; // center of the battery + BOOL m_bPower; // battery exists? + PyroType m_type; + float m_force; + float m_size; + float m_progress; + float m_speed; + float m_time; + float m_lastParticule; + float m_lastParticuleSmoke; + int m_soundChannel; + + int m_lightRank; + int m_lightOperTotal; + PyroLightOper m_lightOper[10]; + float m_lightHeight; + + ObjectType m_burnType; + int m_burnPartTotal; + PyroBurnPart m_burnPart[10]; + int m_burnKeepPart[10]; + float m_burnFall; + + float m_fallFloor; + float m_fallSpeed; + float m_fallBulletTime; + BOOL m_bFallEnding; + + int m_crashSphereUsed; // number of spheres used + D3DVECTOR m_crashSpherePos[50]; + float m_crashSphereRadius[50]; +}; + + +#endif //_PYRO_H_ diff --git a/src/graphics/common/terrain.cpp b/src/graphics/common/terrain.cpp new file mode 100644 index 0000000..31b1cc9 --- /dev/null +++ b/src/graphics/common/terrain.cpp @@ -0,0 +1,2270 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// terrain.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "d3dutil.h" +#include "language.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "modfile.h" +#include "water.h" +#include "terrain.h" + + +#define BMPHEAD 1078 + + + +// Constructor of the terrain. + +CTerrain::CTerrain(CInstanceManager* iMan) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_TERRAIN, this); + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); + + m_mosaic = 20; + m_brick = 1<<4; + m_size = 10.0f; + m_vision = 200.0f; + m_relief = 0; + m_texture = 0; + m_objRank = 0; + m_scaleMapping = 0.01f; + m_scaleRelief = 1.0f; + m_subdivMapping = 1; + m_depth = 2; + m_texBaseName[0]= 0; + m_texBaseExt[0] = 0; + m_bMultiText = TRUE; + m_bLevelText = FALSE; + m_resources = 0; + m_levelMatTotal = 0; + m_levelMatMax = 0; + m_levelDot = 0; + m_wind = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_defHardness = 0.5f; + + FlushBuildingLevel(); + FlushFlyingLimit(); +} + +// Destructor of the terrain. + +CTerrain::~CTerrain() +{ + free(m_relief); + free(m_texture); + free(m_objRank); + free(m_resources); +} + + +// Generates a new flat terrain. +// The terrain is composed of mosaics, themselves composed of bricks. +// Each brick is composed of two triangles. +// mosaic: number of mosaics along the axes X and Z +// brick: number of bricks (power of 2) +// size: size of a brick along the axes X and Z +// vision: vision before a change of resolution +// scaleMapping: scale textures for mapping +// +// ^ z +// | <---> brick*size +// +---+---+---+---+ +// | | | |_|_| mosaic = 4 +// | | | | | | brick = 2 (brickP2=1) +// +---+---+---+---+ +// |\ \| | | | +// |\ \| | | | +// +---+---o---+---+---> x +// | | | | | +// | | | | | +// +---+---+---+---+ +// | | | | | The land is viewed from above here. +// | | | | | +// +---+---+---+---+ +// <---------------> mosaic*brick*size + +BOOL CTerrain::Generate(int mosaic, int brickP2, float size, float vision, + int depth, float hardness) +{ + int dim; + + m_mosaic = mosaic; + m_brick = 1<SetTerrainVision(vision); + + m_bMultiText = TRUE; + m_bLevelText = FALSE; + m_scaleMapping = 1.0f/(m_brick*m_size); + m_subdivMapping = 1; + + dim = (m_mosaic*m_brick+1)*(m_mosaic*m_brick+1); + m_relief = (float*)malloc(sizeof(float)*dim); + ZeroMemory(m_relief, sizeof(float)*dim); + + dim = m_mosaic*m_subdivMapping*m_mosaic*m_subdivMapping; + m_texture = (int*)malloc(sizeof(int)*dim); + ZeroMemory(m_texture, sizeof(int)*dim); + + dim = m_mosaic*m_mosaic; + m_objRank = (int*)malloc(sizeof(int)*dim); + ZeroMemory(m_objRank, sizeof(int)*dim); + + return TRUE; +} + + +int CTerrain::RetMosaic() +{ + return m_mosaic; +} + +int CTerrain::RetBrick() +{ + return m_brick; +} + +float CTerrain::RetSize() +{ + return m_size; +} + +float CTerrain::RetScaleRelief() +{ + return m_scaleRelief; +} + + +// Initializes the names of textures to use for the land. + +BOOL CTerrain::InitTextures(char* baseName, int* table, int dx, int dy) +{ + int x, y; + char* p; + + m_bLevelText = FALSE; + + strcpy(m_texBaseName, baseName); + p = strchr(m_texBaseName, '.'); // p <- ^beginning of the extension + if ( p == 0 ) + { + strcpy(m_texBaseExt, ".tga"); + } + else + { + strcpy(m_texBaseExt, p); // m_texBaseExt <- ".tga" or ".bmp" + *p = 0; // m_texBaseName <- name without extension + } + + for ( y=0 ; y= MAXMATTERRAIN-1 ) return FALSE; + + LevelOpenTable(); + + if ( id == 0 ) + { + id = m_levelID++; // puts an ID internal standard + } + + strcpy(m_levelMat[i].texName, baseName); + m_levelMat[i].id = id; + m_levelMat[i].u = u; + m_levelMat[i].v = v; + m_levelMat[i].mat[0] = up; + m_levelMat[i].mat[1] = right; + m_levelMat[i].mat[2] = down; + m_levelMat[i].mat[3] = left; + m_levelMat[i].hardness = hardness; + + if ( m_levelMatMax < up+1 ) m_levelMatMax = up+1; + if ( m_levelMatMax < right+1 ) m_levelMatMax = right+1; + if ( m_levelMatMax < down+1 ) m_levelMatMax = down+1; + if ( m_levelMatMax < left+1 ) m_levelMatMax = left+1; + + m_bLevelText = TRUE; + m_subdivMapping = 4; + + m_levelMatTotal ++; + return TRUE; +} + + +// Load relief from a BMP file. +// The size of the image must be dimension dx and dy with dx=dy=(mosaic*brick)+1. +// The image must be 8 bits/pixel, 256 colors with a standard pallet. + +// Converts coordinated image (x;y) -> world (x;-;z) : +// Wx = 5*Ix-400 +// Wz = -(5*Iy-400) + +// Converts coordinated world (x;-;z) -> image (x;y) : +// Ix = (400+Wx)/5 +// Iy = (400-Wz)/5 + +BOOL CTerrain::ResFromBMP(const char* filename) +{ + FILE* file; + int size, sizem; + + file = fopen(filename, "rb"); + if ( file == NULL ) return FALSE; + + size = (m_mosaic*m_brick)+1; + sizem = ((size+4-1)/4)*4; // upper size multiple of 4 + + if ( m_resources != 0 ) + { + free(m_resources); + } + + m_resources = (unsigned char*)malloc(BMPHEAD+sizem*size); + fread(m_resources, BMPHEAD+sizem*size, 1, file); + + if ( m_resources[18] != (size&0xff) || m_resources[19] != (size>>8) || + m_resources[22] != (size&0xff) || m_resources[23] != (size>>8) ) + { + free(m_resources); + m_resources = 0; + fclose(file); + return FALSE; + } + + fclose(file); + return TRUE; +} + +// Returns the resource type available underground. + +TerrainRes CTerrain::RetResource(const D3DVECTOR &p) +{ + int x, y, size, sizem, ress; + + if ( m_resources == 0 ) return TR_NULL; + + x = (int)((p.x + (m_mosaic*m_brick*m_size)/2.0f)/m_size); + y = (int)((p.z + (m_mosaic*m_brick*m_size)/2.0f)/m_size); + + if ( x < 0 || x > m_mosaic*m_brick || + y < 0 || y > m_mosaic*m_brick ) return TR_NULL; + + size = (m_mosaic*m_brick)+1; + sizem = ((size+4-1)/4)*4; // upper size multiple of 4 + + ress = m_resources[BMPHEAD+x+sizem*y]; + if ( ress == 5 ) return TR_STONE; // red? + if ( ress == 35 ) return TR_URANIUM; // yellow? + if ( ress == 30 ) return TR_POWER; // green? + if ( ress == 24 ) return TR_KEYa; // ~green? + if ( ress == 25 ) return TR_KEYb; // ~green? + if ( ress == 26 ) return TR_KEYc; // ~green? + if ( ress == 27 ) return TR_KEYd; // ~green? + + return TR_NULL; +} + + +// Initializes a completely flat terrain. + +void CTerrain::FlushRelief() +{ + free(m_relief); + m_relief = 0; +} + +// Load relief from a BMP file. +// The size of the image must be dimension dx and dy with dx=dy=(mosaic*brick)+1. +// The image must be 8 bits/pixel, 256 gray scale: +// white = ground (y=0) +// black = mountain (y=255*scaleRelief) + +// Converts coordinated image(x;y) -> world (x;-;z) : +// Wx = 5*Ix-400 +// Wz = -(5*Iy-400) + +// Converts coordinated world (x;-;z) -> image (x;y) : +// Ix = (400+Wx)/5 +// Iy = (400-Wz)/5 + +BOOL CTerrain::ReliefFromBMP(const char* filename, float scaleRelief, + BOOL adjustBorder) +{ + FILE* file; + unsigned char* buffer; + int size, sizem, x, y; + float level, limit, dist, border; + + m_scaleRelief = scaleRelief; + + file = fopen(filename, "rb"); + if ( file == NULL ) return FALSE; + + size = (m_mosaic*m_brick)+1; + sizem = ((size+4-1)/4)*4; // upper size multiple of 4 + + buffer = (unsigned char*)malloc(BMPHEAD+sizem*size); + fread(buffer, BMPHEAD+sizem*size, 1, file); + + if ( buffer[18] != (size&0xff) || buffer[19] != (size>>8) || + buffer[22] != (size&0xff) || buffer[23] != (size>>8) ) + { + free(buffer); + fclose(file); + return FALSE; + } + + limit = 0.9f; + for ( y=0 ; y limit && adjustBorder ) + { + dist = (dist-limit)/(1.0f-limit); // 0..1 + if ( dist > 1.0f ) dist = 1.0f; + border = 300.0f+Rand()*20.0f; + level = level+dist*(border-level); + } + + m_relief[x+y*size] = level; + } + } + + free(buffer); + fclose(file); + return TRUE; +} + +// Adds a point of elevation in the buffer of relief. + +BOOL CTerrain::ReliefAddDot(D3DVECTOR pos, float scaleRelief) +{ + float dim; + int size, x, y; + + dim = (m_mosaic*m_brick*m_size)/2.0f; + size = (m_mosaic*m_brick)+1; + + pos.x = (pos.x+dim)/m_size; + pos.z = (pos.z+dim)/m_size; + + x = (int)pos.x; + y = (int)pos.z; + + if ( x < 0 || x >= size || + y < 0 || y >= size ) return FALSE; + + if ( m_relief[x+y*size] < pos.y*scaleRelief ) + { + m_relief[x+y*size] = pos.y*scaleRelief; + } + return TRUE; +} + +// Load relief from a DXF file. + +BOOL CTerrain::ReliefFromDXF(const char* filename, float scaleRelief) +{ + FILE* file = NULL; + char line[100]; + int command, rankSommet, nbSommet, nbFace, size; + D3DVECTOR* table; + BOOL bWaitNbSommet; + BOOL bWaitNbFace; + BOOL bWaitSommetX; + BOOL bWaitSommetY; + BOOL bWaitSommetZ; + BOOL bWaitFaceX; + BOOL bWaitFaceY; + BOOL bWaitFaceZ; + float x,y,z; + int p1,p2,p3; + + ZeroMemory(m_relief, sizeof(float)*(m_mosaic*m_brick+1)*(m_mosaic*m_brick+1)); + + file = fopen(filename, "r"); + if ( file == NULL ) return FALSE; + + size = (m_mosaic*m_brick)+1; + table = (D3DVECTOR*)malloc(sizeof(D3DVECTOR)*size*size); + + rankSommet = 0; + bWaitNbSommet = FALSE; + bWaitNbFace = FALSE; + bWaitSommetX = FALSE; + bWaitSommetY = FALSE; + bWaitSommetZ = FALSE; + bWaitFaceX = FALSE; + bWaitFaceY = FALSE; + bWaitFaceZ = FALSE; + + while ( fgets(line, 100, file) != NULL ) + { + sscanf(line, "%d", &command); + if ( fgets(line, 100, file) == NULL ) break; + + if ( command == 66 ) + { + bWaitNbSommet = TRUE; + } + + if ( command == 71 && bWaitNbSommet ) + { + bWaitNbSommet = FALSE; + sscanf(line, "%d", &nbSommet); + if ( nbSommet > size*size ) nbSommet = size*size; + rankSommet = 0; + bWaitNbFace = TRUE; + } + + if ( command == 72 && bWaitNbFace ) + { + bWaitNbFace = FALSE; + sscanf(line, "%d", &nbFace); + bWaitSommetX = TRUE; + } + + if ( command == 10 && bWaitSommetX ) + { + bWaitSommetX = FALSE; + sscanf(line, "%f", &x); + bWaitSommetY = TRUE; + } + + if ( command == 20 && bWaitSommetY ) + { + bWaitSommetY = FALSE; + sscanf(line, "%f", &y); + bWaitSommetZ = TRUE; + } + + if ( command == 30 && bWaitSommetZ ) + { + bWaitSommetZ = FALSE; + sscanf(line, "%f", &z); + + nbSommet --; + if ( nbSommet >= 0 ) + { + D3DVECTOR p(x,z,y); // permutation of Y and Z! + table[rankSommet++] = p; + bWaitSommetX = TRUE; + } + else + { + bWaitFaceX = TRUE; + } + } + + if ( command == 71 && bWaitFaceX ) + { + bWaitFaceX = FALSE; + sscanf(line, "%d", &p1); + if ( p1 < 0 ) p1 = -p1; + bWaitFaceY = TRUE; + } + + if ( command == 72 && bWaitFaceY ) + { + bWaitFaceY = FALSE; + sscanf(line, "%d", &p2); + if ( p2 < 0 ) p2 = -p2; + bWaitFaceZ = TRUE; + } + + if ( command == 73 && bWaitFaceZ ) + { + bWaitFaceZ = FALSE; + sscanf(line, "%d", &p3); + if ( p3 < 0 ) p3 = -p3; + + nbFace --; + if ( nbFace >= 0 ) + { + ReliefAddDot(table[p3-1], scaleRelief); + ReliefAddDot(table[p2-1], scaleRelief); + ReliefAddDot(table[p1-1], scaleRelief); + bWaitFaceX = TRUE; + } + } + + } + + free(table); + fclose(file); + return TRUE; +} + + +// Adjusts a position so that it does not exceed the boundaries. + +void CTerrain::LimitPos(D3DVECTOR &pos) +{ + float dim; + +#if _TEEN + dim = (m_mosaic*m_brick*m_size)/2.0f*0.98f; +#else + dim = (m_mosaic*m_brick*m_size)/2.0f*0.92f; +#endif + + if ( pos.x < -dim ) pos.x = -dim; + if ( pos.x > dim ) pos.x = dim; + if ( pos.z < -dim ) pos.z = -dim; + if ( pos.z > dim ) pos.z = dim; +} + + +// Adjust the edges of each mosaic to be compatible with all lower resolutions. + +void CTerrain::AdjustRelief() +{ + int x, y, xx, yy, ii, b; + float level1, level2; + + if ( m_depth == 1 ) return; + + ii = m_mosaic*m_brick+1; + b = 1<<(m_depth-1); + + for ( y=0 ; y= 0 && x <= m_mosaic*m_brick && + y >= 0 && y <= m_mosaic*m_brick ) + { + p.y = m_relief[x+y*(m_mosaic*m_brick+1)]; + } + else + { + p.y = 0.0f; + } + + return p; +} + +// Calculates a vertex of the terrain. +// Calculates a normal soft, taking into account the six adjacent triangles: +// +// ^ y +// | +// b---c---+ +// |\ |\ | +// | \| \| +// a---o---d +// |\ |\ | +// | \| \| +// +---f---e--> x + +D3DVERTEX2 CTerrain::RetVertex(int x, int y, int step) +{ + D3DVERTEX2 v; + D3DVECTOR o, oo, a,b,c,d,e,f, n, s; + int brick; + + o = RetVector(x, y); + v.x = o.x; + v.y = o.y; + v.z = o.z; + + a = RetVector(x-step, y ); + b = RetVector(x-step, y+step); + c = RetVector(x, y+step); + d = RetVector(x+step, y ); + e = RetVector(x+step, y-step); + f = RetVector(x, y-step); + + s = D3DVECTOR(0.0f, 0.0f, 0.0f); + + if ( x-step >= 0 && y+step <= m_mosaic*m_brick+1 ) + { + s += ComputeNormal(b,a,o); + s += ComputeNormal(c,b,o); + } + + if ( x+step <= m_mosaic*m_brick+1 && y+step <= m_mosaic*m_brick+1 ) + { + s += ComputeNormal(d,c,o); + } + + if ( x+step <= m_mosaic*m_brick+1 && y-step >= 0 ) + { + s += ComputeNormal(e,d,o); + s += ComputeNormal(f,e,o); + } + + if ( x-step >= 0 && y-step >= 0 ) + { + s += ComputeNormal(a,f,o); + } + + s = Normalize(s); + v.nx = s.x; + v.ny = s.y; + v.nz = s.z; + + if ( m_bMultiText ) + { + brick = m_brick/m_subdivMapping; + oo = RetVector((x/brick)*brick, (y/brick)*brick); + o = RetVector(x, y); + v.tu = (o.x-oo.x)*m_scaleMapping*m_subdivMapping; + v.tv = 1.0f - (o.z-oo.z)*m_scaleMapping*m_subdivMapping; + } + else + { + v.tu = o.x*m_scaleMapping; + v.tv = o.z*m_scaleMapping; + } + + return v; +} + +// Creates all objects of a mosaic. +// The origin of mosaic is his center. +// +// ^ z +// | +// | 2---4---6-- +// | |\ |\ |\ +// | | \| \| +// | 1---3---5--- ... +// | +// +-------------------> x + +BOOL CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, + const D3DMATERIAL7 &mat, + float min, float max) +{ + D3DMATRIX transform; + D3DVERTEX2 o, p1, p2; + D3DObjLevel6* buffer; + FPOINT uv; + int brick, total, size, mx, my, x, y, xx, yy, i; + char texName1[20]; + char texName2[20]; + float pixel, dp; + + if ( step == 1 && m_engine->RetGroundSpot() ) + { + i = (ox/5) + (oy/5)*(m_mosaic/5); + sprintf(texName2, "shadow%.2d.tga", i); + } + else + { + texName2[0] = 0; + } + + brick = m_brick/m_subdivMapping; + + o = RetVertex(ox*m_brick+m_brick/2, oy*m_brick+m_brick/2, step); + total = ((brick/step)+1)*2; + size = sizeof(D3DObjLevel6)+sizeof(D3DVERTEX2)*(total-1); + + pixel = 1.0f/256.0f; // 1 pixel cover (*) +//? dp = 0.5f/512.0f; + dp = 1.0f/512.0f; + + for ( my=0 ; mytotalPossible = total; + buffer->totalUsed = total; + buffer->type = D3DTYPE6S; + buffer->material = mat; + if ( m_bMultiText ) + { +//? buffer->state = D3DSTATENORMAL; + buffer->state = D3DSTATEWRAP; + } + else + { + buffer->state = D3DSTATEWRAP; + } + buffer->state |= D3DSTATESECOND; + if ( step == 1 ) + { + buffer->state |= D3DSTATEDUALb; + } + i = 0; + for ( x=0 ; x<=brick ; x+=step ) + { + p1 = RetVertex(ox*m_brick+mx*brick+x, oy*m_brick+my*brick+y+0 , step); + p2 = RetVertex(ox*m_brick+mx*brick+x, oy*m_brick+my*brick+y+step, step); + p1.x -= o.x; p1.z -= o.z; + p2.x -= o.x; p2.z -= o.z; + + if ( m_bMultiText ) + { + if ( x == 0 ) + { + p1.tu = 0.0f+(0.5f/256.0f); + p2.tu = 0.0f+(0.5f/256.0f); + } + if ( x == brick ) + { + p1.tu = 1.0f-(0.5f/256.0f); + p2.tu = 1.0f-(0.5f/256.0f); + } + if ( y == 0 ) + { + p1.tv = 1.0f-(0.5f/256.0f); + } + if ( y == brick-step ) + { + p2.tv = 0.0f+(0.5f/256.0f); + } + } + + if ( m_bLevelText ) + { + p1.tu /= m_subdivMapping; // 0..1 -> 0..0.25 + p1.tv /= m_subdivMapping; + p2.tu /= m_subdivMapping; + p2.tv /= m_subdivMapping; + + if ( x == 0 ) + { + p1.tu = 0.0f+dp; + p2.tu = 0.0f+dp; + } + if ( x == brick ) + { + p1.tu = (1.0f/m_subdivMapping)-dp; + p2.tu = (1.0f/m_subdivMapping)-dp; + } + if ( y == 0 ) + { + p1.tv = (1.0f/m_subdivMapping)-dp; + } + if ( y == brick-step ) + { + p2.tv = 0.0f+dp; + } + + p1.tu += uv.x; + p1.tv += uv.y; + p2.tu += uv.x; + p2.tv += uv.y; + } + +#if 1 + xx = mx*(m_brick/m_subdivMapping) + x; + yy = my*(m_brick/m_subdivMapping) + y; + p1.tu2 = ((float)(ox%5)*m_brick+xx+0.0f)/(m_brick*5); + p1.tv2 = ((float)(oy%5)*m_brick+yy+0.0f)/(m_brick*5); + p2.tu2 = ((float)(ox%5)*m_brick+xx+0.0f)/(m_brick*5); + p2.tv2 = ((float)(oy%5)*m_brick+yy+1.0f)/(m_brick*5); + + // Correction for 1 pixel cover (*). + p1.tu2 = (p1.tu2+pixel)*(1.0f-pixel)/(1.0f+pixel); + p1.tv2 = (p1.tv2+pixel)*(1.0f-pixel)/(1.0f+pixel); + p2.tu2 = (p2.tu2+pixel)*(1.0f-pixel)/(1.0f+pixel); + p2.tv2 = (p2.tv2+pixel)*(1.0f-pixel)/(1.0f+pixel); +#endif + + buffer->vertex[i++] = p1; + buffer->vertex[i++] = p2; + } + m_engine->AddQuick(objRank, buffer, texName1, texName2, min, max, TRUE); + } + } + } + + D3DUtil_SetIdentityMatrix(transform); + transform._41 = o.x; + transform._43 = o.z; + m_engine->SetObjectTransform(objRank, transform); + + return TRUE; +} + +// (*) There is 1 pixel cover around each of the 16 surfaces: +// +// |<--------------256-------------->| +// | |<----------254---------->| | +// |---|---|---|-- ... --|---|---|---| +// | 0.0 1.0 | +// | | | | +// 0.0 min max 1.0 +// +// The uv coordinates used for texturing are between min and max (instead of 0 and 1). +// This allows to exclude the pixels situated in a margin of a pixel around the surface. + + +// Seeks a materials based on theirs identifier. + +TerrainMaterial* CTerrain::LevelSearchMat(int id) +{ + int i; + + for ( i=0 ; itexName); + strcpy(name, tm->texName); + uv.x = tm->u; + uv.y = tm->v; + } +} + +// Returns the height of the terrain. + +float CTerrain::LevelRetHeight(int x, int y) +{ + int size; + + size = (m_mosaic*m_brick+1); + + if ( x < 0 ) x = 0; + if ( x >= size ) x = size-1; + if ( y < 0 ) y = 0; + if ( y >= size ) y = size-1; + + return m_relief[x+y*size]; +} + +// Decide whether a point is using the materials. + +BOOL CTerrain::LevelGetDot(int x, int y, float min, float max, float slope) +{ + float hc, h[4]; + int i; + + hc = LevelRetHeight(x, y); + h[0] = LevelRetHeight(x+0, y+1); + h[1] = LevelRetHeight(x+1, y+0); + h[2] = LevelRetHeight(x+0, y-1); + h[3] = LevelRetHeight(x-1, y+0); + + if ( hc < min || + hc > max ) return FALSE; + + if ( slope == 0.0f ) + { + return TRUE; + } + + if ( slope > 0.0f ) + { + for ( i=0 ; i<4 ; i++ ) + { + if ( Abs(hc-h[i]) >= slope ) + { + return FALSE; + } + } + return TRUE; + } + + if ( slope < 0.0f ) + { + for ( i=0 ; i<4 ; i++ ) + { + if ( Abs(hc-h[i]) < -slope ) + { + return FALSE; + } + } + return TRUE; + } + + return FALSE; +} + +// Seeks if material exists. +// Returns the index within m_levelMat or -1 if there is not. +// m_levelMat[i].id gives the identifier. + +int CTerrain::LevelTestMat(char *mat) +{ + int i; + + for ( i=0 ; imat[0] != mat[0] || + tm->mat[1] != mat[1] || + tm->mat[2] != mat[2] || + tm->mat[3] != mat[3] ) // id incompatible with mat? + { + ii = LevelTestMat(mat); + if ( ii == -1 ) return; + id = m_levelMat[ii].id; // looking for a id compatible with mat + } + + // Changes the point. + m_levelDot[x+y*m_levelDotSize].id = id; + m_levelDot[x+y*m_levelDotSize].mat[0] = mat[0]; + m_levelDot[x+y*m_levelDotSize].mat[1] = mat[1]; + m_levelDot[x+y*m_levelDotSize].mat[2] = mat[2]; + m_levelDot[x+y*m_levelDotSize].mat[3] = mat[3]; + + // Changes the lower neighbor. + if ( (x+0) >= 0 && (x+0) < m_levelDotSize && + (y-1) >= 0 && (y-1) < m_levelDotSize ) + { + i = (x+0)+(y-1)*m_levelDotSize; + if ( m_levelDot[i].mat[0] != mat[2] ) + { + m_levelDot[i].mat[0] = mat[2]; + ii = LevelTestMat(m_levelDot[i].mat); + if ( ii != -1 ) + { + m_levelDot[i].id = m_levelMat[ii].id; + } + } + } + + // Modifies the left neighbor. + if ( (x-1) >= 0 && (x-1) < m_levelDotSize && + (y+0) >= 0 && (y+0) < m_levelDotSize ) + { + i = (x-1)+(y+0)*m_levelDotSize; + if ( m_levelDot[i].mat[1] != mat[3] ) + { + m_levelDot[i].mat[1] = mat[3]; + ii = LevelTestMat(m_levelDot[i].mat); + if ( ii != -1 ) + { + m_levelDot[i].id = m_levelMat[ii].id; + } + } + } + + // Changes the upper neighbor. + if ( (x+0) >= 0 && (x+0) < m_levelDotSize && + (y+1) >= 0 && (y+1) < m_levelDotSize ) + { + i = (x+0)+(y+1)*m_levelDotSize; + if ( m_levelDot[i].mat[2] != mat[0] ) + { + m_levelDot[i].mat[2] = mat[0]; + ii = LevelTestMat(m_levelDot[i].mat); + if ( ii != -1 ) + { + m_levelDot[i].id = m_levelMat[ii].id; + } + } + } + + // Changes the right neighbor. + if ( (x+1) >= 0 && (x+1) < m_levelDotSize && + (y+0) >= 0 && (y+0) < m_levelDotSize ) + { + i = (x+1)+(y+0)*m_levelDotSize; + if ( m_levelDot[i].mat[3] != mat[1] ) + { + m_levelDot[i].mat[3] = mat[1]; + ii = LevelTestMat(m_levelDot[i].mat); + if ( ii != -1 ) + { + m_levelDot[i].id = m_levelMat[ii].id; + } + } + } +} + +// Tests if a material can give a place, according to its four neighbors. +// If yes, puts the point. + +BOOL CTerrain::LevelIfDot(int x, int y, int id, char *mat) +{ + char test[4]; + + // Compatible with lower neighbor? + if ( x+0 >= 0 && x+0 < m_levelDotSize && + y-1 >= 0 && y-1 < m_levelDotSize ) + { + test[0] = mat[2]; + test[1] = m_levelDot[(x+0)+(y-1)*m_levelDotSize].mat[1]; + test[2] = m_levelDot[(x+0)+(y-1)*m_levelDotSize].mat[2]; + test[3] = m_levelDot[(x+0)+(y-1)*m_levelDotSize].mat[3]; + + if ( LevelTestMat(test) == -1 ) return FALSE; + } + + // Compatible with left neighbor? + if ( x-1 >= 0 && x-1 < m_levelDotSize && + y+0 >= 0 && y+0 < m_levelDotSize ) + { + test[0] = m_levelDot[(x-1)+(y+0)*m_levelDotSize].mat[0]; + test[1] = mat[3]; + test[2] = m_levelDot[(x-1)+(y+0)*m_levelDotSize].mat[2]; + test[3] = m_levelDot[(x-1)+(y+0)*m_levelDotSize].mat[3]; + + if ( LevelTestMat(test) == -1 ) return FALSE; + } + + // Compatible with upper neighbor? + if ( x+0 >= 0 && x+0 < m_levelDotSize && + y+1 >= 0 && y+1 < m_levelDotSize ) + { + test[0] = m_levelDot[(x+0)+(y+1)*m_levelDotSize].mat[0]; + test[1] = m_levelDot[(x+0)+(y+1)*m_levelDotSize].mat[1]; + test[2] = mat[0]; + test[3] = m_levelDot[(x+0)+(y+1)*m_levelDotSize].mat[3]; + + if ( LevelTestMat(test) == -1 ) return FALSE; + } + + // Compatible with right neighbor? + if ( x+1 >= 0 && x+1 < m_levelDotSize && + y+0 >= 0 && y+0 < m_levelDotSize ) + { + test[0] = m_levelDot[(x+1)+(y+0)*m_levelDotSize].mat[0]; + test[1] = m_levelDot[(x+1)+(y+0)*m_levelDotSize].mat[1]; + test[2] = m_levelDot[(x+1)+(y+0)*m_levelDotSize].mat[2]; + test[3] = mat[1]; + + if ( LevelTestMat(test) == -1 ) return FALSE; + } + + LevelSetDot(x, y, id, mat); // puts the point + return TRUE; +} + +// Modifies the state of a point. + +BOOL CTerrain::LevelPutDot(int x, int y, int id) +{ + TerrainMaterial *tm; + char mat[4]; + int up, right, down, left; + + x /= m_brick/m_subdivMapping; + y /= m_brick/m_subdivMapping; + + if ( x < 0 || x >= m_levelDotSize || + y < 0 || y >= m_levelDotSize ) return FALSE; + + tm = LevelSearchMat(id); + if ( tm == 0 ) return FALSE; + + // Tries without changing neighbors. + if ( LevelIfDot(x, y, id, tm->mat) ) return TRUE; + + // Tries changing a single neighbor (4x). + for ( up=0 ; upmat[1]; + mat[2] = tm->mat[2]; + mat[3] = tm->mat[3]; + + if ( LevelIfDot(x, y, id, mat) ) return TRUE; + } + + for ( right=0 ; rightmat[0]; + mat[1] = right; + mat[2] = tm->mat[2]; + mat[3] = tm->mat[3]; + + if ( LevelIfDot(x, y, id, mat) ) return TRUE; + } + + for ( down=0 ; downmat[0]; + mat[1] = tm->mat[1]; + mat[2] = down; + mat[3] = tm->mat[3]; + + if ( LevelIfDot(x, y, id, mat) ) return TRUE; + } + + for ( left=0 ; leftmat[0]; + mat[1] = tm->mat[1]; + mat[2] = tm->mat[2]; + mat[3] = left; + + if ( LevelIfDot(x, y, id, mat) ) return TRUE; + } + + // Tries changing two neighbors (6x). + for ( up=0 ; upmat[1]; + mat[2] = down; + mat[3] = tm->mat[3]; + + if ( LevelIfDot(x, y, id, mat) ) return TRUE; + } + } + + for ( right=0 ; rightmat[0]; + mat[1] = right; + mat[2] = tm->mat[2]; + mat[3] = left; + + if ( LevelIfDot(x, y, id, mat) ) return TRUE; + } + } + + for ( up=0 ; upmat[2]; + mat[3] = tm->mat[3]; + + if ( LevelIfDot(x, y, id, mat) ) return TRUE; + } + } + + for ( right=0 ; rightmat[0]; + mat[1] = right; + mat[2] = down; + mat[3] = tm->mat[3]; + + if ( LevelIfDot(x, y, id, mat) ) return TRUE; + } + } + + for ( down=0 ; downmat[0]; + mat[1] = tm->mat[1]; + mat[2] = down; + mat[3] = left; + + if ( LevelIfDot(x, y, id, mat) ) return TRUE; + } + } + + for ( up=0 ; upmat[1]; + mat[2] = tm->mat[2]; + mat[3] = left; + + if ( LevelIfDot(x, y, id, mat) ) return TRUE; + } + } + + // Tries changing all the neighbors. + for ( up=0 ; upmat[j]; + } + } + + return TRUE; +} + +// Generates a level in the terrain. + +BOOL CTerrain::LevelGenerate(int *id, float min, float max, + float slope, float freq, + D3DVECTOR center, float radius) +{ + TerrainMaterial *tm; + D3DVECTOR pos; + int i, numID, x, y, xx, yy, group, rnd; + float dim; + + static char random[100] = + { + 84,25,12, 6,34,52,85,38,97,16, + 21,31,65,19,62,40,72,22,48,61, + 56,47, 8,53,73,77, 4,91,26,88, + 76, 1,44,93,39,11,71,17,98,95, + 88,83,18,30, 3,57,28,49,74, 9, + 32,13,96,66,15,70,36,10,59,94, + 45,86, 2,29,63,42,51, 0,79,27, + 54, 7,20,69,89,23,64,43,81,92, + 90,33,46,14,67,35,50, 5,87,60, + 68,55,24,78,41,75,58,80,37,82, + }; + + i = 0; + while ( id[i] != 0 ) + { + tm = LevelSearchMat(id[i++]); + if ( tm == 0 ) return FALSE; + } + numID = i; + + group = m_brick/m_subdivMapping; + + if ( radius > 0.0f && radius < 5.0f ) // just a square? + { + dim = (m_mosaic*m_brick*m_size)/2.0f; + + xx = (int)((center.x+dim)/m_size); + yy = (int)((center.z+dim)/m_size); + + x = xx/group; + y = yy/group; + + tm = LevelSearchMat(id[0]); + if ( tm != 0 ) + { + LevelSetDot(x, y, id[0], tm->mat); // puts the point + } +//? LevelPutDot(xx,yy, id[0]); + } + else + { + for ( y=0 ; y radius ) continue; + } + + if ( freq < 100.0f ) + { + rnd = random[(x%10)+(y%10)*10]; + if ( (float)rnd > freq ) continue; + } + + xx = x*group + group/2; + yy = y*group + group/2; + + if ( LevelGetDot(xx,yy, min, max, slope) ) + { + rnd = random[(x%10)+(y%10)*10]; + i = rnd%numID; + LevelPutDot(xx,yy, id[i]); + } + } + } + } + + return TRUE; +} + +// Initializes an table with empty levels. + +void CTerrain::LevelOpenTable() +{ + int i, j; + + if ( !m_bLevelText ) return; + if ( m_levelDot != 0 ) return; // already allocated + + m_levelDotSize = (m_mosaic*m_brick)/(m_brick/m_subdivMapping)+1; + m_levelDot = (DotLevel*)malloc(m_levelDotSize*m_levelDotSize*sizeof(DotLevel)); + + for ( i=0 ; iCreateObject(); + m_engine->SetObjectType(objRank, TYPETERRAIN); // it is a terrain + + m_objRank[x+y*m_mosaic] = objRank; + + if ( bMultiRes ) + { + min = 0.0f; + max = m_vision; + max *= m_engine->RetClippingDistance(); + for ( step=0 ; step tp2.x ) + { + x = tp1.x; + tp1.x = tp2.x; + tp2.x = x; + } + + if ( tp1.y > tp2.y ) + { + y = tp1.y; + tp1.y = tp2.y; + tp2.y = y; + } + + size = (m_mosaic*m_brick)+1; + + // Calculates the current average height. + avg = 0.0f; + nb = 0; + for ( y=tp1.y ; y<=tp2.y ; y++ ) + { + for ( x=tp1.x ; x<=tp2.x ; x++ ) + { + avg += m_relief[x+y*size]; + nb ++; + } + } + avg /= (float)nb; + + // Changes the description of the relief. + for ( y=tp1.y ; y<=tp2.y ; y++ ) + { + for ( x=tp1.x ; x<=tp2.x ; x++ ) + { + m_relief[x+y*size] = avg+height; + + if ( x%m_brick == 0 && y%m_depth != 0 ) + { + m_relief[(x+0)+(y-1)*size] = avg+height; + m_relief[(x+0)+(y+1)*size] = avg+height; + } + + if ( y%m_brick == 0 && x%m_depth != 0 ) + { + m_relief[(x-1)+(y+0)*size] = avg+height; + m_relief[(x+1)+(y+0)*size] = avg+height; + } + } + } + AdjustRelief(); + + pp1.x = (tp1.x-2)/m_brick; + pp1.y = (tp1.y-2)/m_brick; + pp2.x = (tp2.x+1)/m_brick; + pp2.y = (tp2.y+1)/m_brick; + + if ( pp1.x < 0 ) pp1.x = 0; + if ( pp1.x >= m_mosaic ) pp1.x = m_mosaic-1; + if ( pp1.y < 0 ) pp1.y = 0; + if ( pp1.y >= m_mosaic ) pp1.y = m_mosaic-1; + + for ( y=pp1.y ; y<=pp2.y ; y++ ) + { + for ( x=pp1.x ; x<=pp2.x ; x++ ) + { + m_engine->DeleteObject(m_objRank[x+y*m_mosaic]); + CreateSquare(m_bMultiText, x, y); // recreates the square + } + } + m_engine->Update(); + + return TRUE; +} + + +// Management of the wind. + +void CTerrain::SetWind(D3DVECTOR speed) +{ + m_wind = speed; +} + +D3DVECTOR CTerrain::RetWind() +{ + return m_wind; +} + + +// Gives the exact slope of the terrain of a place given. + +float CTerrain::RetFineSlope(const D3DVECTOR &pos) +{ + D3DVECTOR n; + + if ( !GetNormal(n, pos) ) return 0.0f; + return Abs(RotateAngle(Length(n.x, n.z), n.y)-PI/2.0f); +} + +// Gives the approximate slope of the terrain of a specific location. + +float CTerrain::RetCoarseSlope(const D3DVECTOR &pos) +{ + float dim, level[4], min, max; + int x, y; + + if ( m_relief == 0 ) return 0.0f; + + dim = (m_mosaic*m_brick*m_size)/2.0f; + + x = (int)((pos.x+dim)/m_size); + y = (int)((pos.z+dim)/m_size); + + if ( x < 0 || x >= m_mosaic*m_brick || + y < 0 || y >= m_mosaic*m_brick ) return 0.0f; + + level[0] = m_relief[(x+0)+(y+0)*(m_mosaic*m_brick+1)]; + level[1] = m_relief[(x+1)+(y+0)*(m_mosaic*m_brick+1)]; + level[2] = m_relief[(x+0)+(y+1)*(m_mosaic*m_brick+1)]; + level[3] = m_relief[(x+1)+(y+1)*(m_mosaic*m_brick+1)]; + + min = Min(level[0], level[1], level[2], level[3]); + max = Max(level[0], level[1], level[2], level[3]); + + return atanf((max-min)/m_size); +} + +// Gives the normal vector at the position p (x,-,z) of the ground. + +BOOL CTerrain::GetNormal(D3DVECTOR &n, const D3DVECTOR &p) +{ + D3DVECTOR p1, p2, p3, p4; + float dim; + int x, y; + + dim = (m_mosaic*m_brick*m_size)/2.0f; + + x = (int)((p.x+dim)/m_size); + y = (int)((p.z+dim)/m_size); + + if ( x < 0 || x > m_mosaic*m_brick || + y < 0 || y > m_mosaic*m_brick ) return FALSE; + + p1 = RetVector(x+0, y+0); + p2 = RetVector(x+1, y+0); + p3 = RetVector(x+0, y+1); + p4 = RetVector(x+1, y+1); + + if ( Abs(p.z-p2.z) < Abs(p.x-p2.x) ) + { + n = ComputeNormal(p1,p2,p3); + } + else + { + n = ComputeNormal(p2,p4,p3); + } + return TRUE; +} + +// Returns the height of the ground. + +float CTerrain::RetFloorLevel(const D3DVECTOR &p, BOOL bBrut, BOOL bWater) +{ + D3DVECTOR p1, p2, p3, p4, ps; + float dim, level; + int x, y; + + dim = (m_mosaic*m_brick*m_size)/2.0f; + + x = (int)((p.x+dim)/m_size); + y = (int)((p.z+dim)/m_size); + + if ( x < 0 || x > m_mosaic*m_brick || + y < 0 || y > m_mosaic*m_brick ) return FALSE; + + p1 = RetVector(x+0, y+0); + p2 = RetVector(x+1, y+0); + p3 = RetVector(x+0, y+1); + p4 = RetVector(x+1, y+1); + + ps = p; + if ( Abs(p.z-p2.z) < Abs(p.x-p2.x) ) + { + if ( !IntersectY(p1, p2, p3, ps) ) return 0.0f; + } + else + { + if ( !IntersectY(p2, p4, p3, ps) ) return 0.0f; + } + + if ( !bBrut ) AdjustBuildingLevel(ps); + + if ( bWater ) // not going underwater? + { + level = m_water->RetLevel(); + if ( ps.y < level ) ps.y = level; // not under water + } + + return ps.y; +} + +// Returns the height to the ground. +// This height is positive when you are above the ground. + +float CTerrain::RetFloorHeight(const D3DVECTOR &p, BOOL bBrut, BOOL bWater) +{ + D3DVECTOR p1, p2, p3, p4, ps; + float dim, level; + int x, y; + + dim = (m_mosaic*m_brick*m_size)/2.0f; + + x = (int)((p.x+dim)/m_size); + y = (int)((p.z+dim)/m_size); + + if ( x < 0 || x > m_mosaic*m_brick || + y < 0 || y > m_mosaic*m_brick ) return FALSE; + + p1 = RetVector(x+0, y+0); + p2 = RetVector(x+1, y+0); + p3 = RetVector(x+0, y+1); + p4 = RetVector(x+1, y+1); + + ps = p; + if ( Abs(p.z-p2.z) < Abs(p.x-p2.x) ) + { + if ( !IntersectY(p1, p2, p3, ps) ) return 0.0f; + } + else + { + if ( !IntersectY(p2, p4, p3, ps) ) return 0.0f; + } + + if ( !bBrut ) AdjustBuildingLevel(ps); + + if ( bWater ) // not going underwater? + { + level = m_water->RetLevel(); + if ( ps.y < level ) ps.y = level; // not under water + } + + return p.y-ps.y; +} + +// Modifies the coordinate "y" of point "p" to rest on the ground floor. + +BOOL CTerrain::MoveOnFloor(D3DVECTOR &p, BOOL bBrut, BOOL bWater) +{ + D3DVECTOR p1, p2, p3, p4; + float dim, level; + int x, y; + + dim = (m_mosaic*m_brick*m_size)/2.0f; + + x = (int)((p.x+dim)/m_size); + y = (int)((p.z+dim)/m_size); + + if ( x < 0 || x > m_mosaic*m_brick || + y < 0 || y > m_mosaic*m_brick ) return FALSE; + + p1 = RetVector(x+0, y+0); + p2 = RetVector(x+1, y+0); + p3 = RetVector(x+0, y+1); + p4 = RetVector(x+1, y+1); + + if ( Abs(p.z-p2.z) < Abs(p.x-p2.x) ) + { + if ( !IntersectY(p1, p2, p3, p) ) return FALSE; + } + else + { + if ( !IntersectY(p2, p4, p3, p) ) return FALSE; + } + + if ( !bBrut ) AdjustBuildingLevel(p); + + if ( bWater ) // not going underwater? + { + level = m_water->RetLevel(); + if ( p.y < level ) p.y = level; // not under water + } + + return TRUE; +} + +// Modifies a coordinate so that it is on the ground. +// Returns FALSE if the initial coordinate was too far. + +BOOL CTerrain::ValidPosition(D3DVECTOR &p, float marging) +{ + BOOL bOK = TRUE; + float limit; + + limit = m_mosaic*m_brick*m_size/2.0f - marging; + + if ( p.x < -limit ) + { + p.x = -limit; + bOK = FALSE; + } + + if ( p.z < -limit ) + { + p.z = -limit; + bOK = FALSE; + } + + if ( p.x > limit ) + { + p.x = limit; + bOK = FALSE; + } + + if ( p.z > limit ) + { + p.z = limit; + bOK = FALSE; + } + + return bOK; +} + + + +// Empty the table of elevations. + +void CTerrain::FlushBuildingLevel() +{ + m_buildingUsed = 0; +} + +// Adds a new elevation for a building. + +BOOL CTerrain::AddBuildingLevel(D3DVECTOR center, float min, float max, + float height, float factor) +{ + int i; + + for ( i=0 ; i= MAXBUILDINGLEVEL ) return FALSE; + i = m_buildingUsed++; + + update: + m_buildingTable[i].center = center; + m_buildingTable[i].min = min; + m_buildingTable[i].max = max; + m_buildingTable[i].level = RetFloorLevel(center, TRUE); + m_buildingTable[i].height = height; + m_buildingTable[i].factor = factor; + m_buildingTable[i].bboxMinX = center.x-max; + m_buildingTable[i].bboxMaxX = center.x+max; + m_buildingTable[i].bboxMinZ = center.z-max; + m_buildingTable[i].bboxMaxZ = center.z+max; + + return TRUE; +} + +// Updates the elevation for a building when it was moved up (after a terraforming). + +BOOL CTerrain::UpdateBuildingLevel(D3DVECTOR center) +{ + int i; + + for ( i=0 ; i m_buildingTable[i].bboxMaxX || + p.z < m_buildingTable[i].bboxMinZ || + p.z > m_buildingTable[i].bboxMaxZ ) continue; + + dist = Length2d(p, m_buildingTable[i].center); + + if ( dist <= m_buildingTable[i].max ) + { + return m_buildingTable[i].factor; + } + } + return 1.0f; // it is normal on the ground +} + +// Adjusts a position according to a possible rise. + +void CTerrain::AdjustBuildingLevel(D3DVECTOR &p) +{ + D3DVECTOR border; + float dist, base; + int i; + + for ( i=0 ; i m_buildingTable[i].bboxMaxX || + p.z < m_buildingTable[i].bboxMinZ || + p.z > m_buildingTable[i].bboxMaxZ ) continue; + + dist = Length2d(p, m_buildingTable[i].center); + + if ( dist > m_buildingTable[i].max ) continue; + + if ( dist < m_buildingTable[i].min ) + { + p.y = m_buildingTable[i].level+m_buildingTable[i].height; + return; + } + +#if 0 + p.y = m_buildingTable[i].level; + p.y += (m_buildingTable[i].max-dist)/ + (m_buildingTable[i].max-m_buildingTable[i].min)* + m_buildingTable[i].height; + + base = RetFloorLevel(p, TRUE); + if ( p.y < base ) p.y = base; +#else + border.x = ((p.x-m_buildingTable[i].center.x)*m_buildingTable[i].max)/ + dist+m_buildingTable[i].center.x; + border.z = ((p.z-m_buildingTable[i].center.z)*m_buildingTable[i].max)/ + dist+m_buildingTable[i].center.z; + + base = RetFloorLevel(border, TRUE); + + p.y = (m_buildingTable[i].max-dist)/ + (m_buildingTable[i].max-m_buildingTable[i].min)* + (m_buildingTable[i].level+m_buildingTable[i].height-base)+ + base; +#endif + return; + } +} + + +// Returns the hardness of the ground in a given place. +// The hardness determines the noise (SOUND_STEP and SOUND_BOUM). + +float CTerrain::RetHardness(const D3DVECTOR &p) +{ + TerrainMaterial* tm; + float factor, dim; + int x, y, id; + + factor = RetBuildingFactor(p); + if ( factor != 1.0f ) return 1.0f; // on building + + if ( m_levelDot == 0 ) return m_defHardness; + + dim = (m_mosaic*m_brick*m_size)/2.0f; + + x = (int)((p.x+dim)/m_size); + y = (int)((p.z+dim)/m_size); + + if ( x < 0 || x > m_mosaic*m_brick || + y < 0 || y > m_mosaic*m_brick ) return m_defHardness; + + x /= m_brick/m_subdivMapping; + y /= m_brick/m_subdivMapping; + + if ( x < 0 || x >= m_levelDotSize || + y < 0 || y >= m_levelDotSize ) return m_defHardness; + + id = m_levelDot[x+y*m_levelDotSize].id; + tm = LevelSearchMat(id); + if ( tm == 0 ) return m_defHardness; + + return tm->hardness; +} + + +// Shows the flat areas on the ground. + +void CTerrain::GroundFlat(D3DVECTOR pos) +{ + D3DVECTOR p; + float rapport, angle; + int x, y, i; + static char table[41*41]; + + + rapport = 3200.0f/1024.0f; + + for ( y=0 ; y<=40 ; y++ ) + { + for ( x=0 ; x<=40 ; x++ ) + { + i = x + y*41; + table[i] = 0; + + p.x = (x-20)*rapport; + p.z = (y-20)*rapport; + p.y = 0.0f; + if ( Length(p.x, p.y) > 20.0f*rapport ) continue; + + angle = RetFineSlope(pos+p); + + if ( angle < FLATLIMIT ) + { + table[i] = 1; + } + else + { + table[i] = 2; + } + } + } + + m_engine->GroundMarkCreate(pos, 40.0f, 0.001f, 15.0f, 0.001f, 41, 41, table); +} + + +// Calculates the radius of the largest flat area available. +// This calculation is not optimized! + +float CTerrain::RetFlatZoneRadius(D3DVECTOR center, float max) +{ + D3DVECTOR pos; + FPOINT c, p; + float ref, radius, angle, h; + int i, nb; + + angle = RetFineSlope(center); + if ( angle >= FLATLIMIT ) return 0.0f; + + ref = RetFloorLevel(center, TRUE); + + radius = 1.0f; + while ( radius <= max ) + { + angle = 0.0f; + nb = (int)(2.0f*PI*radius); + if ( nb < 8 ) nb = 8; + for ( i=0 ; i 1.0f ) return radius; + + angle += PI*2.0f/8.0f; + } + radius += 1.0f; + } + return max; +} + + + +// Specifies the maximum height of flight. + +void CTerrain::SetFlyingMaxHeight(float height) +{ + m_flyingMaxHeight = height; +} + +// Returns the maximum height of flight. + +float CTerrain::RetFlyingMaxHeight() +{ + return m_flyingMaxHeight; +} + + +// Empty the limits table of flight. + +void CTerrain::FlushFlyingLimit() +{ + m_flyingMaxHeight = 280.0f; + m_flyingLimitTotal = 0; +} + +// Empty the limits table of flight. + +BOOL CTerrain::AddFlyingLimit(D3DVECTOR center, + float extRadius, float intRadius, + float maxHeight) +{ + int i; + + if ( m_flyingLimitTotal >= MAXFLYINGLIMIT ) return FALSE; + + i = m_flyingLimitTotal; + m_flyingLimit[i].center = center; + m_flyingLimit[i].extRadius = extRadius; + m_flyingLimit[i].intRadius = intRadius; + m_flyingLimit[i].maxHeight = maxHeight; + m_flyingLimitTotal = i+1; + + return TRUE; +} + +// Returns the maximum height of flight. + +float CTerrain::RetFlyingLimit(D3DVECTOR pos, BOOL bNoLimit) +{ + float dist, h; + int i; + + if ( bNoLimit ) return 280.0f; + if ( m_flyingLimitTotal == 0 ) return m_flyingMaxHeight; + + for ( i=0 ; i= m_flyingLimit[i].extRadius ) continue; + + if ( dist <= m_flyingLimit[i].intRadius ) + { + return m_flyingLimit[i].maxHeight; + } + + dist -= m_flyingLimit[i].intRadius; + + h = dist*(m_flyingMaxHeight-m_flyingLimit[i].maxHeight)/ + (m_flyingLimit[i].extRadius-m_flyingLimit[i].intRadius); + + return h + m_flyingLimit[i].maxHeight; + } + + return m_flyingMaxHeight; +} + diff --git a/src/graphics/common/terrain.h b/src/graphics/common/terrain.h new file mode 100644 index 0000000..4fc4ace --- /dev/null +++ b/src/graphics/common/terrain.h @@ -0,0 +1,214 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// terrain.h + +#ifndef _TERRAIN_H_ +#define _TERRAIN_H_ + + +#include "d3dengine.h" + + +class CInstanceManager; +class CD3DEngine; +class CWater; + + + +#define FLATLIMIT (5.0f*PI/180.0f) + + +enum TerrainRes +{ + TR_NULL = 0, + TR_STONE = 1, + TR_URANIUM = 2, + TR_POWER = 3, + TR_KEYa = 4, + TR_KEYb = 5, + TR_KEYc = 6, + TR_KEYd = 7, +}; + + +#define MAXBUILDINGLEVEL 100 + +typedef struct +{ + D3DVECTOR center; + float factor; + float min; + float max; + float level; + float height; + float bboxMinX; + float bboxMaxX; + float bboxMinZ; + float bboxMaxZ; +} +BuildingLevel; + + +#define MAXMATTERRAIN 100 + +typedef struct +{ + short id; + char texName[20]; + float u,v; + float hardness; + char mat[4]; // up, right, down, left +} +TerrainMaterial; + +typedef struct +{ + short id; + char mat[4]; // up, right, down, left +} +DotLevel; + + +#define MAXFLYINGLIMIT 10 + +typedef struct +{ + D3DVECTOR center; + float extRadius; + float intRadius; + float maxHeight; +} +FlyingLimit; + + + +class CTerrain +{ +public: + CTerrain(CInstanceManager* iMan); + ~CTerrain(); + + BOOL Generate(int mosaic, int brickP2, float size, float vision, int depth, float hardness); + BOOL InitTextures(char* baseName, int* table, int dx, int dy); + void LevelFlush(); + BOOL LevelMaterial(int id, char* baseName, float u, float v, int up, int right, int down, int left, float hardness); + BOOL LevelInit(int id); + BOOL LevelGenerate(int *id, float min, float max, float slope, float freq, D3DVECTOR center, float radius); + void FlushRelief(); + BOOL ReliefFromBMP(const char* filename, float scaleRelief, BOOL adjustBorder); + BOOL ReliefFromDXF(const char* filename, float scaleRelief); + BOOL ResFromBMP(const char* filename); + BOOL CreateObjects(BOOL bMultiRes); + BOOL Terraform(const D3DVECTOR &p1, const D3DVECTOR &p2, float height); + + void SetWind(D3DVECTOR speed); + D3DVECTOR RetWind(); + + float RetFineSlope(const D3DVECTOR &pos); + float RetCoarseSlope(const D3DVECTOR &pos); + BOOL GetNormal(D3DVECTOR &n, const D3DVECTOR &p); + float RetFloorLevel(const D3DVECTOR &p, BOOL bBrut=FALSE, BOOL bWater=FALSE); + float RetFloorHeight(const D3DVECTOR &p, BOOL bBrut=FALSE, BOOL bWater=FALSE); + BOOL MoveOnFloor(D3DVECTOR &p, BOOL bBrut=FALSE, BOOL bWater=FALSE); + BOOL ValidPosition(D3DVECTOR &p, float marging); + TerrainRes RetResource(const D3DVECTOR &p); + void LimitPos(D3DVECTOR &pos); + + void FlushBuildingLevel(); + BOOL AddBuildingLevel(D3DVECTOR center, float min, float max, float height, float factor); + BOOL UpdateBuildingLevel(D3DVECTOR center); + BOOL DeleteBuildingLevel(D3DVECTOR center); + float RetBuildingFactor(const D3DVECTOR &p); + float RetHardness(const D3DVECTOR &p); + + int RetMosaic(); + int RetBrick(); + float RetSize(); + float RetScaleRelief(); + + void GroundFlat(D3DVECTOR pos); + float RetFlatZoneRadius(D3DVECTOR center, float max); + + void SetFlyingMaxHeight(float height); + float RetFlyingMaxHeight(); + void FlushFlyingLimit(); + BOOL AddFlyingLimit(D3DVECTOR center, float extRadius, float intRadius, float maxHeight); + float RetFlyingLimit(D3DVECTOR pos, BOOL bNoLimit); + +protected: + BOOL ReliefAddDot(D3DVECTOR pos, float scaleRelief); + void AdjustRelief(); + D3DVECTOR RetVector(int x, int y); + D3DVERTEX2 RetVertex(int x, int y, int step); + BOOL CreateMosaic(int ox, int oy, int step, int objRank, const D3DMATERIAL7 &mat, float min, float max); + BOOL CreateSquare(BOOL bMultiRes, int x, int y); + + TerrainMaterial* LevelSearchMat(int id); + void LevelTextureName(int x, int y, char *name, FPOINT &uv); + float LevelRetHeight(int x, int y); + BOOL LevelGetDot(int x, int y, float min, float max, float slope); + int LevelTestMat(char *mat); + void LevelSetDot(int x, int y, int id, char *mat); + BOOL LevelIfDot(int x, int y, int id, char *mat); + BOOL LevelPutDot(int x, int y, int id); + void LevelOpenTable(); + void LevelCloseTable(); + + void AdjustBuildingLevel(D3DVECTOR &p); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CWater* m_water; + + int m_mosaic; // number of mosaics + int m_brick; // number of bricks per mosaics + float m_size; // size of an item in an brick + float m_vision; // vision before a change of resolution + float* m_relief; // table of the relief + int* m_texture; // table of textures + int* m_objRank; // table of rows of objects + BOOL m_bMultiText; + BOOL m_bLevelText; + float m_scaleMapping; // scale of the mapping + float m_scaleRelief; + int m_subdivMapping; + int m_depth; // number of different resolutions (1,2,3,4) + char m_texBaseName[20]; + char m_texBaseExt[10]; + float m_defHardness; + + TerrainMaterial m_levelMat[MAXMATTERRAIN+1]; + int m_levelMatTotal; + int m_levelMatMax; + int m_levelDotSize; + DotLevel* m_levelDot; + int m_levelID; + + int m_buildingUsed; + BuildingLevel m_buildingTable[MAXBUILDINGLEVEL]; + + unsigned char* m_resources; + D3DVECTOR m_wind; // wind speed + + float m_flyingMaxHeight; + int m_flyingLimitTotal; + FlyingLimit m_flyingLimit[MAXFLYINGLIMIT]; +}; + + +#endif //_TERRAIN_H_ diff --git a/src/graphics/common/text.cpp b/src/graphics/common/text.cpp new file mode 100644 index 0000000..88cfe0a --- /dev/null +++ b/src/graphics/common/text.cpp @@ -0,0 +1,1881 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// text.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "language.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "text.h" + + + +static short table_text_colobot[] = +{ +// x1, y1, x2, y2 + 219,34, 225,50, // 0 + 1,188, 9,203, // . + 51,188,59,203, // square + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 11,188,19,203, // \t + 21,188,29,203, // \n + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, // \r + 219,34, 225,50, + 219,34, 225,50, + 41,188,49,203, // > + 31,188,39,203, // < + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + +#if _NEWLOOK + 0, 0, 4, 16, // 32 + 7, 0, 9, 16, // ! + 9, 0, 13, 16, // " + 13, 0, 24, 16, // # + 24, 0, 31, 16, // $ + 31, 0, 43, 16, // % + 43, 0, 54, 16, // & + 54, 0, 56, 16, // ' + 56, 0, 61, 16, // ( + 61, 0, 67, 16, // ) + 67, 0, 73, 16, // * + 73, 0, 83, 16, // + + 83, 0, 87, 16, // , + 87, 0, 92, 16, // - + 92, 0, 94, 16, // . + 94, 0, 101,16, // / + 101,0, 109,16, // 0 + 109,0, 114,16, // 1 + 114,0, 122,16, // 2 + 122,0, 129,16, // 3 + 129,0, 138,16, // 4 + 138,0, 146,16, // 5 + 146,0, 154,16, // 6 + 154,0, 161,16, // 7 + 161,0, 169,16, // 8 + 169,0, 177,16, // 9 + 177,0, 179,16, // : + 179,0, 183,16, // ; + 183,0, 193,16, // < + 193,0, 203,16, // = + 203,0, 213,16, // > + 213,0, 219,16, // ? + + 0, 17, 14, 33, // @ 64 + 14, 17, 26, 33, // A + 26, 17, 33, 33, // B + 33, 17, 42, 33, // C + 42, 17, 51, 33, // D + 51, 17, 58, 33, // E + 58, 17, 63, 33, // F + 63, 17, 73, 33, // G + 73, 17, 82, 33, // H + 82, 17, 84, 33, // I + 84, 17, 90, 33, // J + 90, 17, 98, 33, // K + 98, 17, 103,33, // L + 103,17, 115,33, // M + 115,17, 124,33, // N + 124,17, 136,33, // O + 136,17, 142,33, // P + 142,17, 154,33, // Q + 154,17, 160,33, // R + 160,17, 167,33, // S + 167,17, 175,33, // T + 175,17, 183,33, // U + 183,17, 194,33, // V + 194,17, 208,33, // W + 208,17, 218,33, // X + 218,17, 227,33, // Y + 227,17, 236,33, // Z + 236,17, 241,33, // [ + 241,17, 248,33, // \ + 248,17, 252,33, // ] + 219,0, 229,16, // ^ + 0, 34, 9, 50, // _ + + 54, 0, 56, 16, // ` 96 + 9, 34, 16, 50, // a + 16, 34, 25, 50, // b + 25, 34, 33, 50, // c + 33, 34, 42, 50, // d + 42, 34, 50, 50, // e + 50, 34, 55, 50, // f + 55, 34, 62, 50, // g + 62, 34, 69, 50, // h + 69, 34, 71, 50, // i + 71, 34, 75, 50, // j + 75, 34, 81, 50, // k + 81, 34, 83, 50, // l + 83, 34, 93, 50, // m + 93, 34, 100,50, // n + 100,34, 109,50, // o + 109,34, 118,50, // p + 118,34, 127,50, // q + 127,34, 132,50, // r + 132,34, 138,50, // s + 138,34, 143,50, // t + 143,34, 150,50, // u + 150,34, 158,50, // v + 158,34, 171,50, // w + 171,34, 179,50, // x + 179,34, 187,50, // y + 187,34, 195,50, // z + 195,34, 201,50, // { + 201,34, 203,50, // | + 203,34, 209,50, // } + 209,34, 219,50, // ~ + 219,34, 228,50, // + + 219,34, 225,50, // 128 + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + + 219,34, 225,50, // 144 + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + + 219,34, 225,50, // 160 + 219,34, 225,50, // 161 A1 ! reverse + 219,34, 225,50, + 219,34, 225,50, // 163 A3 Å + 219,34, 225,50, + 219,34, 225,50, + 0, 0, 4, 16, // 166 A6 ¦ (space) + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + + 219,34, 225,50, // 176 + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, // 191 BF ? reverse + + 12, 51, 24, 67, // 192 C0 Å• big + 0, 51, 12, 67, // 193 C1 á big + 24, 51, 36, 67, // 194 C2 â big + 48, 51, 60, 67, // 195 C3 ă big + 36, 51, 48, 67, // 196 C4 ä big + 219,34, 225,50, + 219,34, 225,50, + 60, 51, 69, 67, // 199 C7 ç big + 77, 51, 84, 67, // 200 C8 Ä big + 70, 51, 77, 67, // 201 C9 é big + 85, 51, 92, 67, // 202 CA Ä™ big + 93, 51, 100,67, // 203 CB ë big + 219,34, 225,50, + 100,51, 104,67, // 205 CD í big + 108,51, 113,67, // 206 CE î big + 113,51, 117,67, // 207 CF Ä big + + 219,34, 225,50, // 208 + 117,51, 126,67, // 209 D1 Å„ big + 219,34, 225,50, + 126,51, 138,67, // 211 D3 ó big + 150,51, 162,67, // 212 D4 ô big + 219,34, 225,50, + 162,51, 174,67, // 214 D6 ö big + 219,34, 225,50, + 219,34, 225,50, + 194,51, 202,67, // 217 D9 ů big + 186,51, 194,67, // 218 DA ú big + 202,51, 210,67, // 219 DB ű big + 210,51, 218,67, // 220 DC ü big + 219,34, 225,50, + 219,34, 225,50, + 218,51, 227,67, // 223 DF German SS + + 7, 68, 14, 84, // 224 E0 Å• small + 0, 68, 7, 84, // 225 E1 á small + 14, 68, 21, 84, // 226 E2 â small + 28, 68, 35, 84, // 227 E3 ă small + 21, 68, 28, 84, // 228 E4 ä small + 219,34, 225,50, + 219,34, 225,50, + 35, 68, 43, 84, // 231 E7 ç small + 51, 68, 59, 84, // 232 E8 Ä small + 43, 68, 51, 84, // 233 E9 é small + 59, 68, 67, 84, // 234 EA Ä™ small + 67, 68, 75, 84, // 235 EB ë small + 219,34, 225,50, + 75, 68, 79, 84, // 237 ED í small + 83, 68, 88, 84, // 238 EE î small + 88, 68, 92, 84, // 239 EF Ä small + + 219,34, 225,50, // 240 + 92, 68, 99, 84, // 241 F1 Å„ small + 219,34, 225,50, + 99, 68, 108,84, // 243 F3 ó small + 117,68, 126,84, // 244 F4 ô small + 219,34, 225,50, + 126,68, 135,84, // 246 F6 ö small + 219,34, 225,50, + 219,34, 225,50, + 151,68, 158,84, // 249 F9 ů small + 144,68, 151,84, // 250 FA ú small + 158,68, 165,84, // 251 FB ű small + 165,68, 172,84, // 252 FC ü small + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, +#else + 0, 0, 4, 16, // 32 + 4, 0, 7, 16, // ! + 7, 0, 13, 16, + 14, 0, 21, 16, + 22, 0, 28, 16, + 29, 0, 38, 16, + 39, 0, 48, 16, + 48, 0, 51, 16, + 51, 0, 55, 16, + 55, 0, 59, 16, + 59, 0, 65, 16, + 66, 0, 72, 16, + 73, 0, 76, 16, + 76, 0, 82, 16, + 82, 0, 85, 16, + 85, 0, 90, 16, + 90, 0, 97, 16, + 98, 0, 103,16, + 104,0, 111,16, + 111,0, 118,16, + 118,0, 125,16, + 125,0, 132,16, + 132,0, 139,16, + 139,0, 146,16, + 146,0, 153,16, + 153,0, 160,16, + 160,0, 165,16, // : + 164,0, 169,16, // ; + 169,0, 177,16, // < + 177,0, 185,16, // = + 185,0, 193,16, // > + 193,0, 201,16, // ? + + 201,0, 215,16, // 64 + 0, 17, 10, 33, // A + 10, 17, 18, 33, + 19, 17, 28, 33, + 28, 17, 36, 33, + 37, 17, 44, 33, + 45, 17, 52, 33, + 53, 17, 62, 33, + 63, 17, 71, 33, + 72, 17, 75, 33, + 75, 17, 82, 33, + 83, 17, 91, 33, + 92, 17, 99, 33, + 100,17, 110,33, + 111,17, 119,33, +//? 120,17, 129,33, // O + 216,0, 227,16, // O + 130,17, 138,33, + 139,17, 148,33, + 149,17, 158,33, + 158,17, 166,33, + 166,17, 175,33, + 175,17, 183,33, + 183,17, 193,33, + 193,17, 207,33, + 207,17, 215,33, + 215,17, 224,33, + 224,17, 232,33, // Z + 232,17, 236,33, + 236,17, 241,33, + 241,17, 245,33, + 245,17, 252,33, // ^ + 0, 34, 8, 50, // _ + + 45, 17, 52, 33, // 96 + 8, 34, 15, 50, // a + 16, 34, 23, 50, + 24, 34, 31, 50, + 31, 34, 38, 50, + 39, 34, 46, 50, + 46, 34, 52, 50, + 52, 34, 59, 50, + 60, 34, 67, 50, + 68, 34, 71, 50, + 71, 34, 76, 50, + 77, 34, 84, 50, + 84, 34, 87, 50, + 88, 34, 99, 50, + 100,34, 107,50, +//? 108,34, 115,50, // o + 238,0, 246,16, // o + 116,34, 123,50, + 124,34, 131,50, + 132,34, 137,50, + 137,34, 144,50, + 144,34, 149,50, + 149,34, 156,50, + 156,34, 164,50, + 164,34, 176,50, + 176,34, 183,50, + 183,34, 191,50, + 191,34, 197,50, // z + 197,34, 203,50, + 203,34, 205,50, + 205,34, 211,50, + 211,34, 219,50, + 219,34, 225,50, + +#if _POLISH + 219,34, 225,50, // 128 + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 0, 51, 8, 67, // 140 S´ + 219,34, 225,50, + 219,34, 225,50, + 9, 51, 17, 67, // 143 Z´ + + 219,34, 225,50, // 144 + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 0, 68, 7, 84, // 156 s´ + 219,34, 225,50, + 219,34, 225,50, + 8, 68, 14, 84, // 159 z´ + + 219,34, 225,50, // 160 + 219,34, 225,50, + 219,34, 225,50, + 18, 51, 27, 67, // 163 L/ + 219,34, 225,50, + 28, 51, 39, 67, // 165 A, + 0, 0, 4, 16, // 166 A6 ¦ (space) + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 40, 51, 48, 67, // 175 Zo + + 219,34, 225,50, // 176 + 219,34, 225,50, + 219,34, 225,50, + 16, 68, 21, 84, // 179 l/ + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 23, 68, 31, 84, // 185 a, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 32, 68, 38, 84, // 191 zo + + 219,34, 225,50, // 192 + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 49, 51, 58, 67, // 198 C´ + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 59, 51, 66, 67, // 202 E, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + + 219,34, 225,50, // 208 + 67, 51, 75, 67, // 209 N´ + 219,34, 225,50, +//? 76, 51, 85, 67, // 211 O´ + 86, 51, 97, 67, // 211 O´ + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + + 219,34, 225,50, // 224 + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 39, 68, 46, 84, // 230 c´ + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 47, 68, 54, 84, // 234 e, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + + 219,34, 225,50, // 240 + 55, 68, 62, 84, // 241 n´ + 219,34, 225,50, +//? 63, 68, 70, 84, // 243 o´ + 71, 68, 79, 84, // 243 o´ + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, +#else + 219,34, 225,50, // 128 + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + + 219,34, 225,50, // 144 + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + + 219,34, 225,50, // 160 + 219,34, 225,50, // 161 A1 ! reverse + 219,34, 225,50, + 219,34, 225,50, // 163 A3 Å + 219,34, 225,50, + 219,34, 225,50, + 0, 0, 4, 16, // 166 A6 ¦ (space) + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + + 219,34, 225,50, // 176 + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, // 191 BF ? reverse + + 10, 51, 20, 67, // 192 C0 Å• big + 0, 51, 10, 67, // 193 C1 á big + 20, 51, 30, 67, // 194 C2 â big + 40, 51, 50, 67, // 195 C3 ă big + 30, 51, 40, 67, // 196 C4 ä big + 219,34, 225,50, + 219,34, 225,50, + 50, 51, 59, 67, // 199 C7 ç big + 67, 51, 74, 67, // 200 C8 Ä big + 59, 51, 66, 67, // 201 C9 é big + 75, 51, 82, 67, // 202 CA Ä™ big + 83, 51, 90, 67, // 203 CB ë big + 219,34, 225,50, + 91, 51, 95, 67, // 205 CD í big + 100,51, 103,67, // 206 CE î big + 104,51, 109,67, // 207 CF Ä big + + 219,34, 225,50, // 208 + 109,51, 117,67, // 209 D1 Å„ big + 219,34, 225,50, + 118,51, 127,67, // 211 D3 ó big + 138,51, 147,67, // 212 D4 ô big + 219,34, 225,50, + 148,51, 157,67, // 214 D6 ö big + 219,34, 225,50, + 219,34, 225,50, + 177,51, 185,67, // 217 D9 ů big + 168,51, 176,67, // 218 DA ú big + 186,51, 194,67, // 219 DB ű big + 195,51, 203,67, // 220 DC ü big + 219,34, 225,50, + 219,34, 225,50, + 211,51, 220,67, // 223 DF German SS + + 8, 68, 15, 84, // 224 E0 Å• small + 0, 68, 7, 84, // 225 E1 á small + 16, 68, 23, 84, // 226 E2 â small + 32, 68, 39, 84, // 227 E3 ă small + 24, 68, 31, 84, // 228 E4 ä small + 219,34, 225,50, + 219,34, 225,50, + 40, 68, 47, 84, // 231 E7 ç small + 55, 68, 62, 84, // 232 E8 Ä small + 47, 68, 54, 84, // 233 E9 é small + 63, 68, 70, 84, // 234 EA Ä™ small + 71, 68, 78, 84, // 235 EB ë small + 219,34, 225,50, + 79, 68, 83, 84, // 237 ED í small + 88, 68, 92, 84, // 238 EE î small + 92, 68, 97, 84, // 239 EF Ä small + + 219,34, 225,50, // 240 + 97, 68, 104,84, // 241 F1 Å„ small + 219,34, 225,50, + 105,68, 112,84, // 243 F3 ó small + 121,68, 128,84, // 244 F4 ô small + 219,34, 225,50, + 129,68, 136,84, // 246 F6 ö small + 219,34, 225,50, + 219,34, 225,50, + 153,68, 160,84, // 249 F9 ů small + 145,68, 152,84, // 250 FA ú small + 161,68, 168,84, // 251 FB ű small + 169,68, 176,84, // 252 FC ü small + 219,34, 225,50, + 219,34, 225,50, + 219,34, 225,50, +#endif +#endif +}; + + +static short table_text_courier[] = +{ +// x1, y1, x2, y2 + 231,137,239,153, // 0 + 1,188, 9,204, // . + 51,188,59,204, // square + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 11,188,19,204, // \t + 21,188,29,204, // \n + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, // \r + 231,137,239,153, + 231,137,239,153, + 41,188,49,204, // > + 31,188,39,204, // < + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + + 1, 86, 9,102, // 32 + 11, 86, 19,102, + 21, 86, 29,102, + 31, 86, 39,102, + 41, 86, 49,102, + 51, 86, 59,102, + 61, 86, 69,102, + 71, 86, 79,102, + 81, 86, 89,102, + 91, 86, 99,102, + 101, 86,109,102, + 111, 86,119,102, + 121, 86,129,102, + 131, 86,139,102, + 141, 86,149,102, + 151, 86,159,102, + 161, 86,169,102, + 171, 86,179,102, + 181, 86,189,102, + 191, 86,199,102, + 201, 86,209,102, + 211, 86,219,102, + 221, 86,229,102, + 231, 86,239,102, + 1,103, 9,119, // 56 + 11,103, 19,119, + 21,103, 29,119, + 31,103, 39,119, + 41,103, 49,119, + 51,103, 59,119, + 61,103, 69,119, + 71,103, 79,119, + + 81,103, 89,119, // @ + 91,103, 99,119, + 101,103,109,119, + 111,103,119,119, + 121,103,129,119, + 131,103,139,119, + 141,103,149,119, + 151,103,159,119, + 161,103,169,119, + 171,103,179,119, + 181,103,189,119, + 191,103,199,119, + 201,103,209,119, + 211,103,219,119, + 221,103,229,119, + 231,103,239,119, + 1,120, 9,136, // P + 11,120, 19,136, + 21,120, 29,136, + 31,120, 39,136, + 41,120, 49,136, + 51,120, 59,136, + 61,120, 69,136, + 71,120, 79,136, + 81,120, 89,136, + 91,120, 99,136, + 101,120,109,136, + 111,120,119,136, // [ + 121,120,129,136, + 131,120,139,136, + 141,120,149,136, + 151,120,159,136, // _ + + 161,120,169,136, + 171,120,179,136, // a + 181,120,189,136, + 191,120,199,136, + 201,120,209,136, + 211,120,219,136, + 221,120,229,136, + 231,120,239,136, + 1,137, 9,153, + 11,137, 19,153, + 21,137, 29,153, + 31,137, 39,153, + 41,137, 49,153, + 51,137, 59,153, + 61,137, 69,153, + 71,137, 79,153, // o + 81,137, 89,153, + 91,137, 99,153, + 101,137,109,153, + 111,137,119,153, + 121,137,129,153, + 131,137,139,153, + 141,137,149,153, + 151,137,159,153, + 161,137,169,153, + 171,137,179,153, + 181,137,189,153, + 191,137,199,153, + 201,137,209,153, + 211,137,219,153, + 221,137,229,153, // ~ + 231,137,239,153, + +#if _POLISH + 231,137,239,153, // 128 + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 1,154, 9,170, // 140 S´ + 231,137,239,153, + 231,137,239,153, + 11,154, 19,170, // 143 Z´ + + 231,137,239,153, // 144 + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 1,171, 9,187, // 156 s´ + 231,137,239,153, + 231,137,239,153, + 11,171, 19,187, // 159 z´ + + 231,137,239,153, // 160 + 231,137,239,153, + 231,137,239,153, + 21,154, 29,170, // 163 L/ + 231,137,239,153, + 31,154, 39,170, // 165 A, + 1, 86, 9,102, // 166 A6 ¦ (space) + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 41,154, 49,170, // 175 Zo + + 231,137,239,153, // 176 + 231,137,239,153, + 231,137,239,153, + 21,171, 29,187, // 179 l/ + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 31,171, 39,187, // 185 a, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 41,171, 49,187, // 191 zo + + 231,137,239,153, // 192 + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 51,154, 59,170, // 198 C´ + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 61,154, 69,170, // 202 E, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + + 231,137,239,153, // 208 + 71,154, 79,170, // 209 N´ + 231,137,239,153, + 81,171, 89,187, // 211 O´ + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + + 231,137,239,153, // 224 + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 51,171, 59,187, // 230 c´ + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 61,171, 69,187, // 234 e, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + + 231,137,239,153, // 240 + 71,171, 79,187, // 241 n´ + 231,137,239,153, + 81,171, 89,187, // 243 ó small + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, +#else + 231,137,239,153, // 128 + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + + 231,137,239,153, // 144 + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + + 231,137,239,153, // 160 + 231,137,239,153, // 161 A1 ! reverse + 231,137,239,153, + 231,137,239,153, // 163 A3 Å + 231,137,239,153, + 231,137,239,153, + 1, 86, 9,102, // 166 A6 ¦ (space) + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + + 231,137,239,153, // 176 + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, // 191 BF ? reverse + + 11,154, 19,170, // Å• big + 1,154, 9,170, // á big + 21,154, 29,170, // â big + 41,154, 49,170, // ă big + 31,154, 39,170, // ä big + 231,137,239,153, + 231,137,239,153, + 51,154, 59,170, // ç big + 71,154, 79,170, // Ä big + 61,154, 69,170, // é big + 81,154, 89,170, // Ä™ big + 91,154, 99,170, // ë big + 231,137,239,153, + 101,154,109,170, // í big + 121,154,129,170, // î big + 131,154,139,170, // Ä big + 231,137,239,153, + 141,154,149,170, // Å„ big + 231,137,239,153, + 151,154,159,170, // ó big + 171,154,179,170, // ô big + 231,137,239,153, + 181,154,189,170, // ö big + 231,137,239,153, + 231,137,239,153, + 211,154,219,170, // ů big + 201,154,209,170, // ú big + 221,154,229,170, // ű big + 231,154,239,170, // ü big + 231,137,239,153, + 231,137,239,153, + 241,154,249,170, // 223 DF German SS + + 11,171, 19,187, // Å• small + 1,171, 9,187, // á small + 21,171, 29,187, // â small + 41,171, 49,187, // ă small + 31,171, 39,187, // ä small + 231,137,239,153, + 231,137,239,153, + 51,171, 59,187, // ç small + 71,171, 79,187, // Ä small + 61,171, 69,187, // é small + 81,171, 89,187, // Ä™ small + 91,171, 99,187, // ë small + 231,137,239,153, + 111,171,119,187, // Ä› small + 121,171,129,187, // î small + 131,171,139,187, // Ä small + 231,137,239,153, + 141,171,149,187, // Å„ small + 231,137,239,153, + 151,171,159,187, // ó small + 171,171,179,187, // ô small + 231,137,239,153, + 181,171,189,187, // ö small + 231,137,239,153, + 231,137,239,153, + 211,171,219,187, // ů small + 201,171,209,187, // ú small + 221,171,229,187, // ű small + 231,171,239,187, // ü small + 231,137,239,153, + 231,137,239,153, + 231,137,239,153, +#endif +}; + + +// Returns the pointer to the table by the font. + +short* RetTable(FontType font) +{ + if ( font == FONT_COLOBOT ) return table_text_colobot; + else return table_text_courier; +} + + + +// Object's constructor. + +CText::CText(CInstanceManager* iMan, CD3DEngine* engine) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_TEXT, this); + + m_pD3DDevice = 0; + m_engine = engine; +} + +// Object's destructor. + +CText::~CText() +{ + m_iMan->DeleteInstance(CLASS_TEXT, this); +} + + +void CText::SetD3DDevice(LPDIRECT3DDEVICE7 device) +{ + m_pD3DDevice = device; +} + + +// Displays multi-font text. +// The vertical position is at the bottom of the box of the character. + +void CText::DrawText(char *string, char *format, int len, FPOINT pos, + float width, int justif, float size, float stretch, + int eol) +{ + float sw; + + if ( justif == 0 ) // center? + { + sw = RetStringWidth(string, format, len, size, stretch); + if ( sw > width ) sw = width; + pos.x -= sw/2.0f; + } + if ( justif < 0 ) // flag was left? + { + sw = RetStringWidth(string, format, len, size, stretch); + if ( sw > width ) sw = width; + pos.x -= sw; + } + DrawString(string, format, len, pos, width, size, stretch, eol); +} + +// Displays multi-font text. +// The vertical position is at the bottom of the box of the character. + +void CText::DrawText(char *string, char *format, FPOINT pos, float width, + int justif, float size, float stretch, + int eol) +{ + DrawText(string, format, strlen(string), pos, width, justif, size, stretch, eol); +} + +// Displays text. +// The vertical position is at the bottom of the box of the character. + +void CText::DrawText(char *string, int len, FPOINT pos, float width, + int justif, float size, float stretch, FontType font, + int eol) +{ + float sw; + + if ( justif == 0 ) // center? + { + sw = RetStringWidth(string, len, size, stretch, font); + if ( sw > width ) sw = width; + pos.x -= sw/2.0f; + } + if ( justif < 0 ) // flag was left? + { + sw = RetStringWidth(string, len, size, stretch, font); + if ( sw > width ) sw = width; + pos.x -= sw; + } + DrawString(string, len, pos, width, size, stretch, font, eol); +} + +// Displays text. +// The vertical position is at the bottom of the box of the character. + +void CText::DrawText(char *string, FPOINT pos, float width, + int justif, float size, float stretch, FontType font, + int eol) +{ + DrawText(string, strlen(string), pos, width, justif, size, stretch, font, eol); +} + + +// Returns the size of a multi-font text. + +void CText::DimText(char *string, char *format, int len, FPOINT pos, + int justif, float size, float stretch, + FPOINT &start, FPOINT &end) +{ + float sw; + + start = end = pos; + + sw = RetStringWidth(string, format, len, size, stretch); + end.x += sw; + if ( justif == 0 ) // center? + { + start.x -= sw/2.0f; + end.x -= sw/2.0f; + } + if ( justif < 0 ) // flag was left? + { + start.x -= sw; + end.x -= sw; + } + + start.y -= RetDescent(size, FONT_COLOBOT); + end.y += RetAscent(size, FONT_COLOBOT); +} + +// Returns the size of a multi-font text. + +void CText::DimText(char *string, char *format, FPOINT pos, int justif, + float size, float stretch, + FPOINT &start, FPOINT &end) +{ + DimText(string, format, strlen(string), pos, justif, size, stretch, start, end); +} + +// Returns the size of a text. + +void CText::DimText(char *string, int len, FPOINT pos, int justif, + float size, float stretch, FontType font, + FPOINT &start, FPOINT &end) +{ + float sw; + + start = end = pos; + + sw = RetStringWidth(string, len, size, stretch, font); + end.x += sw; + if ( justif == 0 ) // center? + { + start.x -= sw/2.0f; + end.x -= sw/2.0f; + } + if ( justif < 0 ) // flag was left? + { + start.x -= sw; + end.x -= sw; + } + + start.y -= RetDescent(size, font); + end.y += RetAscent(size, font); +} + +// Returns the size of a text. + +void CText::DimText(char *string, FPOINT pos, int justif, + float size, float stretch, FontType font, + FPOINT &start, FPOINT &end) +{ + DimText(string, strlen(string), pos, justif, size, stretch, font, start, end); +} + + +// Returns the height above the baseline. + +float CText::RetAscent(float size, FontType font) +{ + return (13.0f/256.0f)*(size/20.0f); +} + +// Returns the height below the baseline. + +float CText::RetDescent(float size, FontType font) +{ + return (3.0f/256.0f)*(size/20.0f); +} + +// Returns the total height of the character. + +float CText::RetHeight(float size, FontType font) +{ + return (16.0f/256.0f)*(size/20.0f); +} + + +// Returns the width of a string of multi-font characters. + +float CText::RetStringWidth(char *string, char *format, int len, + float size, float stretch) +{ + FontType font; + float st, tab, w, width = 0.0f; + short *table, *pt; + int i, c; + + for ( i=0 ; iRetEditIndentValue(); + w = tab-Mod(width, tab); + if ( w < tab*0.1f ) w += tab; + width += w; + continue; + } + + if ( c > 255 ) continue; + + pt = table+c*4; + st = stretch; + if ( font == FONT_COLOBOT && (c == 'O' || c == 'o') ) st = 0.8f; + width += (float)(pt[2]-pt[0])/256.0f*(size/20.0f)*st; + } + } + + return width; +} + +// Returns the width of a string of characters. + +float CText::RetStringWidth(char *string, int len, + float size, float stretch, FontType font) +{ + float st, tab, w, width = 0.0f; + short *table, *pt; + int i, c; + + table = RetTable(font); + for ( i=0 ; iRetEditIndentValue(); + w = tab-Mod(width, tab); + if ( w < tab*0.1f ) w += tab; + width += w; + continue; + } + + if ( c > 255 ) continue; + + pt = table+c*4; + st = stretch; + if ( font == FONT_COLOBOT && (c == 'O' || c == 'o') ) st = 0.8f; + width += (float)(pt[2]-pt[0])/256.0f*(size/20.0f)*st; + } + + return width; +} + +// Returns the width of a character. +// 'offset' is the current position in the line. + +float CText::RetCharWidth(int character, float offset, + float size, float stretch, FontType font) +{ + float st, tab, w; + short* pt; + + if ( font == FONT_BUTTON ) return (12.0f/256.0f)*(size/20.0f); + + if ( character == '\t' ) + { + pt = RetTable(font)+' '*4; + tab = (float)(pt[2]-pt[0])/256.0f*(size/20.0f)*stretch*m_engine->RetEditIndentValue(); + w = tab-Mod(offset, tab); + if ( w < tab*0.1f ) w += tab; + return w; + } + + if ( character > 255 ) return 0.0f; + + pt = RetTable(font)+character*4; + st = stretch; +#if !_NEWLOOK + if ( font == FONT_COLOBOT && (character == 'O' || character == 'o') ) st = 0.8f; +#endif + return (float)(pt[2]-pt[0])/256.0f*(size/20.0f)*st; +} + + +// Justifies a line of multi-font text. Returns the offset of the cut. + +int CText::Justif(char *string, char *format, int len, float width, + float size, float stretch) +{ + FontType font; + float pos; + int i, character, cut; + + pos = 0.0f; + cut = 0; + for ( i=0 ; i width ) + { + if ( cut == 0 ) return i; + else return cut; + } + } + return i; +} + +// Justify a line of text. Returns the offset of the cut. + +int CText::Justif(char *string, int len, float width, + float size, float stretch, FontType font) +{ + float pos; + int i, character, cut; + + pos = 0.0f; + cut = 0; + for ( i=0 ; i width ) + { + if ( cut == 0 ) return i; + else return cut; + } + } + return i; +} + +// Returns the most suitable position to a given offset (multi-font). + +int CText::Detect(char *string, char *format, int len, float offset, + float size, float stretch) +{ + FontType font; + float pos, width; + int i, character, cut; + + pos = 0.0f; + cut = 0; + for ( i=0 ; iSetTexture("textp.tga"); +#else + m_engine->SetTexture("text.tga"); +#endif + m_engine->SetState(D3DSTATETTw); + + font = FONT_COLOBOT; + + start = pos.x; + offset = 0.0f; + for ( i=0 ; i width ) // exceeds the maximum width? + { + cw = RetCharWidth(16, offset, size, stretch, font); + pos.x = start+width-cw; + DrawChar(16, pos, size, stretch, font); // > + break; + } + + if ( (format[i]&COLOR_MASK) != 0 ) + { + DrawColor(pos, size, cw, format[i]&COLOR_MASK); + } + DrawChar(c, pos, size, stretch, font); + offset += cw; + pos.x += cw; + } + + if ( eol != 0 ) + { + DrawChar(eol, pos, size, stretch, font); + } +} + +// Displays text. + +void CText::DrawString(char *string, int len, FPOINT pos, float width, + float size, float stretch, FontType font, + int eol) +{ + float start, offset, cw; + int i, c; + +#if _POLISH + m_engine->SetTexture("textp.tga"); +#else + m_engine->SetTexture("text.tga"); +#endif + m_engine->SetState(D3DSTATETTw); + + start = pos.x; + offset = 0.0f; + for ( i=0 ; i width ) // exceeds the maximum width? + { + cw = RetCharWidth(16, offset, size, stretch, font); + pos.x = start+width-cw; + DrawChar(16, pos, size, stretch, font); // > + break; + } + + DrawChar(c, pos, size, stretch, font); + offset += cw; + pos.x += cw; + } + + if ( eol != 0 ) + { + DrawChar(eol, pos, size, stretch, font); + } +} + +// Displays the link to a character. + +void CText::DrawColor(FPOINT pos, float size, float width, int color) +{ + D3DVERTEX2 vertex[4]; // 2 triangles + FPOINT p1, p2; + POINT dim; + D3DVECTOR n; + float h, u1, u2, v1, v2, dp; + int icon; + + icon = -1; + if ( color == COLOR_LINK ) icon = 9; // blue + if ( color == COLOR_TOKEN ) icon = 4; // orange + if ( color == COLOR_TYPE ) icon = 5; // green + if ( color == COLOR_CONST ) icon = 8; // red + if ( color == COLOR_REM ) icon = 6; // magenta + if ( color == COLOR_KEY ) icon = 10; // gray + if ( icon == -1 ) return; + + if ( color == COLOR_LINK ) + { + m_engine->SetState(D3DSTATENORMAL); + } + + dim = m_engine->RetDim(); + if ( dim.y <= 768.0f ) // 1024x768 or less? + { + h = 1.01f/dim.y; // 1 pixel + } + else // more than 1024x768? + { + h = 2.0f/dim.y; // 2 pixels + } + + p1.x = pos.x; + p2.x = pos.x + width; + + if ( color == COLOR_LINK ) + { + p1.y = pos.y; + p2.y = pos.y + h; // just emphasized + } + else + { +#if 1 + p1.y = pos.y; + p2.y = pos.y + (16.0f/256.0f)*(size/20.0f); +//? p2.y = pos.y + h*4.0f; // just emphasized thick +#else + p1.y = pos.y; + p2.y = pos.y + (16.0f/256.0f)*(size/20.0f)/4.0f; +#endif + } + + u1 = (16.0f/256.0f)*(icon%16); + v1 = (240.0f/256.0f); + u2 = (16.0f/256.0f)+u1; + v2 = (16.0f/256.0f)+v1; + + dp = 0.5f/256.0f; + u1 += dp; + v1 += dp; + u2 -= dp; + v2 -= dp; + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal + + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); + vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); + vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); + + if ( color == COLOR_LINK ) + { + m_engine->SetState(D3DSTATETTw); + } +} + +// Displays a character. + +void CText::DrawChar(int character, FPOINT pos, float size, + float stretch, FontType font) +{ + D3DVERTEX2 vertex[4]; // 2 triangles + FPOINT p1, p2; + D3DVECTOR n; + float width, height, u1, u2, v1, v2, dp; + short* pt; + + dp = 0.5f/256.0f; + n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal + + if ( font == FONT_BUTTON ) + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + + p1.x = pos.x; + p1.y = pos.y; + p2.x = pos.x + (12.0f/256.0f)*(size/20.0f); + p2.y = pos.y + (16.0f/256.0f)*(size/20.0f); + + if ( character <= 64 || character >= 128+56 ) + { + u1 = 66.0f/256.0f; + v1 = 2.0f/256.0f; + u2 = 94.0f/256.0f; + v2 = 30.0f/256.0f; + } + else + { + u1 = 224.0f/256.0f; + v1 = 32.0f/256.0f; + u2 = 256.0f/256.0f; + v2 = 64.0f/256.0f; + } + + u1 += dp; + v1 += dp; + u2 -= dp; + v2 -= dp; + + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); + vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); + vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); + +//? p1.x += (12.0f/256.0f)*(size/20.0f)*0.1f; +//? p1.y += (16.0f/256.0f)*(size/20.0f)*0.1f; +//? p2.x -= (12.0f/256.0f)*(size/20.0f)*0.1f; +//? p2.y -= (16.0f/256.0f)*(size/20.0f)*0.1f; + + if ( character >= 64 && character < 64+64 ) + { + character -= 64; + m_engine->SetTexture("button2.tga"); + } + if ( character >= 128 && character < 128+64 ) + { + character -= 128; + m_engine->SetTexture("button3.tga"); + } + + m_engine->SetState(D3DSTATETTw); + + u1 = (32.0f/256.0f)*(character%8); + v1 = (32.0f/256.0f)*(character/8); // uv texture + u2 = (32.0f/256.0f)+u1; + v2 = (32.0f/256.0f)+v1; + + u1 += dp; + v1 += dp; + u2 -= dp; + v2 -= dp; + + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); + vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); + vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); + + +#if _POLISH + m_engine->SetTexture("textp.tga"); +#else + m_engine->SetTexture("text.tga"); +#endif + return; + } + + if ( character > 255 ) return; + +//? if ( character == '\t' ) character = ' '; // if tab, does not display -> + +#if !_NEWLOOK + if ( font == FONT_COLOBOT && (character == 'O' || character == 'o') ) + { + stretch = 0.8f; + } +#endif + if ( font == FONT_COURIER ) + { + stretch *= 1.2f; + } + + pt = RetTable(font)+character*4; + width = (float)(pt[2]-pt[0])/256.0f*stretch*0.9f; +//? width = (float)(pt[2]-pt[0])/256.0f*stretch; + height = (float)(pt[3]-pt[1])/256.0f; + +#if _NEWLOOK + pos.y += height*(size/20.0f)/17.0f; +#endif + p1.x = pos.x; + p1.y = pos.y; + p2.x = pos.x + width*(size/20.0f); + p2.y = pos.y + height*(size/20.0f); + + u1 = (float)pt[0]/256.0f; + v1 = (float)pt[1]/256.0f; + u2 = (float)pt[2]/256.0f; + v2 = (float)pt[3]/256.0f; + + if ( font == FONT_COLOBOT ) + { + u1 += dp; + u2 += dp; +#if _NEWLOOK + v2 += dp; +#endif + } + if ( font == FONT_COURIER ) + { + u1 -= dp; + u2 += dp*2.0f; + } + + + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); + vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); + vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); +} + diff --git a/src/graphics/common/text.h b/src/graphics/common/text.h new file mode 100644 index 0000000..4407039 --- /dev/null +++ b/src/graphics/common/text.h @@ -0,0 +1,113 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// text.h + +#ifndef _TEXT_H_ +#define _TEXT_H_ + + +#include "d3dengine.h" + + +class CInstanceManager; + + + +#define SMALLFONT 10.0f +#define BIGFONT 15.0f + +#define NORMSTRETCH 0.8f + + + +enum FontType +{ + FONT_COLOBOT = 0, + FONT_COURIER = 1, + FONT_BUTTON = 2, +}; + +enum FontTitle +{ + TITLE_BIG = 0x04, + TITLE_NORM = 0x08, + TITLE_LITTLE = 0x0c, +}; + +enum FontColor +{ + COLOR_LINK = 0x10, + COLOR_TOKEN = 0x20, + COLOR_TYPE = 0x30, + COLOR_CONST = 0x40, + COLOR_REM = 0x50, + COLOR_KEY = 0x60, + COLOR_TABLE = 0x70, +}; + +#define FONT_MASK 0x03 +#define TITLE_MASK 0x0c +#define COLOR_MASK 0x70 +#define IMAGE_MASK 0x80 + + + +class CText +{ +public: + CText(CInstanceManager *iMan, CD3DEngine* engine); + ~CText(); + + void SetD3DDevice(LPDIRECT3DDEVICE7 device); + + void DrawText(char *string, char *format, int len, FPOINT pos, float width, int justif, float size, float stretch, int eol); + void DrawText(char *string, char *format, FPOINT pos, float width, int justif, float size, float stretch, int eol); + void DrawText(char *string, int len, FPOINT pos, float width, int justif, float size, float stretch, FontType font, int eol); + void DrawText(char *string, FPOINT pos, float width, int justif, float size, float stretch, FontType font, int eol); + void DimText(char *string, char *format, int len, FPOINT pos, int justif, float size, float stretch, FPOINT &start, FPOINT &end); + void DimText(char *string, char *format, FPOINT pos, int justif, float size, float stretch, FPOINT &start, FPOINT &end); + void DimText(char *string, int len, FPOINT pos, int justif, float size, float stretch, FontType font, FPOINT &start, FPOINT &end); + void DimText(char *string, FPOINT pos, int justif, float size, float stretch, FontType font, FPOINT &start, FPOINT &end); + + float RetAscent(float size, FontType font); + float RetDescent(float size, FontType font); + float RetHeight(float size, FontType font); + + float RetStringWidth(char *string, char *format, int len, float size, float stretch); + float RetStringWidth(char *string, int len, float size, float stretch, FontType font); + float RetCharWidth(int character, float offset, float size, float stretch, FontType font); + + int Justif(char *string, char *format, int len, float width, float size, float stretch); + int Justif(char *string, int len, float width, float size, float stretch, FontType font); + int Detect(char *string, char *format, int len, float offset, float size, float stretch); + int Detect(char *string, int len, float offset, float size, float stretch, FontType font); + +protected: + void DrawString(char *string, char *format, int len, FPOINT pos, float width, float size, float stretch, int eol); + void DrawString(char *string, int len, FPOINT pos, float width, float size, float stretch, FontType font, int eol); + void DrawColor(FPOINT pos, float size, float width, int color); + void DrawChar(int character, FPOINT pos, float size, float stretch, FontType font); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + LPDIRECT3DDEVICE7 m_pD3DDevice; + +}; + + +#endif //_TEXT_H_ diff --git a/src/graphics/common/water.cpp b/src/graphics/common/water.cpp new file mode 100644 index 0000000..59963cc --- /dev/null +++ b/src/graphics/common/water.cpp @@ -0,0 +1,835 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// water.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "d3dutil.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "sound.h" +#include "water.h" + + + + +// Constructor of the terrain. + +CWater::CWater(CInstanceManager* iMan, CD3DEngine* engine) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_WATER, this); + + m_engine = engine; + m_terrain = 0; + m_particule = 0; + m_sound = 0; + + m_type[0] = WATER_NULL; + m_type[1] = WATER_NULL; + m_level = 0.0f; + m_bDraw = TRUE; + m_bLava = FALSE; + m_color = 0xffffffff; + m_subdiv = 4; + m_filename[0] = 0; +} + +// Destructor of the terrain. + +CWater::~CWater() +{ +} + + +BOOL CWater::EventProcess(const Event &event) +{ + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { +#if 0 + if ( event.param == 'S' ) + { + if ( m_subdiv == 1 ) m_subdiv = 2; + else if ( m_subdiv == 2 ) m_subdiv = 4; + else if ( m_subdiv == 4 ) m_subdiv = 8; + else if ( m_subdiv == 8 ) m_subdiv = 1; + SetLevel(m_level); + } + if ( event.param == 'M' ) + { + SetLevel(m_level+1.0f); + } + if ( event.param == 'D' ) + { + SetLevel(m_level-1.0f); + } + if ( event.param == 'H' ) + { + m_bDraw = !m_bDraw; + } + if ( event.param == 'C' ) + { + if ( m_color == 0xffffffff ) m_color = 0xcccccccc; + else if ( m_color == 0xcccccccc ) m_color = 0x88888888; + else if ( m_color == 0x88888888 ) m_color = 0x44444444; + else if ( m_color == 0x44444444 ) m_color = 0x00000000; + else if ( m_color == 0x00000000 ) m_color = 0xffffffff; + } + if ( event.param == 'Q' ) + { + int i; + i = (m_color>>24); + i += 0x44; + i &= 0xff; + i = (i<<24); + m_color &= 0x00ffffff; + m_color |= i; + } + if ( event.param == 'W' ) + { + int i; + i = (m_color>>16); + i += 0x44; + i &= 0xff; + i = (i<<16); + m_color &= 0xff00ffff; + m_color |= i; + } + if ( event.param == 'E' ) + { + int i; + i = (m_color>>8); + i += 0x44; + i &= 0xff; + i = (i<<8); + m_color &= 0xffff00ff; + m_color |= i; + } + if ( event.param == 'R' ) + { + int i; + i = m_color; + i += 0x44; + i &= 0xff; + m_color &= 0xffffff00; + m_color |= i; + } +#endif + } + return TRUE; +} + +// Makes water evolve. + +BOOL CWater::EventFrame(const Event &event) +{ + if ( m_engine->RetPause() ) return TRUE; + + m_time += event.rTime; + + if ( m_type[0] == WATER_NULL ) return TRUE; + + if ( m_bLava ) + { + LavaFrame(event.rTime); + } + return TRUE; +} + +// Makes evolve the steam jets on the lava. + +void CWater::LavaFrame(float rTime) +{ + D3DVECTOR eye, lookat, dir, perp, pos; + float distance, shift, level; + int i; + + if ( m_particule == 0 ) + { + m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + } + + for ( i=0 ; i= 0.1f ) + { + eye = m_engine->RetEyePt(); + lookat = m_engine->RetLookatPt(); + + distance = Rand()*200.0f; + shift = (Rand()-0.5f)*200.0f; + + dir = Normalize(lookat-eye); + pos = eye + dir*distance; + + perp.x = -dir.z; + perp.y = dir.y; + perp.z = dir.x; + pos = pos + perp*shift; + + level = m_terrain->RetFloorLevel(pos, TRUE); + if ( level < m_level ) + { + pos.y = m_level; + + level = Rand(); + if ( level < 0.8f ) + { + if ( VaporCreate(PARTIFIRE, pos, 0.02f+Rand()*0.06f) ) + { + m_lastLava = m_time; + } + } + else if ( level < 0.9f ) + { + if ( VaporCreate(PARTIFLAME, pos, 0.5f+Rand()*3.0f) ) + { + m_lastLava = m_time; + } + } + else + { + if ( VaporCreate(PARTIVAPOR, pos, 0.2f+Rand()*2.0f) ) + { + m_lastLava = m_time; + } + } + } + } +} + +// Removes all the steam jets. + +void CWater::VaporFlush() +{ + int i; + + for ( i=0 ; iPlay(SOUND_BLUP, pos, 1.0f, 1.0f-Rand()*0.5f); + } + if ( m_vapor[i].type == PARTIFLAME ) + { +//? m_sound->Play(SOUND_SWIM, pos, 1.0f, 1.0f-Rand()*0.5f); + } + if ( m_vapor[i].type == PARTIVAPOR ) + { + m_sound->Play(SOUND_PSHHH, pos, 0.3f, 2.0f); + } + + return TRUE; + } + } + return FALSE; +} + +// Makes evolve a steam jet, + +void CWater::VaporFrame(int i, float rTime) +{ + D3DVECTOR pos, speed; + FPOINT dim; + int j; + + m_vapor[i].time += rTime; + + if ( m_sound == 0 ) + { + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + } + + if ( m_vapor[i].time <= m_vapor[i].delay ) + { + if ( m_time-m_vapor[i].last >= m_engine->ParticuleAdapt(0.02f) ) + { + m_vapor[i].last = m_time; + + if ( m_vapor[i].type == PARTIFIRE ) + { + for ( j=0 ; j<10 ; j++ ) + { + pos = m_vapor[i].pos; + pos.x += (Rand()-0.5f)*2.0f; + pos.z += (Rand()-0.5f)*2.0f; + pos.y -= 1.0f; + speed.x = (Rand()-0.5f)*6.0f; + speed.z = (Rand()-0.5f)*6.0f; + speed.y = 8.0f+Rand()*5.0f; + dim.x = Rand()*1.5f+1.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIERROR, 2.0f, 10.0f); + } + } + else if ( m_vapor[i].type == PARTIFLAME ) + { + pos = m_vapor[i].pos; + pos.x += (Rand()-0.5f)*8.0f; + pos.z += (Rand()-0.5f)*8.0f; + pos.y -= 2.0f; + speed.x = (Rand()-0.5f)*2.0f; + speed.z = (Rand()-0.5f)*2.0f; + speed.y = 4.0f+Rand()*4.0f; + dim.x = Rand()*2.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFLAME); + } + else + { + pos = m_vapor[i].pos; + pos.x += (Rand()-0.5f)*4.0f; + pos.z += (Rand()-0.5f)*4.0f; + pos.y -= 2.0f; + speed.x = (Rand()-0.5f)*2.0f; + speed.z = (Rand()-0.5f)*2.0f; + speed.y = 8.0f+Rand()*8.0f; + dim.x = Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIVAPOR); + } + } + } + else + { + m_vapor[i].bUsed = FALSE; + } +} + + +// Adjusts the position to normal, to imitate reflections on an expanse of water at rest. + +void CWater::AdjustLevel(D3DVECTOR &pos, D3DVECTOR &norm, + FPOINT &uv1, FPOINT &uv2) +{ +#if 0 + float t1, t2; + + uv1.x = (pos.x+10000.0f)/40.0f; + uv1.y = (pos.z+10000.0f)/40.0f; + + t1 = m_time*1.5f + pos.x*0.1f * pos.z*0.2f; + pos.y += sinf(t1)*m_eddy.y; + + t1 = m_time*0.6f + pos.x*0.1f * pos.z*0.2f; + t2 = m_time*0.7f + pos.x*0.3f * pos.z*0.4f; + pos.x += sinf(t1)*m_eddy.x; + pos.z += sinf(t2)*m_eddy.z; + +//? uv2.x = (pos.x+10000.0f)/40.0f+0.3f; +//? uv2.y = (pos.z+10000.0f)/40.0f+0.4f; + uv2.x = (pos.x+10000.0f)/20.0f; + uv2.y = (pos.z+10000.0f)/20.0f; + + t1 = m_time*0.7f + pos.x*5.5f + pos.z*5.6f; + t2 = m_time*0.8f + pos.x*5.7f + pos.z*5.8f; + norm = D3DVECTOR(sinf(t1)*m_glint, 1.0f, sinf(t2)*m_glint); +#else + float t1, t2; + + t1 = m_time*1.5f + pos.x*0.1f * pos.z*0.2f; + pos.y += sinf(t1)*m_eddy.y; + + t1 = m_time*1.5f; + uv1.x = (pos.x+10000.0f)/40.0f+sinf(t1)*m_eddy.x*0.02f; + uv1.y = (pos.z+10000.0f)/40.0f-cosf(t1)*m_eddy.z*0.02f; + uv2.x = (pos.x+10010.0f)/20.0f+cosf(-t1)*m_eddy.x*0.02f; + uv2.y = (pos.z+10010.0f)/20.0f-sinf(-t1)*m_eddy.z*0.02f; + + t1 = m_time*0.50f + pos.x*2.1f + pos.z*1.1f; + t2 = m_time*0.75f + pos.x*2.0f + pos.z*1.0f; + norm = D3DVECTOR(sinf(t1)*m_glint, 1.0f, sinf(t2)*m_glint); +#endif +} + +// Draw the back surface of the water. +// This surface prevents to see the sky (background) underwater! + +void CWater::DrawBack() +{ + LPDIRECT3DDEVICE7 device; + D3DVERTEX2 vertex[4]; // 2 triangles + D3DMATERIAL7 material; + D3DMATRIX matrix; + D3DVECTOR eye, lookat, n, p, p1, p2; + FPOINT uv1, uv2; + float deep, dist; + + if ( !m_bDraw ) return; + if ( m_type[0] == WATER_NULL ) return; + if ( m_lineUsed == 0 ) return; + + eye = m_engine->RetEyePt(); + lookat = m_engine->RetLookatPt(); + + ZeroMemory( &material, sizeof(D3DMATERIAL7) ); + material.diffuse = m_diffuse; + material.ambient = m_ambient; + m_engine->SetMaterial(material); + + m_engine->SetTexture("", 0); + + device = m_engine->RetD3DDevice(); + device->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE); + device->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); + device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + m_engine->SetState(D3DSTATENORMAL); + + deep = m_engine->RetDeepView(0); + m_engine->SetDeepView(deep*2.0f, 0); + m_engine->SetFocus(m_engine->RetFocus()); + m_engine->UpdateMatProj(); // twice the depth of view + + D3DUtil_SetIdentityMatrix(matrix); + device->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); + + p.x = eye.x; + p.z = eye.z; + dist = Length2d(eye, lookat); + p.x = (lookat.x-eye.x)*deep*1.0f/dist + eye.x; + p.z = (lookat.z-eye.z)*deep*1.0f/dist + eye.z; + + p1.x = (lookat.z-eye.z)*deep*2.0f/dist + p.x; + p1.z = -(lookat.x-eye.x)*deep*2.0f/dist + p.z; + p2.x = -(lookat.z-eye.z)*deep*2.0f/dist + p.x; + p2.z = (lookat.x-eye.x)*deep*2.0f/dist + p.z; + + p1.y = -50.0f; + p2.y = m_level; + + n.x = (lookat.x-eye.x)/dist; + n.z = (lookat.z-eye.z)/dist; + n.y = 0.0f; + + uv1.x = uv1.y = 0.0f; + uv2.x = uv2.y = 0.0f; + + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, p1.z), n, uv1.x,uv2.y); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, p1.z), n, uv1.x,uv1.y); + vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, p2.z), n, uv2.x,uv2.y); + vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, p2.z), n, uv2.x,uv1.y); + + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); + + m_engine->SetDeepView(deep, 0); + m_engine->SetFocus(m_engine->RetFocus()); + m_engine->UpdateMatProj(); // gives the initial depth of view + + device->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE); + device->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE); + device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); +} + +// Draws the flat surface of the water. + +void CWater::DrawSurf() +{ + LPDIRECT3DDEVICE7 device; + D3DVERTEX2* vertex; // triangles + D3DMATERIAL7 material; + D3DMATRIX matrix; + D3DVECTOR eye, lookat, n, pos, p; + FPOINT uv1, uv2; + BOOL bUnder; + DWORD flags; + float deep, size, sizez, radius; + int rankview, i, j, u; + + if ( !m_bDraw ) return; + if ( m_type[0] == WATER_NULL ) return; + if ( m_lineUsed == 0 ) return; + + vertex = (D3DVERTEX2*)malloc(sizeof(D3DVERTEX2)*(m_brick+2)*2); + + eye = m_engine->RetEyePt(); + lookat = m_engine->RetLookatPt(); + + rankview = m_engine->RetRankView(); + bUnder = ( rankview == 1); + + device = m_engine->RetD3DDevice(); +//? device->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); +//? device->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE); +//? device->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); + device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + + D3DUtil_SetIdentityMatrix(matrix); + device->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); + + ZeroMemory( &material, sizeof(D3DMATERIAL7) ); + material.diffuse = m_diffuse; + material.ambient = m_ambient; + m_engine->SetMaterial(material); + + m_engine->SetTexture(m_filename, 0); + m_engine->SetTexture(m_filename, 1); + + if ( m_type[rankview] == WATER_TT ) + { + m_engine->SetState(D3DSTATETTb|D3DSTATEDUALw|D3DSTATEWRAP, m_color); + } + if ( m_type[rankview] == WATER_TO ) + { + m_engine->SetState(D3DSTATENORMAL|D3DSTATEDUALw|D3DSTATEWRAP); + } + if ( m_type[rankview] == WATER_CT ) + { + m_engine->SetState(D3DSTATETTb); + } + if ( m_type[rankview] == WATER_CO ) + { + m_engine->SetState(D3DSTATENORMAL); + } + device->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE); + + size = m_size/2.0f; + if ( bUnder ) sizez = -size; + else sizez = size; + + // Draws all the lines. + deep = m_engine->RetDeepView(0)*1.5f; + + for ( i=0 ; i deep+radius ) continue; + device->ComputeSphereVisibility(&p, &radius, 1, 0, &flags); + if ( flags & D3DSTATUS_CLIPINTERSECTIONALL ) continue; + + u = 0; + p.x = pos.x-size; + p.z = pos.z-sizez; + p.y = pos.y; + AdjustLevel(p, n, uv1, uv2); + if ( bUnder ) n.y = -n.y; + vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y); + + p.x = pos.x-size; + p.z = pos.z+sizez; + p.y = pos.y; + AdjustLevel(p, n, uv1, uv2); + if ( bUnder ) n.y = -n.y; + vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y); + + for ( j=0 ; jDrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, u, NULL); + m_engine->AddStatisticTriangle(u-2); + } + + free(vertex); +} + + +// Indicates if there is water in a given position. + +BOOL CWater::RetWater(int x, int y) +{ + D3DVECTOR pos; + float size, offset, level; + int dx, dy; + + x *= m_subdiv; + y *= m_subdiv; + + size = m_size/m_subdiv; + offset = m_brick*m_size/2.0f; + + for ( dy=0 ; dy<=m_subdiv ; dy++ ) + { + for ( dx=0 ; dx<=m_subdiv ; dx++ ) + { + pos.x = (x+dx)*size - offset; + pos.z = (y+dy)*size - offset; + pos.y = 0.0f; + level = m_terrain->RetFloorLevel(pos, TRUE); + if ( level < m_level+m_eddy.y ) return TRUE; + } + } + return FALSE; +} + +// Updates the positions, relative to the ground. + +BOOL CWater::CreateLine(int x, int y, int len) +{ + float offset; + + m_line[m_lineUsed].x = x; + m_line[m_lineUsed].y = y; + m_line[m_lineUsed].len = len; + + offset = m_brick*m_size/2.0f - m_size/2.0f; + + m_line[m_lineUsed].px1 = m_size* m_line[m_lineUsed].x - offset; + m_line[m_lineUsed].px2 = m_size*(m_line[m_lineUsed].x+m_line[m_lineUsed].len) - offset; + m_line[m_lineUsed].pz = m_size* m_line[m_lineUsed].y - offset; + + m_lineUsed ++; + + return ( m_lineUsed < MAXWATERLINE ); +} + +// Creates all expanses of water. + +BOOL CWater::Create(WaterType type1, WaterType type2, const char *filename, + D3DCOLORVALUE diffuse, D3DCOLORVALUE ambient, + float level, float glint, D3DVECTOR eddy) +{ + int x, y, len; + + m_type[0] = type1; + m_type[1] = type2; + m_diffuse = diffuse; + m_ambient = ambient; + m_level = level; + m_glint = glint; + m_eddy = eddy; + m_time = 0.0f; + m_lastLava = 0.0f; + strcpy(m_filename, filename); + + VaporFlush(); + + if ( m_filename[0] != 0 ) + { + m_engine->LoadTexture(m_filename, 0); + m_engine->LoadTexture(m_filename, 1); + } + + if ( m_terrain == 0 ) + { + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + } + m_brick = m_terrain->RetBrick()*m_terrain->RetMosaic(); + m_size = m_terrain->RetSize(); + + m_brick /= m_subdiv; + m_size *= m_subdiv; + + if ( m_type[0] == WATER_NULL ) return TRUE; + + m_lineUsed = 0; + for ( y=0 ; y= 5 ) + { + if ( !CreateLine(x-len+1, y, len) ) return FALSE; + len = 0; + } + } + else // dry? + { + if ( len != 0 ) + { + if ( !CreateLine(x-len, y, len) ) return FALSE; + len = 0; + } + } + } + if ( len != 0 ) + { + if ( !CreateLine(x-len, y, len) ) return FALSE; + } + } + return TRUE; +} + +// Removes all the water. + +void CWater::Flush() +{ + m_type[0] = WATER_NULL; + m_type[1] = WATER_NULL; + m_level = 0.0f; + m_bLava = FALSE; +} + + +// Changes the level of the water. + +BOOL CWater::SetLevel(float level) +{ + m_level = level; + + return Create(m_type[0], m_type[1], m_filename, m_diffuse, m_ambient, + m_level, m_glint, m_eddy); +} + +// Returns the current level of water. + +float CWater::RetLevel() +{ + return m_level; +} + +// Returns the current level of water for a given object. + +float CWater::RetLevel(CObject* object) +{ + ObjectType type; + + type = object->RetType(); + + if ( type == OBJECT_HUMAN || + type == OBJECT_TECH ) + { + return m_level-3.0f; + } + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEtg || + type == OBJECT_MOBILEft || + type == OBJECT_MOBILEtt || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEit || + type == OBJECT_MOBILEdr ) + { + return m_level-2.0f; + } + + return m_level; +} + + +// Management of the mode of lava/water. + +void CWater::SetLava(BOOL bLava) +{ + m_bLava = bLava; +} + +BOOL CWater::RetLava() +{ + return m_bLava; +} + + +// Adjusts the eye of the camera, not to be in the water. + +void CWater::AdjustEye(D3DVECTOR &eye) +{ + if ( m_bLava ) + { + if ( eye.y < m_level+2.0f ) + { + eye.y = m_level+2.0f; // never under the lava + } + } + else + { + if ( eye.y >= m_level-2.0f && + eye.y <= m_level+2.0f ) // close to the surface? + { + eye.y = m_level+2.0f; // bam, well above + } + } +} + diff --git a/src/graphics/common/water.h b/src/graphics/common/water.h new file mode 100644 index 0000000..dc9384d --- /dev/null +++ b/src/graphics/common/water.h @@ -0,0 +1,134 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// water.h + +#ifndef _WATER_H_ +#define _WATER_H_ + + +#include "d3dengine.h" +#include "particule.h" + + +class CInstanceManager; +class CTerrain; +class CSound; + + + +#define MAXWATERLINE 500 + +typedef struct +{ + short x, y; // beginning + short len; // length by x + float px1, px2, pz; +} +WaterLine; + + +#define MAXWATVAPOR 10 + +typedef struct +{ + BOOL bUsed; + ParticuleType type; + D3DVECTOR pos; + float delay; + float time; + float last; +} +WaterVapor; + + +enum WaterType +{ + WATER_NULL = 0, // no water + WATER_TT = 1, // transparent texture + WATER_TO = 2, // opaque texture + WATER_CT = 3, // transparent color + WATER_CO = 4, // opaque color +}; + + +class CWater +{ +public: + CWater(CInstanceManager* iMan, CD3DEngine* engine); + ~CWater(); + + void SetD3DDevice(LPDIRECT3DDEVICE7 device); + BOOL EventProcess(const Event &event); + void Flush(); + BOOL Create(WaterType type1, WaterType type2, const char *filename, D3DCOLORVALUE diffuse, D3DCOLORVALUE ambient, float level, float glint, D3DVECTOR eddy); + void DrawBack(); + void DrawSurf(); + + BOOL SetLevel(float level); + float RetLevel(); + float RetLevel(CObject* object); + + void SetLava(BOOL bLava); + BOOL RetLava(); + + void AdjustEye(D3DVECTOR &eye); + +protected: + BOOL EventFrame(const Event &event); + void LavaFrame(float rTime); + void AdjustLevel(D3DVECTOR &pos, D3DVECTOR &norm, FPOINT &uv1, FPOINT &uv2); + BOOL RetWater(int x, int y); + BOOL CreateLine(int x, int y, int len); + + void VaporFlush(); + BOOL VaporCreate(ParticuleType type, D3DVECTOR pos, float delay); + void VaporFrame(int i, float rTime); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + LPDIRECT3DDEVICE7 m_pD3DDevice; + CTerrain* m_terrain; + CParticule* m_particule; + CSound* m_sound; + + WaterType m_type[2]; + char m_filename[100]; + float m_level; // overall level + float m_glint; // amplitude of reflections + D3DVECTOR m_eddy; // amplitude of swirls + D3DCOLORVALUE m_diffuse; // diffuse color + D3DCOLORVALUE m_ambient; // ambient color + float m_time; + float m_lastLava; + int m_subdiv; + + int m_brick; // number of brick*mosaics + float m_size; // size of a item in an brick + + int m_lineUsed; + WaterLine m_line[MAXWATERLINE]; + + WaterVapor m_vapor[MAXWATVAPOR]; + + BOOL m_bDraw; + BOOL m_bLava; + D3DCOLOR m_color; +}; + + +#endif //_WATER_H_ diff --git a/src/graphics/d3d/d3dengine.cpp b/src/graphics/d3d/d3dengine.cpp new file mode 100644 index 0000000..bbfb89e --- /dev/null +++ b/src/graphics/d3d/d3dengine.cpp @@ -0,0 +1,5727 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// D3DEngine.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include + +#include "struct.h" +#include "d3dapp.h" +#include "d3dtextr.h" +#include "d3dutil.h" +#include "d3dmath.h" +#include "d3dengine.h" +#include "language.h" +#include "iman.h" +#include "event.h" +#include "profile.h" +#include "math3d.h" +#include "object.h" +#include "interface.h" +#include "light.h" +#include "text.h" +#include "particule.h" +#include "terrain.h" +#include "water.h" +#include "cloud.h" +#include "blitz.h" +#include "planet.h" +#include "sound.h" + + + +#define SIZEBLOC_TEXTURE 50 +#define SIZEBLOC_TRANSFORM 100 +#define SIZEBLOC_MINMAX 5 +#define SIZEBLOC_LIGHT 10 +#define SIZEBLOC_MATERIAL 100 +#define SIZEBLOC_TRIANGLE 200 + + + +#if 0 +static int debug_blend1 = 1; +static int debug_blend2 = 3; +static int debug_blend3 = 8; +static int debug_blend4 = 0; + +static int table_blend[13] = +{ + D3DBLEND_ZERO, // 0 + D3DBLEND_ONE, // 1 + D3DBLEND_SRCCOLOR, // 2 + D3DBLEND_INVSRCCOLOR, // 3 + D3DBLEND_SRCALPHA, // 4 + D3DBLEND_INVSRCALPHA, // 5 + D3DBLEND_DESTALPHA, // 6 + D3DBLEND_INVDESTALPHA, // 7 + D3DBLEND_DESTCOLOR, // 8 + D3DBLEND_INVDESTCOLOR, // 9 + D3DBLEND_SRCALPHASAT, // 10 + D3DBLEND_BOTHSRCALPHA, // 11 + D3DBLEND_BOTHINVSRCALPHA, // 12 +}; +#endif + +static int s_resol = 0; + + + +// Converts a FLOAT to a DWORD for use in SetRenderState() calls. + +inline DWORD F2DW( FLOAT f ) +{ + return *((DWORD*)&f); +} + + + + +// Application constructor. Sets attributes for the app. + +CD3DEngine::CD3DEngine(CInstanceManager *iMan, CD3DApplication *app) +{ + int i; + + m_iMan = iMan; + m_iMan->AddInstance(CLASS_ENGINE, this); + m_app = app; + + m_light = new CLight(m_iMan, this); + m_text = new CText(m_iMan, this); + m_particule = new CParticule(m_iMan, this); + m_water = new CWater(m_iMan, this); + m_cloud = new CCloud(m_iMan, this); + m_blitz = new CBlitz(m_iMan, this); + m_planet = new CPlanet(m_iMan, this); + m_pD3DDevice = 0; + m_sound = 0; + m_terrain = 0; + + m_dim.x = 640; + m_dim.y = 480; + m_lastDim = m_dim; + m_focus = 0.75f; + m_baseTime = 0; + m_lastTime = 0; + m_absTime = 0.0f; + m_rankView = 0; + m_ambiantColor[0] = 0x80808080; + m_ambiantColor[1] = 0x80808080; + m_fogColor[0] = 0xffffffff; // white + m_fogColor[1] = 0xffffffff; // white + m_deepView[0] = 1000.0f; + m_deepView[1] = 1000.0f; + m_fogStart[0] = 0.75f; + m_fogStart[1] = 0.75f; + m_waterAddColor.r = 0.0f; + m_waterAddColor.g = 0.0f; + m_waterAddColor.b = 0.0f; + m_waterAddColor.a = 0.0f; + m_bPause = FALSE; + m_bRender = TRUE; + m_bMovieLock = FALSE; + m_bShadow = TRUE; + m_bGroundSpot = TRUE; + m_bDirty = TRUE; + m_bFog = TRUE; + m_speed = 1.0f; + m_secondTexNum = 0; + m_eyeDirH = 0.0f; + m_eyeDirV = 0.0f; + m_backgroundName[0] = 0; // no background image + m_backgroundColorUp = 0; + m_backgroundColorDown = 0; + m_backgroundCloudUp = 0; + m_backgroundCloudDown = 0; + m_bBackgroundFull = FALSE; + m_bBackgroundQuarter = FALSE; + m_bOverFront = TRUE; + m_overColor = 0; + m_overMode = D3DSTATETCb; + m_frontsizeName[0] = 0; // no front image + m_hiliteRank[0] = -1; // empty list + m_mousePos = FPOINT(0.5f, 0.5f); + m_mouseType = D3DMOUSENORM; + m_bMouseHide = FALSE; + m_imageSurface = 0; + m_imageCopy = 0; + m_eyePt = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_lookatPt = D3DVECTOR(0.0f, 0.0f, 1.0f); + m_bDrawWorld = TRUE; + m_bDrawFront = FALSE; + m_limitLOD[0] = 100.0f; + m_limitLOD[1] = 200.0f; + m_particuleDensity = 1.0f; + m_clippingDistance = 1.0f; + m_lastClippingDistance = m_clippingDistance; + m_objectDetail = 1.0f; + m_lastObjectDetail = m_objectDetail; + m_terrainVision = 1000.0f; + m_gadgetQuantity = 1.0f; + m_textureQuality = 1; + m_bTotoMode = TRUE; + m_bLensMode = TRUE; + m_bWaterMode = TRUE; + m_bSkyMode = TRUE; + m_bBackForce = TRUE; + m_bPlanetMode = TRUE; + m_bLightMode = TRUE; + m_bEditIndentMode = TRUE; + m_editIndentValue = 4; + m_tracePrecision = 1.0f; + + m_alphaMode = 1; + if ( GetProfileInt("Engine", "AlphaMode", i) ) + { + m_alphaMode = i; + } + + if ( GetProfileInt("Engine", "StateColor", i) && i != -1 ) + { + m_bForceStateColor = TRUE; + m_bStateColor = i; + } + else + { + m_bForceStateColor = FALSE; + m_bStateColor = FALSE; + } + + m_blackSrcBlend[0] = 0; + m_blackDestBlend[0] = 0; + m_whiteSrcBlend[0] = 0; + m_whiteDestBlend[0] = 0; + m_diffuseSrcBlend[0] = 0; + m_diffuseDestBlend[0] = 0; + m_alphaSrcBlend[0] = 0; + m_alphaDestBlend[0] = 0; + + if ( GetProfileInt("Engine", "BlackSrcBlend", i) ) m_blackSrcBlend[0] = i; + if ( GetProfileInt("Engine", "BlackDestBlend", i) ) m_blackDestBlend[0] = i; + if ( GetProfileInt("Engine", "WhiteSrcBlend", i) ) m_whiteSrcBlend[0] = i; + if ( GetProfileInt("Engine", "WhiteDestBlend", i) ) m_whiteDestBlend[0] = i; + if ( GetProfileInt("Engine", "DiffuseSrcBlend", i) ) m_diffuseSrcBlend[0] = i; + if ( GetProfileInt("Engine", "DiffuseDestBlend", i) ) m_diffuseDestBlend[0] = i; + if ( GetProfileInt("Engine", "AlphaSrcBlend", i) ) m_alphaSrcBlend[0] = i; + if ( GetProfileInt("Engine", "AlphaDestBlend", i) ) m_alphaDestBlend[0] = i; + + m_bUpdateGeometry = FALSE; + + for ( i=0 ; i<10 ; i++ ) + { + m_infoText[i][0] = 0; + } + + m_objectPointer = 0; + MemSpace1(m_objectPointer, 0); + + m_objectParam = (D3DObject*)malloc(sizeof(D3DObject)*D3DMAXOBJECT); + ZeroMemory(m_objectParam, sizeof(D3DObject)*D3DMAXOBJECT); + m_objectParamTotal = 0; + + m_shadow = (D3DShadow*)malloc(sizeof(D3DShadow)*D3DMAXSHADOW); + ZeroMemory(m_shadow, sizeof(D3DShadow)*D3DMAXSHADOW); + m_shadowTotal = 0; + + m_groundSpot = (D3DGroundSpot*)malloc(sizeof(D3DGroundSpot)*D3DMAXGROUNDSPOT); + ZeroMemory(m_groundSpot, sizeof(D3DGroundSpot)*D3DMAXGROUNDSPOT); + + ZeroMemory(&m_groundMark, sizeof(D3DGroundMark)); + + D3DTextr_SetTexturePath("textures\\"); +} + +// Application destructor. Free memory. + +CD3DEngine::~CD3DEngine() +{ + D3DObjLevel1* p1; + D3DObjLevel2* p2; + D3DObjLevel3* p3; + D3DObjLevel4* p4; + D3DObjLevel5* p5; + D3DObjLevel6* p6; + int l1, l2, l3, l4, l5; + + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; + free(p6); + } + free(p5); + } + free(p4); + } + free(p3); + } + free(p2); + } + free(p1); + + delete m_light; + delete m_particule; + delete m_water; + delete m_cloud; + delete m_blitz; + delete m_planet; +} + + + +void CD3DEngine::SetD3DDevice(LPDIRECT3DDEVICE7 device) +{ + D3DDEVICEDESC7 ddDesc; + + m_pD3DDevice = device; + m_light->SetD3DDevice(device); + m_text->SetD3DDevice(device); + m_particule->SetD3DDevice(device); + + if ( !m_bForceStateColor ) + { + m_pD3DDevice->GetCaps(&ddDesc); + if( ddDesc.dpcTriCaps.dwTextureBlendCaps & D3DPTBLENDCAPS_ADD ) + { + m_bStateColor = TRUE; + } + else + { + m_bStateColor = FALSE; + } + } + + m_blackSrcBlend[1] = D3DBLEND_ONE; // = 2 + m_blackDestBlend[1] = D3DBLEND_INVSRCCOLOR; // = 4 + m_whiteSrcBlend[1] = D3DBLEND_DESTCOLOR; // = 9 + m_whiteDestBlend[1] = D3DBLEND_ZERO; // = 1 + m_diffuseSrcBlend[1] = D3DBLEND_SRCALPHA; // = 5 + m_diffuseDestBlend[1] = D3DBLEND_DESTALPHA; // = 7 + m_alphaSrcBlend[1] = D3DBLEND_ONE; // = 2 + m_alphaDestBlend[1] = D3DBLEND_INVSRCCOLOR; // = 4 + +//? if ( !m_bStateColor ) m_whiteDestBlend[1] = D3DBLEND_INVSRCALPHA; // = 6 + +// Fix for the graphics bug: + //if ( m_blackSrcBlend[0] ) m_blackSrcBlend[1] = m_blackSrcBlend[0]; + //if ( m_blackDestBlend[0] ) m_blackDestBlend[1] = m_blackDestBlend[0]; + //if ( m_whiteSrcBlend[0] ) m_whiteSrcBlend[1] = m_whiteSrcBlend[0]; + //if ( m_whiteDestBlend[0] ) m_whiteDestBlend[1] = m_whiteDestBlend[0]; + + if ( m_diffuseSrcBlend[0] ) m_diffuseSrcBlend[1] = m_diffuseSrcBlend[0]; + if ( m_diffuseDestBlend[0] ) m_diffuseDestBlend[1] = m_diffuseDestBlend[0]; + if ( m_alphaSrcBlend[0] ) m_alphaSrcBlend[1] = m_alphaSrcBlend[0]; + if ( m_alphaDestBlend[0] ) m_alphaDestBlend[1] = m_alphaDestBlend[0]; + +#if 0 + DWORD pass; + m_pD3DDevice->ValidateDevice(&pass); + char s[100]; + sprintf(s, "NbPass=%d", pass); + SetInfoText(3, s); +#endif +} + +LPDIRECT3DDEVICE7 CD3DEngine::RetD3DDevice() +{ + return m_pD3DDevice; +} + + +// Gives the pointer to the existing terrain. + +void CD3DEngine::SetTerrain(CTerrain* terrain) +{ + m_terrain = terrain; +} + + +// Saving the state of the graphics engine in COLOBOT.INI. + +BOOL CD3DEngine::WriteProfile() +{ + SetProfileInt("Engine", "AlphaMode", m_alphaMode); + + if ( m_bForceStateColor ) + { + SetProfileInt("Engine", "StateColor", m_bStateColor); + } + else + { + SetProfileInt("Engine", "StateColor", -1); + } + + SetProfileInt("Engine", "BlackSrcBlend", m_blackSrcBlend[0]); + SetProfileInt("Engine", "BlackDestBlend", m_blackDestBlend[0]); + SetProfileInt("Engine", "WhiteSrcBlend", m_whiteSrcBlend[0]); + SetProfileInt("Engine", "WhiteDestBlend", m_whiteDestBlend[0]); + SetProfileInt("Engine", "DiffuseSrcBlend", m_diffuseSrcBlend[0]); + SetProfileInt("Engine", "DiffuseDestBlend", m_diffuseDestBlend[0]); + SetProfileInt("Engine", "AlphaSrcBlend", m_alphaSrcBlend[0]); + SetProfileInt("Engine", "AlphaDestBlend", m_alphaDestBlend[0]); + + return TRUE; +} + + +// Setup the app so it can support single-stepping. + +void CD3DEngine::TimeInit() +{ + m_baseTime = timeGetTime(); + m_lastTime = 0; + m_absTime = 0.0f; +} + +void CD3DEngine::TimeEnterGel() +{ + m_stopTime = timeGetTime(); +} + +void CD3DEngine::TimeExitGel() +{ + m_baseTime += timeGetTime() - m_stopTime; +} + +float CD3DEngine::TimeGet() +{ + float aTime, rTime; + + aTime = (timeGetTime()-m_baseTime)*0.001f; // in ms + rTime = (aTime - m_lastTime)*m_speed; + m_absTime += rTime; + m_lastTime = aTime; + + return rTime; +} + + +void CD3DEngine::SetPause(BOOL bPause) +{ + m_bPause = bPause; +} + +BOOL CD3DEngine::RetPause() +{ + return m_bPause; +} + + +void CD3DEngine::SetMovieLock(BOOL bLock) +{ + m_bMovieLock = bLock; +} + +BOOL CD3DEngine::RetMovieLock() +{ + return m_bMovieLock; +} + + +void CD3DEngine::SetShowStat(BOOL bShow) +{ + m_app->SetShowStat(bShow); +} + +BOOL CD3DEngine::RetShowStat() +{ + return m_app->RetShowStat(); +} + + +void CD3DEngine::SetRenderEnable(BOOL bEnable) +{ + m_bRender = bEnable; +} + + +// Prepare a structure to add D3DObjLevel6 +// qq D3DVERTEX2 elements. + +void CD3DEngine::MemSpace6(D3DObjLevel6 *&p, int nb) +{ + D3DObjLevel6* pp; + int total, size; + + if ( p == 0 ) + { + total = SIZEBLOC_TRIANGLE+nb; + size = sizeof(D3DObjLevel6)+sizeof(D3DVERTEX2)*(total-1); + p = (D3DObjLevel6*)malloc(size); + ZeroMemory(p, size); + p->totalPossible = total; + return; + } + + if ( p->totalUsed+nb > p->totalPossible ) + { + total = p->totalPossible+SIZEBLOC_TRIANGLE+nb; + size = sizeof(D3DObjLevel6)+sizeof(D3DVERTEX2)*(total-1); + pp = (D3DObjLevel6*)malloc(size); + ZeroMemory(pp, size); + CopyMemory(pp, p, sizeof(D3DObjLevel6)+sizeof(D3DVERTEX2)*(p->totalPossible-1)); + pp->totalPossible = total; + free(p); + p = pp; + } +} + +// Prepare a structure to add D3DObjLevel5 +// qq elements D3DObjLevel6. + +void CD3DEngine::MemSpace5(D3DObjLevel5 *&p, int nb) +{ + D3DObjLevel5* pp; + int total, size; + + if ( p == 0 ) + { + total = SIZEBLOC_MATERIAL+nb; + size = sizeof(D3DObjLevel5)+sizeof(D3DObjLevel6*)*(total-1); + p = (D3DObjLevel5*)malloc(size); + ZeroMemory(p, size); + p->totalPossible = total; + return; + } + + if ( p->totalUsed+nb > p->totalPossible ) + { + total = p->totalPossible+SIZEBLOC_MATERIAL+nb; + size = sizeof(D3DObjLevel5)+sizeof(D3DObjLevel6*)*(total-1); + pp = (D3DObjLevel5*)malloc(size); + ZeroMemory(pp, size); + CopyMemory(pp, p, sizeof(D3DObjLevel5)+sizeof(D3DObjLevel6*)*(p->totalPossible-1)); + pp->totalPossible = total; + free(p); + p = pp; + } +} + +// Prepare a structure to add D3DObjLevel4 +// qq D3DObjLevel5 elements. + +void CD3DEngine::MemSpace4(D3DObjLevel4 *&p, int nb) +{ + D3DObjLevel4* pp; + int total, size; + + if ( p == 0 ) + { + total = SIZEBLOC_LIGHT+nb; + size = sizeof(D3DObjLevel4)+sizeof(D3DObjLevel5*)*(total-1); + p = (D3DObjLevel4*)malloc(size); + ZeroMemory(p, size); + p->totalPossible = total; + return; + } + + if ( p->totalUsed+nb > p->totalPossible ) + { + total = p->totalPossible+SIZEBLOC_LIGHT+nb; + size = sizeof(D3DObjLevel4)+sizeof(D3DObjLevel5*)*(total-1); + pp = (D3DObjLevel4*)malloc(size); + ZeroMemory(pp, size); + CopyMemory(pp, p, sizeof(D3DObjLevel4)+sizeof(D3DObjLevel5*)*(p->totalPossible-1)); + pp->totalPossible = total; + free(p); + p = pp; + } +} + +// Prepare a structure to add D3DObjLevel3 +// qq D3DObjLevel4 elements. + +void CD3DEngine::MemSpace3(D3DObjLevel3 *&p, int nb) +{ + D3DObjLevel3* pp; + int total, size; + + if ( p == 0 ) + { + total = SIZEBLOC_MINMAX+nb; + size = sizeof(D3DObjLevel3)+sizeof(D3DObjLevel4*)*(total-1); + p = (D3DObjLevel3*)malloc(size); + ZeroMemory(p, size); + p->totalPossible = total; + return; + } + + if ( p->totalUsed+nb > p->totalPossible ) + { + total = p->totalPossible+SIZEBLOC_MINMAX+nb; + size = sizeof(D3DObjLevel3)+sizeof(D3DObjLevel4*)*(total-1); + pp = (D3DObjLevel3*)malloc(size); + ZeroMemory(pp, size); + CopyMemory(pp, p, sizeof(D3DObjLevel3)+sizeof(D3DObjLevel4*)*(p->totalPossible-1)); + pp->totalPossible = total; + free(p); + p = pp; + } +} + +// Prepare a structure to add D3DObjLevel2 +// qq D3DObjLevel3 elements. + +void CD3DEngine::MemSpace2(D3DObjLevel2 *&p, int nb) +{ + D3DObjLevel2* pp; + int total, size; + + if ( p == 0 ) + { + total = SIZEBLOC_TRANSFORM+nb; + size = sizeof(D3DObjLevel2)+sizeof(D3DObjLevel3*)*(total-1); + p = (D3DObjLevel2*)malloc(size); + ZeroMemory(p, size); + p->totalPossible = total; + return; + } + + if ( p->totalUsed+nb > p->totalPossible ) + { + total = p->totalPossible+SIZEBLOC_TRANSFORM+nb; + size = sizeof(D3DObjLevel2)+sizeof(D3DObjLevel3*)*(total-1); + pp = (D3DObjLevel2*)malloc(size); + ZeroMemory(pp, size); + CopyMemory(pp, p, sizeof(D3DObjLevel2)+sizeof(D3DObjLevel3*)*(p->totalPossible-1)); + pp->totalPossible = total; + free(p); + p = pp; + } +} + +// Prepare a structure to add D3DObjLevel1 +// qq D3DObjLevel2 elements. + +void CD3DEngine::MemSpace1(D3DObjLevel1 *&p, int nb) +{ + D3DObjLevel1* pp; + int total, size; + + if ( p == 0 ) + { + total = SIZEBLOC_TEXTURE+nb; + size = sizeof(D3DObjLevel1)+sizeof(D3DObjLevel2*)*(total-1); + p = (D3DObjLevel1*)malloc(size); + ZeroMemory(p, size); + p->totalPossible = total; + return; + } + + if ( p->totalUsed+nb > p->totalPossible ) + { + total = p->totalPossible+SIZEBLOC_TEXTURE+nb; + size = sizeof(D3DObjLevel1)+sizeof(D3DObjLevel2*)*(total-1); + pp = (D3DObjLevel1*)malloc(size); + ZeroMemory(pp, size); + CopyMemory(pp, p, sizeof(D3DObjLevel1)+sizeof(D3DObjLevel2*)*(p->totalPossible-1)); + pp->totalPossible = total; + free(p); + p = pp; + } +} + + +// Returns the number of objects that can still be created. + +int CD3DEngine::RetRestCreate() +{ + return D3DMAXOBJECT-m_objectParamTotal-2; +} + +// Creates a new object. Returns its rank or -1 on error. + +int CD3DEngine::CreateObject() +{ + D3DMATRIX mat; + int i; + + for ( i=0 ; i= m_objectParamTotal ) + { + m_objectParamTotal = i+1; + } + return i; + } + } + OutputDebugString("CD3DEngine::CreateObject() -> Too many object\n"); + return -1; +} + + +// Removes all objects. + +void CD3DEngine::FlushObject() +{ + D3DObjLevel1* p1; + D3DObjLevel2* p2; + D3DObjLevel3* p3; + D3DObjLevel4* p4; + D3DObjLevel5* p5; + D3DObjLevel6* p6; + int l1, l2, l3, l4, l5, i; + + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; + free(p6); + } + free(p5); + } + free(p4); + } + free(p3); + } + free(p2); + p1->table[l1] = 0; + } + p1->totalUsed = 0; + + for ( i=0 ; itotalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + if ( p3->objRank != objRank ) continue; + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; + free(p6); + } + free(p5); + } + free(p4); + } + free(p3); + p2->table[l2] = 0; + } + } + + ShadowDelete(objRank); // removes the shadow + + m_objectParam[objRank].bUsed = FALSE; + + m_objectParamTotal = 0; + for ( i=0 ; i= D3DMAXOBJECT ) return FALSE; + + m_objectParam[objRank].bDrawWorld = bDraw; + return TRUE; +} + +// Indicates whether an object should be drawn over the interface. + +BOOL CD3DEngine::SetDrawFront(int objRank, BOOL bDraw) +{ + if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; + + m_objectParam[objRank].bDrawFront = bDraw; + return TRUE; +} + + +// Prepare Level 1 to add a triangle. + +D3DObjLevel2* CD3DEngine::AddLevel1(D3DObjLevel1 *&p1, char* texName1, char* texName2) +{ + D3DObjLevel2* p2; + int l1; + + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + if ( strcmp(p2->texName1, texName1) == 0 && + strcmp(p2->texName2, texName2) == 0 ) + { + MemSpace2(p1->table[l1], 1); + return p1->table[l1]; + } + } + + MemSpace1(p1, 1); + l1 = p1->totalUsed++; + p1->table[l1] = 0; + + MemSpace2(p1->table[l1], 1); + strcpy(p1->table[l1]->texName1, texName1); + strcpy(p1->table[l1]->texName2, texName2); + return p1->table[l1]; +} + +// Prepare Level 2 to add a triangle. + +D3DObjLevel3* CD3DEngine::AddLevel2(D3DObjLevel2 *&p2, int objRank) +{ + D3DObjLevel3* p3; + int l2; + + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + if ( p3->objRank == objRank ) + { + MemSpace3(p2->table[l2], 1); + return p2->table[l2]; + } + } + + MemSpace2(p2, 1); + l2 = p2->totalUsed++; + p2->table[l2] = 0; + + MemSpace3(p2->table[l2], 1); + p2->table[l2]->objRank = objRank; + return p2->table[l2]; +} + +// Prepare Level 3 to add a triangle. + +D3DObjLevel4* CD3DEngine::AddLevel3(D3DObjLevel3 *&p3, float min, float max) +{ + D3DObjLevel4* p4; + int l3; + + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + if ( p4->min == min && p4->max == max ) + { + MemSpace4(p3->table[l3], 1); + return p3->table[l3]; + } + } + + MemSpace3(p3, 1); + l3 = p3->totalUsed++; + p3->table[l3] = 0; + + MemSpace4(p3->table[l3], 1); + p3->table[l3]->min = min; + p3->table[l3]->max = max; + return p3->table[l3]; +} + +// Prepare Level 4 to add a triangle. + +D3DObjLevel5* CD3DEngine::AddLevel4(D3DObjLevel4 *&p4, int reserve) +{ + D3DObjLevel5* p5; + int l4; + + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + if ( p5->reserve == reserve ) + { + MemSpace5(p4->table[l4], 1); + return p4->table[l4]; + } + } + + MemSpace4(p4, 1); + l4 = p4->totalUsed++; + p4->table[l4] = 0; + + MemSpace5(p4->table[l4], 1); + p4->table[l4]->reserve = reserve; + return p4->table[l4]; +} + +// Prepares Level 5 to add vertices. + +D3DObjLevel6* CD3DEngine::AddLevel5(D3DObjLevel5 *&p5, D3DTypeTri type, + const D3DMATERIAL7 &mat, int state, + int nb) +{ + D3DObjLevel6* p6; + int l5; + + if ( type == D3DTYPE6T ) + { + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; + if ( p6->type == type && + memcmp(&p6->material, &mat, sizeof(D3DMATERIAL7)) == 0 && + p6->state == state ) + { + MemSpace6(p5->table[l5], nb); + return p5->table[l5]; + } + } + } + + MemSpace5(p5, 1); + l5 = p5->totalUsed++; + p5->table[l5] = 0; + + MemSpace6(p5->table[l5], nb); + p5->table[l5]->type = type; + p5->table[l5]->material = mat; + p5->table[l5]->state = state; + return p5->table[l5]; +} + +// Adds one or more triangles to an existing object. +// The number must be divisible by 3. + +BOOL CD3DEngine::AddTriangle(int objRank, D3DVERTEX2* vertex, int nb, + const D3DMATERIAL7 &mat, int state, + char* texName1, char* texName2, + float min, float max, BOOL bGlobalUpdate) +{ + D3DObjLevel2* p2; + D3DObjLevel3* p3; + D3DObjLevel4* p4; + D3DObjLevel5* p5; + D3DObjLevel6* p6; + int i; + + m_lastDim = m_dim; + m_lastObjectDetail = m_objectDetail; + m_lastClippingDistance = m_clippingDistance; + + p2 = AddLevel1(m_objectPointer, texName1, texName2); + p3 = AddLevel2(p2, objRank); + p4 = AddLevel3(p3, min, max); + p5 = AddLevel4(p4, 0); + p6 = AddLevel5(p5, D3DTYPE6T, mat, state, nb); // place for number of vertex + + CopyMemory(&p6->vertex[p6->totalUsed], vertex, sizeof(D3DVERTEX2)*nb); + p6->totalUsed += nb; + + if ( bGlobalUpdate ) + { + m_bUpdateGeometry = TRUE; + } + else + { + for ( i=0 ; ivertex[p6->totalUsed], vertex, sizeof(D3DVERTEX2)*nb); + p6->totalUsed += nb; + + if ( bGlobalUpdate ) + { + m_bUpdateGeometry = TRUE; + } + else + { + for ( i=0 ; itotalUsed++; + p5->table[l5] = buffer; + + if ( bGlobalUpdate ) + { + m_bUpdateGeometry = TRUE; + } + else + { + for ( i=0 ; itotalUsed ; i++ ) + { + m_objectParam[objRank].bboxMin.x = Min(buffer->vertex[i].x, m_objectParam[objRank].bboxMin.x); + m_objectParam[objRank].bboxMin.y = Min(buffer->vertex[i].y, m_objectParam[objRank].bboxMin.y); + m_objectParam[objRank].bboxMin.z = Min(buffer->vertex[i].z, m_objectParam[objRank].bboxMin.z); + m_objectParam[objRank].bboxMax.x = Max(buffer->vertex[i].x, m_objectParam[objRank].bboxMax.x); + m_objectParam[objRank].bboxMax.y = Max(buffer->vertex[i].y, m_objectParam[objRank].bboxMax.y); + m_objectParam[objRank].bboxMax.z = Max(buffer->vertex[i].z, m_objectParam[objRank].bboxMax.z); + } + + m_objectParam[objRank].radius = Max(Length(m_objectParam[objRank].bboxMin), + Length(m_objectParam[objRank].bboxMax)); + } + m_objectParam[objRank].totalTriangle += buffer->totalUsed-2; + + return TRUE; +} + + +// Looking for a list of triangles. + +void CD3DEngine::ChangeLOD() +{ + D3DObjLevel1* p1; + D3DObjLevel2* p2; + D3DObjLevel3* p3; + D3DObjLevel4* p4; + int l1, l2, l3; + float oldLimit[2], newLimit[2]; + float oldTerrain, newTerrain; + + oldLimit[0] = RetLimitLOD(0, TRUE); + oldLimit[1] = RetLimitLOD(1, TRUE); + + newLimit[0] = RetLimitLOD(0, FALSE); + newLimit[1] = RetLimitLOD(1, FALSE); + + oldTerrain = m_terrainVision*m_lastClippingDistance; + newTerrain = m_terrainVision*m_clippingDistance; + + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + + if ( IsEqual(p4->min, 0.0f ) && + IsEqual(p4->max, oldLimit[0]) ) + { + p4->max = newLimit[0]; + } + else if ( IsEqual(p4->min, oldLimit[0]) && + IsEqual(p4->max, oldLimit[1]) ) + { + p4->min = newLimit[0]; + p4->max = newLimit[1]; + } + else if ( IsEqual(p4->min, oldLimit[1]) && + IsEqual(p4->max, 1000000.0f ) ) + { + p4->min = newLimit[1]; + } + else if ( IsEqual(p4->min, 0.0f ) && + IsEqual(p4->max, oldTerrain) ) + { + p4->max = newTerrain; + } + } + } + } + + m_lastDim = m_dim; + m_lastObjectDetail = m_objectDetail; + m_lastClippingDistance = m_clippingDistance; +} + +// Looking for a list of triangles. + +D3DObjLevel6* CD3DEngine::SearchTriangle(int objRank, + const D3DMATERIAL7 &mat, int state, + char* texName1, char* texName2, + float min, float max) +{ + D3DObjLevel1* p1; + D3DObjLevel2* p2; + D3DObjLevel3* p3; + D3DObjLevel4* p4; + D3DObjLevel5* p5; + D3DObjLevel6* p6; + int l1, l2, l3, l4, l5; + + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; +//? if ( strcmp(p2->texName1, texName1) != 0 || +//? strcmp(p2->texName2, texName2) != 0 ) continue; + if ( strcmp(p2->texName1, texName1) != 0 ) continue; + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + if ( p3->objRank != objRank ) continue; + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + if ( p4->min != min || + p4->max != max ) continue; + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; +//? if ( p6->state != state || + if ( (p6->state&(~(D3DSTATEDUALb|D3DSTATEDUALw))) != state || + memcmp(&p6->material, &mat, sizeof(D3DMATERIAL7)) != 0 ) continue; + return p6; + } + } + } + } + } + return 0; +} + +// Secondary changes the texture of an object. + +BOOL CD3DEngine::ChangeSecondTexture(int objRank, char* texName2) +{ + D3DObjLevel2* newp2; + D3DObjLevel1* p1; + D3DObjLevel2* p2; + D3DObjLevel3* p3; + int l1, l2; + + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + if ( strcmp(p2->texName2, texName2) == 0 ) continue; // already new + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + if ( p3->objRank != objRank ) continue; + + newp2 = AddLevel1(m_objectPointer, p2->texName1, texName2); + + if ( newp2->totalUsed >= newp2->totalPossible ) continue; // to do better!!! + newp2->table[newp2->totalUsed++] = p3; + + p2->table[l2] = 0; + } + } + return TRUE; +} + + +// Returns the number of triangles of the object. + +int CD3DEngine::RetTotalTriangles(int objRank) +{ + return m_objectParam[objRank].totalTriangle; +} + +// Return qq triangles of an object. +// qq triangles used to extract an object that explodes. +// "Percent" is between 0 and 1. + +int CD3DEngine::GetTriangles(int objRank, float min, float max, + D3DTriangle* buffer, int size, float percent) +{ + D3DObjLevel1* p1; + D3DObjLevel2* p2; + D3DObjLevel3* p3; + D3DObjLevel4* p4; + D3DObjLevel5* p5; + D3DObjLevel6* p6; + D3DVERTEX2* pv; + int l1, l2, l3, l4, l5, l6, i, rank; + + rank = 0; + i = 0; + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; +//? if ( p2->texName[0] == 0 ) continue; + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + if ( p3->objRank != objRank ) continue; + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + if ( p4->min != min || + p4->max != max ) continue; + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; + if ( p6->type == D3DTYPE6T ) + { + pv = &p6->vertex[0]; + for ( l6=0 ; l6totalUsed/3 ; l6++ ) + { + if ( (float)i/rank <= percent ) + { + if ( i >= size ) break; + buffer[i].triangle[0] = pv[0]; + buffer[i].triangle[1] = pv[1]; + buffer[i].triangle[2] = pv[2]; + buffer[i].material = p6->material; + buffer[i].state = p6->state; + strcpy(buffer[i].texName1, p2->texName1); + strcpy(buffer[i].texName2, p2->texName2); + i ++; + } + rank ++; + pv += 3; + } + } + if ( p6->type == D3DTYPE6S ) + { + pv = &p6->vertex[0]; + for ( l6=0 ; l6totalUsed-2 ; l6++ ) + { + if ( (float)i/rank <= percent ) + { + if ( i >= size ) break; + buffer[i].triangle[0] = pv[0]; + buffer[i].triangle[1] = pv[1]; + buffer[i].triangle[2] = pv[2]; + buffer[i].material = p6->material; + buffer[i].state = p6->state; + strcpy(buffer[i].texName1, p2->texName1); + strcpy(buffer[i].texName2, p2->texName2); + i ++; + } + rank ++; + pv += 1; + } + } + } + } + } + } + } + return i; +} + +// Give the box of an object. + +BOOL CD3DEngine::GetBBox(int objRank, D3DVECTOR &min, D3DVECTOR &max) +{ + min = m_objectParam[objRank].bboxMin; + max = m_objectParam[objRank].bboxMax; + return TRUE; +} + + +// Change the texture mapping for a list of triangles. + +BOOL CD3DEngine::ChangeTextureMapping(int objRank, + const D3DMATERIAL7 &mat, int state, + char* texName1, char* texName2, + float min, float max, + D3DMaping mode, + float au, float bu, + float av, float bv) +{ + D3DObjLevel6* p6; + D3DVERTEX2* pv; + int l6, nb; + + p6 = SearchTriangle(objRank, mat, state, texName1, texName2, min, max); + if ( p6 == 0 ) return FALSE; + + pv = &p6->vertex[0]; + nb = p6->totalUsed; + + if ( mode == D3DMAPPINGX ) + { + for ( l6=0 ; l6tu = pv->z*au+bu; + pv->tv = pv->y*av+bv; + pv ++; + } + } + + if ( mode == D3DMAPPINGY ) + { + for ( l6=0 ; l6tu = pv->x*au+bu; + pv->tv = pv->z*av+bv; + pv ++; + } + } + + if ( mode == D3DMAPPINGZ ) + { + for ( l6=0 ; l6tu = pv->x*au+bu; + pv->tv = pv->y*av+bv; + pv ++; + } + } + + if ( mode == D3DMAPPING1X ) + { + for ( l6=0 ; l6tu = pv->x*au+bu; + pv ++; + } + } + + if ( mode == D3DMAPPING1Y ) + { + for ( l6=0 ; l6tv = pv->y*au+bu; + pv ++; + } + } + + if ( mode == D3DMAPPING1Z ) + { + for ( l6=0 ; l6tu = pv->z*au+bu; + pv ++; + } + } + + return TRUE; +} + +// Change the texture mapping for a list of triangles +// to simulate a caterpillar that turns. +// Only the mapping as "u" is changed. +// +// pos: position on the periphery [p] +// tl: length repetitive element of the texture [t] +// ts: beginning of the texture[t] +// tt: total width of the texture [t] +// +// [p] = distance in the 3D world +// [t] = position in the texture (pixels) + +// ^ y 5 +// | 6 o---------o 4 +// | / \ +// | o o +// | 7 | | 3 +// | o current o +// | \ | / +// | 0 o---------o 2 +// | 1 +// -o-----------------------> x +// | +// +// Quand l6=1 : +// 0 1 2 3 4 ... 7 +// o--o---------o--o--o--o-//-o--o development track +// |ps| | +// <--> pe | +// <------------> +// +// Texture : +// o---------------o +// | | +// | o-o-o-o-o | +// | | | | | |<--- texture of the track +// | o-o-o-o-o | +// | | | tl | +// | ->|-|<--- | +// | | | +// o-----|---------o--> u +// | ts | | +// <-----> tt | +// <---------------> + +BOOL CD3DEngine::TrackTextureMapping(int objRank, + const D3DMATERIAL7 &mat, int state, + char* texName1, char* texName2, + float min, float max, + D3DMaping mode, float pos, float factor, + float tl, float ts, float tt) +{ + D3DObjLevel6* p6; + D3DVERTEX2* pv; + D3DVECTOR current; + float ps, pe, pps, ppe, offset; + int l6, nb, i, j, s, e; + int is[6], ie[6]; + + p6 = SearchTriangle(objRank, mat, state, texName1, texName2, min, max); + if ( p6 == 0 ) return FALSE; + + pv = &p6->vertex[0]; + nb = p6->totalUsed; + + if ( nb < 12 || nb%6 != 0 ) return FALSE; + + while ( pos < 0.0f ) + { + pos += 1000000.0f; // never negative! + } + + for ( i=0 ; i<6 ; i++ ) + { + for ( j=0 ; j<6 ; j++ ) + { + if ( pv[i].x == pv[j+6].x && + pv[i].y == pv[j+6].y ) + { + current.x = pv[i].x; // position end link + current.y = pv[i].y; + break; + } + } + } + + ps = 0.0f; // start position on the periphery + for ( l6=0 ; l6= (nb/6)-1 ) break; + for ( i=0 ; i<6 ; i++ ) + { + if ( Abs(pv[i+6].x-current.x) > 0.0001f || + Abs(pv[i+6].y-current.y) > 0.0001f ) + { + current.x = pv[i+6].x; // end next link + current.y = pv[i+6].y; + break; + } + } + ps = pe; // following start position on the periphery + pv += 6; + } + + return TRUE; +} + + +// Updates all the geometric parameters of objects. + +void CD3DEngine::UpdateGeometry() +{ + D3DObjLevel1* p1; + D3DObjLevel2* p2; + D3DObjLevel3* p3; + D3DObjLevel4* p4; + D3DObjLevel5* p5; + D3DObjLevel6* p6; + int l1, l2, l3, l4, l5, objRank, i; + + if ( !m_bUpdateGeometry ) return; + + for ( i=0 ; itotalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + objRank = p3->objRank; + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; + + for ( i=0 ; itotalUsed ; i++ ) + { + m_objectParam[objRank].bboxMin.x = Min(p6->vertex[i].x, m_objectParam[objRank].bboxMin.x); + m_objectParam[objRank].bboxMin.y = Min(p6->vertex[i].y, m_objectParam[objRank].bboxMin.y); + m_objectParam[objRank].bboxMin.z = Min(p6->vertex[i].z, m_objectParam[objRank].bboxMin.z); + m_objectParam[objRank].bboxMax.x = Max(p6->vertex[i].x, m_objectParam[objRank].bboxMax.x); + m_objectParam[objRank].bboxMax.y = Max(p6->vertex[i].y, m_objectParam[objRank].bboxMax.y); + m_objectParam[objRank].bboxMax.z = Max(p6->vertex[i].z, m_objectParam[objRank].bboxMax.z); + } + + m_objectParam[objRank].radius = Max(Length(m_objectParam[objRank].bboxMin), + Length(m_objectParam[objRank].bboxMax)); + } + } + } + } + } + + m_bUpdateGeometry = FALSE; +} + + +// Determines whether an object is visible, even partially. +// Transformation of "world" must be done​​! + +BOOL CD3DEngine::IsVisible(int objRank) +{ + D3DVECTOR center; + DWORD flags; + float radius; + + radius = m_objectParam[objRank].radius; + center = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_pD3DDevice->ComputeSphereVisibility(¢er, &radius, 1, 0, &flags); + + if ( flags & D3DSTATUS_CLIPINTERSECTIONALL ) + { + m_objectParam[objRank].bVisible = FALSE; + return FALSE; + } + m_objectParam[objRank].bVisible = TRUE; + return TRUE; +} + + +// Detects the target object with the mouse. +// Returns the rank of the object or -1. + +int CD3DEngine::DetectObject(FPOINT mouse) +{ + D3DObjLevel1* p1; + D3DObjLevel2* p2; + D3DObjLevel3* p3; + D3DObjLevel4* p4; + D3DObjLevel5* p5; + D3DObjLevel6* p6; + D3DVERTEX2* pv; + int l1, l2, l3, l4, l5, i, objRank, nearest; + float dist, min; + + min = 1000000.0f; + nearest = -1; + + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + objRank = p3->objRank; + if ( m_objectParam[objRank].type == TYPETERRAIN ) continue; + if ( !DetectBBox(objRank, mouse) ) continue; + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + if ( p4->min != 0.0f ) continue; // LOD B or C? + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; + + if ( p6->type == D3DTYPE6T ) + { + pv = &p6->vertex[0]; + for ( i=0 ; itotalUsed/3 ; i++ ) + { + if ( DetectTriangle(mouse, pv, objRank, dist) && + dist < min ) + { + min = dist; + nearest = objRank; + } + pv += 3; + } + } + if ( p6->type == D3DTYPE6S ) + { + pv = &p6->vertex[0]; + for ( i=0 ; itotalUsed-2 ; i++ ) + { + if ( DetectTriangle(mouse, pv, objRank, dist) && + dist < min ) + { + min = dist; + nearest = objRank; + } + pv += 1; + } + } + } + } + } + } + } + return nearest; +} + +// Detects whether the mouse is in a triangle. + +BOOL CD3DEngine::DetectTriangle(FPOINT mouse, D3DVERTEX2 *triangle, + int objRank, float &dist) +{ + D3DVECTOR p2D[3], p3D; + FPOINT a, b, c; + int i; + + for ( i=0 ; i<3 ; i++ ) + { + p3D.x = triangle[i].x; + p3D.y = triangle[i].y; + p3D.z = triangle[i].z; + if ( !TransformPoint(p2D[i], objRank, p3D) ) return FALSE; + } + + if ( mouse.x < p2D[0].x && + mouse.x < p2D[1].x && + mouse.x < p2D[2].x ) return FALSE; + if ( mouse.x > p2D[0].x && + mouse.x > p2D[1].x && + mouse.x > p2D[2].x ) return FALSE; + if ( mouse.y < p2D[0].y && + mouse.y < p2D[1].y && + mouse.y < p2D[2].y ) return FALSE; + if ( mouse.y > p2D[0].y && + mouse.y > p2D[1].y && + mouse.y > p2D[2].y ) return FALSE; + + a.x = p2D[0].x; + a.y = p2D[0].y; + b.x = p2D[1].x; + b.y = p2D[1].y; + c.x = p2D[2].x; + c.y = p2D[2].y; + if ( !IsInsideTriangle(a, b, c, mouse) ) return FALSE; + + dist = (p2D[0].z+p2D[1].z+p2D[2].z)/3.0f; + return TRUE; +} + +// Detects whether an object is affected by the mouse. + +BOOL CD3DEngine::DetectBBox(int objRank, FPOINT mouse) +{ + D3DVECTOR p, pp; + FPOINT min, max; + int i; + + min.x = 1000000.0f; + min.y = 1000000.0f; + max.x = -1000000.0f; + max.y = -1000000.0f; + + for ( i=0 ; i<8 ; i++ ) + { + if ( i & (1<<0) ) p.x = m_objectParam[objRank].bboxMin.x; + else p.x = m_objectParam[objRank].bboxMax.x; + if ( i & (1<<1) ) p.y = m_objectParam[objRank].bboxMin.y; + else p.y = m_objectParam[objRank].bboxMax.y; + if ( i & (1<<2) ) p.z = m_objectParam[objRank].bboxMin.z; + else p.z = m_objectParam[objRank].bboxMax.z; + if ( TransformPoint(pp, objRank, p) ) + { + if ( pp.x < min.x ) min.x = pp.x; + if ( pp.x > max.x ) max.x = pp.x; + if ( pp.y < min.y ) min.y = pp.y; + if ( pp.y > max.y ) max.y = pp.y; + } + } + + return ( mouse.x >= min.x && + mouse.x <= max.x && + mouse.y >= min.y && + mouse.y <= max.y ); +} + +// Transforms a 3D point (x, y, z) in 2D space (x, y, -) of the window. +// The coordinated p2D.z gives the distance. + +BOOL CD3DEngine::TransformPoint(D3DVECTOR &p2D, int objRank, D3DVECTOR p3D) +{ + p3D = Transform(m_objectParam[objRank].transform, p3D); + p3D = Transform(m_matView, p3D); + + if ( p3D.z < 2.0f ) return FALSE; // behind? + + p2D.x = (p3D.x/p3D.z)*m_matProj._11; + p2D.y = (p3D.y/p3D.z)*m_matProj._22; + p2D.z = p3D.z; + + p2D.x = (p2D.x+1.0f)/2.0f; // [-1..1] -> [0..1] + p2D.y = (p2D.y+1.0f)/2.0f; + + return TRUE; +} + + +// Calculating the distances between the viewpoint and the origin +// of different objects. + +void CD3DEngine::ComputeDistance() +{ + D3DVECTOR v; + int i; + float distance; + + if ( s_resol == 0 ) + { + for ( i=0 ; iIsVideo8MB() ) + { + SetGroundSpot(FALSE); + SetSkyMode(FALSE); + } + + if ( m_app->IsVideo32MB() && bFirst ) + { + SetObjectDetail(2.0f); + } +} + +// Returns the total amount of video memory for textures. + +int CD3DEngine::GetVidMemTotal() +{ + return m_app->GetVidMemTotal(); +} + +BOOL CD3DEngine::IsVideo8MB() +{ + return m_app->IsVideo8MB(); +} + +BOOL CD3DEngine::IsVideo32MB() +{ + return m_app->IsVideo32MB(); +} + + +// Perform the list of all graphics devices available. + +BOOL CD3DEngine::EnumDevices(char *bufDevices, int lenDevices, + char *bufModes, int lenModes, + int &totalDevices, int &selectDevices, + int &totalModes, int &selectModes) +{ + return m_app->EnumDevices(bufDevices, lenDevices, + bufModes, lenModes, + totalDevices, selectDevices, + totalModes, selectModes); +} + +BOOL CD3DEngine::RetFullScreen() +{ + return m_app->RetFullScreen(); +} + +BOOL CD3DEngine::ChangeDevice(char *device, char *mode, BOOL bFull) +{ + return m_app->ChangeDevice(device, mode, bFull); +} + + + +D3DMATRIX* CD3DEngine::RetMatView() +{ + return &m_matView; +} + +D3DMATRIX* CD3DEngine::RetMatLeftView() +{ + return &m_matLeftView; +} + +D3DMATRIX* CD3DEngine::RetMatRightView() +{ + return &m_matRightView; +} + + +// Specifies the location and direction of view. + +void CD3DEngine::SetViewParams(const D3DVECTOR &vEyePt, + const D3DVECTOR &vLookatPt, + const D3DVECTOR &vUpVec, + FLOAT fEyeDistance) +{ +#if 0 + m_eyePt = vEyePt; + + // Adjust camera position for left or right eye along the axis + // perpendicular to the view direction vector and the up vector. + D3DVECTOR vView = (vLookatPt) - (vEyePt); + vView = CrossProduct( vView, (vUpVec) ); + vView = Normalize( vView ) * fEyeDistance; + + D3DVECTOR vLeftEyePt = (vEyePt) + vView; + D3DVECTOR vRightEyePt = (vEyePt) - vView; + + // Set the view matrices + D3DUtil_SetViewMatrix( m_matLeftView, (D3DVECTOR)vLeftEyePt, (D3DVECTOR)vLookatPt, (D3DVECTOR)vUpVec ); + D3DUtil_SetViewMatrix( m_matRightView, (D3DVECTOR)vRightEyePt, (D3DVECTOR)vLookatPt, (D3DVECTOR)vUpVec ); + D3DUtil_SetViewMatrix( m_matView, (D3DVECTOR)vEyePt, (D3DVECTOR)vLookatPt, (D3DVECTOR)vUpVec ); +#else + m_eyePt = vEyePt; + m_lookatPt = vLookatPt; + m_eyeDirH = RotateAngle(vEyePt.x-vLookatPt.x, vEyePt.z-vLookatPt.z); + m_eyeDirV = RotateAngle(Length2d(vEyePt, vLookatPt), vEyePt.y-vLookatPt.y); + + D3DUtil_SetViewMatrix(m_matView, (D3DVECTOR&)vEyePt, (D3DVECTOR&)vLookatPt, (D3DVECTOR&)vUpVec); + + if ( m_sound == 0 ) + { + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + } + m_sound->SetListener(vEyePt, vLookatPt); +#endif +} + + +// Specifies the transformation matrix of an object. + +BOOL CD3DEngine::SetObjectTransform(int objRank, const D3DMATRIX &transform) +{ + if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; + + m_objectParam[objRank].transform = transform; + return TRUE; +} + +// Gives the transformation matrix of an object. + +BOOL CD3DEngine::GetObjectTransform(int objRank, D3DMATRIX &transform) +{ + if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; + + transform = m_objectParam[objRank].transform; + return TRUE; +} + +// Specifies the type of an object. + +BOOL CD3DEngine::SetObjectType(int objRank, D3DTypeObj type) +{ + if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; + + m_objectParam[objRank].type = type; + return TRUE; +} + +// Returns the type of an object. + +D3DTypeObj CD3DEngine::RetObjectType(int objRank) +{ + return m_objectParam[objRank].type; +} + +// Specifies the transparency of an object. + +BOOL CD3DEngine::SetObjectTransparency(int objRank, float value) +{ + if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; + + m_objectParam[objRank].transparency = value; + return TRUE; +} + + +// Allocates a table for shade, if necessary. + +BOOL CD3DEngine::ShadowCreate(int objRank) +{ + int i; + + // Already allocated? + if ( m_objectParam[objRank].shadowRank != -1 ) return TRUE; + + for ( i=0 ; i= D3DMAXOBJECT ) return FALSE; + + int i = m_objectParam[objRank].shadowRank; + if ( i == -1 ) return FALSE; + + m_shadow[i].bHide = bHide; + return TRUE; +} + +// Specifies the type of the shadow of the object. + +BOOL CD3DEngine::SetObjectShadowType(int objRank, D3DShadowType type) +{ + if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; + + int i = m_objectParam[objRank].shadowRank; + if ( i == -1 ) return FALSE; + + m_shadow[i].type = type; + return TRUE; +} + +// Specifies the position of the shadow of the object. + +BOOL CD3DEngine::SetObjectShadowPos(int objRank, const D3DVECTOR &pos) +{ + if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; + + int i = m_objectParam[objRank].shadowRank; + if ( i == -1 ) return FALSE; + + m_shadow[i].pos = pos; + return TRUE; +} + +// Specifies the normal shadow to the field of the object. + +BOOL CD3DEngine::SetObjectShadowNormal(int objRank, const D3DVECTOR &n) +{ + if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; + + int i = m_objectParam[objRank].shadowRank; + if ( i == -1 ) return FALSE; + + m_shadow[i].normal = n; + return TRUE; +} + +// Specifies the angle of the shadow of the object. + +BOOL CD3DEngine::SetObjectShadowAngle(int objRank, float angle) +{ + if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; + + int i = m_objectParam[objRank].shadowRank; + if ( i == -1 ) return FALSE; + + m_shadow[i].angle = angle; + return TRUE; +} + +// Specifies the radius of the shadow of the object. + +BOOL CD3DEngine::SetObjectShadowRadius(int objRank, float radius) +{ + if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; + + int i = m_objectParam[objRank].shadowRank; + if ( i == -1 ) return FALSE; + + m_shadow[i].radius = radius; + return TRUE; +} + +// Returns the radius of the shadow of the object. + +float CD3DEngine::RetObjectShadowRadius(int objRank) +{ + if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return 0.0f; + + int i = m_objectParam[objRank].shadowRank; + if ( i == -1 ) return FALSE; + + return m_shadow[i].radius; +} + +// Specifies the intensity of the shadow of the object. + +BOOL CD3DEngine::SetObjectShadowIntensity(int objRank, float intensity) +{ + if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; + + int i = m_objectParam[objRank].shadowRank; + if ( i == -1 ) return FALSE; + + m_shadow[i].intensity = intensity; + return TRUE; +} + +// Specifies the height of the shadow of the object. + +BOOL CD3DEngine::SetObjectShadowHeight(int objRank, float h) +{ + if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return FALSE; + + int i = m_objectParam[objRank].shadowRank; + if ( i == -1 ) return FALSE; + + m_shadow[i].height = h; + return TRUE; +} + + +// Clears all marks on the ground. + +void CD3DEngine::GroundSpotFlush() +{ + LPDIRECTDRAWSURFACE7 surface; + DDSURFACEDESC2 ddsd; + WORD* pbSurf; + char texName[20]; + int s, y; + + ZeroMemory(m_groundSpot, sizeof(D3DGroundSpot)*D3DMAXGROUNDSPOT); + m_bFirstGroundSpot = TRUE; // drawing power first + + for ( s=0 ; s<16 ; s++ ) + { + sprintf(texName, "shadow%.2d.tga", s); + surface = D3DTextr_GetSurface(texName); + if ( surface == 0 ) continue; + + ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2)); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + if ( surface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) != DD_OK ) continue; + + if ( ddsd.ddpfPixelFormat.dwRGBBitCount != 16 ) continue; + + for ( y=0 ; y<(int)ddsd.dwHeight ; y++ ) + { + pbSurf = (WORD*)ddsd.lpSurface; + pbSurf += ddsd.lPitch*y/2; + memset(pbSurf, -1, ddsd.lPitch); // all blank + } + + surface->Unlock(NULL); + } +} + +// Allocates a table for a mark on the ground, if necessary. + +int CD3DEngine::GroundSpotCreate() +{ + int i; + + for ( i=0 ; i 1 ) rank = 1; + + if ( m_rankView == 0 && rank == 1 ) // enters the water? + { + m_light->AdaptLightColor(m_waterAddColor, +1.0f); + } + + if ( m_rankView == 1 && rank == 0 ) // out of the water? + { + m_light->AdaptLightColor(m_waterAddColor, -1.0f); + } + + m_rankView = rank; +} + +int CD3DEngine::RetRankView() +{ + return m_rankView; +} + +// Whether to draw the world from the interface. + +void CD3DEngine::SetDrawWorld(BOOL bDraw) +{ + m_bDrawWorld = bDraw; +} + +// Whether to draw the world on the interface. + +void CD3DEngine::SetDrawFront(BOOL bDraw) +{ + m_bDrawFront = bDraw; +} + +// Color management ambient. +// color = 0x00rrggbb +// rr: red +// gg: green +// bb: blue + +void CD3DEngine::SetAmbiantColor(D3DCOLOR color, int rank) +{ + m_ambiantColor[rank] = color; +} + +D3DCOLOR CD3DEngine::RetAmbiantColor(int rank) +{ + return m_ambiantColor[rank]; +} + + +// Color management under water. + +void CD3DEngine::SetWaterAddColor(D3DCOLORVALUE color) +{ + m_waterAddColor = color; +} + +D3DCOLORVALUE CD3DEngine::RetWaterAddColor() +{ + return m_waterAddColor; +} + + +// Management of the fog color. + +void CD3DEngine::SetFogColor(D3DCOLOR color, int rank) +{ + m_fogColor[rank] = color; +} + +D3DCOLOR CD3DEngine::RetFogColor(int rank) +{ + return m_fogColor[rank]; +} + + +// Management of the depth of field. +// Beyond this distance, nothing is visible. +// Shortly (according SetFogStart), one enters the fog. + +void CD3DEngine::SetDeepView(float length, int rank, BOOL bRef) +{ + if ( bRef ) + { + length *= m_clippingDistance; + } + + m_deepView[rank] = length; +} + +float CD3DEngine::RetDeepView(int rank) +{ + return m_deepView[rank]; +} + + +// Management the start of fog. +// With 0.0, the fog from the point of view (fog max). +// With 1.0, the fog from the depth of field (no fog). + +void CD3DEngine::SetFogStart(float start, int rank) +{ + m_fogStart[rank] = start; +} + +float CD3DEngine::RetFogStart(int rank) +{ + return m_fogStart[rank]; +} + + +// Gives the background image to use. + +void CD3DEngine::SetBackground(char *name, D3DCOLOR up, D3DCOLOR down, + D3DCOLOR cloudUp, D3DCOLOR cloudDown, + BOOL bFull, BOOL bQuarter) +{ + strcpy(m_backgroundName, name); + m_backgroundColorUp = up; + m_backgroundColorDown = down; + m_backgroundCloudUp = cloudUp; + m_backgroundCloudDown = cloudDown; + m_bBackgroundFull = bFull; + m_bBackgroundQuarter = bQuarter; +} + +// Gives the background image used. + +void CD3DEngine::RetBackground(char *name, D3DCOLOR &up, D3DCOLOR &down, + D3DCOLOR &cloudUp, D3DCOLOR &cloudDown, + BOOL &bFull, BOOL &bQuarter) +{ + strcpy(name, m_backgroundName); + up = m_backgroundColorUp; + down = m_backgroundColorDown; + cloudUp = m_backgroundCloudUp; + cloudDown = m_backgroundCloudDown; + bFull = m_bBackgroundFull; + bQuarter = m_bBackgroundQuarter; +} + +// Gives the foreground image to use. + +void CD3DEngine::SetFrontsizeName(char *name) +{ + if ( m_frontsizeName[0] != 0 ) + { + FreeTexture(m_frontsizeName); + } + + strcpy(m_frontsizeName, name); +} + +// Specifies whether to draw the foreground. + +void CD3DEngine::SetOverFront(BOOL bFront) +{ + m_bOverFront = bFront; +} + +// Gives color to the foreground. + +void CD3DEngine::SetOverColor(D3DCOLOR color, int mode) +{ + m_overColor = color; + m_overMode = mode; +} + + + +// Management of the particle density. + +void CD3DEngine::SetParticuleDensity(float value) +{ + if ( value < 0.0f ) value = 0.0f; + if ( value > 2.0f ) value = 2.0f; + m_particuleDensity = value; +} + +float CD3DEngine::RetParticuleDensity() +{ + return m_particuleDensity; +} + +float CD3DEngine::ParticuleAdapt(float factor) +{ + if ( m_particuleDensity == 0.0f ) + { + return 1000000.0f; + } + return factor/m_particuleDensity; +} + +// Management of the distance of clipping. + +void CD3DEngine::SetClippingDistance(float value) +{ + if ( value < 0.5f ) value = 0.5f; + if ( value > 2.0f ) value = 2.0f; + m_clippingDistance = value; +} + +float CD3DEngine::RetClippingDistance() +{ + return m_clippingDistance; +} + +// Management of objects detals. + +void CD3DEngine::SetObjectDetail(float value) +{ + if ( value < 0.0f ) value = 0.0f; + if ( value > 2.0f ) value = 2.0f; + m_objectDetail = value; +} + +float CD3DEngine::RetObjectDetail() +{ + return m_objectDetail; +} + +// The amount of management objects gadgets. + +void CD3DEngine::SetGadgetQuantity(float value) +{ + if ( value < 0.0f ) value = 0.0f; + if ( value > 1.0f ) value = 1.0f; + + m_gadgetQuantity = value; +} + +float CD3DEngine::RetGadgetQuantity() +{ + return m_gadgetQuantity; +} + +// Managing the quality of textures. + +void CD3DEngine::SetTextureQuality(int value) +{ + if ( value < 0 ) value = 0; + if ( value > 2 ) value = 2; + + if ( value != m_textureQuality ) + { + m_textureQuality = value; + LoadAllTexture(); + } +} + +int CD3DEngine::RetTextureQuality() +{ + return m_textureQuality; +} + + +// Management mode of toto. + +void CD3DEngine::SetTotoMode(BOOL bPresent) +{ + m_bTotoMode = bPresent; +} + +BOOL CD3DEngine::RetTotoMode() +{ + return m_bTotoMode; +} + + +// Managing the mode of foreground. + +void CD3DEngine::SetLensMode(BOOL bPresent) +{ + m_bLensMode = bPresent; +} + +BOOL CD3DEngine::RetLensMode() +{ + return m_bLensMode; +} + + +// Managing the mode of water. + +void CD3DEngine::SetWaterMode(BOOL bPresent) +{ + m_bWaterMode = bPresent; +} + +BOOL CD3DEngine::RetWaterMode() +{ + return m_bWaterMode; +} + + +// Managing the mode of sky. + +void CD3DEngine::SetSkyMode(BOOL bPresent) +{ + m_bSkyMode = bPresent; +} + +BOOL CD3DEngine::RetSkyMode() +{ + return m_bSkyMode; +} + + +// Managing the mode of background. + +void CD3DEngine::SetBackForce(BOOL bPresent) +{ + m_bBackForce = bPresent; +} + +BOOL CD3DEngine::RetBackForce() +{ + return m_bBackForce; +} + + +// Managing the mode of planets. + +void CD3DEngine::SetPlanetMode(BOOL bPresent) +{ + m_bPlanetMode = bPresent; +} + +BOOL CD3DEngine::RetPlanetMode() +{ + return m_bPlanetMode; +} + + +// Managing the mode of dymanic lights. + +void CD3DEngine::SetLightMode(BOOL bPresent) +{ + m_bLightMode = bPresent; +} + +BOOL CD3DEngine::RetLightMode() +{ + return m_bLightMode; +} + + +// Management of the indentation mode while editing (CEdit). + +void CD3DEngine::SetEditIndentMode(BOOL bAuto) +{ + m_bEditIndentMode = bAuto; +} + +BOOL CD3DEngine::RetEditIndentMode() +{ + return m_bEditIndentMode; +} + + +// Management in advance of a tab when editing (CEdit). + +void CD3DEngine::SetEditIndentValue(int value) +{ + m_editIndentValue = value; +} + +int CD3DEngine::RetEditIndentValue() +{ + return m_editIndentValue; +} + + +void CD3DEngine::SetSpeed(float speed) +{ + m_speed = speed; +} + +float CD3DEngine::RetSpeed() +{ + return m_speed; +} + + +void CD3DEngine::SetTracePrecision(float factor) +{ + m_tracePrecision = factor; +} + +float CD3DEngine::RetTracePrecision() +{ + return m_tracePrecision; +} + + +// Updates the scene after a change of parameters. + +void CD3DEngine::ApplyChange() +{ + m_deepView[0] /= m_lastClippingDistance; + m_deepView[1] /= m_lastClippingDistance; + + SetFocus(m_focus); + ChangeLOD(); + + m_deepView[0] *= m_clippingDistance; + m_deepView[1] *= m_clippingDistance; +} + + + +// Returns the point of view of the user. + +D3DVECTOR CD3DEngine::RetEyePt() +{ + return m_eyePt; +} + +D3DVECTOR CD3DEngine::RetLookatPt() +{ + return m_lookatPt; +} + +float CD3DEngine::RetEyeDirH() +{ + return m_eyeDirH; +} + +float CD3DEngine::RetEyeDirV() +{ + return m_eyeDirV; +} + +POINT CD3DEngine::RetDim() +{ + return m_dim; +} + + +// Generates an image name of the watch. + +void QuarterName(char *buffer, char *name, int quarter) +{ + while ( *name != 0 ) + { + if ( *name == '.' ) + { + *buffer++ = 'a'+quarter; + } + *buffer++ = *name++; + } + *buffer++ = 0; +} + +// Frees texture. + +BOOL CD3DEngine::FreeTexture(char* name) +{ + if ( name[0] == 0 ) return TRUE; + + if ( D3DTextr_DestroyTexture(name) != S_OK ) + { + return FALSE; + } + return TRUE; +} + +// Load a texture. + +BOOL CD3DEngine::LoadTexture(char* name, int stage) +{ + DWORD mode; + + if ( name[0] == 0 ) return TRUE; + + if ( D3DTextr_GetSurface(name) == NULL ) + { + if ( strstr(name, ".tga") == 0 ) + { + mode = 0; + } + else + { + mode = D3DTEXTR_CREATEWITHALPHA; + } + + if ( D3DTextr_CreateTextureFromFile(name, stage, mode) != S_OK ) + { + return FALSE; + } + + if ( D3DTextr_Restore(name, m_pD3DDevice) != S_OK ) + { + return FALSE; + } + } + return TRUE; +} + +// Load all the textures of the scene. + +BOOL CD3DEngine::LoadAllTexture() +{ + D3DObjLevel1* p1; + D3DObjLevel2* p2; + int l1, i; + char name[50]; + BOOL bOK = TRUE; + +#if _POLISH + LoadTexture("textp.tga"); +#else + LoadTexture("text.tga"); +#endif + LoadTexture("mouse.tga"); + LoadTexture("button1.tga"); + LoadTexture("button2.tga"); + LoadTexture("button3.tga"); + LoadTexture("effect00.tga"); + LoadTexture("effect01.tga"); + LoadTexture("effect02.tga"); + LoadTexture("map.tga"); + + if ( m_backgroundName[0] != 0 ) + { + if ( m_bBackgroundQuarter ) // image into 4 pieces? + { + for ( i=0 ; i<4 ; i++ ) + { + QuarterName(name, m_backgroundName, i); + LoadTexture(name); + } + } + else + { + LoadTexture(m_backgroundName); + } + } + if ( m_frontsizeName[0] != 0 ) + { + LoadTexture(m_frontsizeName); + } + + m_planet->LoadTexture(); + + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + + if ( p2 == 0 || p2->texName1[0] != 0 ) + { + if ( !LoadTexture(p2->texName1, 0) ) bOK = FALSE; + } + + if ( p2 == 0 || p2->texName2[0] != 0 ) + { + if ( !LoadTexture(p2->texName2, 1) ) bOK = FALSE; + } + } + return bOK; +} + + +// Called during initial app startup, this function performs all the +// permanent initialization. + +HRESULT CD3DEngine::OneTimeSceneInit() +{ + return S_OK; +} + + +// Updated after creating objects. + +void CD3DEngine::Update() +{ + ComputeDistance(); + UpdateGeometry(); +} + +// Called once per frame, the call is the entry point for animating +// the scene. + +HRESULT CD3DEngine::FrameMove(float rTime) +{ + m_light->FrameLight(rTime); + m_particule->FrameParticule(rTime); + ComputeDistance(); + UpdateGeometry(); + + if ( m_groundMark.bUsed ) + { + if ( m_groundMark.phase == 1 ) // growing? + { + m_groundMark.intensity += rTime*(1.0f/m_groundMark.delay[0]); + if ( m_groundMark.intensity >= 1.0f ) + { + m_groundMark.intensity = 1.0f; + m_groundMark.fix = 0.0f; + m_groundMark.phase = 2; + } + } + else if ( m_groundMark.phase == 2 ) // fixed? + { + m_groundMark.fix += rTime*(1.0f/m_groundMark.delay[1]); + if ( m_groundMark.fix >= 1.0f ) + { + m_groundMark.phase = 3; + } + } + else if ( m_groundMark.phase == 3 ) // decay? + { + m_groundMark.intensity -= rTime*(1.0f/m_groundMark.delay[2]); + if ( m_groundMark.intensity < 0.0f ) + { + m_groundMark.intensity = 0.0f; + m_groundMark.phase = 0; + m_groundMark.bUsed = FALSE; + } + } + } + + if ( m_sound == 0 ) + { + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + } + m_sound->FrameMove(rTime); + + return S_OK; +} + +// Evolved throughout the game + +void CD3DEngine::StepSimul(float rTime) +{ + m_app->StepSimul(rTime); +} + + + +// Changes the state associated with a material. +// (*) Does not work without this instruction, mystery! + +void CD3DEngine::SetState(int state, D3DCOLOR color) +{ + BOOL bSecond; + + if ( state == m_lastState && + color == m_lastColor ) return; + m_lastState = state; + m_lastColor = color; + + if ( m_alphaMode != 1 && (state & D3DSTATEALPHA) ) + { + state &= ~D3DSTATEALPHA; + + if ( m_alphaMode == 2 ) + { + state |= D3DSTATETTb; + } + } + + if ( state & D3DSTATETTb ) // The transparent black texture? + { + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_blackSrcBlend[1]); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_blackDestBlend[1]); +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, table_blend[debug_blend1]); +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, table_blend[debug_blend2]); + + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, color); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); // (*) + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + } + else if ( state & D3DSTATETTw ) // The transparent white texture? + { + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_whiteSrcBlend[1]); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_whiteDestBlend[1]); +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, table_blend[debug_blend3]); +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, table_blend[debug_blend4]); + + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, ~color); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_ADD); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); // (*) + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + } + else if ( state & D3DSTATETCb ) // The transparent black color? + { + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_blackSrcBlend[1]); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_blackDestBlend[1]); +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, table_blend[debug_blend1]); +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, table_blend[debug_blend2]); + + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, color); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + } + else if ( state & D3DSTATETCw ) // The transparent white color? + { + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_whiteSrcBlend[1]); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_whiteDestBlend[1]); +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, table_blend[debug_blend3]); +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, table_blend[debug_blend4]); + + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, ~color); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + } + else if ( state & D3DSTATETD ) // diffuse color as transparent? + { + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_diffuseSrcBlend[1]); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_diffuseDestBlend[1]); + + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + } + else if ( state & D3DSTATEALPHA ) // image with alpha channel? + { + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHAFUNC, D3DCMP_GREATER); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHAREF, (DWORD)(128)); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_alphaSrcBlend[1]); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_alphaSrcBlend[1]); + + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, color); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + } + else // normal ? + { + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE); + + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + } + + if ( state & D3DSTATEFOG ) + { + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE); + } + + bSecond = m_bGroundSpot|m_bDirty; + if ( !m_bGroundSpot && (state & D3DSTATESECOND) != 0 ) bSecond = FALSE; + if ( !m_bDirty && (state & D3DSTATESECOND) == 0 ) bSecond = FALSE; + + if ( (state & D3DSTATEDUALb) && bSecond ) + { + m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + m_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + m_pD3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + } + else if ( (state & D3DSTATEDUALw) && bSecond ) + { + m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD); + m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + m_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + m_pD3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + } + else + { + m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + m_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + } + + if ( state & D3DSTATEWRAP ) + { +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_WRAP0, D3DWRAP_U|D3DWRAP_V); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); + m_pD3DDevice->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); + } + else if ( state & D3DSTATECLAMP ) + { +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_WRAP0, 0); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); + m_pD3DDevice->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); + } + else + { +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_WRAP0, 0); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); + m_pD3DDevice->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); + } + + if ( state & D3DSTATE2FACE ) + { + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); + } + else + { + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CCW); + } + + if ( state & D3DSTATELIGHT ) + { + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); + } + else + { + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, m_ambiantColor[m_rankView]); + } +} + +// Specifies a texture to use. + +void CD3DEngine::SetTexture(char *name, int stage) +{ +//? if ( stage == 1 && !m_bDirty ) return; +//? if ( stage == 1 && !m_bShadow ) return; + + if ( strcmp(name, m_lastTexture[stage]) == 0 ) return; + strcpy(m_lastTexture[stage], name); + + m_pD3DDevice->SetTexture(stage, D3DTextr_GetSurface(name)); +} + +// Specifies the material to use. + +void CD3DEngine::SetMaterial(const D3DMATERIAL7 &mat) +{ + if ( memcmp(&mat, &m_lastMaterial, sizeof(D3DMATERIAL7)) == 0 ) return; + m_lastMaterial = mat; + + m_pD3DDevice->SetMaterial(&m_lastMaterial); +} + + +// Deletes a point in a surface (draw in white). + +inline void ClearDot(DDSURFACEDESC2* ddsd, int x, int y) +{ + WORD* pbSurf; + + if ( ddsd->ddpfPixelFormat.dwRGBBitCount != 16 ) return; + + pbSurf = (WORD*)ddsd->lpSurface; + pbSurf += ddsd->lPitch*y/2; + pbSurf += x; + + *pbSurf = 0xffff; // white +} + +// Deletes a point in a surface (draw in white) + +void AddDot(DDSURFACEDESC2* ddsd, int x, int y, D3DCOLORVALUE color) +{ + WORD* pbSurf; + WORD r,g,b, w; + + if ( ddsd->ddpfPixelFormat.dwRGBBitCount != 16 ) return; + + if ( color.r < 0.0f ) color.r = 0.0f; + if ( color.r > 1.0f ) color.r = 1.0f; + r = (int)(color.r*32.0f); + if ( r >= 32 ) r = 31; // 5 bits + + if ( color.g < 0.0f ) color.g = 0.0f; + if ( color.g > 1.0f ) color.g = 1.0f; + g = (int)(color.g*32.0f); + if ( g >= 32 ) g = 31; // 5 bits + + if ( color.b < 0.0f ) color.b = 0.0f; + if ( color.b > 1.0f ) color.b = 1.0f; + b = (int)(color.b*32.0f); + if ( b >= 32 ) b = 31; // 5 bits + + if ( ddsd->ddpfPixelFormat.dwRBitMask == 0xf800 ) // 565 ? + { + w = (r<<11)|(g<<6)|b; + } + else if ( ddsd->ddpfPixelFormat.dwRBitMask == 0x7c00 ) // 555 ? + { + w = (r<<10)|(g<<5)|b; + } + else + { + w = -1; // blank + } + + pbSurf = (WORD*)ddsd->lpSurface; + pbSurf += ddsd->lPitch*y/2; + pbSurf += x; + + *pbSurf &= w; +} + +// Displays a point in a surface. + +void SetDot(DDSURFACEDESC2* ddsd, int x, int y, D3DCOLORVALUE color) +{ + if ( ddsd->ddpfPixelFormat.dwRGBBitCount == 16 ) + { + WORD* pbSurf; + WORD r,g,b, w; + + if ( color.r < 0.0f ) color.r = 0.0f; + if ( color.r > 1.0f ) color.r = 1.0f; + if ( color.g < 0.0f ) color.g = 0.0f; + if ( color.g > 1.0f ) color.g = 1.0f; + if ( color.b < 0.0f ) color.b = 0.0f; + if ( color.b > 1.0f ) color.b = 1.0f; + + r = (int)(color.r*32.0f); + g = (int)(color.g*32.0f); + b = (int)(color.b*32.0f); + + if ( r >= 32 ) r = 31; // 5 bits + if ( g >= 32 ) g = 31; // 5 bits + if ( b >= 32 ) b = 31; // 5 bits + + if ( ddsd->ddpfPixelFormat.dwRBitMask == 0xf800 ) // 565 ? + { + w = (r<<11)|(g<<6)|b; + } + else if ( ddsd->ddpfPixelFormat.dwRBitMask == 0x7c00 ) // 555 ? + { + w = (r<<10)|(g<<5)|b; + } + else + { + w = -1; // blank + } + + pbSurf = (WORD*)ddsd->lpSurface; + pbSurf += ddsd->lPitch*y/2; + pbSurf += x; + + *pbSurf = w; + } + + if ( ddsd->ddpfPixelFormat.dwRGBBitCount == 32 ) // image .tga ? + { + LONG* pbSurf; + LONG r,g,b, w; + + if ( color.r < 0.0f ) color.r = 0.0f; + if ( color.r > 1.0f ) color.r = 1.0f; + if ( color.g < 0.0f ) color.g = 0.0f; + if ( color.g > 1.0f ) color.g = 1.0f; + if ( color.b < 0.0f ) color.b = 0.0f; + if ( color.b > 1.0f ) color.b = 1.0f; + + r = (int)(color.r*256.0f); + g = (int)(color.g*256.0f); + b = (int)(color.b*256.0f); + + if ( r >= 256 ) r = 255; // 8 bits + if ( g >= 256 ) g = 255; // 8 bits + if ( b >= 256 ) b = 255; // 8 bits + + if ( ddsd->ddpfPixelFormat.dwRBitMask == 0xff0000 ) + { + w = (r<<16)|(g<<8)|b; + + pbSurf = (LONG*)ddsd->lpSurface; + pbSurf += ddsd->lPitch*y/4; + pbSurf += x; + + *pbSurf &= 0xff000000; // keeps alpha channel + *pbSurf |= w; + } + } +} + +// Gives a point in a surface. + +D3DCOLORVALUE GetDot(DDSURFACEDESC2* ddsd, int x, int y) +{ + D3DCOLORVALUE color; + + if ( ddsd->ddpfPixelFormat.dwRGBBitCount == 16 ) + { + WORD* pbSurf; + WORD r,g,b, w; + + pbSurf = (WORD*)ddsd->lpSurface; + pbSurf += ddsd->lPitch*y/2; + pbSurf += x; + + w = *pbSurf; + + if ( ddsd->ddpfPixelFormat.dwRBitMask == 0xf800 ) // 565 ? + { + r = (w>>10)&0x003e; + g = (w>> 5)&0x003f; + b = (w<< 1)&0x003e; + } + else if ( ddsd->ddpfPixelFormat.dwRBitMask == 0x7c00 ) // 555 ? + { + r = (w>> 9)&0x003e; + g = (w>> 4)&0x003e; + b = (w<< 1)&0x003e; + } + else + { + r = 0; + g = 0; + b = 0; // black + } + + color.r = (float)r/63.0f; + color.g = (float)g/63.0f; + color.b = (float)b/63.0f; + color.a = 0.0f; + return color; + } + + if ( ddsd->ddpfPixelFormat.dwRGBBitCount == 32 ) // image .tga ? + { + LONG* pbSurf; + LONG r,g,b, w; + + pbSurf = (LONG*)ddsd->lpSurface; + pbSurf += ddsd->lPitch*y/4; + pbSurf += x; + + w = *pbSurf; + + if ( ddsd->ddpfPixelFormat.dwRBitMask == 0xff0000 ) + { + r = (w>>16)&0x00ff; + g = (w>> 8)&0x00ff; + b = (w<< 0)&0x00ff; + } + else + { + r = 0; + g = 0; + b = 0; // black + } + + color.r = (float)r/255.0f; + color.g = (float)g/255.0f; + color.b = (float)b/255.0f; + color.a = 0.0f; + return color; + } + + color.r = 0.0f; + color.g = 0.0f; + color.b = 0.0f; + color.a = 0.0f; // black + return color; +} + +// Draw all the shadows. + +// There is a pixel collection around each of the 16 surfaces: +// +// |<----------------------->|<----------------------->|<---- ... +// 0 | 1 2 253 254|255 | +// |---|---|---|-- ... --|---|---|---| | +// 0 | 1 2 253 254|255 +// |---|---|---|-- ... --|---|---|---| +// +// So we draw in 254x254 pixels surfaces. +// The pixel margin around it is drawn twice (in two adjacent surfaces), +// so that the filter produces the same results! + +void CD3DEngine::RenderGroundSpot() +{ + LPDIRECTDRAWSURFACE7 surface; + DDSURFACEDESC2 ddsd; + WORD* pbSurf; + D3DCOLORVALUE color; + D3DVECTOR pos; + FPOINT min, max; + int s, i, j, dot, ix, iy, y; + float tu, tv, cx, cy, px, py, ppx, ppy; + float intensity, level; + char texName[20]; + BOOL bClear, bSet; + + if ( !m_bFirstGroundSpot && + m_groundMark.drawPos.x == m_groundMark.pos.x && + m_groundMark.drawPos.z == m_groundMark.pos.z && + m_groundMark.drawRadius == m_groundMark.radius && + m_groundMark.drawIntensity == m_groundMark.intensity ) return; + + for ( s=0 ; s<16 ; s++ ) + { + min.x = (s%4)*254.0f-1.0f; // 1 pixel cover + min.y = (s/4)*254.0f-1.0f; + max.x = min.x+254.0f+2.0f; + max.y = min.y+254.0f+2.0f; + + bClear = FALSE; + bSet = FALSE; + + // Calculate the area to be erased. + dot = (int)(m_groundMark.drawRadius/2.0f); + + tu = (m_groundMark.drawPos.x+1600.0f)/3200.0f; + tv = (m_groundMark.drawPos.z+1600.0f)/3200.0f; // 0..1 + + cx = (tu*254.0f*4.0f)-0.5f; + cy = (tv*254.0f*4.0f)-0.5f; + + if ( dot == 0 ) + { + cx += 0.5f; + cy += 0.5f; + } + + px = cx-Mod(cx, 1.0f); + py = cy-Mod(cy, 1.0f); // multiple of 1 + + if ( m_bFirstGroundSpot || + ( m_groundMark.drawRadius != 0.0f && + px+dot >= min.x && py+dot >= min.y && + px-dot <= max.x && py-dot <= max.y ) ) + { + bClear = TRUE; + } + + // Calculate the area to draw. + dot = (int)(m_groundMark.radius/2.0f); + + tu = (m_groundMark.pos.x+1600.0f)/3200.0f; + tv = (m_groundMark.pos.z+1600.0f)/3200.0f; // 0..1 + + cx = (tu*254.0f*4.0f)-0.5f; + cy = (tv*254.0f*4.0f)-0.5f; + + if ( dot == 0 ) + { + cx += 0.5f; + cy += 0.5f; + } + + px = cx-Mod(cx, 1.0f); + py = cy-Mod(cy, 1.0f); // multiple of 1 + + if ( m_groundMark.bUsed && + px+dot >= min.x && py+dot >= min.y && + px-dot <= max.x && py-dot <= max.y ) + { + bSet = TRUE; + } + + if ( bClear || bSet ) + { + // Load the song. + sprintf(texName, "shadow%.2d.tga", s); + surface = D3DTextr_GetSurface(texName); + if ( surface == 0 ) continue; + + ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2)); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + if ( surface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) != DD_OK ) continue; + + // Clears in blank whole piece. + if ( ddsd.ddpfPixelFormat.dwRGBBitCount == 16 ) + { + for ( y=0 ; y<(int)ddsd.dwHeight ; y++ ) + { + pbSurf = (WORD*)ddsd.lpSurface; + pbSurf += ddsd.lPitch*y/2; + memset(pbSurf, -1, ddsd.lPitch); // all blank + } + } + + // Draw the new shadows. + for ( i=0 ; i max.x || py-dot > max.y ) continue; + + for ( iy=-dot ; iy<=dot ; iy++ ) + { + for ( ix=-dot ; ix<=dot ; ix++ ) + { + ppx = px+ix; + ppy = py+iy; + + if ( ppx < min.x || ppy < min.y || + ppx >= max.x || ppy >= max.y ) continue; + + if ( dot == 0 ) + { + intensity = 0.0f; + } + else + { + intensity = Length(ppx-cx, ppy-cy)/dot; + //? intensity = powf(intensity, m_groundSpot[i].smooth); + } + + color.r = m_groundSpot[i].color.r+intensity; + color.g = m_groundSpot[i].color.g+intensity; + color.b = m_groundSpot[i].color.b+intensity; + + ppx -= min.x; // on the texture + ppy -= min.y; + AddDot(&ddsd, (int)ppx, (int)ppy, color); + } + } + } + else + { + for ( iy=0 ; iy<256 ; iy++ ) + { + for ( ix=0 ; ix<256 ; ix++ ) + { + pos.x = (256.0f*(s%4)+ix)*3200.0f/1024.0f - 1600.0f; + pos.z = (256.0f*(s/4)+iy)*3200.0f/1024.0f - 1600.0f; + pos.y = 0.0f; + level = m_terrain->RetFloorLevel(pos, TRUE); + if ( level < m_groundSpot[i].min || + level > m_groundSpot[i].max ) continue; + + if ( level > (m_groundSpot[i].max+m_groundSpot[i].min)/2.0f ) + { + intensity = 1.0f-(m_groundSpot[i].max-level)/m_groundSpot[i].smooth; + } + else + { + intensity = 1.0f-(level-m_groundSpot[i].min)/m_groundSpot[i].smooth; + } + if ( intensity < 0.0f ) intensity = 0.0f; + + color.r = m_groundSpot[i].color.r+intensity; + color.g = m_groundSpot[i].color.g+intensity; + color.b = m_groundSpot[i].color.b+intensity; + + AddDot(&ddsd, ix, iy, color); + } + } + } + } + + if ( bSet ) + { + dot = (int)(m_groundMark.radius/2.0f); + + tu = (m_groundMark.pos.x+1600.0f)/3200.0f; + tv = (m_groundMark.pos.z+1600.0f)/3200.0f; // 0..1 + + cx = (tu*254.0f*4.0f)-0.5f; + cy = (tv*254.0f*4.0f)-0.5f; + + if ( dot == 0 ) + { + cx += 0.5f; + cy += 0.5f; + } + + px = cx-Mod(cx, 1.0f); + py = cy-Mod(cy, 1.0f); // multiple of 1 + + for ( iy=-dot ; iy<=dot ; iy++ ) + { + for ( ix=-dot ; ix<=dot ; ix++ ) + { + ppx = px+ix; + ppy = py+iy; + + if ( ppx < min.x || ppy < min.y || + ppx >= max.x || ppy >= max.y ) continue; + + ppx -= min.x; // on the texture + ppy -= min.y; + + intensity = 1.0f-Length((float)ix, (float)iy)/dot; + if ( intensity <= 0.0f ) continue; + intensity *= m_groundMark.intensity; + + j = (ix+dot) + (iy+dot)*m_groundMark.dx; + if ( m_groundMark.table[j] == 1 ) // green ? + { + color.r = 1.0f-intensity; + color.g = 1.0f; + color.b = 1.0f-intensity; + AddDot(&ddsd, (int)ppx, (int)ppy, color); + } + if ( m_groundMark.table[j] == 2 ) // red ? + { + color.r = 1.0f; + color.g = 1.0f-intensity; + color.b = 1.0f-intensity; + AddDot(&ddsd, (int)ppx, (int)ppy, color); + } + } + } + } + + surface->Unlock(NULL); + } + } + + for ( i=0 ; iSetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE); + + D3DUtil_SetIdentityMatrix(matrix); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); + + ZeroMemory( &material, sizeof(D3DMATERIAL7) ); + material.diffuse.r = 1.0f; + material.diffuse.g = 1.0f; + material.diffuse.b = 1.0f; // white + material.ambient.r = 0.5f; + material.ambient.g = 0.5f; + material.ambient.b = 0.5f; + SetMaterial(material); + +#if _POLISH + SetTexture("textp.tga"); +#else + SetTexture("text.tga"); +#endif + + dp = 0.5f/256.0f; + ts.y = 192.0f/256.0f; + ti.y = 224.0f/256.0f; + ts.y += dp; + ti.y -= dp; + + n = D3DVECTOR(0.0f, 1.0f, 0.0f); + + startDeepView = m_deepView[m_rankView]*m_fogStart[m_rankView]; + endDeepView = m_deepView[m_rankView]; + + lastIntensity = -1.0f; + for ( i=0 ; i pos.y ) // camera on? + { + height = m_eyePt.y-pos.y; + h = m_shadow[i].radius; + max = height*0.5f; + if ( h > max ) h = max; + if ( h > 4.0f ) h = 4.0f; + + D = Length(m_eyePt, pos); + if ( D >= endDeepView ) continue; + d = D*h/height; + + pos.x += (m_eyePt.x-pos.x)*d/D; + pos.z += (m_eyePt.z-pos.z)*d/D; + pos.y += h; + } + else // camera underneath? + { + height = pos.y-m_eyePt.y; + h = m_shadow[i].radius; + max = height*0.1f; + if ( h > max ) h = max; + if ( h > 4.0f ) h = 4.0f; + + D = Length(m_eyePt, pos); + if ( D >= endDeepView ) continue; + d = D*h/height; + + pos.x += (m_eyePt.x-pos.x)*d/D; + pos.z += (m_eyePt.z-pos.z)*d/D; + pos.y -= h; + } + + // The hFactor decreases the intensity and size increases more + // the object is high relative to the ground. + hFactor = m_shadow[i].height/20.0f; + if ( hFactor < 0.0f ) hFactor = 0.0f; + if ( hFactor > 1.0f ) hFactor = 1.0f; + hFactor = powf(1.0f-hFactor, 2.0f); + if ( hFactor < 0.2f ) hFactor = 0.2f; + + radius = m_shadow[i].radius*1.5f; + radius *= 2.0f-hFactor; // greater if high + radius *= 1.0f-d/D; // smaller if close + + if ( m_shadow[i].type == D3DSHADOWNORM ) + { + corner[0].x = +radius; + corner[0].z = +radius; + corner[0].y = 0.0f; + + corner[1].x = -radius; + corner[1].z = +radius; + corner[1].y = 0.0f; + + corner[2].x = +radius; + corner[2].z = -radius; + corner[2].y = 0.0f; + + corner[3].x = -radius; + corner[3].z = -radius; + corner[3].y = 0.0f; + + ts.x = 64.0f/256.0f; + ti.x = 96.0f/256.0f; + } + else + { + rot = RotatePoint(-m_shadow[i].angle, FPOINT(radius, radius)); + corner[0].x = rot.x; + corner[0].z = rot.y; + corner[0].y = 0.0f; + + rot = RotatePoint(-m_shadow[i].angle, FPOINT(-radius, radius)); + corner[1].x = rot.x; + corner[1].z = rot.y; + corner[1].y = 0.0f; + + rot = RotatePoint(-m_shadow[i].angle, FPOINT(radius, -radius)); + corner[2].x = rot.x; + corner[2].z = rot.y; + corner[2].y = 0.0f; + + rot = RotatePoint(-m_shadow[i].angle, FPOINT(-radius, -radius)); + corner[3].x = rot.x; + corner[3].z = rot.y; + corner[3].y = 0.0f; + + if ( m_shadow[i].type == D3DSHADOWWORM ) + { + ts.x = 96.0f/256.0f; + ti.x = 128.0f/256.0f; + } + else + { + ts.x = 64.0f/256.0f; + ti.x = 96.0f/256.0f; + } + } + + corner[0] = Cross(corner[0], m_shadow[i].normal); + corner[1] = Cross(corner[1], m_shadow[i].normal); + corner[2] = Cross(corner[2], m_shadow[i].normal); + corner[3] = Cross(corner[3], m_shadow[i].normal); + + corner[0] += pos; + corner[1] += pos; + corner[2] += pos; + corner[3] += pos; + + ts.x += dp; + ti.x -= dp; + + vertex[0] = D3DVERTEX2(corner[1], n, ts.x, ts.y); + vertex[1] = D3DVERTEX2(corner[0], n, ti.x, ts.y); + vertex[2] = D3DVERTEX2(corner[3], n, ts.x, ti.y); + vertex[3] = D3DVERTEX2(corner[2], n, ti.x, ti.y); + + intensity = (0.5f+m_shadow[i].intensity*0.5f)*hFactor; + + // Decreases the intensity of the shade if you're in the area + // between the beginning and the end of the fog. + if ( D > startDeepView ) + { + intensity *= 1.0f-(D-startDeepView)/(endDeepView-startDeepView); + } + + // Decreases if the intensity is almost horizontal + // with shade (shade very platte). +//? if ( height < 4.0f ) intensity *= height/4.0f; + + if ( intensity == 0.0f ) continue; + + if ( lastIntensity != intensity ) // intensity changed? + { + lastIntensity = intensity; + SetState(D3DSTATETTw, RetColor(intensity)); + } + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + AddStatisticTriangle(2); + } + + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE); +} + + +// Called ounces per frame, the call is the entry point for 3d rendering. +// This function sets up render states, clears the +// viewport, and renders the scene. + +HRESULT CD3DEngine::Render() +{ + D3DObjLevel1* p1; + D3DObjLevel2* p2; + D3DObjLevel3* p3; + D3DObjLevel4* p4; + D3DObjLevel5* p5; + D3DObjLevel6* p6; + D3DVERTEX2* pv; + int l1, l2, l3, l4, l5, objRank, tState; + CInterface* pInterface; + BOOL bTransparent; + D3DCOLOR color, tColor; + + if ( !m_bRender ) return S_OK; + + m_statisticTriangle = 0; + m_lastState = -1; + m_lastColor = 999; + m_lastTexture[0][0] = 0; + m_lastTexture[1][0] = 0; + ZeroMemory(&m_lastMaterial, sizeof(D3DMATERIAL7)); + + if ( m_bGroundSpot ) + { + RenderGroundSpot(); + } + + // Clear the viewport + if ( m_bSkyMode && m_cloud->RetLevel() != 0.0f ) // clouds? + { + color = m_backgroundCloudDown; + } + else + { + color = m_backgroundColorDown; + } + m_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, + color, 1.0f, 0L ); + + m_light->LightUpdate(); + + // Begin the scene + if( FAILED( m_pD3DDevice->BeginScene() ) ) return S_OK; + + if ( m_bDrawWorld ) + { + DrawBackground(); // draws the background + if ( m_bPlanetMode ) DrawPlanet(); // draws the planets + if ( m_bSkyMode ) m_cloud->Draw(); // draws the clouds + + // Display the objects + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE); +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZBIAS, F2DW(16)); +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProj); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE); + + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, m_fogColor[m_rankView]); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_LINEAR); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGSTART, F2DW(m_deepView[m_rankView]*m_fogStart[m_rankView])); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGEND, F2DW(m_deepView[m_rankView])); + + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matView); + + if ( m_bWaterMode ) m_water->DrawBack(); // draws water + + if ( m_bShadow ) + { + // Draw the field. + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + SetTexture(p2->texName1, 0); + SetTexture(p2->texName2, 1); + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + objRank = p3->objRank; + if ( m_objectParam[objRank].type != TYPETERRAIN ) continue; + if ( !m_objectParam[objRank].bDrawWorld ) continue; + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, + &m_objectParam[objRank].transform); + if ( !IsVisible(objRank) ) continue; + m_light->LightUpdate(m_objectParam[objRank].type); + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + if ( m_objectParam[objRank].distance < p4->min || + m_objectParam[objRank].distance >= p4->max ) continue; + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; + SetMaterial(p6->material); + SetState(p6->state); + if ( p6->type == D3DTYPE6T ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed/3; + } + if ( p6->type == D3DTYPE6S ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed-2; + } + } + } + } + } + } + + DrawShadow(); // draws the shadows + } + + // Draw objects. + bTransparent = FALSE; + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + SetTexture(p2->texName1, 0); + SetTexture(p2->texName2, 1); + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + objRank = p3->objRank; + if ( m_bShadow && m_objectParam[objRank].type == TYPETERRAIN ) continue; + if ( !m_objectParam[objRank].bDrawWorld ) continue; + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, + &m_objectParam[objRank].transform); + if ( !IsVisible(objRank) ) continue; + m_light->LightUpdate(m_objectParam[objRank].type); + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + if ( m_objectParam[objRank].distance < p4->min || + m_objectParam[objRank].distance >= p4->max ) continue; + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; + SetMaterial(p6->material); + if ( m_objectParam[objRank].transparency != 0.0f ) // transparent ? + { + bTransparent = TRUE; + continue; + } + SetState(p6->state); + if ( p6->type == D3DTYPE6T ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed/3; + } + if ( p6->type == D3DTYPE6S ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed-2; + } + } + } + } + } + } + + if ( bTransparent ) + { + if ( m_bStateColor ) + { + tState = D3DSTATETTb|D3DSTATE2FACE; + tColor = 0x44444444; + } + else + { + tState = D3DSTATETTb; + tColor = 0x88888888; + } + + // Draw transparent objects. + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + SetTexture(p2->texName1, 0); + SetTexture(p2->texName2, 1); + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + objRank = p3->objRank; + if ( m_bShadow && m_objectParam[objRank].type == TYPETERRAIN ) continue; + if ( !m_objectParam[objRank].bDrawWorld ) continue; + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, + &m_objectParam[objRank].transform); + if ( !IsVisible(objRank) ) continue; + m_light->LightUpdate(m_objectParam[objRank].type); + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + if ( m_objectParam[objRank].distance < p4->min || + m_objectParam[objRank].distance >= p4->max ) continue; + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; + SetMaterial(p6->material); + if ( m_objectParam[objRank].transparency == 0.0f ) continue; + SetState(tState, tColor); + if ( p6->type == D3DTYPE6T ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed/3; + } + if ( p6->type == D3DTYPE6S ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed-2; + } + } + } + } + } + } + } + + m_light->LightUpdate(TYPETERRAIN); + if ( m_bWaterMode ) m_water->DrawSurf(); // draws water +//? m_cloud->Draw(); // draws the clouds + + m_particule->DrawParticule(SH_WORLD); // draws the particles of the 3D world + m_blitz->Draw(); // draws lightning + if ( m_bLensMode ) DrawFrontsize(); // draws the foreground + if ( !m_bOverFront ) DrawOverColor(); // draws the foreground color + } + + // Draw the user interface over the scene. + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); + + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matViewInterface); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProjInterface); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matWorldInterface); + + pInterface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); + if ( pInterface != 0 ) + { + pInterface->Draw(); // draws the entire interface + } + m_particule->DrawParticule(SH_INTERFACE); // draws the particles of the interface + + if ( m_bDrawFront ) + { + // Display the objects + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE); +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZBIAS, F2DW(16)); +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProj); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, m_ambiantColor[m_rankView]); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE); + + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, m_fogColor[m_rankView]); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_LINEAR); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGSTART, F2DW(m_deepView[m_rankView]*m_fogStart[m_rankView])); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGEND, F2DW(m_deepView[m_rankView])); + + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matView); + + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + SetTexture(p2->texName1, 0); + SetTexture(p2->texName2, 1); + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + objRank = p3->objRank; + if ( !m_objectParam[objRank].bDrawFront ) continue; + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, + &m_objectParam[objRank].transform); + if ( !IsVisible(objRank) ) continue; + m_light->LightUpdate(m_objectParam[objRank].type); + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + if ( m_objectParam[objRank].distance < p4->min || + m_objectParam[objRank].distance >= p4->max ) continue; + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; + SetMaterial(p6->material); + SetState(p6->state); + if ( p6->type == D3DTYPE6T ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed/3; + } + if ( p6->type == D3DTYPE6S ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed-2; + } + } + } + } + } + } + + m_particule->DrawParticule(SH_FRONT); // draws the particles of the 3D world + + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); + + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matViewInterface); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProjInterface); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matWorldInterface); + } + + if ( m_bOverFront ) DrawOverColor(); // draws the foreground color + + if ( m_mouseType != D3DMOUSEHIDE ) + { + DrawMouse(); + } + + // End the scene. + m_pD3DDevice->EndScene(); + + DrawHilite(); + return S_OK; +} + + +// Draw the gradient background. + +void CD3DEngine::DrawBackground() +{ + if ( m_bSkyMode && m_cloud->RetLevel() != 0.0f ) // clouds ? + { + if ( m_backgroundCloudUp != m_backgroundCloudDown ) // degraded? + { + DrawBackgroundGradient(m_backgroundCloudUp, m_backgroundCloudDown); + } + } + else + { + if ( m_backgroundColorUp != m_backgroundColorDown ) // degraded? + { + DrawBackgroundGradient(m_backgroundColorUp, m_backgroundColorDown); + } + } + + if ( m_bBackForce || (m_bSkyMode && m_backgroundName[0] != 0) ) + { + DrawBackgroundImage(); // image + } +} + +// Draw the gradient background. + +void CD3DEngine::DrawBackgroundGradient(D3DCOLOR up, D3DCOLOR down) +{ + D3DLVERTEX vertex[4]; // 2 triangles + D3DCOLOR color[3]; + FPOINT p1, p2; + + p1.x = 0.0f; + p1.y = 0.5f; + p2.x = 1.0f; + p2.y = 1.0f; + + color[0] = up; + color[1] = down; + color[2] = 0x00000000; + +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE ); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE ); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); + + SetTexture("xxx.tga"); // no texture + SetState(D3DSTATENORMAL); + + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matViewInterface); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProjInterface); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matWorldInterface); + + vertex[0] = D3DLVERTEX(D3DVECTOR(p1.x, p1.y, 0.0f), color[1],color[2], 0.0f,0.0f); + vertex[1] = D3DLVERTEX(D3DVECTOR(p1.x, p2.y, 0.0f), color[0],color[2], 0.0f,0.0f); + vertex[2] = D3DLVERTEX(D3DVECTOR(p2.x, p1.y, 0.0f), color[1],color[2], 0.0f,0.0f); + vertex[3] = D3DLVERTEX(D3DVECTOR(p2.x, p2.y, 0.0f), color[0],color[2], 0.0f,0.0f); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, vertex, 4, NULL); + AddStatisticTriangle(2); +} + +// Draws a portion of the image background. + +void CD3DEngine::DrawBackgroundImageQuarter(FPOINT p1, FPOINT p2, char *name) +{ + D3DVERTEX2 vertex[4]; // 2 triangles + D3DVECTOR n; + float u1, u2, v1, v2, h, a; + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal + + if ( m_bBackgroundFull ) + { + u1 = 0.0f; + v1 = 0.0f; + u2 = 1.0f; + v2 = 1.0f; + + if ( m_bBackgroundQuarter ) + { + u1 += 0.5f/512.0f; + v1 += 0.5f/384.0f; + u2 -= 0.5f/512.0f; + v2 -= 0.5f/384.0f; + } + } + else + { + h = 0.5f; // visible area vertically (1=all) + a = m_eyeDirV-PI*0.15f; + if ( a > PI ) a -= PI*2.0f; // a = -PI..PI + if ( a > PI/4.0f ) a = PI/4.0f; + if ( a < -PI/4.0f ) a = -PI/4.0f; + + u1 = -m_eyeDirH/PI; + u2 = u1+1.0f/PI; +//? u1 = -m_eyeDirH/(PI*2.0f); +//? u2 = u1+1.0f/(PI*2.0f); + + v1 = (1.0f-h)*(0.5f+a/(2.0f*PI/4.0f))+0.1f; + v2 = v1+h; + } + +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE ); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE ); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); + + SetTexture(name); + SetState(D3DSTATEWRAP); + + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matViewInterface); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProjInterface); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matWorldInterface); + + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); + vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); + vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + AddStatisticTriangle(2); +} + +// Draws the image background. + +void CD3DEngine::DrawBackgroundImage() +{ + FPOINT p1, p2; + char name[50]; + + if ( m_bBackgroundQuarter ) + { + p1.x = 0.0f; + p1.y = 0.5f; + p2.x = 0.5f; + p2.y = 1.0f; + QuarterName(name, m_backgroundName, 0); + DrawBackgroundImageQuarter(p1, p2, name); + + p1.x = 0.5f; + p1.y = 0.5f; + p2.x = 1.0f; + p2.y = 1.0f; + QuarterName(name, m_backgroundName, 1); + DrawBackgroundImageQuarter(p1, p2, name); + + p1.x = 0.0f; + p1.y = 0.0f; + p2.x = 0.5f; + p2.y = 0.5f; + QuarterName(name, m_backgroundName, 2); + DrawBackgroundImageQuarter(p1, p2, name); + + p1.x = 0.5f; + p1.y = 0.0f; + p2.x = 1.0f; + p2.y = 0.5f; + QuarterName(name, m_backgroundName, 3); + DrawBackgroundImageQuarter(p1, p2, name); + } + else + { + p1.x = 0.0f; + p1.y = 0.0f; + p2.x = 1.0f; + p2.y = 1.0f; + DrawBackgroundImageQuarter(p1, p2, m_backgroundName); + } +} + +// Draws all the planets. + +void CD3DEngine::DrawPlanet() +{ + if ( !m_planet->PlanetExist() ) return; + +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE ); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE ); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); + + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matViewInterface); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProjInterface); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matWorldInterface); + + m_planet->Draw(); // draws the planets +} + +// Draws the image foreground. + +void CD3DEngine::DrawFrontsize() +{ + D3DVERTEX2 vertex[4]; // 2 triangles + D3DVECTOR n; + FPOINT p1, p2; + float u1, u2, v1, v2; + + if ( m_frontsizeName[0] == 0 ) return; + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal + + p1.x = 0.0f; + p1.y = 0.0f; + p2.x = 1.0f; + p2.y = 1.0f; + + u1 = -m_eyeDirH/(PI*0.6f)+PI*0.5f; + u2 = u1+0.50f; + + v1 = 0.2f; + v2 = 1.0f; + +#if 0 + char s[100]; + sprintf(s, "h=%.2f v=%.2f u=%.2f;%.2f v=%.2f;%.2f", m_eyeDirH, m_eyeDirV, u1, u2, v1, v2); + SetInfoText(3, s); +#endif + + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); + vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); + vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); + +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE ); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); + + SetTexture(m_frontsizeName); + SetState(D3DSTATECLAMP|D3DSTATETTb); + + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matViewInterface); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProjInterface); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matWorldInterface); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + AddStatisticTriangle(2); +} + +// Draws the foreground color. + +void CD3DEngine::DrawOverColor() +{ + D3DLVERTEX vertex[4]; // 2 triangles + D3DCOLOR color[3]; + FPOINT p1, p2; + + if ( !m_bStateColor ) return; + if ( (m_overColor == 0x00000000 && m_overMode == D3DSTATETCb) || + (m_overColor == 0xffffffff && m_overMode == D3DSTATETCw) ) return; + + p1.x = 0.0f; + p1.y = 0.0f; + p2.x = 1.0f; + p2.y = 1.0f; + + color[0] = m_overColor; + color[1] = m_overColor; + color[2] = 0x00000000; + +//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE ); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE ); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); + + SetTexture("xxx.tga"); // no texture + SetState(m_overMode); + + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_matViewInterface); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProjInterface); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matWorldInterface); + + vertex[0] = D3DLVERTEX(D3DVECTOR(p1.x, p1.y, 0.0f), color[1],color[2], 0.0f,0.0f); + vertex[1] = D3DLVERTEX(D3DVECTOR(p1.x, p2.y, 0.0f), color[0],color[2], 0.0f,0.0f); + vertex[2] = D3DLVERTEX(D3DVECTOR(p2.x, p1.y, 0.0f), color[1],color[2], 0.0f,0.0f); + vertex[3] = D3DLVERTEX(D3DVECTOR(p2.x, p2.y, 0.0f), color[0],color[2], 0.0f,0.0f); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, vertex, 4, NULL); + AddStatisticTriangle(2); +} + + +// Lists the ranks of objects and subobjects selected. + +void CD3DEngine::SetHiliteRank(int *rankList) +{ + int i; + + i = 0; + while ( *rankList != -1 ) + { + m_hiliteRank[i++] = *rankList++; + } + m_hiliteRank[i] = -1; // terminator +} + +// Give the box in the 2D screen of any object. + +BOOL CD3DEngine::GetBBox2D(int objRank, FPOINT &min, FPOINT &max) +{ + D3DVECTOR p, pp; + int i; + + min.x = 1000000.0f; + min.y = 1000000.0f; + max.x = -1000000.0f; + max.y = -1000000.0f; + + for ( i=0 ; i<8 ; i++ ) + { + if ( i & (1<<0) ) p.x = m_objectParam[objRank].bboxMin.x; + else p.x = m_objectParam[objRank].bboxMax.x; + if ( i & (1<<1) ) p.y = m_objectParam[objRank].bboxMin.y; + else p.y = m_objectParam[objRank].bboxMax.y; + if ( i & (1<<2) ) p.z = m_objectParam[objRank].bboxMin.z; + else p.z = m_objectParam[objRank].bboxMax.z; + if ( TransformPoint(pp, objRank, p) ) + { + if ( pp.x < min.x ) min.x = pp.x; + if ( pp.x > max.x ) max.x = pp.x; + if ( pp.y < min.y ) min.y = pp.y; + if ( pp.y > max.y ) max.y = pp.y; + } + } + + if ( min.x == 1000000.0f || + min.y == 1000000.0f || + max.x == -1000000.0f || + max.y == -1000000.0f ) return FALSE; + + return TRUE; +} + +// Determines the rectangle of the object highlighted, which will be designed by CD3DApplication. + +void CD3DEngine::DrawHilite() +{ + FPOINT min, max, omin, omax; + int i; + + min.x = 1000000.0f; + min.y = 1000000.0f; + max.x = -1000000.0f; + max.y = -1000000.0f; + + i = 0; + while ( m_hiliteRank[i] != -1 ) + { + if ( GetBBox2D(m_hiliteRank[i++], omin, omax) ) + { + min.x = Min(min.x, omin.x); + min.y = Min(min.y, omin.y); + max.x = Max(max.x, omax.x); + max.y = Max(max.y, omax.y); + } + } + + if ( min.x == 1000000.0f || + min.y == 1000000.0f || + max.x == -1000000.0f || + max.y == -1000000.0f ) + { + m_bHilite = FALSE; // not highlighted + } + else + { + m_hiliteP1 = min; + m_hiliteP2 = max; + m_bHilite = TRUE; + } +} + +// Give the rectangle highlighted by drawing CD3DApplication. + +BOOL CD3DEngine::GetHilite(FPOINT &p1, FPOINT &p2) +{ + p1 = m_hiliteP1; + p2 = m_hiliteP2; + return m_bHilite; +} + + +// Triangles adds qq records for statistics. + +void CD3DEngine::AddStatisticTriangle(int nb) +{ + m_statisticTriangle += nb; +} + +// Returns the number of triangles rendered. + +int CD3DEngine::RetStatisticTriangle() +{ + return m_statisticTriangle; +} + +BOOL CD3DEngine::GetSpriteCoord(int &x, int &y) +{ + D3DVIEWPORT7 vp; + D3DVECTOR v, vv; + + return FALSE; + //? + vv = D3DVECTOR(0.0f, 0.0f, 0.0f); + if ( !TransformPoint(v, 20*20+1, vv) ) return FALSE; + + m_pD3DDevice->GetViewport(&vp); + v.x *= vp.dwWidth/2; + v.y *= vp.dwHeight/2; + v.x = v.x+vp.dwWidth/2; + v.y = vp.dwHeight-(v.y+vp.dwHeight/2); + + x = (int)v.x; + y = (int)v.y; + return TRUE; +} + + +// Tests whether to exclude a point. + +BOOL IsExcludeColor(FPOINT *pExclu, int x, int y) +{ + int i; + + i = 0; + while ( pExclu[i+0].x != 0.0f || pExclu[i+0].y != 0.0f || + pExclu[i+1].y != 0.0f || pExclu[i+1].y != 0.0f ) + { + if ( x >= (int)(pExclu[i+0].x*256.0f) && + x < (int)(pExclu[i+1].x*256.0f) && + y >= (int)(pExclu[i+0].y*256.0f) && + y < (int)(pExclu[i+1].y*256.0f) ) return TRUE; // exclude + + i += 2; + } + + return FALSE; // point to include +} + +// Change the color of a texture. + +BOOL CD3DEngine::ChangeColor(char *name, + D3DCOLORVALUE colorRef1, D3DCOLORVALUE colorNew1, + D3DCOLORVALUE colorRef2, D3DCOLORVALUE colorNew2, + float tolerance1, float tolerance2, + FPOINT ts, FPOINT ti, + FPOINT *pExclu, float shift, BOOL bHSV) +{ + LPDIRECTDRAWSURFACE7 surface; + DDSURFACEDESC2 ddsd; + D3DCOLORVALUE color; + ColorHSV cr1, cn1, cr2, cn2, c; + int dx, dy, x, y, sx, sy, ex, ey; + + D3DTextr_Invalidate(name); + LoadTexture(name); // reloads the initial texture + + if ( colorRef1.r == colorNew1.r && + colorRef1.g == colorNew1.g && + colorRef1.b == colorNew1.b && + colorRef2.r == colorNew2.r && + colorRef2.g == colorNew2.g && + colorRef2.b == colorNew2.b ) return TRUE; + + surface = D3DTextr_GetSurface(name); + if ( surface == 0 ) return FALSE; + + ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2)); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + if ( surface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) != DD_OK ) return FALSE; + + dx = ddsd.dwWidth; + dy = ddsd.dwHeight; + + sx = (int)(ts.x*dx); + sy = (int)(ts.y*dy); + ex = (int)(ti.x*dx); + ey = (int)(ti.y*dy); + + RGB2HSV(colorRef1, cr1); + RGB2HSV(colorNew1, cn1); + RGB2HSV(colorRef2, cr2); + RGB2HSV(colorNew2, cn2); + + for ( y=sy ; y 0.01f && Abs(c.h-cr1.h) < tolerance1 ) + { + c.h += cn1.h-cr1.h; + c.s += cn1.s-cr1.s; + c.v += cn1.v-cr1.v; + if ( c.h < 0.0f ) c.h -= 1.0f; + if ( c.h > 1.0f ) c.h += 1.0f; + HSV2RGB(c, color); + color.r += shift; + color.g += shift; + color.b += shift; + ::SetDot(&ddsd, x, y, color); + } + else + if ( tolerance2 != -1.0f && + c.s > 0.01f && Abs(c.h-cr2.h) < tolerance2 ) + { + c.h += cn2.h-cr2.h; + c.s += cn2.s-cr2.s; + c.v += cn2.v-cr2.v; + if ( c.h < 0.0f ) c.h -= 1.0f; + if ( c.h > 1.0f ) c.h += 1.0f; + HSV2RGB(c, color); + color.r += shift; + color.g += shift; + color.b += shift; + ::SetDot(&ddsd, x, y, color); + } + } + else + { + if ( Abs(color.r-colorRef1.r)+ + Abs(color.g-colorRef1.g)+ + Abs(color.b-colorRef1.b) < tolerance1*3.0f ) + { + color.r = colorNew1.r+color.r-colorRef1.r+shift; + color.g = colorNew1.g+color.g-colorRef1.g+shift; + color.b = colorNew1.b+color.b-colorRef1.b+shift; + ::SetDot(&ddsd, x, y, color); + } + else + if ( tolerance2 != -1 && + Abs(color.r-colorRef2.r)+ + Abs(color.g-colorRef2.g)+ + Abs(color.b-colorRef2.b) < tolerance2*3.0f ) + { + color.r = colorNew2.r+color.r-colorRef2.r+shift; + color.g = colorNew2.g+color.g-colorRef2.g+shift; + color.b = colorNew2.b+color.b-colorRef2.b+shift; + ::SetDot(&ddsd, x, y, color); + } + } + } + } + + surface->Unlock(NULL); + return TRUE; +} + + +// Open an image to work directly in it. + +BOOL CD3DEngine::OpenImage(char *name) +{ +//? D3DTextr_Invalidate(name); +//? LoadTexture(name); + + m_imageSurface = D3DTextr_GetSurface(name); + if ( m_imageSurface == 0 ) return FALSE; + + ZeroMemory(&m_imageDDSD, sizeof(DDSURFACEDESC2)); + m_imageDDSD.dwSize = sizeof(DDSURFACEDESC2); + if ( m_imageSurface->Lock(NULL, &m_imageDDSD, DDLOCK_WAIT, NULL) != DD_OK ) + { + return FALSE; + } + + if ( m_imageDDSD.ddpfPixelFormat.dwRGBBitCount != 16 ) + { + m_imageSurface->Unlock(NULL); + return FALSE; + } + + m_imageDX = m_imageDDSD.dwWidth; + m_imageDY = m_imageDDSD.dwHeight; + + return TRUE; +} + +// Copy the working image. + +BOOL CD3DEngine::CopyImage() +{ + WORD* pbSurf; + int y; + + if ( m_imageCopy == 0 ) + { + m_imageCopy = (WORD*)malloc(m_imageDX*m_imageDY*sizeof(WORD)); + } + + for ( y=0 ; y 0 ) + { + for ( y=0 ; y=-dx ; x-- ) + { + m_imageCopy[x+y*m_imageDX] = m_imageCopy[x+dx+y*m_imageDX]; + } + } + } + + if ( dy > 0 ) + { + for ( y=0 ; y=-dy ; y-- ) + { + memcpy(m_imageCopy+y*m_imageDX, m_imageCopy+(y+dy)*m_imageDX, m_imageDX*sizeof(WORD)); + } + } + + return TRUE; +} + +// Draws a point in the image work. + +BOOL CD3DEngine::SetDot(int x, int y, D3DCOLORVALUE color) +{ + WORD* pbSurf; + WORD r,g,b, w; + + if ( x < 0 || x >= m_imageDX || + y < 0 || y >= m_imageDY ) return FALSE; + +#if 1 + if ( color.r < 0.0f ) color.r = 0.0f; + if ( color.r > 1.0f ) color.r = 1.0f; + if ( color.g < 0.0f ) color.g = 0.0f; + if ( color.g > 1.0f ) color.g = 1.0f; + if ( color.b < 0.0f ) color.b = 0.0f; + if ( color.b > 1.0f ) color.b = 1.0f; + + r = (int)(color.r*32.0f); + g = (int)(color.g*32.0f); + b = (int)(color.b*32.0f); + + if ( r >= 32 ) r = 31; // 5 bits + if ( g >= 32 ) g = 31; // 5 bits + if ( b >= 32 ) b = 31; // 5 bits +#else + r = (int)(color.r*31.0f); + g = (int)(color.g*31.0f); + b = (int)(color.b*31.0f); +#endif + + if ( m_imageDDSD.ddpfPixelFormat.dwRBitMask == 0xf800 ) // 565 ? + { + w = (r<<11)|(g<<6)|b; + } + else if ( m_imageDDSD.ddpfPixelFormat.dwRBitMask == 0x7c00 ) // 555 ? + { + w = (r<<10)|(g<<5)|b; + } + else + { + w = -1; // blank + } + + pbSurf = (WORD*)m_imageDDSD.lpSurface; + pbSurf += m_imageDDSD.lPitch*y/2; + pbSurf += x; + + *pbSurf = w; + return TRUE; +} + +// Closes the working image. + +BOOL CD3DEngine::CloseImage() +{ + m_imageSurface->Unlock(NULL); + return TRUE; +} + + +// Writes a .BMP screenshot. + +BOOL CD3DEngine::WriteScreenShot(char *filename, int width, int height) +{ + return m_app->WriteScreenShot(filename, width, height); +} + +// Initializes an hDC on the rendering surface. + +BOOL CD3DEngine::GetRenderDC(HDC &hDC) +{ + return m_app->GetRenderDC(hDC); +} + +// Frees the hDC of the rendering surface. + +BOOL CD3DEngine::ReleaseRenderDC(HDC &hDC) +{ + return m_app->ReleaseRenderDC(hDC); +} + +PBITMAPINFO CD3DEngine::CreateBitmapInfoStruct(HBITMAP hBmp) +{ + return m_app->CreateBitmapInfoStruct(hBmp); +} + +BOOL CD3DEngine::CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC) +{ + return m_app->CreateBMPFile(pszFile, pbi, hBMP, hDC); +} + +// Returns the pointer to the class cText. + +CText* CD3DEngine::RetText() +{ + return m_text; +} + + +// Managing of information text displayed in the window. + +void CD3DEngine::SetInfoText(int line, char* text) +{ + strcpy(m_infoText[line], text); +} + +char* CD3DEngine::RetInfoText(int line) +{ + return m_infoText[line]; +} + + + +// Specifies the length of the camera. +// 0.75 = normal +// 1.50 = wide-angle + +void CD3DEngine::SetFocus(float focus) +{ + D3DVIEWPORT7 vp; + float fAspect; + + m_focus = focus; + + if ( m_pD3DDevice != 0 ) + { + m_pD3DDevice->GetViewport(&vp); + m_dim.x = vp.dwWidth; + m_dim.y = vp.dwHeight; + } + + fAspect = ((float)m_dim.y) / m_dim.x; +//? D3DUtil_SetProjectionMatrix(m_matProj, m_focus, fAspect, 0.5f, m_deepView[m_rankView]); + D3DUtil_SetProjectionMatrix(m_matProj, m_focus, fAspect, 0.5f, m_deepView[0]); +} + +float CD3DEngine::RetFocus() +{ + return m_focus; +} + +// + +void CD3DEngine::UpdateMatProj() +{ + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_matProj); +} + + + +// Ignores key presses. + +void CD3DEngine::FlushPressKey() +{ + m_app->FlushPressKey(); +} + +// Resets the default keys. + +void CD3DEngine::ResetKey() +{ + m_app->ResetKey(); +} + +// Modifies a button. + +void CD3DEngine::SetKey(int keyRank, int option, int key) +{ + m_app->SetKey(keyRank, option, key); +} + +// Gives a key. + +int CD3DEngine::RetKey(int keyRank, int option) +{ + return m_app->RetKey(keyRank, option); +} + + +// Use the joystick or keyboard. + +void CD3DEngine::SetJoystick(BOOL bEnable) +{ + m_app->SetJoystick(bEnable); +} + +BOOL CD3DEngine::RetJoystick() +{ + return m_app->RetJoystick(); +} + + +void CD3DEngine::SetDebugMode(BOOL bMode) +{ + m_app->SetDebugMode(bMode); +} + +BOOL CD3DEngine::RetDebugMode() +{ + return m_app->RetDebugMode(); +} + +BOOL CD3DEngine::RetSetupMode() +{ + return m_app->RetSetupMode(); +} + + +// Indicates whether a point is visible. + +BOOL CD3DEngine::IsVisiblePoint(const D3DVECTOR &pos) +{ + return ( Length(m_eyePt, pos) <= m_deepView[0] ); +} + + +// Initialize scene objects. + +HRESULT CD3DEngine::InitDeviceObjects() +{ + // Set miscellaneous render states. + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, TRUE); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SHADEMODE, D3DSHADE_GOURAUD); + m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID); + + // Set up the textures. + D3DTextr_RestoreAllTextures(m_pD3DDevice); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_LINEAR); + m_pD3DDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR); + m_pD3DDevice->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTFN_LINEAR); + m_pD3DDevice->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTFG_LINEAR); + + SetFocus(m_focus); + + // Definitions of the matrices for the interface. + D3DUtil_SetIdentityMatrix(m_matWorldInterface); + + D3DUtil_SetIdentityMatrix(m_matViewInterface); + m_matViewInterface._41 = -0.5f; + m_matViewInterface._42 = -0.5f; + m_matViewInterface._43 = 1.0f; + + D3DUtil_SetIdentityMatrix(m_matProjInterface); + m_matProjInterface._11 = 2.0f; + m_matProjInterface._22 = 2.0f; + m_matProjInterface._34 = 1.0f; + m_matProjInterface._43 = -1.0f; + m_matProjInterface._44 = 0.0f; + + return S_OK; +} + + +// Restore all surfaces. + +HRESULT CD3DEngine::RestoreSurfaces() +{ + return S_OK; +} + + +// Called when the app is exitting, or the device is being changed, +// this function deletes any device dependant objects. + +HRESULT CD3DEngine::DeleteDeviceObjects() +{ + D3DTextr_InvalidateAllTextures(); + return S_OK; +} + + +// Called before the app exits, this function gives the app the chance +// to cleanup after itself. + +HRESULT CD3DEngine::FinalCleanup() +{ + return S_OK; +} + + +// Overrrides the main WndProc, so the sample can do custom message +// handling (e.g. processing mouse, keyboard, or menu commands). + +LRESULT CD3DEngine::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ +#if 0 + if ( uMsg == WM_KEYDOWN ) // Alt+key ? + { + if ( wParam == 'Q' ) + { + debug_blend1 ++; + if ( debug_blend1 > 13 ) debug_blend1 = 0; + } + if ( wParam == 'W' ) + { + debug_blend2 ++; + if ( debug_blend2 > 13 ) debug_blend2 = 0; + } + if ( wParam == 'E' ) + { + debug_blend3 ++; + if ( debug_blend3 > 13 ) debug_blend3 = 0; + } + if ( wParam == 'R' ) + { + debug_blend4 ++; + if ( debug_blend4 > 13 ) debug_blend4 = 0; + } + char s[100]; + sprintf(s, "src=%d, dest=%d, src=%d, dest=%d", debug_blend1, debug_blend2, debug_blend3, debug_blend4); + SetInfoText(4, s); + } +#endif + +#if 1 + if ( uMsg == WM_SYSKEYDOWN ) // Alt+key ? + { + if ( wParam == VK_F7 ) // Alt+F7 ? + { + s_resol = 0; + } + if ( wParam == VK_F8 ) // Alt+F8 ? + { + s_resol = 1; + } + if ( wParam == VK_F9 ) // Alt+F9 ? + { + s_resol = 2; + } + if ( wParam == VK_F10 ) // Alt+F10 ? + { + s_resol = 3; + } + } +#endif + + return 0; +} + + +// Mouse control. + +void CD3DEngine::MoveMousePos(FPOINT pos) +{ + m_mousePos = pos; + m_app->SetMousePos(pos); +} + +void CD3DEngine::SetMousePos(FPOINT pos) +{ + m_mousePos = pos; +} + +FPOINT CD3DEngine::RetMousePos() +{ + return m_mousePos; +} + +void CD3DEngine::SetMouseType(D3DMouse type) +{ + m_mouseType = type; +} + +D3DMouse CD3DEngine::RetMouseType() +{ + return m_mouseType; +} + +void CD3DEngine::SetMouseHide(BOOL bHide) +{ + if ( m_bMouseHide == bHide ) return; + + if ( bHide ) // hide the mouse? + { + m_bNiceMouse = m_app->RetNiceMouse(); + if ( !m_bNiceMouse ) + { + m_app->SetNiceMouse(TRUE); + } + m_bMouseHide = TRUE; + } + else // shows the mouse? + { + if ( !m_bNiceMouse ) + { + m_app->SetNiceMouse(FALSE); + } + m_bMouseHide = FALSE; + } +} + +BOOL CD3DEngine::RetMouseHide() +{ + return m_bMouseHide; +} + +void CD3DEngine::SetNiceMouse(BOOL bNice) +{ + m_app->SetNiceMouse(bNice); +} + +BOOL CD3DEngine::RetNiceMouse() +{ + return m_app->RetNiceMouse(); +} + +BOOL CD3DEngine::RetNiceMouseCap() +{ + return m_app->RetNiceMouseCap(); +} + +// Draws the sprite of the mouse. + +void CD3DEngine::DrawMouse() +{ + D3DMATERIAL7 material; + FPOINT pos, ppos, dim; + int i; + + typedef struct + { + D3DMouse type; + int icon1, icon2, iconShadow; + int mode1, mode2; + float hotx, hoty; + } + Mouse; + + static Mouse table[] = + { + { D3DMOUSENORM, 0, 1,32, D3DSTATETTw, D3DSTATETTb, 1.0f, 1.0f}, + { D3DMOUSEWAIT, 2, 3,33, D3DSTATETTw, D3DSTATETTb, 8.0f, 12.0f}, + { D3DMOUSEHAND, 4, 5,34, D3DSTATETTw, D3DSTATETTb, 7.0f, 2.0f}, + { D3DMOUSENO, 6, 7,35, D3DSTATETTw, D3DSTATETTb, 10.0f, 10.0f}, + { D3DMOUSEEDIT, 8, 9,-1, D3DSTATETTb, D3DSTATETTw, 6.0f, 10.0f}, + { D3DMOUSECROSS, 10,11,-1, D3DSTATETTb, D3DSTATETTw, 10.0f, 10.0f}, + { D3DMOUSEMOVEV, 12,13,-1, D3DSTATETTb, D3DSTATETTw, 5.0f, 11.0f}, + { D3DMOUSEMOVEH, 14,15,-1, D3DSTATETTb, D3DSTATETTw, 11.0f, 5.0f}, + { D3DMOUSEMOVED, 16,17,-1, D3DSTATETTb, D3DSTATETTw, 9.0f, 9.0f}, + { D3DMOUSEMOVEI, 18,19,-1, D3DSTATETTb, D3DSTATETTw, 9.0f, 9.0f}, + { D3DMOUSEMOVE, 20,21,-1, D3DSTATETTb, D3DSTATETTw, 11.0f, 11.0f}, + { D3DMOUSETARGET, 22,23,-1, D3DSTATETTb, D3DSTATETTw, 15.0f, 15.0f}, + { D3DMOUSESCROLLL, 24,25,43, D3DSTATETTb, D3DSTATETTw, 2.0f, 9.0f}, + { D3DMOUSESCROLLR, 26,27,44, D3DSTATETTb, D3DSTATETTw, 17.0f, 9.0f}, + { D3DMOUSESCROLLU, 28,29,45, D3DSTATETTb, D3DSTATETTw, 9.0f, 2.0f}, + { D3DMOUSESCROLLD, 30,31,46, D3DSTATETTb, D3DSTATETTw, 9.0f, 17.0f}, + { D3DMOUSEHIDE }, + }; + + if ( m_bMouseHide ) return; + if ( !m_app->RetNiceMouse() ) return; // mouse windows? + + ZeroMemory( &material, sizeof(D3DMATERIAL7) ); + material.diffuse.r = 1.0f; + material.diffuse.g = 1.0f; + material.diffuse.b = 1.0f; + material.ambient.r = 0.5f; + material.ambient.g = 0.5f; + material.ambient.b = 0.5f; + SetMaterial(material); + + SetTexture("mouse.tga"); + + i = 0; + while ( table[i].type != D3DMOUSEHIDE ) + { + if ( m_mouseType == table[i].type ) + { + dim.x = 0.05f*0.75f; + dim.y = 0.05f; + + pos.x = m_mousePos.x - (table[i].hotx*dim.x)/32.0f; + pos.y = m_mousePos.y - ((32.0f-table[i].hoty)*dim.y)/32.0f; + + ppos.x = pos.x+(4.0f/640.0f); + ppos.y = pos.y-(3.0f/480.0f); + SetState(D3DSTATETTw); + DrawSprite(ppos, dim, table[i].iconShadow); + + SetState(table[i].mode1); + DrawSprite(pos, dim, table[i].icon1); + + SetState(table[i].mode2); + DrawSprite(pos, dim, table[i].icon2); + break; + } + i ++; + } +} + +// Draws the sprite of the mouse. + +void CD3DEngine::DrawSprite(FPOINT pos, FPOINT dim, int icon) +{ + D3DVERTEX2 vertex[4]; // 2 triangles + FPOINT p1, p2; + D3DVECTOR n; + float u1, u2, v1, v2, dp; + + if ( icon == -1 ) return; + + p1.x = pos.x; + p1.y = pos.y; + p2.x = pos.x + dim.x; + p2.y = pos.y + dim.y; + + u1 = (32.0f/256.0f)*(icon%8); + v1 = (32.0f/256.0f)*(icon/8); // u-v texture + u2 = (32.0f/256.0f)+u1; + v2 = (32.0f/256.0f)+v1; + + dp = 0.5f/256.0f; + u1 += dp; + v1 += dp; + u2 -= dp; + v2 -= dp; + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal + + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); + vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); + vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); + + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + AddStatisticTriangle(2); +} + diff --git a/src/graphics/d3d/d3dengine.h b/src/graphics/d3d/d3dengine.h new file mode 100644 index 0000000..a99db93 --- /dev/null +++ b/src/graphics/d3d/d3dengine.h @@ -0,0 +1,686 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// d3dengine.h + +#ifndef _D3DENGINE_H_ +#define _D3DENGINE_H_ + + +#include "struct.h" + + +class CD3DApplication; +class CInstanceManager; +class CObject; +class CLight; +class CText; +class CParticule; +class CWater; +class CCloud; +class CBlitz; +class CPlanet; +class CSound; +class CTerrain; + + +#define D3DMAXOBJECT 1200 +#define D3DMAXSHADOW 500 +#define D3DMAXGROUNDSPOT 100 + + +enum D3DTypeObj +{ + TYPENULL = 0, // object doesn't exist + TYPETERRAIN = 1, // terrain + TYPEFIX = 2, // fixed object + TYPEVEHICULE = 3, // moving object + TYPEDESCENDANT = 4, // part of a moving object + TYPEQUARTZ = 5, // fixed object type quartz + TYPEMETAL = 6, // fixed object type metal +}; + +enum D3DTypeTri +{ + D3DTYPE6T = 1, // triangles + D3DTYPE6S = 2, // surfaces +}; + +enum D3DMaping +{ + D3DMAPPINGX = 1, + D3DMAPPINGY = 2, + D3DMAPPINGZ = 3, + D3DMAPPING1X = 4, + D3DMAPPING1Y = 5, + D3DMAPPING1Z = 6, +}; + +enum D3DMouse +{ + D3DMOUSEHIDE = 0, // no mouse + D3DMOUSENORM = 1, + D3DMOUSEWAIT = 2, + D3DMOUSEEDIT = 3, + D3DMOUSEHAND = 4, + D3DMOUSECROSS = 5, + D3DMOUSESHOW = 6, + D3DMOUSENO = 7, + D3DMOUSEMOVE = 8, // + + D3DMOUSEMOVEH = 9, // - + D3DMOUSEMOVEV = 10, // | + D3DMOUSEMOVED = 11, // / + D3DMOUSEMOVEI = 12, // \ // + D3DMOUSESCROLLL = 13, // << + D3DMOUSESCROLLR = 14, // >> + D3DMOUSESCROLLU = 15, // ^ + D3DMOUSESCROLLD = 16, // v + D3DMOUSETARGET = 17, +}; + +enum D3DShadowType +{ + D3DSHADOWNORM = 0, + D3DSHADOWWORM = 1, +}; + + +#define D3DSTATENORMAL 0 // normal opaque materials +#define D3DSTATETTb (1<<0) // the transparent texture (black = no) +#define D3DSTATETTw (1<<1) // the transparent texture (white = no) +#define D3DSTATETD (1<<2) // the transparent diffuse color +#define D3DSTATEWRAP (1<<3) // texture wrappe +#define D3DSTATECLAMP (1<<4) // texture borders with solid color +#define D3DSTATELIGHT (1<<5) // light texture (ambient max) +#define D3DSTATEDUALb (1<<6) // double black texturing +#define D3DSTATEDUALw (1<<7) // double white texturing +#define D3DSTATEPART1 (1<<8) // part 1 (no change in. MOD!) +#define D3DSTATEPART2 (1<<9) // part 2 +#define D3DSTATEPART3 (1<<10) // part 3 +#define D3DSTATEPART4 (1<<11) // part 4 +#define D3DSTATE2FACE (1<<12) // double-sided face +#define D3DSTATEALPHA (1<<13) // image using alpha channel +#define D3DSTATESECOND (1<<14) // always use 2nd floor texturing +#define D3DSTATEFOG (1<<15) // causes the fog +#define D3DSTATETCb (1<<16) // the transparent color (black = no) +#define D3DSTATETCw (1<<17) // the transparent color (white = no) + + +typedef struct +{ + D3DVERTEX2 triangle[3]; + D3DMATERIAL7 material; + int state; + char texName1[20]; + char texName2[20]; +} +D3DTriangle; + + +typedef struct +{ + int totalPossible; + int totalUsed; + D3DMATERIAL7 material; + int state; + D3DTypeTri type; // D3DTYPE6x + D3DVERTEX2 vertex[1]; +} +D3DObjLevel6; + +typedef struct +{ + int totalPossible; + int totalUsed; + int reserve; + D3DObjLevel6* table[1]; +} +D3DObjLevel5; + +typedef struct +{ + int totalPossible; + int totalUsed; + float min, max; + D3DObjLevel5* table[1]; +} +D3DObjLevel4; + +typedef struct +{ + int totalPossible; + int totalUsed; + int objRank; + D3DObjLevel4* table[1]; +} +D3DObjLevel3; + +typedef struct +{ + int totalPossible; + int totalUsed; + char texName1[20]; + char texName2[20]; + D3DObjLevel3* table[1]; +} +D3DObjLevel2; + +typedef struct +{ + int totalPossible; + int totalUsed; + D3DObjLevel2* table[1]; +} +D3DObjLevel1; + + +typedef struct +{ + char bUsed; // TRUE -> object exists + char bVisible; // TRUE -> visible object + char bDrawWorld; // TRUE -> shape behind the interface + char bDrawFront; // TRUE -> shape before the interface + int totalTriangle; // number of triangles used + D3DTypeObj type; // type of the object (TYPE*) + D3DMATRIX transform; // transformation matrix + float distance; // distance point of view - original + D3DVECTOR bboxMin; // bounding box of the object + D3DVECTOR bboxMax; // (the origin 0, 0, 0 is always included) + float radius; // radius of the sphere at the origin + int shadowRank; // rank of the associated shadow + float transparency; // transparency of the object (0 .. 1) +} +D3DObject; + +typedef struct +{ + char bUsed; // TRUE -> object exists + char bHide; // TRUE -> invisible shadow (object carried by ex.) + int objRank; // rank of the object + D3DShadowType type; // type of shadow + D3DVECTOR pos; // position for the shadow + D3DVECTOR normal; // normal terrain + float angle; // angle of the shadow + float radius; // radius of the shadow + float intensity; // intensity of the shadow + float height; // height from the ground +} +D3DShadow; + +typedef struct +{ + char bUsed; // TRUE -> object exists + D3DCOLORVALUE color; // color of the shadow + float min, max; // altitudes min / max + float smooth; // transition area + D3DVECTOR pos; // position for the shadow + float radius; // radius of the shadow + D3DVECTOR drawPos; // drawn to position the shade + float drawRadius; // radius of the shadow drawn +} +D3DGroundSpot; + +typedef struct +{ + char bUsed; // TRUE -> object exists + char bDraw; // TRUE -> drawn mark + int phase; // 1 = increase, 2 = fixed, 3 = decrease + float delay[3]; // time for 3 phases + float fix; // fixed time + D3DVECTOR pos; // position for marks + float radius; // radius of marks + float intensity; // color intensity + D3DVECTOR drawPos; // drawn in position marks + float drawRadius; // radius marks drawn + float drawIntensity; // current drawn + int dx, dy; // dimensions table + char* table; // pointer to the table +} +D3DGroundMark; + + + +class CD3DEngine +{ +public: + CD3DEngine(CInstanceManager *iMan, CD3DApplication *app); + ~CD3DEngine(); + + void SetD3DDevice(LPDIRECT3DDEVICE7 device); + LPDIRECT3DDEVICE7 RetD3DDevice(); + + void SetTerrain(CTerrain* terrain); + + BOOL WriteProfile(); + + void SetPause(BOOL bPause); + BOOL RetPause(); + + void SetMovieLock(BOOL bLock); + BOOL RetMovieLock(); + + void SetShowStat(BOOL bShow); + BOOL RetShowStat(); + + void SetRenderEnable(BOOL bEnable); + + HRESULT OneTimeSceneInit(); + HRESULT InitDeviceObjects(); + HRESULT DeleteDeviceObjects(); + HRESULT RestoreSurfaces(); + HRESULT Render(); + HRESULT FrameMove(float rTime); + void StepSimul(float rTime); + HRESULT FinalCleanup(); + void AddStatisticTriangle(int nb); + int RetStatisticTriangle(); + void SetHiliteRank(int *rankList); + BOOL GetHilite(FPOINT &p1, FPOINT &p2); + BOOL GetSpriteCoord(int &x, int &y); + void SetInfoText(int line, char* text); + char* RetInfoText(int line); + LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + void FirstExecuteAdapt(BOOL bFirst); + int GetVidMemTotal(); + BOOL IsVideo8MB(); + BOOL IsVideo32MB(); + + BOOL EnumDevices(char *bufDevices, int lenDevices, char *bufModes, int lenModes, int &totalDevices, int &selectDevices, int &totalModes, int &selectModes); + BOOL RetFullScreen(); + BOOL ChangeDevice(char *device, char *mode, BOOL bFull); + + D3DMATRIX* RetMatView(); + D3DMATRIX* RetMatLeftView(); + D3DMATRIX* RetMatRightView(); + + void TimeInit(); + void TimeEnterGel(); + void TimeExitGel(); + float TimeGet(); + + int RetRestCreate(); + int CreateObject(); + void FlushObject(); + BOOL DeleteObject(int objRank); + BOOL SetDrawWorld(int objRank, BOOL bDraw); + BOOL SetDrawFront(int objRank, BOOL bDraw); + BOOL AddTriangle(int objRank, D3DVERTEX2* vertex, int nb, const D3DMATERIAL7 &mat, int state, char* texName1, char* texName2, float min, float max, BOOL bGlobalUpdate); + BOOL AddSurface(int objRank, D3DVERTEX2* vertex, int nb, const D3DMATERIAL7 &mat, int state, char* texName1, char* texName2, float min, float max, BOOL bGlobalUpdate); + BOOL AddQuick(int objRank, D3DObjLevel6* buffer, char* texName1, char* texName2, float min, float max, BOOL bGlobalUpdate); + D3DObjLevel6* SearchTriangle(int objRank, const D3DMATERIAL7 &mat, int state, char* texName1, char* texName2, float min, float max); + void ChangeLOD(); + BOOL ChangeSecondTexture(int objRank, char* texName2); + int RetTotalTriangles(int objRank); + int GetTriangles(int objRank, float min, float max, D3DTriangle* buffer, int size, float percent); + BOOL GetBBox(int objRank, D3DVECTOR &min, D3DVECTOR &max); + BOOL ChangeTextureMapping(int objRank, const D3DMATERIAL7 &mat, int state, char* texName1, char* texName2, float min, float max, D3DMaping mode, float au, float bu, float av, float bv); + BOOL TrackTextureMapping(int objRank, const D3DMATERIAL7 &mat, int state, char* texName1, char* texName2, float min, float max, D3DMaping mode, float pos, float factor, float tl, float ts, float tt); + BOOL SetObjectTransform(int objRank, const D3DMATRIX &transform); + BOOL GetObjectTransform(int objRank, D3DMATRIX &transform); + BOOL SetObjectType(int objRank, D3DTypeObj type); + D3DTypeObj RetObjectType(int objRank); + BOOL SetObjectTransparency(int objRank, float value); + + BOOL ShadowCreate(int objRank); + void ShadowDelete(int objRank); + BOOL SetObjectShadowHide(int objRank, BOOL bHide); + BOOL SetObjectShadowType(int objRank, D3DShadowType type); + BOOL SetObjectShadowPos(int objRank, const D3DVECTOR &pos); + BOOL SetObjectShadowNormal(int objRank, const D3DVECTOR &n); + BOOL SetObjectShadowAngle(int objRank, float angle); + BOOL SetObjectShadowRadius(int objRank, float radius); + BOOL SetObjectShadowIntensity(int objRank, float intensity); + BOOL SetObjectShadowHeight(int objRank, float h); + float RetObjectShadowRadius(int objRank); + + void GroundSpotFlush(); + int GroundSpotCreate(); + void GroundSpotDelete(int rank); + BOOL SetObjectGroundSpotPos(int rank, const D3DVECTOR &pos); + BOOL SetObjectGroundSpotRadius(int rank, float radius); + BOOL SetObjectGroundSpotColor(int rank, D3DCOLORVALUE color); + BOOL SetObjectGroundSpotMinMax(int rank, float min, float max); + BOOL SetObjectGroundSpotSmooth(int rank, float smooth); + + int GroundMarkCreate(D3DVECTOR pos, float radius, float delay1, float delay2, float delay3, int dx, int dy, char* table); + BOOL GroundMarkDelete(int rank); + + void Update(); + + void SetViewParams(const D3DVECTOR &vEyePt, const D3DVECTOR &vLookatPt, const D3DVECTOR &vUpVec, FLOAT fEyeDistance); + + BOOL FreeTexture(char* name); + BOOL LoadTexture(char* name, int stage=0); + BOOL LoadAllTexture(); + + void SetLimitLOD(int rank, float limit); + float RetLimitLOD(int rank, BOOL bLast=FALSE); + + void SetTerrainVision(float vision); + + void SetGroundSpot(BOOL bMode); + BOOL RetGroundSpot(); + void SetShadow(BOOL bMode); + BOOL RetShadow(); + void SetDirty(BOOL bMode); + BOOL RetDirty(); + void SetFog(BOOL bMode); + BOOL RetFog(); + BOOL RetStateColor(); + + void SetSecondTexture(int texNum); + int RetSecondTexture(); + + void SetRankView(int rank); + int RetRankView(); + + void SetDrawWorld(BOOL bDraw); + void SetDrawFront(BOOL bDraw); + + void SetAmbiantColor(D3DCOLOR color, int rank=0); + D3DCOLOR RetAmbiantColor(int rank=0); + + void SetWaterAddColor(D3DCOLORVALUE color); + D3DCOLORVALUE RetWaterAddColor(); + + void SetFogColor(D3DCOLOR color, int rank=0); + D3DCOLOR RetFogColor(int rank=0); + + void SetDeepView(float length, int rank=0, BOOL bRef=FALSE); + float RetDeepView(int rank=0); + + void SetFogStart(float start, int rank=0); + float RetFogStart(int rank=0); + + void SetBackground(char *name, D3DCOLOR up=0, D3DCOLOR down=0, D3DCOLOR cloudUp=0, D3DCOLOR cloudDown=0, BOOL bFull=FALSE, BOOL bQuarter=FALSE); + void RetBackground(char *name, D3DCOLOR &up, D3DCOLOR &down, D3DCOLOR &cloudUp, D3DCOLOR &cloudDown, BOOL &bFull, BOOL &bQuarter); + void SetFrontsizeName(char *name); + void SetOverFront(BOOL bFront); + void SetOverColor(D3DCOLOR color=0, int mode=D3DSTATETCb); + + void SetParticuleDensity(float value); + float RetParticuleDensity(); + float ParticuleAdapt(float factor); + + void SetClippingDistance(float value); + float RetClippingDistance(); + + void SetObjectDetail(float value); + float RetObjectDetail(); + + void SetGadgetQuantity(float value); + float RetGadgetQuantity(); + + void SetTextureQuality(int value); + int RetTextureQuality(); + + void SetTotoMode(BOOL bPresent); + BOOL RetTotoMode(); + + void SetLensMode(BOOL bPresent); + BOOL RetLensMode(); + + void SetWaterMode(BOOL bPresent); + BOOL RetWaterMode(); + + void SetBlitzMode(BOOL bPresent); + BOOL RetBlitzMode(); + + void SetSkyMode(BOOL bPresent); + BOOL RetSkyMode(); + + void SetBackForce(BOOL bPresent); + BOOL RetBackForce(); + + void SetPlanetMode(BOOL bPresent); + BOOL RetPlanetMode(); + + void SetLightMode(BOOL bPresent); + BOOL RetLightMode(); + + void SetEditIndentMode(BOOL bAuto); + BOOL RetEditIndentMode(); + + void SetEditIndentValue(int value); + int RetEditIndentValue(); + + void SetSpeed(float speed); + float RetSpeed(); + + void SetTracePrecision(float factor); + float RetTracePrecision(); + + void SetFocus(float focus); + float RetFocus(); + D3DVECTOR RetEyePt(); + D3DVECTOR RetLookatPt(); + float RetEyeDirH(); + float RetEyeDirV(); + POINT RetDim(); + void UpdateMatProj(); + + void ApplyChange(); + + void FlushPressKey(); + void ResetKey(); + void SetKey(int keyRank, int option, int key); + int RetKey(int keyRank, int option); + + void SetJoystick(BOOL bEnable); + BOOL RetJoystick(); + + void SetDebugMode(BOOL bMode); + BOOL RetDebugMode(); + BOOL RetSetupMode(); + + BOOL IsVisiblePoint(const D3DVECTOR &pos); + + int DetectObject(FPOINT mouse); + void SetState(int state, D3DCOLOR color=0xffffffff); + void SetTexture(char *name, int stage=0); + void SetMaterial(const D3DMATERIAL7 &mat); + + void MoveMousePos(FPOINT pos); + void SetMousePos(FPOINT pos); + FPOINT RetMousePos(); + void SetMouseType(D3DMouse type); + D3DMouse RetMouseType(); + void SetMouseHide(BOOL bHide); + BOOL RetMouseHide(); + void SetNiceMouse(BOOL bNice); + BOOL RetNiceMouse(); + BOOL RetNiceMouseCap(); + + CText* RetText(); + + BOOL ChangeColor(char *name, D3DCOLORVALUE colorRef1, D3DCOLORVALUE colorNew1, D3DCOLORVALUE colorRef2, D3DCOLORVALUE colorNew2, float tolerance1, float tolerance2, FPOINT ts, FPOINT ti, FPOINT *pExclu=0, float shift=0.0f, BOOL bHSV=FALSE); + BOOL OpenImage(char *name); + BOOL CopyImage(); + BOOL LoadImage(); + BOOL ScrollImage(int dx, int dy); + BOOL SetDot(int x, int y, D3DCOLORVALUE color); + BOOL CloseImage(); + BOOL WriteScreenShot(char *filename, int width, int height); + BOOL GetRenderDC(HDC &hDC); + BOOL ReleaseRenderDC(HDC &hDC); + PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp); + BOOL CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC); + +protected: + void MemSpace1(D3DObjLevel1 *&p, int nb); + void MemSpace2(D3DObjLevel2 *&p, int nb); + void MemSpace3(D3DObjLevel3 *&p, int nb); + void MemSpace4(D3DObjLevel4 *&p, int nb); + void MemSpace5(D3DObjLevel5 *&p, int nb); + void MemSpace6(D3DObjLevel6 *&p, int nb); + + D3DObjLevel2* AddLevel1(D3DObjLevel1 *&p1, char* texName1, char* texName2); + D3DObjLevel3* AddLevel2(D3DObjLevel2 *&p2, int objRank); + D3DObjLevel4* AddLevel3(D3DObjLevel3 *&p3, float min, float max); + D3DObjLevel5* AddLevel4(D3DObjLevel4 *&p4, int reserve); + D3DObjLevel6* AddLevel5(D3DObjLevel5 *&p5, D3DTypeTri type, const D3DMATERIAL7 &mat, int state, int nb); + + BOOL IsVisible(int objRank); + BOOL DetectBBox(int objRank, FPOINT mouse); + BOOL DetectTriangle(FPOINT mouse, D3DVERTEX2 *triangle, int objRank, float &dist); + BOOL TransformPoint(D3DVECTOR &p2D, int objRank, D3DVECTOR p3D); + void ComputeDistance(); + void UpdateGeometry(); + void RenderGroundSpot(); + void DrawShadow(); + void DrawBackground(); + void DrawBackgroundGradient(D3DCOLOR up, D3DCOLOR down); + void DrawBackgroundImageQuarter(FPOINT p1, FPOINT p2, char *name); + void DrawBackgroundImage(); + void DrawPlanet(); + void DrawFrontsize(); + void DrawOverColor(); + BOOL GetBBox2D(int objRank, FPOINT &min, FPOINT &max); + void DrawHilite(); + void DrawMouse(); + void DrawSprite(FPOINT pos, FPOINT dim, int icon); + +protected: + CInstanceManager* m_iMan; + CD3DApplication* m_app; + LPDIRECT3DDEVICE7 m_pD3DDevice; + CText* m_text; + CLight* m_light; + CParticule* m_particule; + CWater* m_water; + CCloud* m_cloud; + CBlitz* m_blitz; + CPlanet* m_planet; + CSound* m_sound; + CTerrain* m_terrain; + + int m_blackSrcBlend[2]; + int m_blackDestBlend[2]; + int m_whiteSrcBlend[2]; + int m_whiteDestBlend[2]; + int m_diffuseSrcBlend[2]; + int m_diffuseDestBlend[2]; + int m_alphaSrcBlend[2]; + int m_alphaDestBlend[2]; + + D3DMATRIX m_matProj; + D3DMATRIX m_matLeftView; + D3DMATRIX m_matRightView; + D3DMATRIX m_matView; + float m_focus; + + D3DMATRIX m_matWorldInterface; + D3DMATRIX m_matProjInterface; + D3DMATRIX m_matViewInterface; + + DWORD m_baseTime; + DWORD m_stopTime; + float m_absTime; + float m_lastTime; + float m_speed; + BOOL m_bPause; + BOOL m_bRender; + BOOL m_bMovieLock; + + POINT m_dim; + POINT m_lastDim; + D3DObjLevel1* m_objectPointer; + int m_objectParamTotal; + D3DObject* m_objectParam; + int m_shadowTotal; + D3DShadow* m_shadow; + D3DGroundSpot* m_groundSpot; + D3DGroundMark m_groundMark; + D3DVECTOR m_eyePt; + D3DVECTOR m_lookatPt; + float m_eyeDirH; + float m_eyeDirV; + int m_rankView; + D3DCOLOR m_ambiantColor[2]; + D3DCOLOR m_backColor[2]; + D3DCOLOR m_fogColor[2]; + float m_deepView[2]; + float m_fogStart[2]; + D3DCOLORVALUE m_waterAddColor; + int m_statisticTriangle; + BOOL m_bUpdateGeometry; + char m_infoText[10][200]; + int m_alphaMode; + BOOL m_bStateColor; + BOOL m_bForceStateColor; + BOOL m_bGroundSpot; + BOOL m_bShadow; + BOOL m_bDirty; + BOOL m_bFog; + BOOL m_bFirstGroundSpot; + int m_secondTexNum; + char m_backgroundName[50]; + D3DCOLOR m_backgroundColorUp; + D3DCOLOR m_backgroundColorDown; + D3DCOLOR m_backgroundCloudUp; + D3DCOLOR m_backgroundCloudDown; + BOOL m_bBackgroundFull; + BOOL m_bBackgroundQuarter; + BOOL m_bOverFront; + D3DCOLOR m_overColor; + int m_overMode; + char m_frontsizeName[50]; + BOOL m_bDrawWorld; + BOOL m_bDrawFront; + float m_limitLOD[2]; + float m_particuleDensity; + float m_clippingDistance; + float m_lastClippingDistance; + float m_objectDetail; + float m_lastObjectDetail; + float m_terrainVision; + float m_gadgetQuantity; + int m_textureQuality; + BOOL m_bTotoMode; + BOOL m_bLensMode; + BOOL m_bWaterMode; + BOOL m_bSkyMode; + BOOL m_bBackForce; + BOOL m_bPlanetMode; + BOOL m_bLightMode; + BOOL m_bEditIndentMode; + int m_editIndentValue; + float m_tracePrecision; + + int m_hiliteRank[100]; + BOOL m_bHilite; + FPOINT m_hiliteP1; + FPOINT m_hiliteP2; + + int m_lastState; + D3DCOLOR m_lastColor; + char m_lastTexture[2][50]; + D3DMATERIAL7 m_lastMaterial; + + FPOINT m_mousePos; + D3DMouse m_mouseType; + BOOL m_bMouseHide; + BOOL m_bNiceMouse; + + LPDIRECTDRAWSURFACE7 m_imageSurface; + DDSURFACEDESC2 m_imageDDSD; + WORD* m_imageCopy; + int m_imageDX; + int m_imageDY; +}; + + +#endif //_D3DENGINE_H_ diff --git a/src/graphics/d3d/d3denum.cpp b/src/graphics/d3d/d3denum.cpp new file mode 100644 index 0000000..46497d8 --- /dev/null +++ b/src/graphics/d3d/d3denum.cpp @@ -0,0 +1,621 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +//----------------------------------------------------------------------------- +// File: D3DEnum.cpp +// +// Desc: Functions to enumerate DDraw/D3D drivers, devices, and modes. +// +// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved +//----------------------------------------------------------------------------- +#define STRICT +#include +#include +#include +#include "d3denum.h" +#include "d3dutil.h" // For DEBUG_MSG +#include "d3dres.h" // For dialog controls + + + + +//----------------------------------------------------------------------------- +// Global data for the enumerator functions +//----------------------------------------------------------------------------- +static HRESULT (*g_fnAppConfirmFn)(DDCAPS*, D3DDEVICEDESC7*) = NULL; + +static D3DEnum_DeviceInfo g_pDeviceList[20]; +static DWORD g_dwNumDevicesEnumerated = 0L; +static DWORD g_dwNumDevices = 0L; + + + + +//----------------------------------------------------------------------------- +// Name: SortModesCallback() +// Desc: Callback function for sorting display modes. +//----------------------------------------------------------------------------- +int SortModesCallback( const VOID* arg1, const VOID* arg2 ) +{ + DDSURFACEDESC2* p1 = (DDSURFACEDESC2*)arg1; + DDSURFACEDESC2* p2 = (DDSURFACEDESC2*)arg2; + + if( p1->dwWidth < p2->dwWidth ) + return -1; + if( p1->dwWidth > p2->dwWidth ) + return +1; + + if( p1->dwHeight < p2->dwHeight ) + return -1; + if( p1->dwHeight > p2->dwHeight ) + return +1; + + if( p1->ddpfPixelFormat.dwRGBBitCount < p2->ddpfPixelFormat.dwRGBBitCount ) + return -1; + if( p1->ddpfPixelFormat.dwRGBBitCount > p2->ddpfPixelFormat.dwRGBBitCount ) + return +1; + + return 0; +} + + + + +//----------------------------------------------------------------------------- +// Name: ModeEnumCallback() +// Desc: Callback function for enumerating display modes. +//----------------------------------------------------------------------------- +static HRESULT WINAPI ModeEnumCallback( DDSURFACEDESC2* pddsd, + VOID* pParentInfo ) +{ + D3DEnum_DeviceInfo* pDevice = (D3DEnum_DeviceInfo*)pParentInfo; + + // Reallocate storage for the modes + DDSURFACEDESC2* pddsdNewModes = new DDSURFACEDESC2[pDevice->dwNumModes+1]; + memcpy( pddsdNewModes, pDevice->pddsdModes, + pDevice->dwNumModes * sizeof(DDSURFACEDESC2) ); + delete pDevice->pddsdModes; + pDevice->pddsdModes = pddsdNewModes; + + // Add the new mode + pDevice->pddsdModes[pDevice->dwNumModes++] = (*pddsd); + + return DDENUMRET_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: DeviceEnumCallback() +// Desc: Callback function for enumerating devices +//----------------------------------------------------------------------------- +static HRESULT WINAPI DeviceEnumCallback( TCHAR* strDesc, TCHAR* strName, + D3DDEVICEDESC7* pDesc, + VOID* pParentInfo ) +{ + DWORD i; + + // Keep track of # of devices that were enumerated + g_dwNumDevicesEnumerated++; + + D3DEnum_DeviceInfo* pDriverInfo = (D3DEnum_DeviceInfo*)pParentInfo; + D3DEnum_DeviceInfo* pDeviceInfo = &g_pDeviceList[g_dwNumDevices]; + ZeroMemory( pDeviceInfo, sizeof(D3DEnum_DeviceInfo) ); + + // Select either the HAL or HEL device desc: + pDeviceInfo->bHardware = pDesc->dwDevCaps & D3DDEVCAPS_HWRASTERIZATION; + memcpy( &pDeviceInfo->ddDeviceDesc, pDesc, sizeof(D3DDEVICEDESC7) ); + + // Set up device info for this device + pDeviceInfo->bDesktopCompatible = pDriverInfo->bDesktopCompatible; + pDeviceInfo->ddDriverCaps = pDriverInfo->ddDriverCaps; + pDeviceInfo->ddHELCaps = pDriverInfo->ddHELCaps; + pDeviceInfo->guidDevice = pDesc->deviceGUID; + pDeviceInfo->pDeviceGUID = &pDeviceInfo->guidDevice; + pDeviceInfo->pddsdModes = new DDSURFACEDESC2[pDriverInfo->dwNumModes]; + + // Copy the driver GUID and description for the device + if( pDriverInfo->pDriverGUID ) + { + pDeviceInfo->guidDriver = pDriverInfo->guidDriver; + pDeviceInfo->pDriverGUID = &pDeviceInfo->guidDriver; + lstrcpyn( pDeviceInfo->strDesc, pDriverInfo->strDesc, 39 ); + } + else + { + pDeviceInfo->pDriverGUID = NULL; + lstrcpyn( pDeviceInfo->strDesc, strName, 39 ); + } + +//? if( strstr(strName, "T&L") != 0 ) return D3DENUMRET_OK; + + // Avoid duplicates: only enum HW devices for secondary DDraw drivers. + if( NULL != pDeviceInfo->pDriverGUID && FALSE == pDeviceInfo->bHardware ) + return D3DENUMRET_OK; + + // Give the app a chance to accept or reject this device. + if( g_fnAppConfirmFn ) + if( FAILED( g_fnAppConfirmFn( &pDeviceInfo->ddDriverCaps, + &pDeviceInfo->ddDeviceDesc ) ) ) + return D3DENUMRET_OK; + + // Build list of supported modes for the device + for( i=0; idwNumModes; i++ ) + { + DDSURFACEDESC2 ddsdMode = pDriverInfo->pddsdModes[i]; + DWORD dwRenderDepths = pDeviceInfo->ddDeviceDesc.dwDeviceRenderBitDepth; + DWORD dwDepth = ddsdMode.ddpfPixelFormat.dwRGBBitCount; + + // Accept modes that are compatable with the device + if( ( ( dwDepth == 32 ) && ( dwRenderDepths & DDBD_32 ) ) || + ( ( dwDepth == 24 ) && ( dwRenderDepths & DDBD_24 ) ) || + ( ( dwDepth == 16 ) && ( dwRenderDepths & DDBD_16 ) ) ) + { + // Copy compatible modes to the list of device-supported modes + pDeviceInfo->pddsdModes[pDeviceInfo->dwNumModes++] = ddsdMode; + + // Record whether the device has any stereo modes + if( ddsdMode.ddsCaps.dwCaps2 & DDSCAPS2_STEREOSURFACELEFT ) + pDeviceInfo->bStereoCompatible = TRUE; + } + } + + // Bail if the device has no supported modes + if( 0 == pDeviceInfo->dwNumModes ) + return D3DENUMRET_OK; + + // Find a 640x480x16 mode for the default fullscreen mode + for( i=0; idwNumModes; i++ ) + { + if( ( pDeviceInfo->pddsdModes[i].dwWidth == 640 ) && + ( pDeviceInfo->pddsdModes[i].dwHeight == 480 ) && + ( pDeviceInfo->pddsdModes[i].ddpfPixelFormat.dwRGBBitCount == 16 ) ) + { + pDeviceInfo->ddsdFullscreenMode = pDeviceInfo->pddsdModes[i]; + pDeviceInfo->dwCurrentMode = i; + } + } + + // Select whether the device is initially windowed + pDeviceInfo->bWindowed = pDeviceInfo->bDesktopCompatible; + + // Accept the device and return + g_dwNumDevices++; + + return D3DENUMRET_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: DriverEnumCallback() +// Desc: Callback function for enumerating drivers. +//----------------------------------------------------------------------------- +static BOOL WINAPI DriverEnumCallback( GUID* pGUID, TCHAR* strDesc, + TCHAR* strName, VOID*, HMONITOR ) +{ + D3DEnum_DeviceInfo d3dDeviceInfo; + LPDIRECTDRAW7 pDD; + LPDIRECT3D7 pD3D; + HRESULT hr; + + // Use the GUID to create the DirectDraw object + hr = DirectDrawCreateEx( pGUID, (VOID**)&pDD, IID_IDirectDraw7, NULL ); + if( FAILED(hr) ) + { + DEBUG_MSG( _T("Can't create DDraw during enumeration!") ); + return D3DENUMRET_OK; + } + + // Create a D3D object, to enumerate the d3d devices + hr = pDD->QueryInterface( IID_IDirect3D7, (VOID**)&pD3D ); + if( FAILED(hr) ) + { + pDD->Release(); + DEBUG_MSG( _T("Can't query IDirect3D7 during enumeration!") ); + return D3DENUMRET_OK; + } + + // Copy data to a device info structure + ZeroMemory( &d3dDeviceInfo, sizeof(d3dDeviceInfo) ); + lstrcpyn( d3dDeviceInfo.strDesc, strDesc, 39 ); + d3dDeviceInfo.ddDriverCaps.dwSize = sizeof(DDCAPS); + d3dDeviceInfo.ddHELCaps.dwSize = sizeof(DDCAPS); + pDD->GetCaps( &d3dDeviceInfo.ddDriverCaps, &d3dDeviceInfo.ddHELCaps ); + if( pGUID ) + { + d3dDeviceInfo.guidDriver = (*pGUID); + d3dDeviceInfo.pDriverGUID = &d3dDeviceInfo.guidDriver; + } + + // Record whether the device can render into a desktop window + if( d3dDeviceInfo.ddDriverCaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED ) + if( NULL == d3dDeviceInfo.pDriverGUID ) + d3dDeviceInfo.bDesktopCompatible = TRUE; + + // Enumerate the fullscreen display modes. + pDD->EnumDisplayModes( 0, NULL, &d3dDeviceInfo, ModeEnumCallback ); + + // Sort list of display modes + qsort( d3dDeviceInfo.pddsdModes, d3dDeviceInfo.dwNumModes, + sizeof(DDSURFACEDESC2), SortModesCallback ); + + // Now, enumerate all the 3D devices + pD3D->EnumDevices( DeviceEnumCallback, &d3dDeviceInfo ); + + // Clean up and return + SAFE_DELETE( d3dDeviceInfo.pddsdModes ); + pD3D->Release(); + pDD->Release(); + + return DDENUMRET_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DEnum_EnumerateDevices() +// Desc: Enumerates all drivers, devices, and modes. The callback function is +// called each device, to confirm that the device supports the feature +// set required by the app. +//----------------------------------------------------------------------------- +HRESULT D3DEnum_EnumerateDevices( HRESULT (*AppConfirmFn)(DDCAPS*, D3DDEVICEDESC7*) ) +{ + // Store the device enumeration callback function + g_fnAppConfirmFn = AppConfirmFn; + + // Enumerate drivers, devices, and modes + DirectDrawEnumerateEx( DriverEnumCallback, NULL, + DDENUM_ATTACHEDSECONDARYDEVICES | + DDENUM_DETACHEDSECONDARYDEVICES | + DDENUM_NONDISPLAYDEVICES ); + + // Make sure devices were actually enumerated + if( 0 == g_dwNumDevicesEnumerated ) + { + DEBUG_MSG( _T("No devices and/or modes were enumerated!") ); + return D3DENUMERR_ENUMERATIONFAILED; + } + if( 0 == g_dwNumDevices ) + { + DEBUG_MSG( _T("No enumerated devices were accepted!") ); + DEBUG_MSG( _T("Try enabling the D3D Reference Rasterizer.") ); + return D3DENUMERR_SUGGESTREFRAST; + } + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DEnum_FreeResources() +// Desc: Cleans up any memory allocated during device enumeration +//----------------------------------------------------------------------------- +VOID D3DEnum_FreeResources() +{ + for( DWORD i=0; ibDesktopCompatible ) + bWindowed = FALSE; + + // Add a list of devices to the device combo box + for( DWORD device = 0; device < dwNumDevices; device++ ) + { + D3DEnum_DeviceInfo* pDevice = &pDeviceList[device]; + + // Add device name to the combo box + DWORD dwItem = ComboBox_AddString( hwndDevice, pDevice->strDesc ); + + // Set the remaining UI states for the current device + if( pDevice == pCurrentDevice ) + { + // Set the combobox selection on the current device + ComboBox_SetCurSel( hwndDevice, dwItem ); + + // Enable/set the fullscreen checkbox, as appropriate + if( hwndWindowed ) + { + EnableWindow( hwndWindowed, pDevice->bDesktopCompatible ); + Button_SetCheck( hwndWindowed, bWindowed ); + } + + // Enable/set the stereo checkbox, as appropriate + if( hwndStereo ) + { + EnableWindow( hwndStereo, pDevice->bStereoCompatible && !bWindowed ); + Button_SetCheck( hwndStereo, bStereo ); + } + + // Enable/set the fullscreen modes combo, as appropriate + EnableWindow( hwndMode, !bWindowed ); + EnableWindow( hwndFullscreenText, !bWindowed ); + + // Build the list of fullscreen modes + for( DWORD mode = 0; mode < pDevice->dwNumModes; mode++ ) + { + DDSURFACEDESC2* pddsdMode = &pDevice->pddsdModes[mode]; + + // Skip non-stereo modes, if the device is in stereo mode + if( 0 == (pddsdMode->ddsCaps.dwCaps2&DDSCAPS2_STEREOSURFACELEFT) ) + if( bStereo ) + continue; + + TCHAR strMode[80]; + wsprintf( strMode, _T("%ld x %ld x %ld"), + pddsdMode->dwWidth, pddsdMode->dwHeight, + pddsdMode->ddpfPixelFormat.dwRGBBitCount ); + + // Add mode desc to the combo box + DWORD dwItem = ComboBox_AddString( hwndMode, strMode ); + + // Set the item data to identify this mode + ComboBox_SetItemData( hwndMode, dwItem, mode ); + + // Set the combobox selection on the current mode + if( mode == dwCurrentMode ) + ComboBox_SetCurSel( hwndMode, dwItem ); + + // Since not all modes support stereo, select a default mode in + // case none was chosen yet. + if( bStereo && ( CB_ERR == ComboBox_GetCurSel( hwndMode ) ) ) + ComboBox_SetCurSel( hwndMode, dwItem ); + } + } + } +} + + + + +//----------------------------------------------------------------------------- +// Name: ChangeDeviceProc() +// Desc: Windows message handling function for the device select dialog +//----------------------------------------------------------------------------- +static INT_PTR CALLBACK ChangeDeviceProc( HWND hDlg, UINT uiMsg, WPARAM wParam, + LPARAM lParam ) +{ + static D3DEnum_DeviceInfo** ppDeviceArg; + static D3DEnum_DeviceInfo* pCurrentDevice; + static DWORD dwCurrentMode; + static BOOL bCurrentWindowed; + static BOOL bCurrentStereo; + + // Get access to the enumerated device list + D3DEnum_DeviceInfo* pDeviceList; + DWORD dwNumDevices; + D3DEnum_GetDevices( &pDeviceList, &dwNumDevices ); + + // Handle the initialization message + if( WM_INITDIALOG == uiMsg ) + { + // Get the app's current device, passed in as an lParam argument + ppDeviceArg = (D3DEnum_DeviceInfo**)lParam; + if( NULL == ppDeviceArg ) + return FALSE; + + // Setup temp storage pointers for dialog + pCurrentDevice = (*ppDeviceArg); + dwCurrentMode = pCurrentDevice->dwCurrentMode; + bCurrentWindowed = pCurrentDevice->bWindowed; + bCurrentStereo = pCurrentDevice->bStereo; + + UpdateDialogControls( hDlg, pCurrentDevice, dwCurrentMode, + bCurrentWindowed, bCurrentStereo ); + + return TRUE; + } + else if( WM_COMMAND == uiMsg ) + { + HWND hwndDevice = GetDlgItem( hDlg, IDC_DEVICE_COMBO ); + HWND hwndMode = GetDlgItem( hDlg, IDC_MODE_COMBO ); + HWND hwndWindowed = GetDlgItem( hDlg, IDC_WINDOWED_CHECKBOX ); + HWND hwndStereo = GetDlgItem( hDlg, IDC_STEREO_CHECKBOX ); + + // Get current UI state + DWORD dwDevice = ComboBox_GetCurSel( hwndDevice ); + DWORD dwModeItem = ComboBox_GetCurSel( hwndMode ); + DWORD dwMode = ComboBox_GetItemData( hwndMode, dwModeItem ); + BOOL bWindowed = hwndWindowed ? Button_GetCheck( hwndWindowed ) : 0; + BOOL bStereo = hwndStereo ? Button_GetCheck( hwndStereo ) : 0; + + D3DEnum_DeviceInfo* pDevice = &pDeviceList[dwDevice]; + + if( IDOK == LOWORD(wParam) ) + { + // Handle the case when the user hits the OK button. Check if any + // of the options were changed + if( pDevice != pCurrentDevice || dwMode != dwCurrentMode || + bWindowed != bCurrentWindowed || bStereo != bCurrentStereo ) + { + // Return the newly selected device and its new properties + (*ppDeviceArg) = pDevice; + pDevice->bWindowed = bWindowed; + pDevice->bStereo = bStereo; + pDevice->dwCurrentMode = dwMode; + pDevice->ddsdFullscreenMode = pDevice->pddsdModes[dwMode]; + + EndDialog( hDlg, IDOK ); + } + else + EndDialog( hDlg, IDCANCEL ); + + return TRUE; + } + else if( IDCANCEL == LOWORD(wParam) ) + { + // Handle the case when the user hits the Cancel button + EndDialog( hDlg, IDCANCEL ); + return TRUE; + } + else if( CBN_SELENDOK == HIWORD(wParam) ) + { + if( LOWORD(wParam) == IDC_DEVICE_COMBO ) + { + // Handle the case when the user chooses the device combo + dwMode = pDeviceList[dwDevice].dwCurrentMode; + bWindowed = pDeviceList[dwDevice].bWindowed; + bStereo = pDeviceList[dwDevice].bStereo; + } + } + + // Keep the UI current + UpdateDialogControls( hDlg, &pDeviceList[dwDevice], dwMode, bWindowed, bStereo ); + return TRUE; + } + + return FALSE; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DEnum_UserChangeDevice() +// Desc: Pops up a dialog which allows the user to select a new device. +//----------------------------------------------------------------------------- +HRESULT D3DEnum_UserChangeDevice( D3DEnum_DeviceInfo** ppDevice ) +{ + if( IDOK == DialogBoxParam( (HINSTANCE)GetModuleHandle(NULL), + MAKEINTRESOURCE(IDD_CHANGEDEVICE), + GetForegroundWindow(), + ChangeDeviceProc, (LPARAM)ppDevice ) ) + return S_OK; + + return E_FAIL; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DEnum_SelectDefaultDevice() +// Desc: Pick a default device, preferably hardware and desktop compatible. +//----------------------------------------------------------------------------- +HRESULT D3DEnum_SelectDefaultDevice( D3DEnum_DeviceInfo** ppDevice, + DWORD dwFlags ) +{ + // Check arguments + if( NULL == ppDevice ) + return E_INVALIDARG; + + // Get access to the enumerated device list + D3DEnum_DeviceInfo* pDeviceList; + DWORD dwNumDevices; + D3DEnum_GetDevices( &pDeviceList, &dwNumDevices ); + + // Look for windowable software, hardware, and hardware TnL devices + D3DEnum_DeviceInfo* pRefRastDevice = NULL; + D3DEnum_DeviceInfo* pSoftwareDevice = NULL; + D3DEnum_DeviceInfo* pHardwareDevice = NULL; + D3DEnum_DeviceInfo* pHardwareTnLDevice = NULL; + + for( DWORD i=0; ibWindowed = TRUE; + + return S_OK; +} + + + + + diff --git a/src/graphics/d3d/d3denum.h b/src/graphics/d3d/d3denum.h new file mode 100644 index 0000000..e728ffb --- /dev/null +++ b/src/graphics/d3d/d3denum.h @@ -0,0 +1,136 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +//----------------------------------------------------------------------------- +// File: D3DEnum.h +// +// Desc: Functions to enumerate DDraw/D3D drivers, devices, and modes. +// +// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved +//----------------------------------------------------------------------------- +#ifndef D3DENUM_H +#define D3DENUM_H +#include + + +//----------------------------------------------------------------------------- +// Flag and error definitions +//----------------------------------------------------------------------------- +#define D3DENUM_SOFTWAREONLY 0x00000001 // Software-devices only flag + +#define D3DENUMERR_NODIRECTDRAW 0x81000001 // Could not create DDraw +#define D3DENUMERR_ENUMERATIONFAILED 0x81000002 // Enumeration failed +#define D3DENUMERR_SUGGESTREFRAST 0x81000003 // Suggest using the RefRast +#define D3DENUMERR_NOCOMPATIBLEDEVICES 0x81000004 // No devices were found that + // meet the app's desired + // capabilities +#define D3DENUMERR_ENGINE 0x81000005 // 3D engine error +#define D3DENUMERR_ROBOT 0x81000006 // robot error +#define D3DENUMERR_SOUND 0x81000007 // sound error + + +//----------------------------------------------------------------------------- +// Name: struct D3DEnum_DeviceInfo +// Desc: Structure to hold info about the enumerated Direct3D devices. +//----------------------------------------------------------------------------- +struct D3DEnum_DeviceInfo +{ + // D3D Device info + TCHAR strDesc[40]; + GUID* pDeviceGUID; + D3DDEVICEDESC7 ddDeviceDesc; + BOOL bHardware; + + // DDraw Driver info + GUID* pDriverGUID; + DDCAPS ddDriverCaps; + DDCAPS ddHELCaps; + + // DDraw Mode Info + DDSURFACEDESC2 ddsdFullscreenMode; + BOOL bWindowed; + BOOL bStereo; + + // For internal use (apps should not need to use these) + GUID guidDevice; + GUID guidDriver; + DDSURFACEDESC2* pddsdModes; + DWORD dwNumModes; + DWORD dwCurrentMode; + BOOL bDesktopCompatible; + BOOL bStereoCompatible; +}; + + +// For code not yet switched to new struct name +typedef D3DEnum_DeviceInfo D3DDEVICEINFO; + + + + +//----------------------------------------------------------------------------- +// Name: D3DEnum_EnumerateDevices() +// Desc: Enumerates all drivers, devices, and modes. The callback function is +// called each device, to confirm that the device supports the feature +// set required by the app. +//----------------------------------------------------------------------------- +HRESULT D3DEnum_EnumerateDevices( HRESULT (*fn)(DDCAPS*, D3DDEVICEDESC7*) ); + + + + +//----------------------------------------------------------------------------- +// Name: D3DEnum_FreeResources() +// Desc: Cleans up any memory allocated during device enumeration +//----------------------------------------------------------------------------- +VOID D3DEnum_FreeResources(); + + + + +//----------------------------------------------------------------------------- +// Name: D3DEnum_GetDevices() +// Desc: Returns a ptr to the array of enumerated D3DDEVICEINFO structures. +//----------------------------------------------------------------------------- +VOID D3DEnum_GetDevices( D3DEnum_DeviceInfo** ppDevices, DWORD* pdwCount ); + + + + +//----------------------------------------------------------------------------- +// Name: D3DEnum_SelectDefaultDevice() +// Desc: Picks a driver based on a set of passed in criteria. The +// D3DENUM_SOFTWAREONLY flag can be used to pick a software device. +//----------------------------------------------------------------------------- +HRESULT D3DEnum_SelectDefaultDevice( D3DEnum_DeviceInfo** pDevice, + DWORD dwFlags = 0L ); + + + + +//----------------------------------------------------------------------------- +// Name: D3DEnum_UserChangeDevice() +// Desc: Pops up a dialog which allows the user to select a new device. +//----------------------------------------------------------------------------- +HRESULT D3DEnum_UserChangeDevice( D3DEnum_DeviceInfo** ppDevice ); + + + + +#endif // D3DENUM_H + + + diff --git a/src/graphics/d3d/d3dframe.cpp b/src/graphics/d3d/d3dframe.cpp new file mode 100644 index 0000000..3207a4b --- /dev/null +++ b/src/graphics/d3d/d3dframe.cpp @@ -0,0 +1,623 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +//----------------------------------------------------------------------------- +// File: D3DFrame.cpp +// +// Desc: Class functions to implement a Direct3D app framework. +// +// Copyright (c) 1995-1999 by Microsoft, all rights reserved +//----------------------------------------------------------------------------- +#define STRICT +#include +#include +#include +#include "d3dframe.h" +#include "d3dutil.h" + + + + +//----------------------------------------------------------------------------- +// Name: CD3DFramework7() +// Desc: The constructor. Clears static variables +//----------------------------------------------------------------------------- +CD3DFramework7::CD3DFramework7() +{ + m_hWnd = NULL; + m_bIsFullscreen = FALSE; + m_bIsStereo = FALSE; + m_dwRenderWidth = 0L; + m_dwRenderHeight = 0L; + + m_pddsFrontBuffer = NULL; + m_pddsBackBuffer = NULL; + m_pddsBackBufferLeft = NULL; + + m_pddsZBuffer = NULL; + m_pd3dDevice = NULL; + m_pDD = NULL; + m_pD3D = NULL; + m_dwDeviceMemType = NULL; +} + + + + +//----------------------------------------------------------------------------- +// Name: ~CD3DFramework7() +// Desc: The destructor. Deletes all objects +//----------------------------------------------------------------------------- +CD3DFramework7::~CD3DFramework7() +{ + DestroyObjects(); +} + + + + +//----------------------------------------------------------------------------- +// Name: DestroyObjects() +// Desc: Cleans everything up upon deletion. This code returns an error +// if any of the objects have remaining reference counts. +//----------------------------------------------------------------------------- +HRESULT CD3DFramework7::DestroyObjects() +{ + LONG nDD = 0L; // Number of outstanding DDraw references + LONG nD3D = 0L; // Number of outstanding D3DDevice references + + if( m_pDD ) + { + HRESULT err = m_pDD->SetCooperativeLevel( m_hWnd, DDSCL_NORMAL ); + char s[100]; + sprintf(s, "SetCooperativeLevel error=%d\n", err); + OutputDebugString(s); + } + + // Do a safe check for releasing the D3DDEVICE. RefCount must be zero. + if( m_pd3dDevice ) + if( 0 < ( nD3D = m_pd3dDevice->Release() ) ) + DEBUG_MSG( _T("Error: D3DDevice object is still referenced!") ); + m_pd3dDevice = NULL; + + SAFE_RELEASE( m_pddsBackBuffer ); + SAFE_RELEASE( m_pddsBackBufferLeft ); + SAFE_RELEASE( m_pddsZBuffer ); + SAFE_RELEASE( m_pddsFrontBuffer ); + SAFE_RELEASE( m_pD3D ); + + if( m_pDD ) + { + // Do a safe check for releasing DDRAW. RefCount must be zero. + if( 0 < ( nDD = m_pDD->Release() ) ) + DEBUG_MSG( _T("Error: DDraw object is still referenced!") ); + } + m_pDD = NULL; + + // Return successful, unless there are outstanding DD or D3DDevice refs. + return ( nDD==0 && nD3D==0 ) ? S_OK : D3DFWERR_NONZEROREFCOUNT; +} + + + + +//----------------------------------------------------------------------------- +// Name: Initialize() +// Desc: Creates the internal objects for the framework +//----------------------------------------------------------------------------- +HRESULT CD3DFramework7::Initialize( HWND hWnd, GUID* pDriverGUID, + GUID* pDeviceGUID, DDSURFACEDESC2* pMode, + DWORD dwFlags ) +{ + HRESULT hr; + + // Check params. Note: A NULL mode is valid for windowed modes only. + if( ( NULL==hWnd ) || ( NULL==pDeviceGUID ) || + ( NULL==pMode && (dwFlags&D3DFW_FULLSCREEN) ) ) + return E_INVALIDARG; + + // Setup state for windowed/fullscreen mode + m_hWnd = hWnd; + m_bIsStereo = FALSE; + m_bIsFullscreen = ( dwFlags & D3DFW_FULLSCREEN ) ? TRUE : FALSE; + + // Support stereoscopic viewing for fullscreen modes which support it + if( ( dwFlags & D3DFW_STEREO ) && ( dwFlags & D3DFW_FULLSCREEN ) ) + if( pMode->ddsCaps.dwCaps2 & DDSCAPS2_STEREOSURFACELEFT ) + m_bIsStereo = TRUE; + + // Create the D3D rendering environment (surfaces, device, viewport, etc.) + if( FAILED( hr = CreateEnvironment( pDriverGUID, pDeviceGUID, pMode, + dwFlags ) ) ) + { + DestroyObjects(); + return hr; + } + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: CreateEnvironment() +// Desc: Creates the internal objects for the framework +//----------------------------------------------------------------------------- +HRESULT CD3DFramework7::CreateEnvironment( GUID* pDriverGUID, GUID* pDeviceGUID, + DDSURFACEDESC2* pMode, DWORD dwFlags ) +{ + HRESULT hr; + + // Select the default memory type, for whether the device is HW or SW + if( IsEqualIID( *pDeviceGUID, IID_IDirect3DHALDevice) ) + m_dwDeviceMemType = DDSCAPS_VIDEOMEMORY; + else if( IsEqualIID( *pDeviceGUID, IID_IDirect3DTnLHalDevice) ) + m_dwDeviceMemType = DDSCAPS_VIDEOMEMORY; + else + m_dwDeviceMemType = DDSCAPS_SYSTEMMEMORY; + + // Create the DDraw object + hr = CreateDirectDraw( pDriverGUID, dwFlags ); + if( FAILED( hr ) ) + return hr; + + // Create the front and back buffers, and attach a clipper + if( dwFlags & D3DFW_FULLSCREEN ) + hr = CreateFullscreenBuffers( pMode ); + else + hr = CreateWindowedBuffers(); + if( FAILED( hr ) ) + return hr; + + // Create the Direct3D object and the Direct3DDevice object + hr = CreateDirect3D( pDeviceGUID ); + if( FAILED( hr ) ) + return hr; + + // Create and attach the zbuffer + if( dwFlags & D3DFW_ZBUFFER ) + hr = CreateZBuffer( pDeviceGUID ); + if( FAILED( hr ) ) + return hr; + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: EnumZBufferFormatsCallback() +// Desc: Simply returns the first matching enumerated z-buffer format +//----------------------------------------------------------------------------- +static HRESULT WINAPI EnumZBufferFormatsCallback( DDPIXELFORMAT* pddpf, + VOID* pContext ) +{ + DDPIXELFORMAT* pddpfOut = (DDPIXELFORMAT*)pContext; + + if( pddpfOut->dwRGBBitCount == pddpf->dwRGBBitCount ) + { + (*pddpfOut) = (*pddpf); + return D3DENUMRET_CANCEL; + } + + return D3DENUMRET_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: CreateDirectDraw() +// Desc: Create the DirectDraw interface +//----------------------------------------------------------------------------- +HRESULT CD3DFramework7::CreateDirectDraw( GUID* pDriverGUID, DWORD dwFlags ) +{ + // Create the DirectDraw interface, and query for the DD7 interface + if( FAILED( DirectDrawCreateEx( pDriverGUID, (VOID**)&m_pDD, + IID_IDirectDraw7, NULL ) ) ) + { + DEBUG_MSG( _T("Could not create DirectDraw") ); + return D3DFWERR_NODIRECTDRAW; + } + + // Set the Windows cooperative level + DWORD dwCoopFlags = DDSCL_NORMAL; + if( m_bIsFullscreen ) + dwCoopFlags = DDSCL_ALLOWREBOOT|DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN; + + // By defualt, set the flag to allow D3D to optimize floating point calcs + if( 0L == ( dwFlags & D3DFW_NO_FPUSETUP ) ) + dwCoopFlags |= DDSCL_FPUSETUP; + + if( FAILED( m_pDD->SetCooperativeLevel( m_hWnd, dwCoopFlags ) ) ) + { + DEBUG_MSG( _T("Couldn't set coop level") ); + return D3DFWERR_COULDNTSETCOOPLEVEL; + } + + // Check that we are NOT in a palettized display. That case will fail, + // since the framework doesn't use palettes. + DDSURFACEDESC2 ddsd; + ddsd.dwSize = sizeof(ddsd); + m_pDD->GetDisplayMode( &ddsd ); + if( ddsd.ddpfPixelFormat.dwRGBBitCount <= 8 ) + return D3DFWERR_INVALIDMODE; + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: CreateFullscreenBuffers() +// Desc: Creates the primary and (optional) backbuffer for rendering. +// Windowed mode and fullscreen mode are handled differently. +//----------------------------------------------------------------------------- +HRESULT CD3DFramework7::CreateFullscreenBuffers( DDSURFACEDESC2* pddsd ) +{ + HRESULT hr; + + // Get the dimensions of the screen bounds + // Store the rectangle which contains the renderer + SetRect( &m_rcScreenRect, 0, 0, pddsd->dwWidth, pddsd->dwHeight ); + m_dwRenderWidth = m_rcScreenRect.right - m_rcScreenRect.left; + m_dwRenderHeight = m_rcScreenRect.bottom - m_rcScreenRect.top; + + // Set the display mode to the requested dimensions. Check for + // 320x200x8 modes, and set flag to avoid using ModeX + DWORD dwModeFlags = 0; + + if( (320==m_dwRenderWidth) && (200==m_dwRenderHeight) && + (8==pddsd->ddpfPixelFormat.dwRGBBitCount) ) + dwModeFlags |= DDSDM_STANDARDVGAMODE; + + if( FAILED( m_pDD->SetDisplayMode( m_dwRenderWidth, m_dwRenderHeight, + pddsd->ddpfPixelFormat.dwRGBBitCount, + pddsd->dwRefreshRate, dwModeFlags ) ) ) + { + DEBUG_MSG( _T("Can't set display mode") ); + return D3DFWERR_BADDISPLAYMODE; + } + + // Setup to create the primary surface w/backbuffer + DDSURFACEDESC2 ddsd; + ZeroMemory( &ddsd, sizeof(ddsd) ); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | + DDSCAPS_FLIP | DDSCAPS_COMPLEX; + ddsd.dwBackBufferCount = 1; + + // Support for stereoscopic viewing + if( m_bIsStereo ) + { + ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; + ddsd.ddsCaps.dwCaps2 |= DDSCAPS2_STEREOSURFACELEFT; + } + + // Create the primary surface + if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL ) ) ) + { + DEBUG_MSG( _T("Error: Can't create primary surface") ); + if( hr != DDERR_OUTOFVIDEOMEMORY ) + return D3DFWERR_NOPRIMARY; + DEBUG_MSG( _T("Error: Out of video memory") ); + return DDERR_OUTOFVIDEOMEMORY; + } + + // Get the backbuffer, which was created along with the primary. + DDSCAPS2 ddscaps = { DDSCAPS_BACKBUFFER, 0, 0, 0 }; + if( FAILED( hr = m_pddsFrontBuffer->GetAttachedSurface( &ddscaps, + &m_pddsBackBuffer ) ) ) + { + DEBUG_ERR( hr, _T("Error: Can't get the backbuffer") ); + return D3DFWERR_NOBACKBUFFER; + } + + // Increment the backbuffer count (for consistency with windowed mode) + m_pddsBackBuffer->AddRef(); + + // Support for stereoscopic viewing + if( m_bIsStereo ) + { + // Get the left backbuffer, which was created along with the primary. + DDSCAPS2 ddscaps = { 0, DDSCAPS2_STEREOSURFACELEFT, 0, 0 }; + if( FAILED( hr = m_pddsBackBuffer->GetAttachedSurface( &ddscaps, + &m_pddsBackBufferLeft ) ) ) + { + DEBUG_ERR( hr, _T("Error: Can't get the left backbuffer") ); + return D3DFWERR_NOBACKBUFFER; + } + m_pddsBackBufferLeft->AddRef(); + } + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: CreateWindowedBuffers() +// Desc: Creates the primary and (optional) backbuffer for rendering. +// Windowed mode and fullscreen mode are handled differently. +//----------------------------------------------------------------------------- +HRESULT CD3DFramework7::CreateWindowedBuffers() +{ + HRESULT hr; + + // Get the dimensions of the viewport and screen bounds + GetClientRect( m_hWnd, &m_rcScreenRect ); + ClientToScreen( m_hWnd, (POINT*)&m_rcScreenRect.left ); + ClientToScreen( m_hWnd, (POINT*)&m_rcScreenRect.right ); + m_dwRenderWidth = m_rcScreenRect.right - m_rcScreenRect.left; + m_dwRenderHeight = m_rcScreenRect.bottom - m_rcScreenRect.top; + + // Create the primary surface + DDSURFACEDESC2 ddsd; + ZeroMemory( &ddsd, sizeof(ddsd) ); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + + if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL ) ) ) + { + DEBUG_MSG( _T("Error: Can't create primary surface") ); + if( hr != DDERR_OUTOFVIDEOMEMORY ) + return D3DFWERR_NOPRIMARY; + DEBUG_MSG( _T("Error: Out of video memory") ); + return DDERR_OUTOFVIDEOMEMORY; + } + + // If in windowed-mode, create a clipper object + LPDIRECTDRAWCLIPPER pcClipper; + if( FAILED( hr = m_pDD->CreateClipper( 0, &pcClipper, NULL ) ) ) + { + DEBUG_MSG( _T("Error: Couldn't create clipper") ); + return D3DFWERR_NOCLIPPER; + } + + // Associate the clipper with the window + pcClipper->SetHWnd( 0, m_hWnd ); + m_pddsFrontBuffer->SetClipper( pcClipper ); + SAFE_RELEASE( pcClipper ); + + // Create a backbuffer + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; + ddsd.dwWidth = m_dwRenderWidth; + ddsd.dwHeight = m_dwRenderHeight; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; + + if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsBackBuffer, NULL ) ) ) + { + DEBUG_ERR( hr, _T("Error: Couldn't create the backbuffer") ); + if( hr != DDERR_OUTOFVIDEOMEMORY ) + return D3DFWERR_NOBACKBUFFER; + DEBUG_MSG( _T("Error: Out of video memory") ); + return DDERR_OUTOFVIDEOMEMORY; + } + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: CreateDirect3D() +// Desc: Create the Direct3D interface +//----------------------------------------------------------------------------- +HRESULT CD3DFramework7::CreateDirect3D( GUID* pDeviceGUID ) +{ + // Query DirectDraw for access to Direct3D + if( FAILED( m_pDD->QueryInterface( IID_IDirect3D7, (VOID**)&m_pD3D ) ) ) + { + DEBUG_MSG( _T("Couldn't get the Direct3D interface") ); + return D3DFWERR_NODIRECT3D; + } + + // Create the device + if( FAILED( m_pD3D->CreateDevice( *pDeviceGUID, m_pddsBackBuffer, + &m_pd3dDevice) ) ) + { + DEBUG_MSG( _T("Couldn't create the D3DDevice") ); + return D3DFWERR_NO3DDEVICE; + } + + // Finally, set the viewport for the newly created device + D3DVIEWPORT7 vp = { 0, 0, m_dwRenderWidth, m_dwRenderHeight, 0.0f, 1.0f }; + + if( FAILED( m_pd3dDevice->SetViewport( &vp ) ) ) + { + DEBUG_MSG( _T("Error: Couldn't set current viewport to device") ); + return D3DFWERR_NOVIEWPORT; + } + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: CreateZBuffer() +// Desc: Internal function called by Create() to make and attach a zbuffer +// to the renderer +//----------------------------------------------------------------------------- +HRESULT CD3DFramework7::CreateZBuffer( GUID* pDeviceGUID ) +{ + HRESULT hr; + + // Check if the device supports z-bufferless hidden surface removal. If so, + // we don't really need a z-buffer + D3DDEVICEDESC7 ddDesc; + m_pd3dDevice->GetCaps( &ddDesc ); + if( ddDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR ) + return S_OK; + + // Get z-buffer dimensions from the render target + DDSURFACEDESC2 ddsd; + ddsd.dwSize = sizeof(ddsd); + m_pddsBackBuffer->GetSurfaceDesc( &ddsd ); + + // Setup the surface desc for the z-buffer. + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT; + ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | m_dwDeviceMemType; + ddsd.ddpfPixelFormat.dwSize = 0; // Tag the pixel format as unitialized + + // Get an appropiate pixel format from enumeration of the formats. On the + // first pass, we look for a zbuffer dpeth which is equal to the frame + // buffer depth (as some cards unfornately require this). + m_pD3D->EnumZBufferFormats( *pDeviceGUID, EnumZBufferFormatsCallback, + (VOID*)&ddsd.ddpfPixelFormat ); + if( 0 == ddsd.ddpfPixelFormat.dwSize ) + { + // Try again, just accepting any 16-bit zbuffer + ddsd.ddpfPixelFormat.dwRGBBitCount = 16; + m_pD3D->EnumZBufferFormats( *pDeviceGUID, EnumZBufferFormatsCallback, + (VOID*)&ddsd.ddpfPixelFormat ); + + if( 0 == ddsd.ddpfPixelFormat.dwSize ) + { + DEBUG_MSG( _T("Device doesn't support requested zbuffer format") ); + return D3DFWERR_NOZBUFFER; + } + } + + // Create and attach a z-buffer + if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsZBuffer, NULL ) ) ) + { + DEBUG_MSG( _T("Error: Couldn't create a ZBuffer surface") ); + if( hr != DDERR_OUTOFVIDEOMEMORY ) + return D3DFWERR_NOZBUFFER; + DEBUG_MSG( _T("Error: Out of video memory") ); + return DDERR_OUTOFVIDEOMEMORY; + } + + if( FAILED( m_pddsBackBuffer->AddAttachedSurface( m_pddsZBuffer ) ) ) + { + DEBUG_MSG( _T("Error: Couldn't attach zbuffer to render surface") ); + return D3DFWERR_NOZBUFFER; + } + + // For stereoscopic viewing, attach zbuffer to left surface as well + if( m_bIsStereo ) + { + if( FAILED( m_pddsBackBufferLeft->AddAttachedSurface( m_pddsZBuffer ) ) ) + { + DEBUG_MSG( _T("Error: Couldn't attach zbuffer to left render surface") ); + return D3DFWERR_NOZBUFFER; + } + } + + // Finally, this call rebuilds internal structures + if( FAILED( m_pd3dDevice->SetRenderTarget( m_pddsBackBuffer, 0L ) ) ) + { + DEBUG_MSG( _T("Error: SetRenderTarget() failed after attaching zbuffer!") ); + return D3DFWERR_NOZBUFFER; + } + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: RestoreSurfaces() +// Desc: Checks for lost surfaces and restores them if lost. Note: Don't +// restore render surface, since it's just a duplicate ptr. +//----------------------------------------------------------------------------- +HRESULT CD3DFramework7::RestoreSurfaces() +{ + // Restore all surfaces (including video memory vertex buffers) + m_pDD->RestoreAllSurfaces(); + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: Move() +// Desc: Moves the screen rect for windowed renderers +//----------------------------------------------------------------------------- +VOID CD3DFramework7::Move( INT x, INT y ) +{ + if( TRUE == m_bIsFullscreen ) + return; + + SetRect( &m_rcScreenRect, x, y, x + m_dwRenderWidth, y + m_dwRenderHeight ); +} + + + + +//----------------------------------------------------------------------------- +// Name: FlipToGDISurface() +// Desc: Puts the GDI surface in front of the primary, so that dialog +// boxes and other windows drawing funcs may happen. +//----------------------------------------------------------------------------- +HRESULT CD3DFramework7::FlipToGDISurface( BOOL bDrawFrame ) +{ + if( m_pDD && m_bIsFullscreen ) + { + m_pDD->FlipToGDISurface(); + + if( bDrawFrame ) + { + DrawMenuBar( m_hWnd ); + RedrawWindow( m_hWnd, NULL, NULL, RDW_FRAME ); + } + } + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: ShowFrame() +// Desc: Show the frame on the primary surface, via a blt or a flip. +//----------------------------------------------------------------------------- +HRESULT CD3DFramework7::ShowFrame() +{ + if( NULL == m_pddsFrontBuffer ) + return D3DFWERR_NOTINITIALIZED; + + if( m_bIsFullscreen ) + { + // We are in fullscreen mode, so perform a flip. + if( m_bIsStereo ) + return m_pddsFrontBuffer->Flip( NULL, DDFLIP_WAIT | DDFLIP_STEREO ); + else + return m_pddsFrontBuffer->Flip( NULL, DDFLIP_WAIT ); + } + else + { + // We are in windowed mode, so perform a blit. + return m_pddsFrontBuffer->Blt( &m_rcScreenRect, m_pddsBackBuffer, + NULL, DDBLT_WAIT, NULL ); + } +} + + + diff --git a/src/graphics/d3d/d3dframe.h b/src/graphics/d3d/d3dframe.h new file mode 100644 index 0000000..8e41b83 --- /dev/null +++ b/src/graphics/d3d/d3dframe.h @@ -0,0 +1,142 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +//----------------------------------------------------------------------------- +// File: D3DFrame.h +// +// Desc: Class to manage the Direct3D environment objects such as buffers, +// viewports, and 3D devices. +// +// The class is initialized with the Initialize() function, after which +// the Get????() functions can be used to access the objects needed for +// rendering. If the device or display needs to be changed, the +// ChangeDevice() function can be called. If the display window is moved +// the changes need to be reported with the Move() function. +// +// After rendering a frame, the ShowFrame() function filps or blits the +// backbuffer contents to the primary. If surfaces are lost, they can be +// restored with the RestoreSurfaces() function. Finally, if normal +// Windows output is needed, the FlipToGDISurface() provides a GDI +// surface to draw on. +// +// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved +//----------------------------------------------------------------------------- +#ifndef D3DFRAME_H +#define D3DFRAME_H +#include +#include + + + + +//----------------------------------------------------------------------------- +// Name: CD3DFramework7 +// Desc: The Direct3D sample framework class for DX7. Maintains the D3D +// surfaces and device used for 3D rendering. +//----------------------------------------------------------------------------- +class CD3DFramework7 +{ + // Internal variables for the framework class + HWND m_hWnd; // The window object + BOOL m_bIsFullscreen; // Fullscreen vs. windowed + BOOL m_bIsStereo; // Stereo view mode + DWORD m_dwRenderWidth; // Dimensions of the render target + DWORD m_dwRenderHeight; + RECT m_rcScreenRect; // Screen rect for window + LPDIRECTDRAW7 m_pDD; // The DirectDraw object + LPDIRECT3D7 m_pD3D; // The Direct3D object + LPDIRECT3DDEVICE7 m_pd3dDevice; // The D3D device + LPDIRECTDRAWSURFACE7 m_pddsFrontBuffer; // The primary surface + LPDIRECTDRAWSURFACE7 m_pddsBackBuffer; // The backbuffer surface + LPDIRECTDRAWSURFACE7 m_pddsBackBufferLeft; // For stereo modes + LPDIRECTDRAWSURFACE7 m_pddsZBuffer; // The zbuffer surface + DWORD m_dwDeviceMemType; + + // Internal functions for the framework class + HRESULT CreateZBuffer( GUID* ); + HRESULT CreateFullscreenBuffers( DDSURFACEDESC2* ); + HRESULT CreateWindowedBuffers(); + HRESULT CreateDirectDraw( GUID*, DWORD ); + HRESULT CreateDirect3D( GUID* ); + HRESULT CreateEnvironment( GUID*, GUID*, DDSURFACEDESC2*, DWORD ); + +public: + // Access functions for DirectX objects + LPDIRECTDRAW7 GetDirectDraw() { return m_pDD; } + LPDIRECT3D7 GetDirect3D() { return m_pD3D; } + LPDIRECT3DDEVICE7 GetD3DDevice() { return m_pd3dDevice; } + LPDIRECTDRAWSURFACE7 GetFrontBuffer() { return m_pddsFrontBuffer; } + LPDIRECTDRAWSURFACE7 GetBackBuffer() { return m_pddsBackBuffer; } + LPDIRECTDRAWSURFACE7 GetRenderSurface() { return m_pddsBackBuffer; } + LPDIRECTDRAWSURFACE7 GetRenderSurfaceLeft() { return m_pddsBackBufferLeft; } + + // Functions to aid rendering + HRESULT RestoreSurfaces(); + HRESULT ShowFrame(); + HRESULT FlipToGDISurface( BOOL bDrawFrame = FALSE ); + + // Functions for managing screen and viewport bounds + BOOL IsFullscreen() { return m_bIsFullscreen; } + BOOL IsStereo() { return m_bIsStereo; } + VOID Move( INT x, INT y ); + + // Creates the Framework + HRESULT Initialize( HWND hWnd, GUID* pDriverGUID, GUID* pDeviceGUID, + DDSURFACEDESC2* pddsd, DWORD dwFlags ); + HRESULT DestroyObjects(); + + CD3DFramework7(); + ~CD3DFramework7(); +}; + + + + +//----------------------------------------------------------------------------- +// Flags used for the Initialize() method of a CD3DFramework object +//----------------------------------------------------------------------------- +#define D3DFW_FULLSCREEN 0x00000001 // Use fullscreen mode +#define D3DFW_STEREO 0x00000002 // Use stereo-scopic viewing +#define D3DFW_ZBUFFER 0x00000004 // Create and use a zbuffer +#define D3DFW_NO_FPUSETUP 0x00000008 // Don't use default DDSCL_FPUSETUP flag + + + + +//----------------------------------------------------------------------------- +// Errors that the Initialize() and ChangeDriver() calls may return +//----------------------------------------------------------------------------- +#define D3DFWERR_INITIALIZATIONFAILED 0x82000000 +#define D3DFWERR_NODIRECTDRAW 0x82000001 +#define D3DFWERR_COULDNTSETCOOPLEVEL 0x82000002 +#define D3DFWERR_NODIRECT3D 0x82000003 +#define D3DFWERR_NO3DDEVICE 0x82000004 +#define D3DFWERR_NOZBUFFER 0x82000005 +#define D3DFWERR_INVALIDZBUFFERDEPTH 0x82000006 +#define D3DFWERR_NOVIEWPORT 0x82000007 +#define D3DFWERR_NOPRIMARY 0x82000008 +#define D3DFWERR_NOCLIPPER 0x82000009 +#define D3DFWERR_BADDISPLAYMODE 0x8200000a +#define D3DFWERR_NOBACKBUFFER 0x8200000b +#define D3DFWERR_NONZEROREFCOUNT 0x8200000c +#define D3DFWERR_NORENDERTARGET 0x8200000d +#define D3DFWERR_INVALIDMODE 0x8200000e +#define D3DFWERR_NOTINITIALIZED 0x8200000f + + +#endif // D3DFRAME_H + + diff --git a/src/graphics/d3d/d3dtextr.cpp b/src/graphics/d3d/d3dtextr.cpp new file mode 100644 index 0000000..cceab99 --- /dev/null +++ b/src/graphics/d3d/d3dtextr.cpp @@ -0,0 +1,1080 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +//----------------------------------------------------------------------------- +// File: D3DTextr.cpp +// +// Desc: Functions to manage textures, including creating (loading from a +// file), restoring lost surfaces, invalidating, and destroying. +// +// Note: the implementation of these fucntions maintain an internal list +// of loaded textures. After creation, individual textures are referenced +// via their ASCII names. +// +// Copyright (c) 1996-1999 Microsoft Corporation. All rights reserved +//----------------------------------------------------------------------------- +#define STRICT +#include +#include +#include "d3dtextr.h" +#include "d3dutil.h" +#include "language.h" +#include "misc.h" + + + + +//----------------------------------------------------------------------------- +// Macros, function prototypes and static variable +//----------------------------------------------------------------------------- +static TCHAR g_strTexturePath[512] = _T(""); // Path for files +static BOOL g_bDebugMode = FALSE; + + + +void D3DTextr_SetDebugMode(BOOL bDebug) +{ + g_bDebugMode = bDebug; +} + + + +//----------------------------------------------------------------------------- +// Name: TextureContainer +// Desc: Linked list structure to hold info per texture +//----------------------------------------------------------------------------- +struct TextureContainer +{ + TextureContainer* m_pNext; // Linked list ptr + + TCHAR m_strName[80]; // Name of texture (doubles as image filename) + DWORD m_dwWidth; + DWORD m_dwHeight; + DWORD m_dwStage; // Texture stage (for multitexture devices) + DWORD m_dwBPP; + DWORD m_dwFlags; + BOOL m_bHasAlpha; + + LPDIRECTDRAWSURFACE7 m_pddsSurface; // Surface of the texture + HBITMAP m_hbmBitmap; // Bitmap containing texture image + DWORD* m_pRGBAData; + +public: + HRESULT LoadImageData(); + HRESULT LoadBitmapFile( TCHAR* strPathname ); + HRESULT LoadTargaFile( TCHAR* strPathname, TCHAR* strFilename ); + HRESULT Restore( LPDIRECT3DDEVICE7 pd3dDevice ); + HRESULT CopyBitmapToSurface(); + HRESULT CopyRGBADataToSurface(); + + TextureContainer( TCHAR* strName, DWORD dwStage, DWORD dwFlags ); + ~TextureContainer(); +}; + +// Local list of textures +static TextureContainer* g_ptcTextureList = NULL; + + + + +//----------------------------------------------------------------------------- +// Name: CD3DTextureManager +// Desc: Class used to automatically construct and destruct the static +// texture engine class. +//----------------------------------------------------------------------------- +class CD3DTextureManager +{ +public: + CD3DTextureManager() {} + ~CD3DTextureManager() { if( g_ptcTextureList ) delete g_ptcTextureList; } +}; + +// Global instance +CD3DTextureManager g_StaticTextureEngine; + + + + +//----------------------------------------------------------------------------- +// Name: struct TEXTURESEARCHINFO +// Desc: Structure used to search for texture formats +//----------------------------------------------------------------------------- +struct TEXTURESEARCHINFO +{ + DWORD dwDesiredBPP; // Input for texture format search + BOOL bUseAlpha; + BOOL bUsePalette; + BOOL bFoundGoodFormat; + + DDPIXELFORMAT* pddpf; // Output of texture format search +}; + + + + +//----------------------------------------------------------------------------- +// Name: TextureSearchCallback() +// Desc: Enumeration callback routine to find a best-matching texture format. +// The param data is the DDPIXELFORMAT of the best-so-far matching +// texture. Note: the desired BPP is passed in the dwSize field, and the +// default BPP is passed in the dwFlags field. +//----------------------------------------------------------------------------- +static HRESULT CALLBACK TextureSearchCallback( DDPIXELFORMAT* pddpf, + VOID* param ) +{ + if( NULL==pddpf || NULL==param ) + return DDENUMRET_OK; + + TEXTURESEARCHINFO* ptsi = (TEXTURESEARCHINFO*)param; + + // Skip any funky modes + if( pddpf->dwFlags & (DDPF_LUMINANCE|DDPF_BUMPLUMINANCE|DDPF_BUMPDUDV) ) + return DDENUMRET_OK; + + // Check for palettized formats + if( ptsi->bUsePalette ) + { + if( !( pddpf->dwFlags & DDPF_PALETTEINDEXED8 ) ) + return DDENUMRET_OK; + + // Accept the first 8-bit palettized format we get + memcpy( ptsi->pddpf, pddpf, sizeof(DDPIXELFORMAT) ); + ptsi->bFoundGoodFormat = TRUE; + return DDENUMRET_CANCEL; + } + + // Else, skip any paletized formats (all modes under 16bpp) + if( pddpf->dwRGBBitCount < 16 ) + return DDENUMRET_OK; + + // Skip any FourCC formats + if( pddpf->dwFourCC != 0 ) + return DDENUMRET_OK; + + // Skip any ARGB 4444 formats (which are best used for pre-authored + // content designed speciafically for an ARGB 4444 format). + if( pddpf->dwRGBAlphaBitMask == 0x0000f000 ) + return DDENUMRET_OK; + + // Make sure current alpha format agrees with requested format type + if( (ptsi->bUseAlpha==TRUE) && !(pddpf->dwFlags&DDPF_ALPHAPIXELS) ) + return DDENUMRET_OK; + if( (ptsi->bUseAlpha==FALSE) && (pddpf->dwFlags&DDPF_ALPHAPIXELS) ) + return DDENUMRET_OK; + + // Check if we found a good match + if( pddpf->dwRGBBitCount == ptsi->dwDesiredBPP ) + { + memcpy( ptsi->pddpf, pddpf, sizeof(DDPIXELFORMAT) ); + ptsi->bFoundGoodFormat = TRUE; + return DDENUMRET_CANCEL; + } + + return DDENUMRET_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: FindTexture() +// Desc: Searches the internal list of textures for a texture specified by +// its name. Returns the structure associated with that texture. +//----------------------------------------------------------------------------- +static TextureContainer* FindTexture( TCHAR* strTextureName ) +{ + TextureContainer* ptcTexture = g_ptcTextureList; + + while( ptcTexture ) + { + if( !lstrcmpi( strTextureName, ptcTexture->m_strName ) ) + return ptcTexture; + ptcTexture = ptcTexture->m_pNext; + } + + return NULL; +} + + + + +//----------------------------------------------------------------------------- +// Name: TextureContainer() +// Desc: Constructor for a texture object +//----------------------------------------------------------------------------- +TextureContainer::TextureContainer( TCHAR* strName, DWORD dwStage, + DWORD dwFlags ) +{ + lstrcpy( m_strName, strName ); + m_dwWidth = 0; + m_dwHeight = 0; + m_dwStage = dwStage; + m_dwBPP = 0; + m_dwFlags = dwFlags; + m_bHasAlpha = 0; + + m_pddsSurface = NULL; + m_hbmBitmap = NULL; + m_pRGBAData = NULL; + + // Add the texture to the head of the global texture list + m_pNext = g_ptcTextureList; + g_ptcTextureList = this; + +} + + + + +//----------------------------------------------------------------------------- +// Name: ~TextureContainer() +// Desc: Destructs the contents of the texture container +//----------------------------------------------------------------------------- +TextureContainer::~TextureContainer() +{ + SAFE_RELEASE( m_pddsSurface ); + SAFE_DELETE( m_pRGBAData ); + DeleteObject( m_hbmBitmap ); + + // Remove the texture container from the global list + if( g_ptcTextureList == this ) + g_ptcTextureList = m_pNext; + else + { + for( TextureContainer* ptc=g_ptcTextureList; ptc; ptc=ptc->m_pNext ) + if( ptc->m_pNext == this ) + ptc->m_pNext = m_pNext; + } +} + + + + +//----------------------------------------------------------------------------- +// Name: LoadImageData() +// Desc: Loads the texture map's image data +//----------------------------------------------------------------------------- +HRESULT TextureContainer::LoadImageData() +{ + TCHAR* strExtension; + TCHAR strMetaname[256]; + TCHAR strFilename[256]; + + if ( g_bDebugMode ) + { + if ( _tcsrchr( m_strName, _T('\\') ) == 0 ) + { + lstrcpy( strMetaname, "" ); + lstrcpy( strFilename, g_strTexturePath ); + lstrcat( strFilename, m_strName ); + } + else + { + lstrcpy( strMetaname, "" ); + lstrcpy( strFilename, m_strName ); + } + } + else + { + if ( _tcsrchr( m_strName, _T('\\') ) == 0 ) + { +#if _SCHOOL + lstrcpy( strMetaname, "ceebot1.dat" ); +#else + lstrcpy( strMetaname, "colobot1.dat" ); +#endif + lstrcpy( strFilename, m_strName ); + } + else + { + lstrcpy( strMetaname, "" ); + lstrcpy( strFilename, m_strName ); + } + } + + if ( !g_metafile.IsExist(strMetaname, strFilename) ) + { + return DDERR_NOTFOUND; + } + + // Get the filename extension + if ( NULL == ( strExtension = _tcsrchr( m_strName, _T('.') ) ) ) + { + return DDERR_UNSUPPORTED; + } + + // Load bitmap files + if ( strMetaname[0] == 0 && !lstrcmpi( strExtension, _T(".bmp") ) ) + { + return LoadBitmapFile( strFilename ); + } + + // Load targa files + if ( !lstrcmpi( strExtension, _T(".tga") ) ) + { + return LoadTargaFile( strMetaname, strFilename ); + } + + // Can add code here to check for other file formats before failing + return DDERR_UNSUPPORTED; +} + + + + +//----------------------------------------------------------------------------- +// Name: LoadBitmapFile() +// Desc: Loads data from a .bmp file, and stores it in a bitmap structure. +//----------------------------------------------------------------------------- +HRESULT TextureContainer::LoadBitmapFile( TCHAR* strPathname ) +{ + // Try to load the bitmap as a file + m_hbmBitmap = (HBITMAP)LoadImage( NULL, strPathname, IMAGE_BITMAP, 0, 0, + LR_LOADFROMFILE|LR_CREATEDIBSECTION ); + if( m_hbmBitmap ) + return S_OK; + + return DDERR_NOTFOUND; +} + + + + +//----------------------------------------------------------------------------- +// Name: LoadTargaFile() +// Desc: Loads RGBA data from a .tga file, and stores it in allocated memory +// for the specified texture container +//----------------------------------------------------------------------------- +HRESULT TextureContainer::LoadTargaFile( TCHAR* strMetaname, TCHAR* strFilename ) +{ + if( g_metafile.Open(strMetaname, strFilename) != 0 ) + return E_FAIL; + + struct TargaHeader + { + BYTE IDLength; + BYTE ColormapType; + BYTE ImageType; + BYTE ColormapSpecification[5]; + WORD XOrigin; + WORD YOrigin; + WORD ImageWidth; + WORD ImageHeight; + BYTE PixelDepth; + BYTE ImageDescriptor; + } tga; + + g_metafile.Read(&tga, sizeof(TargaHeader)); + + // Only true color, non-mapped images are supported + if( ( 0 != tga.ColormapType ) || + ( tga.ImageType != 10 && tga.ImageType != 2 ) ) + { + g_metafile.Close(); + return E_FAIL; + } + + // Skip the ID field. The first byte of the header is the length of this field + if( tga.IDLength ) + { + g_metafile.Seek(tga.IDLength); + } + + m_dwWidth = tga.ImageWidth; + m_dwHeight = tga.ImageHeight; + m_dwBPP = tga.PixelDepth; + m_pRGBAData = new DWORD[m_dwWidth*m_dwHeight]; + + if( m_pRGBAData == NULL ) + { + g_metafile.Close(); + return E_FAIL; + } + + for( DWORD y=0; yGetCaps( &ddDesc) ) ) + return E_FAIL; + + // Setup the new surface desc + DDSURFACEDESC2 ddsd; + D3DUtil_InitSurfaceDesc( ddsd ); + ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH| + DDSD_PIXELFORMAT|DDSD_TEXTURESTAGE; + ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + ddsd.dwTextureStage = m_dwStage; + ddsd.dwWidth = m_dwWidth; + ddsd.dwHeight = m_dwHeight; + + // Turn on texture management for hardware devices + if( ddDesc.deviceGUID == IID_IDirect3DHALDevice ) + ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE; + else if( ddDesc.deviceGUID == IID_IDirect3DTnLHalDevice ) + ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE; + else + ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; + + // Adjust width and height to be powers of 2, if the device requires it + if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2 ) + { + for( ddsd.dwWidth=1; m_dwWidth>ddsd.dwWidth; ddsd.dwWidth<<=1 ); + for( ddsd.dwHeight=1; m_dwHeight>ddsd.dwHeight; ddsd.dwHeight<<=1 ); + } + + // Limit max texture sizes, if the driver can't handle large textures + DWORD dwMaxWidth = ddDesc.dwMaxTextureWidth; + DWORD dwMaxHeight = ddDesc.dwMaxTextureHeight; + ddsd.dwWidth = min( ddsd.dwWidth, ( dwMaxWidth ? dwMaxWidth : 256 ) ); + ddsd.dwHeight = min( ddsd.dwHeight, ( dwMaxHeight ? dwMaxHeight : 256 ) ); + + // Make the texture square, if the driver requires it + if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY ) + { + if( ddsd.dwWidth > ddsd.dwHeight ) ddsd.dwHeight = ddsd.dwWidth; + else ddsd.dwWidth = ddsd.dwHeight; + } + + // Setup the structure to be used for texture enumration. + TEXTURESEARCHINFO tsi; + tsi.bFoundGoodFormat = FALSE; + tsi.pddpf = &ddsd.ddpfPixelFormat; + tsi.dwDesiredBPP = m_dwBPP; + tsi.bUsePalette = ( m_dwBPP <= 8 ); + tsi.bUseAlpha = m_bHasAlpha; + if( m_dwFlags & D3DTEXTR_16BITSPERPIXEL ) + tsi.dwDesiredBPP = 16; + else if( m_dwFlags & D3DTEXTR_32BITSPERPIXEL ) + tsi.dwDesiredBPP = 32; + + if( m_dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) ) + { + if( tsi.bUsePalette ) + { + if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE ) + { + tsi.bUseAlpha = TRUE; + tsi.bUsePalette = TRUE; + } + else + { + tsi.bUseAlpha = TRUE; + tsi.bUsePalette = FALSE; + } + } + } + + // Enumerate the texture formats, and find the closest device-supported + // texture pixel format + pd3dDevice->EnumTextureFormats( TextureSearchCallback, &tsi ); + + // If we couldn't find a format, let's try a default format + if( FALSE == tsi.bFoundGoodFormat ) + { + tsi.bUsePalette = FALSE; + tsi.dwDesiredBPP = 16; + pd3dDevice->EnumTextureFormats( TextureSearchCallback, &tsi ); + + // If we still fail, we cannot create this texture + if( FALSE == tsi.bFoundGoodFormat ) + return E_FAIL; + } + + // Get the DirectDraw interface for creating surfaces + LPDIRECTDRAW7 pDD; + LPDIRECTDRAWSURFACE7 pddsRender; + pd3dDevice->GetRenderTarget( &pddsRender ); + pddsRender->GetDDInterface( (VOID**)&pDD ); + pddsRender->Release(); + + // Create a new surface for the texture + HRESULT hr = pDD->CreateSurface( &ddsd, &m_pddsSurface, NULL ); + + // Done with DDraw + pDD->Release(); + + if( FAILED(hr) ) + return hr; + + // For bitmap-based textures, copy the bitmap image. + if( m_hbmBitmap ) + return CopyBitmapToSurface(); + + if( m_pRGBAData ) + return CopyRGBADataToSurface(); + + // At this point, code can be added to handle other file formats (such as + // .dds files, .jpg files, etc.). + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: CopyBitmapToSurface() +// Desc: Copies the image of a bitmap into a surface +//----------------------------------------------------------------------------- +HRESULT TextureContainer::CopyBitmapToSurface() +{ + // Get a DDraw object to create a temporary surface + LPDIRECTDRAW7 pDD; + m_pddsSurface->GetDDInterface( (VOID**)&pDD ); + + // Get the bitmap structure (to extract width, height, and bpp) + BITMAP bm; + GetObject( m_hbmBitmap, sizeof(BITMAP), &bm ); + + // Setup the new surface desc + DDSURFACEDESC2 ddsd; + ddsd.dwSize = sizeof(ddsd); + m_pddsSurface->GetSurfaceDesc( &ddsd ); + ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT| + DDSD_TEXTURESTAGE; + ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE|DDSCAPS_SYSTEMMEMORY; + ddsd.ddsCaps.dwCaps2 = 0L; + ddsd.dwWidth = bm.bmWidth; + ddsd.dwHeight = bm.bmHeight; + + // Create a new surface for the texture + LPDIRECTDRAWSURFACE7 pddsTempSurface; + HRESULT hr; + if( FAILED( hr = pDD->CreateSurface( &ddsd, &pddsTempSurface, NULL ) ) ) + { + pDD->Release(); + return hr; + } + + // Get a DC for the bitmap + HDC hdcBitmap = CreateCompatibleDC( NULL ); + if( NULL == hdcBitmap ) + { + pddsTempSurface->Release(); + pDD->Release(); + return hr; + } + SelectObject( hdcBitmap, m_hbmBitmap ); + + // Handle palettized textures. Need to attach a palette + if( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 ) + { + LPDIRECTDRAWPALETTE pPalette; + DWORD dwPaletteFlags = DDPCAPS_8BIT|DDPCAPS_ALLOW256; + DWORD pe[256]; + WORD wNumColors = GetDIBColorTable( hdcBitmap, 0, 256, (RGBQUAD*)pe ); + + // Create the color table + for( WORD i=0; iCreatePalette( dwPaletteFlags, (PALETTEENTRY*)pe, &pPalette, NULL ); + pddsTempSurface->SetPalette( pPalette ); + m_pddsSurface->SetPalette( pPalette ); + SAFE_RELEASE( pPalette ); + } + + // Copy the bitmap image to the surface. + HDC hdcSurface; + if( SUCCEEDED( pddsTempSurface->GetDC( &hdcSurface ) ) ) + { + BitBlt( hdcSurface, 0, 0, bm.bmWidth, bm.bmHeight, hdcBitmap, 0, 0, + SRCCOPY ); + pddsTempSurface->ReleaseDC( hdcSurface ); + } + DeleteDC( hdcBitmap ); + + // Copy the temp surface to the real texture surface + m_pddsSurface->Blt( NULL, pddsTempSurface, NULL, DDBLT_WAIT, NULL ); + + // Done with the temp surface + pddsTempSurface->Release(); + + // For textures with real alpha (not palettized), set transparent bits + if( ddsd.ddpfPixelFormat.dwRGBAlphaBitMask ) + { + if( m_dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) ) + { + // Lock the texture surface + DDSURFACEDESC2 ddsd; + ddsd.dwSize = sizeof(ddsd); + while( m_pddsSurface->Lock( NULL, &ddsd, 0, NULL ) == + DDERR_WASSTILLDRAWING ); + + DWORD dwAlphaMask = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask; + DWORD dwRGBMask = ( ddsd.ddpfPixelFormat.dwRBitMask | + ddsd.ddpfPixelFormat.dwGBitMask | + ddsd.ddpfPixelFormat.dwBBitMask ); + DWORD dwColorkey = 0x00000000; // Colorkey on black + if( m_dwFlags & D3DTEXTR_TRANSPARENTWHITE ) + dwColorkey = dwRGBMask; // Colorkey on white + + // Add an opaque alpha value to each non-colorkeyed pixel + for( DWORD y=0; yUnlock( NULL ); + } + } + + pDD->Release(); + + return S_OK;; +} + + + + +//----------------------------------------------------------------------------- +// Name: CopyRGBADataToSurface() +// Desc: Invalidates the current texture objects and rebuilds new ones +// using the new device. +//----------------------------------------------------------------------------- +HRESULT TextureContainer::CopyRGBADataToSurface() +{ + // Get a DDraw object to create a temporary surface + LPDIRECTDRAW7 pDD; + m_pddsSurface->GetDDInterface( (VOID**)&pDD ); + + // Setup the new surface desc + DDSURFACEDESC2 ddsd; + ddsd.dwSize = sizeof(ddsd); + m_pddsSurface->GetSurfaceDesc( &ddsd ); + ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT| + DDSD_TEXTURESTAGE; + ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE|DDSCAPS_SYSTEMMEMORY; + ddsd.ddsCaps.dwCaps2 = 0L; + ddsd.dwWidth = m_dwWidth; + ddsd.dwHeight = m_dwHeight; + + // Create a new surface for the texture + LPDIRECTDRAWSURFACE7 pddsTempSurface; + HRESULT hr; + if( FAILED( hr = pDD->CreateSurface( &ddsd, &pddsTempSurface, NULL ) ) ) + { + pDD->Release(); + return NULL; + } + + while( pddsTempSurface->Lock( NULL, &ddsd, 0, 0 ) == DDERR_WASSTILLDRAWING ); + DWORD lPitch = ddsd.lPitch; + BYTE* pBytes = (BYTE*)ddsd.lpSurface; + + DWORD dwRMask = ddsd.ddpfPixelFormat.dwRBitMask; + DWORD dwGMask = ddsd.ddpfPixelFormat.dwGBitMask; + DWORD dwBMask = ddsd.ddpfPixelFormat.dwBBitMask; + DWORD dwAMask = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask; + + DWORD dwRShiftL = 8, dwRShiftR = 0; + DWORD dwGShiftL = 8, dwGShiftR = 0; + DWORD dwBShiftL = 8, dwBShiftR = 0; + DWORD dwAShiftL = 8, dwAShiftR = 0; + + DWORD dwMask; + for( dwMask=dwRMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwRShiftR++; + for( ; dwMask; dwMask>>=1 ) dwRShiftL--; + + for( dwMask=dwGMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwGShiftR++; + for( ; dwMask; dwMask>>=1 ) dwGShiftL--; + + for( dwMask=dwBMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwBShiftR++; + for( ; dwMask; dwMask>>=1 ) dwBShiftL--; + + for( dwMask=dwAMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwAShiftR++; + for( ; dwMask; dwMask>>=1 ) dwAShiftL--; + + for( DWORD y=0; y>24)&0x000000ff); + BYTE g = (BYTE)((dwPixel>>16)&0x000000ff); + BYTE b = (BYTE)((dwPixel>> 8)&0x000000ff); + BYTE a = (BYTE)((dwPixel>> 0)&0x000000ff); + + DWORD dr = ((r>>(dwRShiftL))<>(dwGShiftL))<>(dwBShiftL))<>(dwAShiftL))<Unlock(0); + + // Copy the temp surface to the real texture surface + m_pddsSurface->Blt( NULL, pddsTempSurface, NULL, DDBLT_WAIT, NULL ); + + // Done with the temp objects + pddsTempSurface->Release(); + pDD->Release(); + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DTextr_SetTexturePath() +// Desc: Enumeration callback routine to find a best-matching texture format. +//----------------------------------------------------------------------------- +VOID D3DTextr_SetTexturePath( TCHAR* strTexturePath ) +{ + if( NULL == strTexturePath ) + strTexturePath = _T(""); + lstrcpy( g_strTexturePath, strTexturePath ); +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DTextr_CreateTextureFromFile() +// Desc: Is passed a filename and creates a local Bitmap from that file. +// The texture can not be used until it is restored, however. +//----------------------------------------------------------------------------- +HRESULT D3DTextr_CreateTextureFromFile( TCHAR* strName, DWORD dwStage, + DWORD dwFlags ) +{ + // Check parameters + if( NULL == strName ) + return E_INVALIDARG; + + // Check first to see if the texture is already loaded + if( NULL != FindTexture( strName ) ) + return S_OK; + + // Allocate and add the texture to the linked list of textures; + TextureContainer* ptcTexture = new TextureContainer( strName, dwStage, + dwFlags ); + if( NULL == ptcTexture ) + return E_OUTOFMEMORY; + + // Create a bitmap and load the texture file into it, + if( FAILED( ptcTexture->LoadImageData() ) ) + { + delete ptcTexture; + return E_FAIL; + } + + // Save the image's dimensions + if( ptcTexture->m_hbmBitmap ) + { + BITMAP bm; + GetObject( ptcTexture->m_hbmBitmap, sizeof(BITMAP), &bm ); + ptcTexture->m_dwWidth = (DWORD)bm.bmWidth; + ptcTexture->m_dwHeight = (DWORD)bm.bmHeight; + ptcTexture->m_dwBPP = (DWORD)bm.bmBitsPixel; + } + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DTextr_CreateEmptyTexture() +// Desc: Creates an empty texture. +//----------------------------------------------------------------------------- +HRESULT D3DTextr_CreateEmptyTexture( TCHAR* strName, DWORD dwWidth, + DWORD dwHeight, DWORD dwStage, + DWORD dwFlags ) +{ + // Check parameters + if( NULL == strName ) + return E_INVALIDARG; + + // Check first to see if the texture is already loaded + if( NULL != FindTexture( strName ) ) + return E_FAIL; + + // Allocate and add the texture to the linked list of textures; + TextureContainer* ptcTexture = new TextureContainer( strName, dwStage, + dwFlags ); + if( NULL == ptcTexture ) + return E_OUTOFMEMORY; + + // Save dimensions + ptcTexture->m_dwWidth = dwWidth; + ptcTexture->m_dwHeight = dwHeight; + ptcTexture->m_dwBPP = 16; + if( ptcTexture->m_dwFlags & D3DTEXTR_32BITSPERPIXEL ) + ptcTexture->m_dwBPP = 32; + + // Save alpha usage flag + if( dwFlags & D3DTEXTR_CREATEWITHALPHA ) + ptcTexture->m_bHasAlpha = TRUE; + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DTextr_Restore() +// Desc: Invalidates the current texture objects and rebuilds new ones +// using the new device. +//----------------------------------------------------------------------------- +HRESULT D3DTextr_Restore( TCHAR* strName, LPDIRECT3DDEVICE7 pd3dDevice ) +{ + TextureContainer* ptcTexture = FindTexture( strName ); + if( NULL == ptcTexture ) + return DDERR_NOTFOUND; + + // Restore the texture (this recreates the new surface for this device). + return ptcTexture->Restore( pd3dDevice ); +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DTextr_RestoreAllTextures() +// Desc: This function is called when a mode is changed. It updates all +// texture objects to be valid with the new device. +//----------------------------------------------------------------------------- +HRESULT D3DTextr_RestoreAllTextures( LPDIRECT3DDEVICE7 pd3dDevice ) +{ + TextureContainer* ptcTexture = g_ptcTextureList; + + while( ptcTexture ) + { + D3DTextr_Restore( ptcTexture->m_strName, pd3dDevice ); + ptcTexture = ptcTexture->m_pNext; + } + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DTextr_Invalidate() +// Desc: Used to bump a texture out of (video) memory, this function +// actually destroys the d3dtexture and ddsurface of the texture +//----------------------------------------------------------------------------- +HRESULT D3DTextr_Invalidate( TCHAR* strName ) +{ + TextureContainer* ptcTexture = FindTexture( strName ); + if( NULL == ptcTexture ) + return DDERR_NOTFOUND; + + SAFE_RELEASE( ptcTexture->m_pddsSurface ); + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DTextr_InvalidateAllTextures() +// Desc: This function is called when a mode is changed. It invalidates +// all texture objects so their device can be safely released. +//----------------------------------------------------------------------------- +HRESULT D3DTextr_InvalidateAllTextures() +{ + TextureContainer* ptcTexture = g_ptcTextureList; + + while( ptcTexture ) + { + SAFE_RELEASE( ptcTexture->m_pddsSurface ); + ptcTexture = ptcTexture->m_pNext; + } + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DTextr_DestroyTexture() +// Desc: Frees the resources for the specified texture container +//----------------------------------------------------------------------------- +HRESULT D3DTextr_DestroyTexture( TCHAR* strName ) +{ + TextureContainer* ptcTexture = FindTexture( strName ); + + SAFE_DELETE( ptcTexture ); + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DTextr_GetSurface() +// Desc: Returns a pointer to a d3dSurface from the name of the texture +//----------------------------------------------------------------------------- +LPDIRECTDRAWSURFACE7 D3DTextr_GetSurface( TCHAR* strName ) +{ + TextureContainer* ptcTexture = FindTexture( strName ); + + return ptcTexture ? ptcTexture->m_pddsSurface : NULL; +} + + + + + diff --git a/src/graphics/d3d/d3dtextr.h b/src/graphics/d3d/d3dtextr.h new file mode 100644 index 0000000..54a79bb --- /dev/null +++ b/src/graphics/d3d/d3dtextr.h @@ -0,0 +1,80 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +//----------------------------------------------------------------------------- +// File: D3DTextr.h +// +// Desc: Functions to manage textures, including creating (loading from a +// file), restoring lost surfaces, invalidating, and destroying. +// +// Note: the implementation of these fucntions maintain an internal list +// of loaded textures. After creation, individual textures are referenced +// via their ASCII names. +// +// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved +//----------------------------------------------------------------------------- +#ifndef D3DTEXTR_H +#define D3DTEXTR_H +#include +#include + + + + +//----------------------------------------------------------------------------- +// Access functions for loaded textures. Note: these functions search +// an internal list of the textures, and use the texture associated with the +// ASCII name. +//----------------------------------------------------------------------------- +LPDIRECTDRAWSURFACE7 D3DTextr_GetSurface( TCHAR* strName ); + + + + +//----------------------------------------------------------------------------- +// Texture invalidation and restoration functions +//----------------------------------------------------------------------------- +HRESULT D3DTextr_Invalidate( TCHAR* strName ); +HRESULT D3DTextr_Restore( TCHAR* strName, LPDIRECT3DDEVICE7 pd3dDevice ); +HRESULT D3DTextr_InvalidateAllTextures(); +HRESULT D3DTextr_RestoreAllTextures( LPDIRECT3DDEVICE7 pd3dDevice ); + + + + +//----------------------------------------------------------------------------- +// Texture creation and deletion functions +//----------------------------------------------------------------------------- +#define D3DTEXTR_TRANSPARENTWHITE 0x00000001 +#define D3DTEXTR_TRANSPARENTBLACK 0x00000002 +#define D3DTEXTR_32BITSPERPIXEL 0x00000004 +#define D3DTEXTR_16BITSPERPIXEL 0x00000008 +#define D3DTEXTR_CREATEWITHALPHA 0x00000010 + + +HRESULT D3DTextr_CreateTextureFromFile( TCHAR* strName, DWORD dwStage=0L, + DWORD dwFlags=0L ); +HRESULT D3DTextr_CreateEmptyTexture( TCHAR* strName, DWORD dwWidth, + DWORD dwHeight, DWORD dwStage, + DWORD dwFlags ); +HRESULT D3DTextr_DestroyTexture( TCHAR* strName ); +VOID D3DTextr_SetTexturePath( TCHAR* strTexturePath ); + +void D3DTextr_SetDebugMode(BOOL bDebug); + + + +#endif // D3DTEXTR_H diff --git a/src/graphics/d3d/d3dutil.cpp b/src/graphics/d3d/d3dutil.cpp new file mode 100644 index 0000000..b4a0eb7 --- /dev/null +++ b/src/graphics/d3d/d3dutil.cpp @@ -0,0 +1,327 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +//----------------------------------------------------------------------------- +// File: D3DUtil.cpp +// +// Desc: Shortcut macros and functions for using DX objects +// +// +// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved +//----------------------------------------------------------------------------- +#define D3D_OVERLOADS +#define STRICT +#include +#include +#include +#include "d3dutil.h" + + + + +//----------------------------------------------------------------------------- +// Name: D3DUtil_GetDXSDKMediaPath() +// Desc: Returns the DirectX SDK media path, as stored in the system registry +// during the SDK install. +//----------------------------------------------------------------------------- +const TCHAR* D3DUtil_GetDXSDKMediaPath() +{ + static TCHAR strNull[2] = _T(""); + static TCHAR strPath[512]; + HKEY key; + DWORD type, size = 512; + + // Open the appropriate registry key + LONG result = RegOpenKeyEx( HKEY_LOCAL_MACHINE, + _T("Software\\Microsoft\\DirectX"), + 0, KEY_READ, &key ); + if( ERROR_SUCCESS != result ) + return strNull; + + result = RegQueryValueEx( key, _T("DXSDK Samples Path"), NULL, + &type, (BYTE*)strPath, &size ); + RegCloseKey( key ); + + if( ERROR_SUCCESS != result ) + return strNull; + + lstrcat( strPath, _T("\\D3DIM\\Media\\") ); + + return strPath; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DUtil_InitSurfaceDesc() +// Desc: Helper function called to build a DDSURFACEDESC2 structure, +// typically before calling CreateSurface() or GetSurfaceDesc() +//----------------------------------------------------------------------------- +VOID D3DUtil_InitSurfaceDesc( DDSURFACEDESC2& ddsd, DWORD dwFlags, + DWORD dwCaps ) +{ + ZeroMemory( &ddsd, sizeof(ddsd) ); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = dwFlags; + ddsd.ddsCaps.dwCaps = dwCaps; + ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DUtil_InitMaterial() +// Desc: Helper function called to build a D3DMATERIAL7 structure +//----------------------------------------------------------------------------- +VOID D3DUtil_InitMaterial( D3DMATERIAL7& mtrl, FLOAT r, FLOAT g, FLOAT b, + FLOAT a ) +{ + ZeroMemory( &mtrl, sizeof(D3DMATERIAL7) ); + mtrl.dcvDiffuse.r = mtrl.dcvAmbient.r = r; + mtrl.dcvDiffuse.g = mtrl.dcvAmbient.g = g; + mtrl.dcvDiffuse.b = mtrl.dcvAmbient.b = b; + mtrl.dcvDiffuse.a = mtrl.dcvAmbient.a = a; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DUtil_InitLight() +// Desc: Initializes a D3DLIGHT7 structure +//----------------------------------------------------------------------------- +VOID D3DUtil_InitLight( D3DLIGHT7& light, D3DLIGHTTYPE ltType, + FLOAT x, FLOAT y, FLOAT z ) +{ + ZeroMemory( &light, sizeof(D3DLIGHT7) ); + light.dltType = ltType; + light.dcvDiffuse.r = 1.0f; + light.dcvDiffuse.g = 1.0f; + light.dcvDiffuse.b = 1.0f; + light.dcvSpecular = light.dcvDiffuse; + light.dvPosition.x = light.dvDirection.x = x; + light.dvPosition.y = light.dvDirection.y = y; + light.dvPosition.z = light.dvDirection.z = z; + light.dvAttenuation0 = 1.0f; + light.dvRange = D3DLIGHT_RANGE_MAX; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DUtil_SetViewMatrix() +// Desc: Given an eye point, a lookat point, and an up vector, this +// function builds a 4x4 view matrix. +//----------------------------------------------------------------------------- +HRESULT D3DUtil_SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom, + D3DVECTOR& vAt, D3DVECTOR& vWorldUp ) +{ + // Get the z basis vector, which points straight ahead. This is the + // difference from the eyepoint to the lookat point. + D3DVECTOR vView = vAt - vFrom; + + FLOAT fLength = Magnitude( vView ); + if( fLength < 1e-6f ) + return E_INVALIDARG; + + // Normalize the z basis vector + vView /= fLength; + + // Get the dot product, and calculate the projection of the z basis + // vector onto the up vector. The projection is the y basis vector. + FLOAT fDotProduct = DotProduct( vWorldUp, vView ); + + D3DVECTOR vUp = vWorldUp - fDotProduct * vView; + + // If this vector has near-zero length because the input specified a + // bogus up vector, let's try a default up vector + if( 1e-6f > ( fLength = Magnitude( vUp ) ) ) + { + vUp = D3DVECTOR( 0.0f, 1.0f, 0.0f ) - vView.y * vView; + + // If we still have near-zero length, resort to a different axis. + if( 1e-6f > ( fLength = Magnitude( vUp ) ) ) + { + vUp = D3DVECTOR( 0.0f, 0.0f, 1.0f ) - vView.z * vView; + + if( 1e-6f > ( fLength = Magnitude( vUp ) ) ) + return E_INVALIDARG; + } + } + + // Normalize the y basis vector + vUp /= fLength; + + // The x basis vector is found simply with the cross product of the y + // and z basis vectors + D3DVECTOR vRight = CrossProduct( vUp, vView ); + + // Start building the matrix. The first three rows contains the basis + // vectors used to rotate the view to point at the lookat point + D3DUtil_SetIdentityMatrix( mat ); + mat._11 = vRight.x; mat._12 = vUp.x; mat._13 = vView.x; + mat._21 = vRight.y; mat._22 = vUp.y; mat._23 = vView.y; + mat._31 = vRight.z; mat._32 = vUp.z; mat._33 = vView.z; + + // Do the translation values (rotations are still about the eyepoint) + mat._41 = - DotProduct( vFrom, vRight ); + mat._42 = - DotProduct( vFrom, vUp ); + mat._43 = - DotProduct( vFrom, vView ); + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DUtil_SetProjectionMatrix() +// Desc: Sets the passed in 4x4 matrix to a perpsective projection matrix built +// from the field-of-view (fov, in y), aspect ratio, near plane (D), +// and far plane (F). Note that the projection matrix is normalized for +// element [3][4] to be 1.0. This is performed so that W-based range fog +// will work correctly. +//----------------------------------------------------------------------------- +HRESULT D3DUtil_SetProjectionMatrix( D3DMATRIX& mat, FLOAT fFOV, FLOAT fAspect, + FLOAT fNearPlane, FLOAT fFarPlane ) +{ + if( fabs(fFarPlane-fNearPlane) < 0.01f ) + return E_INVALIDARG; + if( fabs(sin(fFOV/2)) < 0.01f ) + return E_INVALIDARG; + + FLOAT w = fAspect * ( cosf(fFOV/2)/sinf(fFOV/2) ); + FLOAT h = 1.0f * ( cosf(fFOV/2)/sinf(fFOV/2) ); + FLOAT Q = fFarPlane / ( fFarPlane - fNearPlane ); + + ZeroMemory( &mat, sizeof(D3DMATRIX) ); + mat._11 = w; + mat._22 = h; + mat._33 = Q; + mat._34 = 1.0f; + mat._43 = -Q*fNearPlane; + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DUtil_SetRotateXMatrix() +// Desc: Create Rotation matrix about X axis +//----------------------------------------------------------------------------- +VOID D3DUtil_SetRotateXMatrix( D3DMATRIX& mat, FLOAT fRads ) +{ + D3DUtil_SetIdentityMatrix( mat ); + mat._22 = cosf( fRads ); + mat._23 = sinf( fRads ); + mat._32 = -sinf( fRads ); + mat._33 = cosf( fRads ); +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DUtil_SetRotateYMatrix() +// Desc: Create Rotation matrix about Y axis +//----------------------------------------------------------------------------- +VOID D3DUtil_SetRotateYMatrix( D3DMATRIX& mat, FLOAT fRads ) +{ + D3DUtil_SetIdentityMatrix( mat ); + mat._11 = cosf( fRads ); + mat._13 = -sinf( fRads ); + mat._31 = sinf( fRads ); + mat._33 = cosf( fRads ); +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DUtil_SetRotateZMatrix() +// Desc: Create Rotation matrix about Z axis +//----------------------------------------------------------------------------- +VOID D3DUtil_SetRotateZMatrix( D3DMATRIX& mat, FLOAT fRads ) +{ + D3DUtil_SetIdentityMatrix( mat ); + mat._11 = cosf( fRads ); + mat._12 = sinf( fRads ); + mat._21 = -sinf( fRads ); + mat._22 = cosf( fRads ); +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DUtil_SetRotationMatrix +// Desc: Create a Rotation matrix about vector direction +//----------------------------------------------------------------------------- +VOID D3DUtil_SetRotationMatrix( D3DMATRIX& mat, D3DVECTOR& vDir, FLOAT fRads ) +{ + FLOAT fCos = cosf( fRads ); + FLOAT fSin = sinf( fRads ); + D3DVECTOR v = Normalize( vDir ); + + mat._11 = ( v.x * v.x ) * ( 1.0f - fCos ) + fCos; + mat._12 = ( v.x * v.y ) * ( 1.0f - fCos ) - (v.z * fSin); + mat._13 = ( v.x * v.z ) * ( 1.0f - fCos ) + (v.y * fSin); + + mat._21 = ( v.y * v.x ) * ( 1.0f - fCos ) + (v.z * fSin); + mat._22 = ( v.y * v.y ) * ( 1.0f - fCos ) + fCos ; + mat._23 = ( v.y * v.z ) * ( 1.0f - fCos ) - (v.x * fSin); + + mat._31 = ( v.z * v.x ) * ( 1.0f - fCos ) - (v.y * fSin); + mat._32 = ( v.z * v.y ) * ( 1.0f - fCos ) + (v.x * fSin); + mat._33 = ( v.z * v.z ) * ( 1.0f - fCos ) + fCos; + + mat._14 = mat._24 = mat._34 = 0.0f; + mat._41 = mat._42 = mat._43 = 0.0f; + mat._44 = 1.0f; +} + + + + +//----------------------------------------------------------------------------- +// Name: _DbgOut() +// Desc: Outputs a message to the debug stream +//----------------------------------------------------------------------------- +HRESULT _DbgOut( TCHAR* strFile, DWORD dwLine, HRESULT hr, TCHAR* strMsg ) +{ + TCHAR buffer[256]; + wsprintf( buffer, _T("%s(%ld): "), strFile, dwLine ); + OutputDebugString( buffer ); + OutputDebugString( strMsg ); + + if( hr ) + { + wsprintf( buffer, _T("(hr=%08lx)\n"), hr ); + OutputDebugString( buffer ); + } + + OutputDebugString( _T("\n") ); + + return hr; +} + + + diff --git a/src/graphics/d3d/d3dutil.h b/src/graphics/d3d/d3dutil.h new file mode 100644 index 0000000..494722d --- /dev/null +++ b/src/graphics/d3d/d3dutil.h @@ -0,0 +1,114 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +//----------------------------------------------------------------------------- +// File: D3DUtil.h +// +// Desc: Helper functions and typing shortcuts for Direct3D programming. +// +// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved +//----------------------------------------------------------------------------- +#ifndef D3DUTIL_H +#define D3DUTIL_H +#include +#include + + + + +//----------------------------------------------------------------------------- +// Miscellaneous helper functions +//----------------------------------------------------------------------------- +const TCHAR* D3DUtil_GetDXSDKMediaPath(); + +#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } +#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } + + + + +//----------------------------------------------------------------------------- +// Short cut functions for creating and using DX structures +//----------------------------------------------------------------------------- +VOID D3DUtil_InitDeviceDesc( D3DDEVICEDESC7& ddDevDesc ); +VOID D3DUtil_InitSurfaceDesc( DDSURFACEDESC2& ddsd, DWORD dwFlags=0, + DWORD dwCaps=0 ); +VOID D3DUtil_InitMaterial( D3DMATERIAL7& mtrl, FLOAT r=0.0f, FLOAT g=0.0f, + FLOAT b=0.0f, FLOAT a=1.0f ); +VOID D3DUtil_InitLight( D3DLIGHT7& light, D3DLIGHTTYPE ltType, + FLOAT x=0.0f, FLOAT y=0.0f, FLOAT z=0.0f ); + + + + +//----------------------------------------------------------------------------- +// D3D Matrix functions. For performance reasons, some functions are inline. +//----------------------------------------------------------------------------- +HRESULT D3DUtil_SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom, + D3DVECTOR& vAt, D3DVECTOR& vUp ); +HRESULT D3DUtil_SetProjectionMatrix( D3DMATRIX& mat, FLOAT fFOV = 1.570795f, + FLOAT fAspect = 1.0f, + FLOAT fNearPlane = 1.0f, + FLOAT fFarPlane = 1000.0f ); + +inline VOID D3DUtil_SetIdentityMatrix( D3DMATRIX& m ) +{ + m._12 = m._13 = m._14 = m._21 = m._23 = m._24 = 0.0f; + m._31 = m._32 = m._34 = m._41 = m._42 = m._43 = 0.0f; + m._11 = m._22 = m._33 = m._44 = 1.0f; +} + +inline VOID D3DUtil_SetTranslateMatrix( D3DMATRIX& m, FLOAT tx, FLOAT ty, + FLOAT tz ) +{ D3DUtil_SetIdentityMatrix( m ); m._41 = tx; m._42 = ty; m._43 = tz; } + +inline VOID D3DUtil_SetTranslateMatrix( D3DMATRIX& m, D3DVECTOR& v ) +{ D3DUtil_SetTranslateMatrix( m, v.x, v.y, v.z ); } + +inline VOID D3DUtil_SetScaleMatrix( D3DMATRIX& m, FLOAT sx, FLOAT sy, + FLOAT sz ) +{ D3DUtil_SetIdentityMatrix( m ); m._11 = sx; m._22 = sy; m._33 = sz; } + +inline VOID SetScaleMatrix( D3DMATRIX& m, D3DVECTOR& v ) +{ D3DUtil_SetScaleMatrix( m, v.x, v.y, v.z ); } + +VOID D3DUtil_SetRotateXMatrix( D3DMATRIX& mat, FLOAT fRads ); +VOID D3DUtil_SetRotateYMatrix( D3DMATRIX& mat, FLOAT fRads ); +VOID D3DUtil_SetRotateZMatrix( D3DMATRIX& mat, FLOAT fRads ); +VOID D3DUtil_SetRotationMatrix( D3DMATRIX& mat, D3DVECTOR& vDir, + FLOAT fRads ); + + + + +//----------------------------------------------------------------------------- +// Debug printing support +//----------------------------------------------------------------------------- + +HRESULT _DbgOut( TCHAR*, DWORD, HRESULT, TCHAR* ); + +#if defined(DEBUG) | defined(_DEBUG) + #define DEBUG_MSG(str) _DbgOut( __FILE__, (DWORD)__LINE__, 0, str ) + #define DEBUG_ERR(hr,str) _DbgOut( __FILE__, (DWORD)__LINE__, hr, str ) +#else + #define DEBUG_MSG(str) (0L) + #define DEBUG_ERR(hr,str) (hr) +#endif + + + + +#endif // D3DUTIL_H diff --git a/src/group.cpp b/src/group.cpp deleted file mode 100644 index f49fd69..0000000 --- a/src/group.cpp +++ /dev/null @@ -1,646 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// group.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "restext.h" -#include "group.h" - - - - -// Object's constructor. - -CGroup::CGroup(CInstanceManager* iMan) : CControl(iMan) -{ -} - -// Object's destructor. - -CGroup::~CGroup() -{ -} - - -// Creates a new button. - -BOOL CGroup::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - CControl::Create(pos, dim, icon, eventMsg); - - if ( icon == -1 ) - { - char name[100]; - char* p; - - GetResource(RES_EVENT, eventMsg, name); - p = strchr(name, '\\'); - if ( p != 0 ) *p = 0; - SetName(name); - } - - return TRUE; -} - - -// Management of an event. - -BOOL CGroup::EventProcess(const Event &event) -{ - return TRUE; -} - - -// Draw button. - -void CGroup::Draw() -{ - FPOINT uv1,uv2, corner, pos, dim; - float dp; - int icon; - - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - if ( m_state & STATE_SHADOW ) - { - DrawShadow(m_pos, m_dim); - } - - dp = 0.5f/256.0f; - - if ( m_icon == 0 ) // hollow frame? - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 160.0f/256.0f; - uv1.y = 192.0f/256.0f; // u-v texture - uv2.x = 192.0f/256.0f; - uv2.y = 224.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 10.0f/640.0f; - corner.y = 10.0f/480.0f; - DrawIcon(m_pos, m_dim, uv1, uv2, corner, 8.0f/256.0f); - } - if ( m_icon == 1 ) // orange solid opaque? - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 104.0f/256.0f; - uv1.y = 48.0f/256.0f; - uv2.x = 112.0f/256.0f; - uv2.y = 64.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(m_pos, m_dim, uv1, uv2); - } - if ( m_icon == 2 ) // orange degrade -> transparent? - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTw); - uv1.x = 112.0f/256.0f; - uv1.y = 48.0f/256.0f; - uv2.x = 120.0f/256.0f; - uv2.y = 64.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(m_pos, m_dim, uv1, uv2); - } - if ( m_icon == 3 ) // transparent gradient -> gray? - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTw); - uv1.x = 120.0f/256.0f; - uv1.y = 48.0f/256.0f; - uv2.x = 128.0f/256.0f; - uv2.y = 64.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(m_pos, m_dim, uv1, uv2); - } - if ( m_icon == 4 ) // degrade blue corner? - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTw); - uv1.x = 192.0f/256.0f; - uv1.y = 128.0f/256.0f; - uv2.x = 224.0f/256.0f; - uv2.y = 160.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(m_pos, m_dim, uv1, uv2); - } - if ( m_icon == 5 ) // degrade orange corner? - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTw); - uv1.x = 224.0f/256.0f; - uv1.y = 128.0f/256.0f; - uv2.x = 256.0f/256.0f; - uv2.y = 160.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(m_pos, m_dim, uv1, uv2); - } - if ( m_icon == 6 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 0.0f/256.0f; // brown transparent - uv1.y = 75.0f/256.0f; - uv2.x = 64.0f/256.0f; - uv2.y = 128.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 4.0f/640.0f; - corner.y = 4.0f/480.0f; - DrawIcon(m_pos, m_dim, uv1, uv2, corner, 8.0f/256.0f); - } - if ( m_icon == 7 ) - { - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 64.0f/256.0f; - uv1.y = 0.0f/256.0f; - uv2.x = 96.0f/256.0f; - uv2.y = 32.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(m_pos, m_dim, uv1, uv2, 8.0f/256.0f); - } - if ( m_icon == 8 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 64.0f/256.0f; // green transparent - uv1.y = 160.0f/256.0f; - uv2.x = 160.0f/256.0f; - uv2.y = 176.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(m_pos, m_dim, uv1, uv2, 8.0f/256.0f); - } - if ( m_icon == 9 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 64.0f/256.0f; // red transparent - uv1.y = 176.0f/256.0f; - uv2.x = 160.0f/256.0f; - uv2.y = 192.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(m_pos, m_dim, uv1, uv2, 8.0f/256.0f); - } - if ( m_icon == 10 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 64.0f/256.0f; // blue transparent - uv1.y = 192.0f/256.0f; - uv2.x = 160.0f/256.0f; - uv2.y = 208.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(m_pos, m_dim, uv1, uv2, 8.0f/256.0f); - } - if ( m_icon == 11 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 64.0f/256.0f; // yellow transparent - uv1.y = 224.0f/256.0f; - uv2.x = 160.0f/256.0f; - uv2.y = 240.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(m_pos, m_dim, uv1, uv2, 8.0f/256.0f); - } - if ( m_icon == 12 ) // viewfinder cross? - { - dim.x = m_dim.x/2.0f; - dim.y = m_dim.y/2.0f; - - m_engine->SetTexture("mouse.tga"); - m_engine->SetState(D3DSTATETTb); - pos.x = m_pos.x-m_dim.x/300.0f; - pos.y = m_pos.y+m_dim.y/300.0f+dim.y; - uv1.x = 0.5f/256.0f; - uv1.y = 192.5f/256.0f; - uv2.x = 63.5f/256.0f; - uv2.y = 255.5f/256.0f; - DrawIcon(pos, dim, uv1, uv2); // ul - pos.x += dim.x; - Swap(uv1.x, uv2.x); - DrawIcon(pos, dim, uv1, uv2); // ur - pos.y -= dim.y; - Swap(uv1.y, uv2.y); - DrawIcon(pos, dim, uv1, uv2); // dr - pos.x -= dim.x; - Swap(uv1.x, uv2.x); - DrawIcon(pos, dim, uv1, uv2); // dl - - m_engine->SetState(D3DSTATETTw); - pos.x = m_pos.x+m_dim.x/300.0f; - pos.y = m_pos.y-m_dim.y/300.0f+dim.y; - uv1.x = 64.5f/256.0f; - uv1.y = 192.5f/256.0f; - uv2.x = 127.5f/256.0f; - uv2.y = 255.5f/256.0f; - DrawIcon(pos, dim, uv1, uv2); // ul - pos.x += dim.x; - Swap(uv1.x, uv2.x); - DrawIcon(pos, dim, uv1, uv2); // ur - pos.y -= dim.y; - Swap(uv1.y, uv2.y); - DrawIcon(pos, dim, uv1, uv2); // dr - pos.x -= dim.x; - Swap(uv1.x, uv2.x); - DrawIcon(pos, dim, uv1, uv2); // dl - } - if ( m_icon == 13 ) // corner upper / left? - { - m_engine->SetTexture("mouse.tga"); - m_engine->SetState(D3DSTATETTb); - pos.x = m_pos.x-m_dim.x/150.0f; - pos.y = m_pos.y+m_dim.y/150.0f; - uv1.x = 128.5f/256.0f; - uv1.y = 192.5f/256.0f; - uv2.x = 191.5f/256.0f; - uv2.y = 255.5f/256.0f; - DrawIcon(pos, m_dim, uv1, uv2); - - m_engine->SetState(D3DSTATETTw); - pos.x = m_pos.x+m_dim.x/150.0f; - pos.y = m_pos.y-m_dim.y/150.0f; - uv1.x = 192.5f/256.0f; - uv1.y = 192.5f/256.0f; - uv2.x = 255.5f/256.0f; - uv2.y = 255.5f/256.0f; - DrawIcon(pos, m_dim, uv1, uv2); - } - if ( m_icon == 14 ) // corner upper / right? - { - m_engine->SetTexture("mouse.tga"); - m_engine->SetState(D3DSTATETTb); - pos.x = m_pos.x-m_dim.x/150.0f; - pos.y = m_pos.y+m_dim.y/150.0f; - uv2.x = 128.5f/256.0f; - uv1.y = 192.5f/256.0f; - uv1.x = 191.5f/256.0f; - uv2.y = 255.5f/256.0f; - DrawIcon(pos, m_dim, uv1, uv2); - - m_engine->SetState(D3DSTATETTw); - pos.x = m_pos.x+m_dim.x/150.0f; - pos.y = m_pos.y-m_dim.y/150.0f; - uv2.x = 192.5f/256.0f; - uv1.y = 192.5f/256.0f; - uv1.x = 255.5f/256.0f; - uv2.y = 255.5f/256.0f; - DrawIcon(pos, m_dim, uv1, uv2); - } - if ( m_icon == 15 ) // corner lower / left? - { - m_engine->SetTexture("mouse.tga"); - m_engine->SetState(D3DSTATETTb); - pos.x = m_pos.x-m_dim.x/150.0f; - pos.y = m_pos.y+m_dim.y/150.0f; - uv1.x = 128.5f/256.0f; - uv2.y = 192.5f/256.0f; - uv2.x = 191.5f/256.0f; - uv1.y = 255.5f/256.0f; - DrawIcon(pos, m_dim, uv1, uv2); - - m_engine->SetState(D3DSTATETTw); - pos.x = m_pos.x+m_dim.x/150.0f; - pos.y = m_pos.y-m_dim.y/150.0f; - uv1.x = 192.5f/256.0f; - uv2.y = 192.5f/256.0f; - uv2.x = 255.5f/256.0f; - uv1.y = 255.5f/256.0f; - DrawIcon(pos, m_dim, uv1, uv2); - } - if ( m_icon == 16 ) // corner lower / left? - { - m_engine->SetTexture("mouse.tga"); - m_engine->SetState(D3DSTATETTb); - pos.x = m_pos.x-m_dim.x/150.0f; - pos.y = m_pos.y+m_dim.y/150.0f; - uv2.x = 128.5f/256.0f; - uv2.y = 192.5f/256.0f; - uv1.x = 191.5f/256.0f; - uv1.y = 255.5f/256.0f; - DrawIcon(pos, m_dim, uv1, uv2); - - m_engine->SetState(D3DSTATETTw); - pos.x = m_pos.x+m_dim.x/150.0f; - pos.y = m_pos.y-m_dim.y/150.0f; - uv2.x = 192.5f/256.0f; - uv2.y = 192.5f/256.0f; - uv1.x = 255.5f/256.0f; - uv1.y = 255.5f/256.0f; - DrawIcon(pos, m_dim, uv1, uv2); - } - if ( m_icon == 17 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 0.0f/256.0f; // blue frame - uv1.y = 75.0f/256.0f; - uv2.x = 64.0f/256.0f; - uv2.y = 128.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 6.0f/640.0f; - corner.y = 6.0f/480.0f; - DrawIcon(m_pos, m_dim, uv1, uv2, corner, 2.0f/256.0f); - } - if ( m_icon == 18 ) // arrow> for SatCom? - { - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATETTw); - uv1.x = 0.0f/256.0f; // > - uv1.y = 192.0f/256.0f; - uv2.x = 32.0f/256.0f; - uv2.y = 224.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(m_pos, m_dim, uv1, uv2); - } - if ( m_icon == 19 ) // SatCom symbol? - { - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATETTw); - uv1.x = 224.0f/256.0f; // SatCom symbol - uv1.y = 224.0f/256.0f; - uv2.x = 256.0f/256.0f; - uv2.y = 256.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(m_pos, m_dim, uv1, uv2); - } - if ( m_icon == 20 ) // solid blue background? - { - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATETTw); - uv1.x = 224.0f/256.0f; - uv1.y = 32.0f/256.0f; - uv2.x = 256.0f/256.0f; - uv2.y = 64.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(m_pos, m_dim, uv1, uv2); - } - if ( m_icon == 21 ) // stand-by symbol? - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTw); - uv1.x = 160.0f/256.0f; - uv1.y = 32.0f/256.0f; - uv2.x = 192.0f/256.0f; - uv2.y = 64.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(m_pos, m_dim, uv1, uv2); - } - if ( m_icon == 22 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 64.0f/256.0f; // opaque yellow - uv1.y = 224.0f/256.0f; - uv2.x = 160.0f/256.0f; - uv2.y = 240.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 5.0f/640.0f; - corner.y = 5.0f/480.0f; - DrawIcon(m_pos, m_dim, uv1, uv2, corner, 3.0f/256.0f); - } - - if ( m_icon == 23 ) - { - m_engine->SetTexture("button3.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 64.0f/256.0f; // yellow - uv1.y = 192.0f/256.0f; - uv2.x = 80.0f/256.0f; - uv2.y = 208.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 4.0f/640.0f; - corner.y = 4.0f/480.0f; - DrawIcon(m_pos, m_dim, uv1, uv2, corner, 2.0f/256.0f); - } - if ( m_icon == 24 ) - { - m_engine->SetTexture("button3.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 80.0f/256.0f; // orange - uv1.y = 192.0f/256.0f; - uv2.x = 96.0f/256.0f; - uv2.y = 208.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 4.0f/640.0f; - corner.y = 4.0f/480.0f; - DrawIcon(m_pos, m_dim, uv1, uv2, corner, 2.0f/256.0f); - } - if ( m_icon == 25 ) - { - m_engine->SetTexture("button3.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 64.0f/256.0f; // orange - uv1.y = 208.0f/256.0f; - uv2.x = 80.0f/256.0f; - uv2.y = 224.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 4.0f/640.0f; - corner.y = 4.0f/480.0f; - DrawIcon(m_pos, m_dim, uv1, uv2, corner, 2.0f/256.0f); - } - if ( m_icon == 26 ) - { - m_engine->SetTexture("button3.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 80.0f/256.0f; // red - uv1.y = 208.0f/256.0f; - uv2.x = 96.0f/256.0f; - uv2.y = 224.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 4.0f/640.0f; - corner.y = 4.0f/480.0f; - DrawIcon(m_pos, m_dim, uv1, uv2, corner, 2.0f/256.0f); - } - if ( m_icon == 27 ) - { - m_engine->SetTexture("button3.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 32.0f/256.0f; - uv1.y = 0.0f/256.0f; - uv2.x = 64.0f/256.0f; - uv2.y = 32.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(m_pos, m_dim, uv1, uv2); - } - - if ( m_icon >= 100 && m_icon <= 120 ) // building? - { - pos = m_pos; - dim = m_dim; - - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 32.0f/256.0f; - uv1.y = 32.0f/256.0f; - uv2.x = uv1.x+32.0f/256.0f; - uv2.y = uv1.y+32.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2); - - m_engine->SetTexture("button3.tga"); - m_engine->SetState(D3DSTATENORMAL); - pos.x += 8.0f/640.0f; - pos.y += 8.0f/480.0f; - dim.x -= 16.0f/640.0f; - dim.y -= 16.0f/480.0f; - uv1.x = 32.0f/256.0f; - uv1.y = 0.0f/256.0f; - uv2.x = uv1.x+32.0f/256.0f; - uv2.y = uv1.y+32.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2); - - m_engine->SetState(D3DSTATENORMAL); - pos.x += 2.0f/640.0f; - pos.y += 2.0f/480.0f; - dim.x -= 4.0f/640.0f; - dim.y -= 4.0f/480.0f; - uv1.x = 0.0f/256.0f; - uv1.y = 0.0f/256.0f; - uv2.x = uv1.x+32.0f/256.0f; - uv2.y = uv1.y+32.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2); - - m_engine->SetState(D3DSTATETTb); - pos.x += 8.0f/640.0f; - pos.y += 8.0f/480.0f; - dim.x -= 16.0f/640.0f; - dim.y -= 16.0f/480.0f; - if ( m_icon == 100 ) icon = 43; // base ? - if ( m_icon == 101 ) icon = 32; // factory ? - if ( m_icon == 102 ) icon = 35; // research ? - if ( m_icon == 103 ) icon = 34; // convert ? - if ( m_icon == 104 ) icon = 36; // station ? - if ( m_icon == 105 ) icon = 40; // radar ? - if ( m_icon == 106 ) icon = 41; // repair ? - if ( m_icon == 107 ) icon = 37; // tower ? - if ( m_icon == 108 ) icon = 39; // energy ? - if ( m_icon == 109 ) icon = 33; // derrick ? - if ( m_icon == 110 ) icon = 42; // nuclear ? - if ( m_icon == 111 ) icon = 38; // labo ? - if ( m_icon == 112 ) icon = 44; // info ? - if ( m_icon == 113 ) icon = 46; // lightning protection ? - if ( m_icon == 114 ) icon = 47; // vault ? - if ( m_icon == 115 ) icon = 48; // control center? - uv1.x = (32.0f/256.0f)*(icon%8); - uv1.y = (32.0f/256.0f)*(icon/8); // uv texture - uv2.x = uv1.x+32.0f/256.0f; - uv2.y = uv1.y+32.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2); - } -} - - diff --git a/src/group.h b/src/group.h deleted file mode 100644 index 6dab275..0000000 --- a/src/group.h +++ /dev/null @@ -1,48 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// group.h - -#ifndef _GROUP_H_ -#define _GROUP_H_ - - -#include "control.h" - - -class CD3DEngine; - - - -class CGroup : public CControl -{ -public: - CGroup(CInstanceManager* iMan); - virtual ~CGroup(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - - BOOL EventProcess(const Event &event); - - void Draw(); - -protected: - -protected: -}; - - -#endif //_GROUP_H_ diff --git a/src/image.cpp b/src/image.cpp deleted file mode 100644 index 974216a..0000000 --- a/src/image.cpp +++ /dev/null @@ -1,157 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// image.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "restext.h" -#include "image.h" - - - - -// Object's constructor. - -CImage::CImage(CInstanceManager* iMan) : CControl(iMan) -{ - m_filename[0] = 0; -} - -// Object's destructor. - -CImage::~CImage() -{ - if ( m_filename[0] != 0 ) - { - m_engine->FreeTexture(m_filename); - } -} - - -// Creates a new button. - -BOOL CImage::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - CControl::Create(pos, dim, icon, eventMsg); - - if ( icon == -1 ) - { - char name[100]; - char* p; - - GetResource(RES_EVENT, eventMsg, name); - p = strchr(name, '\\'); - if ( p != 0 ) *p = 0; - SetName(name); - } - - return TRUE; -} - - -// Specifies the name of the image display. - -void CImage::SetFilenameImage(char *name) -{ - if ( m_filename[0] != 0 ) - { - m_engine->FreeTexture(m_filename); - } - - strcpy(m_filename, name); -} - -char* CImage::RetFilenameImage() -{ - return m_filename; -} - - -// Management of an event. - -BOOL CImage::EventProcess(const Event &event) -{ - return TRUE; -} - - -// Draws button. - -void CImage::Draw() -{ - FPOINT uv1,uv2, corner, pos, dim; - float dp; - - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - if ( m_state & STATE_SHADOW ) - { - DrawShadow(m_pos, m_dim); - } - - dp = 0.5f/256.0f; - - if ( m_icon == 0 ) // hollow frame? - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 160.0f/256.0f; - uv1.y = 192.0f/256.0f; // u-v texture - uv2.x = 192.0f/256.0f; - uv2.y = 224.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 10.0f/640.0f; - corner.y = 10.0f/480.0f; - DrawIcon(m_pos, m_dim, uv1, uv2, corner, 8.0f/256.0f); - } - - if ( m_filename[0] != 0 ) // displays an image? - { - m_engine->LoadTexture(m_filename); - m_engine->SetTexture(m_filename); - m_engine->SetState(D3DSTATENORMAL); - pos = m_pos; - dim = m_dim; - pos.x += 5.0f/640.0f; - pos.y += 5.0f/480.0f; - dim.x -= 10.0f/640.0f; - dim.y -= 10.0f/480.0f; - uv1.x = 0.0f; - uv1.y = 0.0f; - uv2.x = 1.0f; - uv2.y = 1.0f; - DrawIcon(pos, dim, uv1, uv2); - } -} - - diff --git a/src/image.h b/src/image.h deleted file mode 100644 index 7545ac0..0000000 --- a/src/image.h +++ /dev/null @@ -1,52 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// image.h - -#ifndef _IMAGE_H_ -#define _IMAGE_H_ - - -#include "control.h" - - -class CD3DEngine; - - - -class CImage : public CControl -{ -public: - CImage(CInstanceManager* iMan); - virtual ~CImage(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - - BOOL EventProcess(const Event &event); - - void Draw(); - - void SetFilenameImage(char *name); - char* RetFilenameImage(); - -protected: - -protected: - char m_filename[100]; -}; - - -#endif //_IMAGE_H_ diff --git a/src/iman.cpp b/src/iman.cpp deleted file mode 100644 index eacb3f4..0000000 --- a/src/iman.cpp +++ /dev/null @@ -1,165 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// iman.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include - -#include "struct.h" -#include "iman.h" - - - - -// Object's constructor. - -CInstanceManager::CInstanceManager() -{ - int i; - - for ( i=0 ; i= CLASS_MAX ) return; - if ( m_table[classType].classPointer == 0 ) return; - - free(m_table[classType].classPointer); - m_table[classType].classPointer = 0; -} - - -// Adds a new instance of a class. - -BOOL CInstanceManager::AddInstance(ClassType classType, void* pointer, int max) -{ - int i; - - if ( classType < 0 || classType >= CLASS_MAX ) return FALSE; - - if ( m_table[classType].classPointer == 0 ) - { - m_table[classType].classPointer = (void**)malloc(max*sizeof(void*)); - m_table[classType].totalPossible = max; - m_table[classType].totalUsed = 0; - } - - if ( m_table[classType].totalUsed >= m_table[classType].totalPossible ) return FALSE; - - i = m_table[classType].totalUsed++; - m_table[classType].classPointer[i] = pointer; - return TRUE; -} - -// Deletes an instance of a class. - -BOOL CInstanceManager::DeleteInstance(ClassType classType, void* pointer) -{ - int i; - - if ( classType < 0 || classType >= CLASS_MAX ) return FALSE; - - for ( i=0 ; i= CLASS_MAX ) return 0; - if ( m_table[classType].classPointer == 0 ) return 0; -#endif - if ( rank >= m_table[classType].totalUsed ) return 0; - - return m_table[classType].classPointer[rank]; -} - - -// Fills holes in a table. - -void CInstanceManager::Compress(ClassType classType) -{ - int i, j; - - if ( classType < 0 || classType >= CLASS_MAX ) return; - - j = 0; - for ( i=0 ; i -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "control.h" -#include "button.h" -#include "color.h" -#include "check.h" -#include "key.h" -#include "group.h" -#include "image.h" -#include "label.h" -#include "edit.h" -#include "editvalue.h" -#include "scroll.h" -#include "slider.h" -#include "list.h" -#include "shortcut.h" -#include "compass.h" -#include "target.h" -#include "map.h" -#include "window.h" -#include "camera.h" -#include "interface.h" - - - - -// Object's constructor. - -CInterface::CInterface(CInstanceManager* iMan) -{ - int i; - - m_iMan = iMan; - m_iMan->AddInstance(CLASS_INTERFACE, this); - - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_camera = 0; - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new button. - -CButton* CInterface::CreateButton(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CButton* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new button. - -CColor* CInterface::CreateColor(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CColor* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new button. - -CCheck* CInterface::CreateCheck(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CCheck* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new button. - -CKey* CInterface::CreateKey(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CKey* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new button. - -CGroup* CInterface::CreateGroup(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CGroup* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new button. - -CImage* CInterface::CreateImage(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CImage* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new label. - -CLabel* CInterface::CreateLabel(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, - char *name) -{ - CLabel* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg); - pc->SetName(name); - return pc; - } - } - return 0; -} - -// Creates a new pave editable. - -CEdit* CInterface::CreateEdit(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CEdit* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new pave editable. - -CEditValue* CInterface::CreateEditValue(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CEditValue* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new lift. - -CScroll* CInterface::CreateScroll(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CScroll* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new cursor. - -CSlider* CInterface::CreateSlider(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CSlider* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new list. - -CList* CInterface::CreateList(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, - float expand) -{ - CList* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg, expand); - return pc; - } - } - return 0; -} - -// Creates a new shortcut. - -CShortcut* CInterface::CreateShortcut(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CShortcut* ps; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg); - return ps; - } - } - return 0; -} - -// Creates a new compass. - -CCompass* CInterface::CreateCompass(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CCompass* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new target. - -CTarget* CInterface::CreateTarget(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CTarget* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new map. - -CMap* CInterface::CreateMap(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CMap* pm; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=10 ; iCreate(pos, dim, icon, eventMsg); - return pm; - } - } - return 0; -} - -// Removes a control. - -BOOL CInterface::DeleteControl(EventMsg eventMsg) -{ - int i; - - for ( i=0 ; iRetEventMsg() ) - { - delete m_table[i]; - m_table[i] = 0; - return TRUE; - } - } - } - return FALSE; -} - -// Gives a control. - -CControl* CInterface::SearchControl(EventMsg eventMsg) -{ - int i; - - for ( i=0 ; iRetEventMsg() ) - { - return m_table[i]; - } - } - } - return 0; -} - -// Management of an event. - -BOOL CInterface::EventProcess(const Event &event) -{ - int i; - - if ( event.event == EVENT_MOUSEMOVE ) - { - if ( m_camera == 0 ) - { - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - } - m_engine->SetMouseType(m_camera->RetMouseDef(event.pos)); - } - - for ( i=MAXCONTROL-1 ; i>=0 ; i-- ) - { - if ( m_table[i] != 0 && - m_table[i]->TestState(STATE_ENABLE) ) - { - if ( !m_table[i]->EventProcess(event) ) - { - return FALSE; - } - } - } - - return TRUE; -} - - -// Gives the tooltip binding to the window. - -BOOL CInterface::GetTooltip(FPOINT pos, char* name) -{ - int i; - - for ( i=MAXCONTROL-1 ; i>=0 ; i-- ) - { - if ( m_table[i] != 0 ) - { - if ( m_table[i]->GetTooltip(pos, name) ) - { - return TRUE; - } - } - } - return FALSE; -} - - -// Draws all buttons. - -void CInterface::Draw() -{ - D3DMATERIAL7 material; - int i; - - ZeroMemory( &material, sizeof(D3DMATERIAL7) ); - material.diffuse.r = 1.0f; - material.diffuse.g = 1.0f; - material.diffuse.b = 1.0f; - material.ambient.r = 0.5f; - material.ambient.g = 0.5f; - material.ambient.b = 0.5f; - m_engine->SetMaterial(material); - - for ( i=0 ; i=0 ; i-- ) - { - if ( m_table[i] != 0 ) - { - m_table[i]->Draw(); - } - } -} - - diff --git a/src/interface.h b/src/interface.h deleted file mode 100644 index 4a8f202..0000000 --- a/src/interface.h +++ /dev/null @@ -1,93 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// interface.h - -#ifndef _INTERFACE_H_ -#define _INTERFACE_H_ - - -class CInstanceManager; -class CD3DEngine; -class CControl; -class CWindow; -class CButton; -class CColor; -class CCheck; -class CKey; -class CGroup; -class CImage; -class CLabel; -class CEdit; -class CEditValue; -class CScroll; -class CSlider; -class CList; -class CShortcut; -class CMap; -class CGauge; -class CCompass; -class CTarget; -class CCamera; - - -#define MAXCONTROL 100 - - -class CInterface -{ -public: - CInterface(CInstanceManager* iMan); - ~CInterface(); - - BOOL EventProcess(const Event &event); - BOOL GetTooltip(FPOINT pos, char* name); - - void Flush(); - CWindow* CreateWindows(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CButton* CreateButton(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CColor* CreateColor(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CCheck* CreateCheck(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CKey* CreateKey(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CGroup* CreateGroup(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CImage* CreateImage(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CLabel* CreateLabel(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, char *name); - CEdit* CreateEdit(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CEditValue* CreateEditValue(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CScroll* CreateScroll(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CSlider* CreateSlider(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CList* CreateList(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, float expand=1.2f); - CShortcut* CreateShortcut(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CCompass* CreateCompass(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CTarget* CreateTarget(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CMap* CreateMap(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - BOOL DeleteControl(EventMsg eventMsg); - CControl* SearchControl(EventMsg eventMsg); - - void Draw(); - -protected: - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CCamera* m_camera; - - CControl* m_table[MAXCONTROL]; -}; - - -#endif //_INTERFACE_H_ diff --git a/src/joystick.cpp b/src/joystick.cpp deleted file mode 100644 index 609a1fb..0000000 --- a/src/joystick.cpp +++ /dev/null @@ -1,245 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// joystick.cpp - -#define STRICT -#define DIRECTINPUT_VERSION 0x0700 - -#include -#include -#include - -#include "joystick.h" - - - - -// Global variables. - -LPDIRECTINPUT7 g_pDI = NULL; -LPDIRECTINPUTDEVICE2 g_pJoystick = NULL; -DIDEVCAPS g_diDevCaps; - - - - - -// Called once for each enumerated joystick. If we find one, create a -// device interface on it so we can play with it. - -BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, - VOID* pContext ) -{ - HRESULT hr; - - // Obtain an interface to the enumerated joystick. - hr = g_pDI->CreateDeviceEx( pdidInstance->guidInstance, IID_IDirectInputDevice2, - (VOID**)&g_pJoystick, NULL ); - - // If it failed, then we can't use this joystick. (Maybe the user unplugged - // it while we were in the middle of enumerating it.) - if( FAILED(hr) ) - return DIENUM_CONTINUE; - - - // Stop enumeration. Note: we're just taking the first joystick we get. You - // could store all the enumerated joysticks and let the user pick. - return DIENUM_STOP; -} - - -// Callback function for enumerating the axes on a joystick. - -BOOL CALLBACK EnumAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, - VOID* pContext ) -{ - DIPROPRANGE diprg; - diprg.diph.dwSize = sizeof(DIPROPRANGE); - diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); - diprg.diph.dwHow = DIPH_BYOFFSET; - diprg.diph.dwObj = pdidoi->dwOfs; // Specify the enumerated axis - diprg.lMin = -1000; - diprg.lMax = +1000; - - // Set the range for the axis - if( FAILED( g_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) ) - return DIENUM_STOP; - -#ifndef __MINGW32__ // FIXME Doesn't work under MinGW - // Set the UI to reflect what axes the joystick supports - switch( pdidoi->dwOfs ) - { - case DIJOFS_X: - OutputDebugString("EnumAxesCallback -x\n"); - break; - case DIJOFS_Y: - OutputDebugString("EnumAxesCallback -y\n"); - break; - case DIJOFS_Z: - OutputDebugString("EnumAxesCallback -z\n"); - break; - case DIJOFS_RX: - OutputDebugString("EnumAxesCallback -rx\n"); - break; - case DIJOFS_RY: - OutputDebugString("EnumAxesCallback -ry\n"); - break; - case DIJOFS_RZ: - OutputDebugString("EnumAxesCallback -rz\n"); - break; - case DIJOFS_SLIDER(0): - OutputDebugString("EnumAxesCallback -s0\n"); - break; - case DIJOFS_SLIDER(1): - OutputDebugString("EnumAxesCallback -s1\n"); - break; - } -#endif - - return DIENUM_CONTINUE; -} - - -// Initialize the DirectInput variables. - -BOOL InitDirectInput(HINSTANCE hInst, HWND hWnd) -{ - HRESULT hr; - - // Register with the DirectInput subsystem and get a pointer - // to a IDirectInput interface we can use. -#ifndef __MINGW32__ // FIXME Doesn't work under MinGW - hr = DirectInputCreateEx( hInst, DIRECTINPUT_VERSION,IID_IDirectInput7, (LPVOID*)&g_pDI, NULL ); - if( FAILED(hr) ) return FALSE; -#else - return FALSE; -#endif - - // Look for a simple joystick we can use for this sample program. - hr = g_pDI->EnumDevices( DIDEVTYPE_JOYSTICK, EnumJoysticksCallback, - NULL, DIEDFL_ATTACHEDONLY ); - if( FAILED(hr) ) return FALSE; - - // Make sure we got a joystick - if( NULL == g_pJoystick ) - { -//? MessageBox( NULL, "Joystick not found", "DInput Sample", -//? MB_ICONERROR | MB_OK ); - return FALSE; - } - - // Set the data format to "simple joystick" - a predefined data format - // - // A data format specifies which controls on a device we are interested in, - // and how they should be reported. This tells DInput that we will be - // passing a DIJOYSTATE structure to IDirectInputDevice::GetDeviceState(). - hr = g_pJoystick->SetDataFormat( &c_dfDIJoystick ); - if( FAILED(hr) ) return FALSE; - - // Set the cooperative level to let DInput know how this device should - // interact with the system and with other DInput applications. - hr = g_pJoystick->SetCooperativeLevel( hWnd, DISCL_EXCLUSIVE|DISCL_FOREGROUND ); - if( FAILED(hr) ) return FALSE; - - // Determine how many axis the joystick has (so we don't error out setting - // properties for unavailable axis) - g_diDevCaps.dwSize = sizeof(DIDEVCAPS); - hr = g_pJoystick->GetCapabilities(&g_diDevCaps); - if( FAILED(hr) ) return FALSE; - - - // Enumerate the axes of the joyctick and set the range of each axis. Note: - // we could just use the defaults, but we're just trying to show an example - // of enumerating device objects (axes, buttons, etc.). - g_pJoystick->EnumObjects( EnumAxesCallback, (VOID*)g_pJoystick, DIDFT_AXIS ); - - return TRUE; -} - -// Acquire or unacquire the keyboard, depending on if the app is active -// Input device must be acquired before the GetDeviceState is called. - -BOOL SetAcquire(BOOL bActive) -{ - if ( g_pJoystick ) - { - if( bActive ) g_pJoystick->Acquire(); - else g_pJoystick->Unacquire(); - } - return TRUE; -} - - -// Get the input device's state and display it. - -BOOL UpdateInputState( DIJOYSTATE &js ) -{ - HRESULT hr; - - if ( g_pJoystick ) - { - do - { - // Poll the device to read the current state - hr = g_pJoystick->Poll(); - if ( FAILED(hr) ) return FALSE; - - // Get the input's device state - hr = g_pJoystick->GetDeviceState( sizeof(DIJOYSTATE), &js ); - - if( hr == DIERR_INPUTLOST ) - { - // DInput is telling us that the input stream has been - // interrupted. We aren't tracking any state between polls, so - // we don't have any special reset that needs to be done. We - // just re-acquire and try again. - hr = g_pJoystick->Acquire(); - if ( FAILED(hr) ) return FALSE; - } - } - while ( DIERR_INPUTLOST == hr ); - if ( FAILED(hr) ) return FALSE; - } - return TRUE; -} - - -// Initialize the DirectInput variables. - -BOOL FreeDirectInput() -{ - // Unacquire and release any DirectInputDevice objects. - if( NULL != g_pJoystick ) - { - // Unacquire the device one last time just in case - // the app tried to exit while the device is still acquired. - g_pJoystick->Unacquire(); - g_pJoystick->Release(); - g_pJoystick = NULL; - } - - - // Release any DirectInput objects. - if( g_pDI ) - { - g_pDI->Release(); - g_pDI = NULL; - } - - return TRUE; -} - diff --git a/src/joystick.h b/src/joystick.h deleted file mode 100644 index 4b465e0..0000000 --- a/src/joystick.h +++ /dev/null @@ -1,31 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// joystick.h - -#ifndef _JOYSTICK_H_ -#define _JOYSTICK_H_ - - - -extern BOOL InitDirectInput(HINSTANCE hInst, HWND hWnd); -extern BOOL SetAcquire(BOOL bActive); -extern BOOL UpdateInputState(DIJOYSTATE &js); -extern BOOL FreeDirectInput(); - - - -#endif //_JOYSTICK_H_ diff --git a/src/key.cpp b/src/key.cpp deleted file mode 100644 index c59dac3..0000000 --- a/src/key.cpp +++ /dev/null @@ -1,290 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// key.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "restext.h" -#include "sound.h" -#include "text.h" -#include "key.h" - - - - -// Constructs the name of a button. - -void GetKeyName(char *name, int key) -{ - if ( !GetResource(RES_KEY, key, name) ) - { - if ( (key >= '0' && key <= '9') || - (key >= 'A' && key <= 'Z') || - (key >= 'a' && key <= 'z') ) - { - name[0] = key; - name[1] = 0; - } - else - { - sprintf(name, "Code %d", key); - } - } -} - - - - -// Object's constructor. - -CKey::CKey(CInstanceManager* iMan) : CControl(iMan) -{ - m_key[0] = 0; - m_key[1] = 0; - m_bCatch = FALSE; -} - -// Object's destructor. - -CKey::~CKey() -{ -} - - -// Creates a new button. - -BOOL CKey::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - char name[100]; - char* p; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - CControl::Create(pos, dim, icon, eventMsg); - - GetResource(RES_EVENT, eventMsg, name); - p = strchr(name, '\\'); - if ( p != 0 ) *p = 0; - SetName(name); - - return TRUE; -} - - -// Management of an event. - -BOOL CKey::EventProcess(const Event &event) -{ - if ( m_state & STATE_DEAD ) return TRUE; - - CControl::EventProcess(event); - - if ( event.event == EVENT_LBUTTONDOWN ) - { - if ( Detect(event.pos) ) - { - m_bCatch = TRUE; - } - else - { - m_bCatch = FALSE; - } - } - - if ( event.event == EVENT_KEYDOWN && m_bCatch ) - { - m_bCatch = FALSE; - - if ( TestKey(event.param) ) // impossible ? - { - m_sound->Play(SOUND_TZOING); - } - else - { - if ( event.param == m_key[0] || - event.param == m_key[1] ) - { - m_key[0] = event.param; - m_key[1] = 0; - } - else - { - m_key[1] = m_key[0]; - m_key[0] = event.param; - } - m_sound->Play(SOUND_CLICK); - - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - } - return FALSE; - } - - return TRUE; -} - - -// Seeks when a key is already used. - -BOOL CKey::TestKey(int key) -{ - int i, j; - - if ( key == VK_PAUSE || - key == VK_SNAPSHOT ) return TRUE; // blocked key - - for ( i=0 ; i<20 ; i++ ) - { - for ( j=0 ; j<2 ; j++ ) - { - if ( key == m_engine->RetKey(i, j) ) // key used? - { - m_engine->SetKey(i, j, 0); // nothing! - } - } - - if ( m_engine->RetKey(i, 0) == 0 ) // first free option? - { - m_engine->SetKey(i, 0, m_engine->RetKey(i, 1)); // shift - m_engine->SetKey(i, 1, 0); - } - } - - return FALSE; // not used -} - - -// Draws button. - -void CKey::Draw() -{ - FPOINT iDim, pos; - float zoomExt, zoomInt, h; - int icon; - char text[100]; - - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - iDim = m_dim; - m_dim.x = 200.0f/640.0f; - - if ( m_state & STATE_SHADOW ) - { - DrawShadow(m_pos, m_dim); - } - - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATENORMAL); - - zoomExt = 1.00f; - zoomInt = 0.95f; - - icon = 2; - if ( m_key[0] == 0 && - m_key[1] == 0 ) // no shortcut? - { - icon = 3; - } - if ( m_state & STATE_DEFAULT ) - { - DrawPart(23, 1.3f, 0.0f); - - zoomExt *= 1.15f; - zoomInt *= 1.15f; - } - if ( m_state & STATE_HILIGHT ) - { - icon = 1; - } - if ( m_state & STATE_CHECK ) - { - icon = 0; - } - if ( m_state & STATE_PRESS ) - { - icon = 3; - zoomInt *= 0.9f; - } - if ( (m_state & STATE_ENABLE) == 0 ) - { - icon = 7; - } - if ( m_state & STATE_DEAD ) - { - icon = 17; - } - if ( m_bCatch ) - { - icon = 23; - } - DrawPart(icon, zoomExt, 8.0f/256.0f); // draws the button - - h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; - - GetKeyName(text, m_key[0]); - if ( m_key[1] != 0 ) - { - GetResource(RES_TEXT, RT_KEY_OR, text+strlen(text)); - GetKeyName(text+strlen(text), m_key[1]); - } - - pos.x = m_pos.x+m_dim.x*0.5f; - pos.y = m_pos.y+m_dim.y*0.5f; - pos.y -= h; - m_engine->RetText()->DrawText(text, pos, m_dim.x, 0, m_fontSize, m_fontStretch, m_fontType, 0); - - m_dim = iDim; - - if ( m_state & STATE_DEAD ) return; - - // Draws the name. - pos.x = m_pos.x+(214.0f/640.0f); - pos.y = m_pos.y+m_dim.y*0.5f; - pos.y -= h; - m_engine->RetText()->DrawText(m_name, pos, m_dim.x, 1, m_fontSize, m_fontStretch, m_fontType, 0); -} - - - -void CKey::SetKey(int option, int key) -{ - if ( option < 0 || - option > 1 ) return; - - m_key[option] = key; -} - -int CKey::RetKey(int option) -{ - if ( option < 0 || - option > 1 ) return 0; - - return m_key[option]; -} - diff --git a/src/key.h b/src/key.h deleted file mode 100644 index f292425..0000000 --- a/src/key.h +++ /dev/null @@ -1,54 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// key.h - -#ifndef _KEY_H_ -#define _KEY_H_ - - -#include "control.h" - - -class CD3DEngine; - - - -class CKey : public CControl -{ -public: - CKey(CInstanceManager* iMan); - virtual ~CKey(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - - BOOL EventProcess(const Event &event); - - void Draw(); - - void SetKey(int option, int key); - int RetKey(int option); - -protected: - BOOL TestKey(int key); - -protected: - int m_key[2]; - BOOL m_bCatch; -}; - - -#endif //_KEY_H_ diff --git a/src/label.cpp b/src/label.cpp deleted file mode 100644 index 46d0099..0000000 --- a/src/label.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// label.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "text.h" -#include "label.h" - - - - -// Object's constructor. - -CLabel::CLabel(CInstanceManager* iMan) : CControl(iMan) -{ -} - -// Object's destructor. - -CLabel::~CLabel() -{ -} - - -// Creates a new button. - -BOOL CLabel::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - CControl::Create(pos, dim, icon, eventMsg); - return TRUE; -} - - -// Management of an event. - -BOOL CLabel::EventProcess(const Event &event) -{ -//? CControl::EventProcess(event); - return TRUE; -} - - -// Draws button. - -void CLabel::Draw() -{ - FPOINT pos; - - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - pos.y = m_pos.y+m_dim.y/2.0f; - - if ( m_justif > 0 ) - { - pos.x = m_pos.x; - } - if ( m_justif == 0 ) - { - pos.x = m_pos.x+m_dim.x/2.0f; - } - if ( m_justif < 0 ) - { - pos.x = m_pos.x+m_dim.x; - } - m_engine->RetText()->DrawText(m_name, pos, m_dim.x, m_justif, m_fontSize, m_fontStretch, m_fontType, 0); -} - diff --git a/src/label.h b/src/label.h deleted file mode 100644 index c36a758..0000000 --- a/src/label.h +++ /dev/null @@ -1,48 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// label.h - -#ifndef _LABEL_H_ -#define _LABEL_H_ - - -#include "control.h" - - -class CD3DEngine; - - - -class CLabel : public CControl -{ -public: - CLabel(CInstanceManager* iMan); - virtual ~CLabel(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - - BOOL EventProcess(const Event &event); - - void Draw(); - -protected: - -protected: -}; - - -#endif //_LABEL_H_ diff --git a/src/language.h b/src/language.h deleted file mode 100644 index 4ae97f9..0000000 --- a/src/language.h +++ /dev/null @@ -1,51 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// language.h - -#define _FULL TRUE // CoLoBoT -#define _SCHOOL FALSE // CeeBot-A or Teen - #define _TEEN FALSE // FALSE for CeeBot-A, TRUE for CeeBot-Teen - #define _EDU FALSE - #define _PERSO FALSE - #define _CEEBOTDEMO FALSE -#define _NET FALSE -#define _DEMO FALSE // DEMO only CoLoBoT (with _Full = FALSE)! - -#define _FRENCH TRUE -#define _ENGLISH FALSE -#define _GERMAN FALSE -#define _WG FALSE -#define _POLISH FALSE - -#define _NEWLOOK FALSE // FALSE for CoLoBoT, TRUE for all CeeBot -#define _SOUNDTRACKS FALSE // always FALSE since InitAudioTrackVolume crop in Vista - - -// Verifications - -#if !_FULL & !_SCHOOL & !_NET & !_DEMO --> no version chosen! -#endif - -#if _SCHOOL -#if !_EDU & !_PERSO & !_CEEBOTDEMO --> EDU or PERSO or CEEBOTDEMO? -#endif -#if _EDU & _PERSO & _CEEBOTDEMO --> EDU and PERSO and CEEBOTDEMO not at the same time!!! -#endif -#endif diff --git a/src/light.cpp b/src/light.cpp deleted file mode 100644 index cbb6914..0000000 --- a/src/light.cpp +++ /dev/null @@ -1,503 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// light.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "light.h" - - - - - -// Initializes a progression. - -void ProgInit(LightProg &p, float value) -{ - p.starting = value; - p.ending = value; - p.current = value; - p.progress = 0.0f; - p.speed = 100.0f; -} - -// Makes evolve a progression. - -void ProgFrame(LightProg &p, float rTime) -{ - if ( p.speed < 100.0f ) - { - if ( p.progress < 1.0f ) - { - p.progress += p.speed*rTime; - if ( p.progress > 1.0f ) - { - p.progress = 1.0f; - } - } - - p.current = (p.ending-p.starting)*p.progress + p.starting; - } - else - { - p.current = p.ending; - } -} - -// Change the current value. - -void ProgSet(LightProg &p, float value) -{ - p.starting = p.current; - p.ending = value; - p.progress = 0.0f; -} - - - - - -// Object's constructor. - -CLight::CLight(CInstanceManager* iMan, CD3DEngine* engine) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_LIGHT, this); - - m_pD3DDevice = 0; - m_engine = engine; - - m_lightUsed = 0; - m_lightTable = (Light*)malloc(sizeof(Light)*D3DMAXLIGHT); - ZeroMemory(m_lightTable, sizeof(Light)*D3DMAXLIGHT); - - m_time = 0.0f; -} - -// Object's destructor. - -CLight::~CLight() -{ - free(m_lightTable); - m_iMan->DeleteInstance(CLASS_LIGHT, this); -} - - -void CLight::SetD3DDevice(LPDIRECT3DDEVICE7 device) -{ - m_pD3DDevice = device; -} - - -// Removes all the lights. - -void CLight::FlushLight() -{ - int i; - - for ( i=0 ; iLightEnable(i, FALSE); - } - m_lightUsed = 0; -} - - -// Creates a new light. Returns its rank or -1 on error. - -int CLight::CreateLight() -{ - int i; - - for ( i=0 ; i= D3DMAXLIGHT ) return FALSE; - - m_lightTable[lightRank].bUsed = FALSE; - m_pD3DDevice->LightEnable(lightRank, FALSE); - - m_lightUsed = 0; - for ( i=0 ; i= D3DMAXLIGHT ) return FALSE; - - m_lightTable[lightRank].light = light; - - ProgInit(m_lightTable[lightRank].colorRed, m_lightTable[lightRank].light.dcvDiffuse.r); - ProgInit(m_lightTable[lightRank].colorGreen, m_lightTable[lightRank].light.dcvDiffuse.g); - ProgInit(m_lightTable[lightRank].colorBlue, m_lightTable[lightRank].light.dcvDiffuse.b); - - return TRUE; -} - -// Gives the specifications of a light. - -BOOL CLight::GetLight(int lightRank, D3DLIGHT7 &light) -{ - if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; - - light = m_lightTable[lightRank].light; - return TRUE; -} - - -// Lights up or put out a light. - -BOOL CLight::LightEnable(int lightRank, BOOL bEnable) -{ - if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; - - m_lightTable[lightRank].bEnable = bEnable; - return TRUE; -} - - -// Specifies the type (TYPE *) items included in this light. -// This light does not light up so that this type of objects. - -BOOL CLight::SetLightIncluType(int lightRank, D3DTypeObj type) -{ - if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; - - m_lightTable[lightRank].incluType = type; - return TRUE; -} - -// Specifies the type (TYPE *) items excluded by this light. -// This light does not illuminate then ever these objects. - -BOOL CLight::SetLightExcluType(int lightRank, D3DTypeObj type) -{ - if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; - - m_lightTable[lightRank].excluType = type; - return TRUE; -} - - -// Management of the position of the light. - -BOOL CLight::SetLightPos(int lightRank, D3DVECTOR pos) -{ - if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; - - m_lightTable[lightRank].light.dvPosition = pos; - return TRUE; -} - -D3DVECTOR CLight::RetLightPos(int lightRank) -{ - if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return D3DVECTOR(0.0f, 0.0f, 0.0f); - - return m_lightTable[lightRank].light.dvPosition; -} - - -// Management direction of the light. - -BOOL CLight::SetLightDir(int lightRank, D3DVECTOR dir) -{ - if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; - - m_lightTable[lightRank].light.dvDirection = dir; - return TRUE; -} - -D3DVECTOR CLight::RetLightDir(int lightRank) -{ - if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return D3DVECTOR(0.0f, 0.0f, 0.0f); - - return m_lightTable[lightRank].light.dvDirection; -} - - -// Specifies the rate of change. - -BOOL CLight::SetLightIntensitySpeed(int lightRank, float speed) -{ - if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; - - m_lightTable[lightRank].intensity.speed = speed; - return TRUE; -} - -// Management of the intensity of light. - -BOOL CLight::SetLightIntensity(int lightRank, float value) -{ - if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; - - ProgSet(m_lightTable[lightRank].intensity, value); - return TRUE; -} - -float CLight::RetLightIntensity(int lightRank) -{ - if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return 0.0f; - - return m_lightTable[lightRank].intensity.current; -} - - -// Specifies the rate of change. - -BOOL CLight::SetLightColorSpeed(int lightRank, float speed) -{ - if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; - - m_lightTable[lightRank].colorRed.speed = speed; - m_lightTable[lightRank].colorGreen.speed = speed; - m_lightTable[lightRank].colorBlue.speed = speed; - return TRUE; -} - -// Color management for light. - -BOOL CLight::SetLightColor(int lightRank, D3DCOLORVALUE color) -{ - if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) return FALSE; - - ProgSet(m_lightTable[lightRank].colorRed, color.r); - ProgSet(m_lightTable[lightRank].colorGreen, color.g); - ProgSet(m_lightTable[lightRank].colorBlue, color.b); - return TRUE; -} - -D3DCOLORVALUE CLight::RetLightColor(int lightRank) -{ - D3DCOLORVALUE color; - - if ( lightRank < 0 || lightRank >= D3DMAXLIGHT ) - { - color.r = 0.5f; - color.g = 0.5f; - color.b = 0.5f; - color.a = 0.5f; - return color; - } - - color.r = m_lightTable[lightRank].colorRed.current; - color.g = m_lightTable[lightRank].colorGreen.current; - color.b = m_lightTable[lightRank].colorBlue.current; - return color; -} - - -// Adjusts the color of all lights. - -void CLight::AdaptLightColor(D3DCOLORVALUE color, float factor) -{ - D3DCOLORVALUE value; - int i; - - for ( i=0 ; iRetPause() ) return; - - m_time += rTime; - - for ( i=0 ; iRetEyePt()-m_engine->RetLookatPt(); - angle = RotateAngle(dir.x, dir.z); - angle += PI*0.5f*i; - m_lightTable[i].light.dvDirection.x = sinf(angle*2.0f); - m_lightTable[i].light.dvDirection.z = cosf(angle*2.0f); - } - } -} - - -// Updates all the lights. - -void CLight::LightUpdate() -{ - BOOL bEnable; - float value; - int i; - - for ( i=0 ; iSetLight(i, &m_lightTable[i].light); - m_pD3DDevice->LightEnable(i, bEnable); - } - else - { - m_lightTable[i].light.dcvDiffuse.r = 0.0f; - m_lightTable[i].light.dcvDiffuse.g = 0.0f; - m_lightTable[i].light.dcvDiffuse.b = 0.0f; - - m_pD3DDevice->LightEnable(i, bEnable); - } - } -} - -// Updates the lights for a given type. - -void CLight::LightUpdate(D3DTypeObj type) -{ - BOOL bEnable; - int i; - - for ( i=0 ; iLightEnable(i, bEnable); - } - - if ( m_lightTable[i].excluType != TYPENULL ) - { - bEnable = (m_lightTable[i].excluType != type); - m_pD3DDevice->LightEnable(i, bEnable); - } - } -} - - diff --git a/src/light.h b/src/light.h deleted file mode 100644 index ae2bcfb..0000000 --- a/src/light.h +++ /dev/null @@ -1,113 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// light.h - -#ifndef _LIGHT_H_ -#define _LIGHT_H_ - - -#include "d3dengine.h" - - -class CInstanceManager; -class CD3DEngine; - - -#define D3DMAXLIGHT 100 - - -typedef struct -{ - float starting; - float ending; - float current; - float progress; - float speed; -} -LightProg; - - -typedef struct -{ - char bUsed; // TRUE -> light exists - char bEnable; // TRUE -> light turned on - - D3DTypeObj incluType; // type of all objects included - D3DTypeObj excluType; // type of all objects excluded - - D3DLIGHT7 light; // configuration of the light - - LightProg intensity; // intensity (0 .. 1) - LightProg colorRed; - LightProg colorGreen; - LightProg colorBlue; -} -Light; - - - -class CLight -{ -public: - CLight(CInstanceManager *iMan, CD3DEngine* engine); - virtual ~CLight(); - - void SetD3DDevice(LPDIRECT3DDEVICE7 device); - - void FlushLight(); - int CreateLight(); - BOOL DeleteLight(int lightRank); - BOOL SetLight(int lightRank, const D3DLIGHT7 &light); - BOOL GetLight(int lightRank, D3DLIGHT7 &light); - BOOL LightEnable(int lightRank, BOOL bEnable); - - BOOL SetLightIncluType(int lightRank, D3DTypeObj type); - BOOL SetLightExcluType(int lightRank, D3DTypeObj type); - - BOOL SetLightPos(int lightRank, D3DVECTOR pos); - D3DVECTOR RetLightPos(int lightRank); - - BOOL SetLightDir(int lightRank, D3DVECTOR dir); - D3DVECTOR RetLightDir(int lightRank); - - BOOL SetLightIntensitySpeed(int lightRank, float speed); - BOOL SetLightIntensity(int lightRank, float value); - float RetLightIntensity(int lightRank); - void AdaptLightColor(D3DCOLORVALUE color, float factor); - - BOOL SetLightColorSpeed(int lightRank, float speed); - BOOL SetLightColor(int lightRank, D3DCOLORVALUE color); - D3DCOLORVALUE RetLightColor(int lightRank); - - void FrameLight(float rTime); - void LightUpdate(); - void LightUpdate(D3DTypeObj type); - -protected: - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - LPDIRECT3DDEVICE7 m_pD3DDevice; - - float m_time; - int m_lightUsed; - Light* m_lightTable; -}; - - -#endif //_LIGHT_H_ diff --git a/src/list.cpp b/src/list.cpp deleted file mode 100644 index 08b09c0..0000000 --- a/src/list.cpp +++ /dev/null @@ -1,870 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// list.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "button.h" -#include "scroll.h" -#include "text.h" -#include "list.h" - - - -#define MARGING 4.0f - - - -// Object's constructor. - -CList::CList(CInstanceManager* iMan) : CControl(iMan) -{ - int i; - - for ( i=0 ; iCreate(pos, dim, 0, EVENT_NULL); - m_eventScroll = m_scroll->RetEventMsg(); - - return MoveAdjust(); -} - -// Adjusted after a change of dimensions. - -BOOL CList::MoveAdjust() -{ - FPOINT ipos, idim, ppos, ddim; - float marging, h; - int i; - - for ( i=0 ; iRetText()->RetHeight(m_fontSize, m_fontType)*m_expand; - - m_displayLine = (int)(idim.y/h); - if ( m_displayLine == 0 ) return FALSE; - if ( m_displayLine > LISTMAXDISPLAY ) m_displayLine = LISTMAXDISPLAY; - idim.y = h*m_displayLine; - m_dim.y = idim.y+marging*2.0f/480.f; - - ppos.x = ipos.x; - ppos.y = ipos.y+idim.y-h; - ddim.x = idim.x-SCROLL_WIDTH; - ddim.y = h; - for ( i=0 ; iCreate(ppos, ddim, -1, EVENT_NULL); - m_button[i]->SetJustif(1); - m_button[i]->SetState(STATE_SIMPLY); - m_button[i]->SetFontType(m_fontType); - m_button[i]->SetFontSize(m_fontSize); - ppos.y -= h; - - m_eventButton[i] = m_button[i]->RetEventMsg(); - } - - if ( m_scroll != 0 ) - { - ppos.x = ipos.x+idim.x-SCROLL_WIDTH; - ppos.y = ipos.y; - ddim.x = SCROLL_WIDTH; - ddim.y = idim.y; - m_scroll->SetPos(ppos); - m_scroll->SetDim(ddim); - } - - UpdateScroll(); - UpdateButton(); - return TRUE; -} - - -// Returns the message of a button. - -EventMsg CList::RetEventMsgButton(int i) -{ - if ( i < 0 || i >= m_displayLine ) return EVENT_NULL; - if ( m_button[i] == 0 ) return EVENT_NULL; - return m_button[i]->RetEventMsg(); -} - -// Returns the message from the elevator. - -EventMsg CList::RetEventMsgScroll() -{ - if ( m_scroll == 0 ) return EVENT_NULL; - return m_scroll->RetEventMsg(); -} - - -void CList::SetPos(FPOINT pos) -{ - CControl::SetPos(pos); -} - -void CList::SetDim(FPOINT dim) -{ - m_dim = dim; - MoveAdjust(); - CControl::SetDim(dim); -} - - -BOOL CList::SetState(int state, BOOL bState) -{ - int i; - - if ( state & STATE_ENABLE ) - { - for ( i=0 ; iSetState(state, bState); - } - if ( m_scroll != 0 ) m_scroll->SetState(state, bState); - } - - return CControl::SetState(state, bState); -} - -BOOL CList::SetState(int state) -{ - int i; - - if ( state & STATE_ENABLE ) - { - for ( i=0 ; iSetState(state); - } - if ( m_scroll != 0 ) m_scroll->SetState(state); - } - - return CControl::SetState(state); -} - -BOOL CList::ClearState(int state) -{ - int i; - - if ( state & STATE_ENABLE ) - { - for ( i=0 ; iClearState(state); - } - if ( m_scroll != 0 ) m_scroll->ClearState(state); - } - - return CControl::ClearState(state); -} - - -// Management of an event. - -BOOL CList::EventProcess(const Event &event) -{ - int i; - - if ( m_bBlink && // blinks? - event.event == EVENT_FRAME ) - { - i = m_selectLine-m_firstLine; - - if ( i >= 0 && i < 4 && - m_button[i] != 0 ) - { - m_blinkTime += event.rTime; - if ( Mod(m_blinkTime, 0.7f) < 0.3f ) - { - m_button[i]->ClearState(STATE_ENABLE); - m_button[i]->ClearState(STATE_CHECK); - } - else - { - m_button[i]->SetState(STATE_ENABLE); - m_button[i]->SetState(STATE_CHECK); - } - } - } - - if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; - if ( (m_state & STATE_ENABLE) == 0 ) return TRUE; - - if ( event.event == EVENT_KEYDOWN && - event.param == VK_WHEELUP && - Detect(event.pos) ) - { - if ( m_firstLine > 0 ) m_firstLine --; - UpdateScroll(); - UpdateButton(); - return TRUE; - } - if ( event.event == EVENT_KEYDOWN && - event.param == VK_WHEELDOWN && - Detect(event.pos) ) - { - if ( m_firstLine < m_totalLine-m_displayLine ) m_firstLine ++; - UpdateScroll(); - UpdateButton(); - return TRUE; - } - - CControl::EventProcess(event); - - if ( event.event == EVENT_MOUSEMOVE && Detect(event.pos) ) - { - m_engine->SetMouseType(D3DMOUSENORM); - for ( i=0 ; i= m_totalLine ) break; - if ( m_button[i] != 0 ) - { - m_button[i]->EventProcess(event); - } - } - } - - if ( m_bSelectCap ) - { - for ( i=0 ; i= m_totalLine ) break; - if ( m_button[i] != 0 ) - { - if ( !m_button[i]->EventProcess(event) ) return FALSE; - - if ( event.event == m_eventButton[i] ) - { - SetSelect(m_firstLine+i); - - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); // selected line changes - } - } - } - } - - if ( m_scroll != 0 ) - { - if ( !m_scroll->EventProcess(event) ) return FALSE; - - if ( event.event == m_eventScroll ) - { - MoveScroll(); - UpdateButton(); - } - } - - return TRUE; -} - - -// Draws the list. - -void CList::Draw() -{ - FPOINT uv1, uv2, corner, pos, dim, ppos, ddim; - float dp; - int i, j; - char text[100]; - char *pb, *pe; - - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - if ( m_state & STATE_SHADOW ) - { - DrawShadow(m_pos, m_dim); - } - - dp = 0.5f/256.0f; - - if ( m_icon != -1 ) - { - dim = m_dim; - - if ( m_icon == 0 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - - uv1.x = 128.0f/256.0f; - uv1.y = 64.0f/256.0f; // u-v texture - uv2.x = 160.0f/256.0f; - uv2.y = 96.0f/256.0f; - } - else - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - - uv1.x = 132.0f/256.0f; - uv1.y = 68.0f/256.0f; // u-v texture - uv2.x = 156.0f/256.0f; - uv2.y = 92.0f/256.0f; - - if ( m_button[0] != 0 ) - { - dim = m_button[0]->RetDim(); - dim.y *= m_displayLine; // background sounds spot behind - } - } - - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - corner.x = 10.0f/640.0f; - corner.y = 10.0f/480.0f; - DrawIcon(m_pos, dim, uv1, uv2, corner, 8.0f/256.0f); - } - - if ( m_totalLine < m_displayLine ) // no buttons to the bottom? - { - i = m_totalLine; - if ( m_button[i] != 0 ) - { - pos = m_button[i]->RetPos(); - dim = m_button[i]->RetDim(); - pos.y += dim.y*1.1f; - dim.y *= 0.4f; - pos.y -= dim.y; - - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTw); - uv1.x = 120.0f/256.0f; - uv1.y = 64.0f/256.0f; - uv2.x = 128.0f/256.0f; - uv2.y = 48.0f/256.0f; - uv1.x += dp; - uv1.y -= dp; - uv2.x -= dp; - uv2.y += dp; - DrawIcon(pos, dim, uv1, uv2); // ch'tite shadow cute (?) - } - } - - for ( i=0 ; i= m_totalLine ) break; - - if ( m_button[i] != 0 ) - { - if ( !m_bBlink && i+m_firstLine < m_totalLine ) - { - m_button[i]->SetState(STATE_ENABLE, m_enable[i+m_firstLine] && (m_state & STATE_ENABLE) ); - } - m_button[i]->Draw(); // draws a box without text - - // draws text in the box - pos = m_button[i]->RetPos(); - dim = m_button[i]->RetDim(); - if ( m_tabs[0] == 0.0f ) - { - ppos.x = pos.x+dim.y*0.5f; - ppos.y = pos.y+dim.y*0.5f; - ppos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; - ddim.x = dim.x-dim.y; - DrawCase(m_text[i+m_firstLine], ppos, ddim.x, 1); - } - else - { - ppos.x = pos.x+dim.y*0.5f; - ppos.y = pos.y+dim.y*0.5f; - ppos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; - pb = m_text[i+m_firstLine]; - for ( j=0 ; j<10 ; j++ ) - { - pe = strchr(pb, '\t'); - if ( pe == 0 ) - { - strcpy(text, pb); - } - else - { - strncpy(text, pb, pe-pb); - text[pe-pb] = 0; - } - DrawCase(text, ppos, m_tabs[j], m_justifs[j]); - - if ( pe == 0 ) break; - ppos.x += m_tabs[j]; - pb = pe+1; - } - } - - if ( (m_state & STATE_EXTEND) && i < m_totalLine ) - { - pos = m_button[i]->RetPos(); - dim = m_button[i]->RetDim(); - pos.x += dim.x-dim.y*0.75f; - dim.x = dim.y*0.75f; - pos.x += 2.0f/640.0f; - pos.y += 2.0f/480.0f; - dim.x -= 4.0f/640.0f; - dim.y -= 4.0f/480.0f; - - if ( m_check[i+m_firstLine] ) - { - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 64.0f/256.0f; - uv1.y = 0.0f/256.0f; - uv2.x = 96.0f/256.0f; - uv2.y = 32.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2); // square shape - - m_engine->SetState(D3DSTATETTw); - uv1.x = 0.0f/256.0f; // v - uv1.y = 64.0f/256.0f; - uv2.x = 32.0f/256.0f; - uv2.y = 96.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2); // draws v - } - else - { - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATETTw); - if ( i+m_firstLine == m_selectLine ) - { - uv1.x =224.0f/256.0f; // < - uv1.y =192.0f/256.0f; - uv2.x =256.0f/256.0f; - uv2.y =224.0f/256.0f; - } - else - { - uv1.x = 96.0f/256.0f; // x - uv1.y = 32.0f/256.0f; - uv2.x =128.0f/256.0f; - uv2.y = 64.0f/256.0f; - } - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2); // draws x - } - } - } - } - - if ( m_scroll != 0 ) - { - m_scroll->Draw(); // draws the lift - } -} - -// Displays text in a box. - -void CList::DrawCase(char *text, FPOINT pos, float width, int justif) -{ - if ( justif == 1 ) - { - m_engine->RetText()->DrawText(text, pos, width, 1, m_fontSize, m_fontStretch, m_fontType, 0); - } - else if ( justif == 0 ) - { - pos.x += width/2.0f; - m_engine->RetText()->DrawText(text, pos, width, 0, m_fontSize, m_fontStretch, m_fontType, 0); - } - else - { - pos.x += width; - m_engine->RetText()->DrawText(text, pos, width, -1, m_fontSize, m_fontStretch, m_fontType, 0); - } -} - - -// Empty the list completely. - -void CList::Flush() -{ - m_totalLine = 0; - m_selectLine = -1; - m_firstLine = 0; - UpdateButton(); - UpdateScroll(); -} - - -// Specifies the total number of lines. - -void CList::SetTotal(int i) -{ - m_totalLine = i; -} - -// Returns the total number of lines. - -int CList::RetTotal() -{ - return m_totalLine; -} - - -// Selects a line. - -void CList::SetSelect(int i) -{ - if ( m_bSelectCap ) - { - m_selectLine = i; - } - else - { - m_firstLine = i; - UpdateScroll(); - } - - UpdateButton(); -} - -// Returns the selected line. - -int CList::RetSelect() -{ - if ( m_bSelectCap ) - { - return m_selectLine; - } - else - { - return m_firstLine; - } -} - - -// Management of capability has a select box. - -void CList::SetSelectCap(BOOL bEnable) -{ - m_bSelectCap = bEnable; -} - -BOOL CList::RetSelectCap() -{ - return m_bSelectCap; -} - - -// Blink a line. - -void CList::SetBlink(BOOL bEnable) -{ - int i; - - m_bBlink = bEnable; - m_blinkTime = 0.0f; - - i = m_selectLine-m_firstLine; - - if ( i >= 0 && i < 4 && - m_button[i] != 0 ) - { - if ( !bEnable ) - { - m_button[i]->SetState(STATE_CHECK); - m_button[i]->ClearState(STATE_ENABLE); - } - } -} - -BOOL CList::RetBlink() -{ - return m_bBlink; -} - - -// Specifies the text of a line. - -void CList::SetName(int i, char* name) -{ - if ( i < 0 || i >= LISTMAXTOTAL ) return; - - if ( i >= m_totalLine ) - { - m_totalLine = i+1; // expands the list - } - - if ( name[0] == 0 ) - { - strcpy(m_text[i], " "); - } - else - { - strcpy(m_text[i], name); - } - UpdateButton(); - UpdateScroll(); -} - -// Returns the text of a line. - -char* CList::RetName(int i) -{ - if ( i < 0 || i >= m_totalLine ) return 0; - - return m_text[i]; -} - - -// Specifies the bit "check" for a box. - -void CList::SetCheck(int i, BOOL bMode) -{ - if ( i < 0 || i >= m_totalLine ) return; - - m_check[i] = bMode; -} - -// Returns the bit "check" for a box. - -BOOL CList::RetCheck(int i) -{ - if ( i < 0 || i >= m_totalLine ) return FALSE; - - return m_check[i]; -} - - -// Specifies the bit "enable" for a box. - -void CList::SetEnable(int i, BOOL bMode) -{ - if ( i < 0 || i >= m_totalLine ) return; - - m_enable[i] = bMode; -} - -// Returns the bit "enable" for a box. - -BOOL CList::RetEnable(int i) -{ - if ( i < 0 || i >= m_totalLine ) return FALSE; - - return m_enable[i]; -} - - -// Management of the position of the tabs. - -void CList::SetTabs(int i, float pos, int justif) -{ - if ( i < 0 || i >= 10 ) return; - m_tabs[i] = pos; - m_justifs[i] = justif; -} - -float CList::RetTabs(int i) -{ - if ( i < 0 || i >= 10 ) return 0.0f; - return m_tabs[i]; -} - - -// Moves the lift to see the list of the selected line. - -void CList::ShowSelect(BOOL bFixed) -{ - int sel; - - if ( bFixed && - m_selectLine >= m_firstLine && - m_selectLine < m_firstLine+m_displayLine ) return; // all good - - sel = m_selectLine; - - // Down from 1/2 * h. - sel += m_displayLine/2; - if ( sel > m_totalLine-1 ) sel = m_totalLine-1; - - // Back to h-1. - sel -= m_displayLine-1; - if ( sel < 0 ) sel = 0; - - m_firstLine = sel; - - UpdateButton(); - UpdateScroll(); -} - - -// Updates all button names. - -void CList::UpdateButton() -{ - int state, i, j; - - state = CControl::RetState(); - - j = m_firstLine; - for ( i=0 ; iSetState(STATE_CHECK, (j == m_selectLine)); - - if ( j < m_totalLine ) - { -//? m_button[i]->SetName(m_text[j]); - m_button[i]->SetName(" "); // blank button - m_button[i]->SetState(STATE_ENABLE, (state & STATE_ENABLE)); - } - else - { - m_button[i]->SetName(" "); // blank button - m_button[i]->ClearState(STATE_ENABLE); - } - j ++; - } -} - -// Updates the lift. - -void CList::UpdateScroll() -{ - float ratio, value, step; - - if ( m_scroll == 0 ) return; - - if ( m_totalLine <= m_displayLine ) - { - ratio = 1.0f; - value = 0.0f; - step = 0.0f; - } - else - { - ratio = (float)m_displayLine/m_totalLine; - if ( ratio > 1.0f ) ratio = 1.0f; - - value = (float)m_firstLine/(m_totalLine-m_displayLine); - if ( value < 0.0f ) value = 0.0f; - if ( value > 1.0f ) value = 1.0f; - - step = (float)1.0f/(m_totalLine-m_displayLine); - if ( step < 0.0f ) step = 0.0f; - } - - m_scroll->SetVisibleRatio(ratio); - m_scroll->SetVisibleValue(value); - m_scroll->SetArrowStep(step); -} - -// Update when the lift is moving. - -void CList::MoveScroll() -{ - float pos; - int n; - - if ( m_scroll == 0 ) return; - - n = m_totalLine-m_displayLine; - pos = m_scroll->RetVisibleValue(); - pos += m_scroll->RetArrowStep()/2.0f; // it's magic! - m_firstLine = (int)(pos*n); - if ( m_firstLine < 0 ) m_firstLine = 0; - if ( m_firstLine > n ) m_firstLine = n; -} - - diff --git a/src/list.h b/src/list.h deleted file mode 100644 index 43d155f..0000000 --- a/src/list.h +++ /dev/null @@ -1,117 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// list.h - -#ifndef _LIST_H_ -#define _LIST_H_ - - -#include "control.h" -#include "event.h" - - -class CD3DEngine; -class CButton; -class CScroll; - - -#define LISTMAXDISPLAY 20 // maximum number of visible lines -#define LISTMAXTOTAL 100 // maximum total number of lines - - - -class CList : public CControl -{ -public: - CList(CInstanceManager* iMan); - ~CList(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, float expand); - - void SetPos(FPOINT pos); - void SetDim(FPOINT dim); - - BOOL SetState(int state, BOOL bState); - BOOL SetState(int state); - BOOL ClearState(int state); - - BOOL EventProcess(const Event &event); - void Draw(); - - void Flush(); - - void SetTotal(int i); - int RetTotal(); - - void SetSelect(int i); - int RetSelect(); - - void SetSelectCap(BOOL bEnable); - BOOL RetSelectCap(); - - void SetBlink(BOOL bEnable); - BOOL RetBlink(); - - void SetName(int i, char* name); - char* RetName(int i); - - void SetCheck(int i, BOOL bMode); - BOOL RetCheck(int i); - - void SetEnable(int i, BOOL bEnable); - BOOL RetEnable(int i); - - void SetTabs(int i, float pos, int justif=1); - float RetTabs(int i); - - void ShowSelect(BOOL bFixed); - - EventMsg RetEventMsgButton(int i); - EventMsg RetEventMsgScroll(); - -protected: - BOOL MoveAdjust(); - void UpdateButton(); - void UpdateScroll(); - void MoveScroll(); - void DrawCase(char *text, FPOINT pos, float width, int justif); - -protected: - CButton* m_button[LISTMAXDISPLAY]; - CScroll* m_scroll; - - EventMsg m_eventButton[LISTMAXDISPLAY]; - EventMsg m_eventScroll; - - float m_expand; - int m_totalLine; // total number of lines - int m_displayLine; // number of visible lines - int m_selectLine; // selected line - int m_firstLine; // first visible line - BOOL m_bBlink; - BOOL m_bSelectCap; - float m_blinkTime; - float m_tabs[10]; - int m_justifs[10]; - - char m_text[LISTMAXTOTAL][100]; - char m_check[LISTMAXTOTAL]; - char m_enable[LISTMAXTOTAL]; -}; - - -#endif //_LIST_H_ diff --git a/src/maindialog.cpp b/src/maindialog.cpp deleted file mode 100644 index a216cd9..0000000 --- a/src/maindialog.cpp +++ /dev/null @@ -1,6937 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// maindialog.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "global.h" -#include "language.h" -#include "event.h" -#include "misc.h" -#include "profile.h" -#include "iman.h" -#include "restext.h" -#include "math3d.h" -#include "particule.h" -#include "interface.h" -#include "button.h" -#include "color.h" -#include "check.h" -#include "key.h" -#include "group.h" -#include "image.h" -#include "scroll.h" -#include "slider.h" -#include "list.h" -#include "label.h" -#include "window.h" -#include "edit.h" -#include "editvalue.h" -#include "text.h" -#include "camera.h" -#include "sound.h" -#include "cmdtoken.h" -#include "robotmain.h" -#include "maindialog.h" - - - -#define KEY_VISIBLE 6 // number of visible keys redefinable - -#if _SCHOOL & _TEEN -#define KEY_TOTAL 13 // total number of keys redefinable -#else -#define KEY_TOTAL 21 // total number of keys redefinable -#endif - -#define WELCOME_LENGTH 6.0f - - - -static int perso_color[3*10*3] = -{ - // hair: - 193, 221, 226, // white - 255, 255, 181, // yellow - 204, 155, 84, // blond - 165, 48, 10, // red - 140, 75, 84, // brown - 83, 64, 51, // brown - 90, 95, 85, // black - 85, 48, 9, // brown - 60, 0, 23, // black - 0, 0, 0, // - // spacesuit: - 203, 206, 204, // dirty white - 0, 205, 203, // bluish - 108, 176, 0, // greenish - 207, 207, 32, // yellow - 170, 141, 0, // orange - 108, 84, 0, // brown - 0, 84, 136, // bluish - 56, 61, 146, // bluish - 56, 56, 56, // black - 0, 0, 0, // - // strips: - 255, 255, 255, // white - 255, 255, 0, // yellow - 255, 132, 1, // orange - 255, 0, 255, // magenta - 255, 0, 0, // red - 0, 255, 0, // green - 0, 255, 255, // cyan - 0, 0, 255, // blue - 70, 51, 84, // dark - 0, 0, 0, // -}; - - -#if _NET -// Check if the key "school" is present in the registry. - -BOOL SchoolCheck() -{ - HKEY key; - char buffer[100]; - LONG i; - DWORD type, len; - - i = RegOpenKeyEx(HKEY_LOCAL_MACHINE, -#if _NEWLOOK - "Software\\Epsitec\\CeeBot\\Setup", -#else - "Software\\Epsitec\\Colobot\\Setup", -#endif - 0, KEY_READ, &key); - if ( i != ERROR_SUCCESS ) return FALSE; - - type = REG_SZ; - len = sizeof(buffer); - i = RegQueryValueEx(key, "School", NULL, &type, (LPBYTE)buffer, &len); - if ( i != ERROR_SUCCESS || type != REG_SZ ) return FALSE; - - if ( strcmp(buffer, "ToBoLoC") != 0 ) return FALSE; - - return TRUE; -} -#endif - - -// Constructor of robot application. - -CMainDialog::CMainDialog(CInstanceManager* iMan) -{ - int i; - - m_iMan = iMan; - m_iMan->AddInstance(CLASS_DIALOG, this); - - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - - m_phase = PHASE_NAME; - m_phaseSetup = PHASE_SETUPg; - m_phaseTerm = PHASE_TRAINER; - m_sceneRead[0] = 0; - m_stackRead[0] = 0; - m_sceneName[0] = 0; - m_sceneRank = 0; - m_bSceneSoluce = FALSE; - m_bSimulSetup = FALSE; -#if _NET - m_accessEnable = SchoolCheck(); - m_accessMission= FALSE; - m_accessUser = FALSE; -#else - m_accessEnable = TRUE; - m_accessMission= TRUE; - m_accessUser = TRUE; -#endif - m_bDeleteGamer = TRUE; - - for ( i=0 ; i<10 ; i++ ) - { - m_chap[i] = 0; - m_sel[i] = 0; - } - m_index = 0; - m_maxList = 0; - - ZeroMemory(&m_perso, sizeof(GamerPerso)); - DefPerso(); - - m_bTooltip = TRUE; - m_bGlint = TRUE; - m_bRain = TRUE; - m_bSoluce4 = TRUE; - m_bMovies = TRUE; - m_bNiceReset = TRUE; - m_bHimselfDamage = TRUE; -#if _TEEN - m_bCameraScroll = FALSE; -#else - m_bCameraScroll = TRUE; -#endif - m_bCameraInvertX = FALSE; - m_bCameraInvertY = FALSE; - m_bEffect = TRUE; - m_shotDelay = 0; - - m_glintMouse = FPOINT(0.0f, 0.0f); - m_glintTime = 1000.0f; - - for ( i=0 ; i<10 ; i++ ) - { - m_partiPhase[i] = 0; - m_partiTime[i] = 0.0f; - } - - strcpy(m_sceneDir, "scene"); - strcpy(m_savegameDir, "savegame"); - strcpy(m_publicDir, "program"); - strcpy(m_userDir, "user"); - strcpy(m_filesDir, "files"); - - m_bDialog = FALSE; -} - -// Destructor of robot application. - -CMainDialog::~CMainDialog() -{ -} - - -// Changes phase. - -void CMainDialog::ChangePhase(Phase phase) -{ - CWindow* pw; - CEdit* pe; - CEditValue* pv; - CLabel* pl; - CList* pli; - CCheck* pc; - CScroll* ps; - CSlider* psl; - CButton* pb; - CColor* pco; - CGroup* pg; - CImage* pi; - FPOINT pos, dim, ddim; - float ox, oy, sx, sy; - char name[100]; - char* gamer; - int res, i, j; - - m_camera->SetType(CAMERA_DIALOG); - m_engine->SetOverFront(FALSE); - m_engine->SetOverColor(RetColor(0.0f), D3DSTATETCb); - - if ( phase == PHASE_TERM ) - { - phase = m_phaseTerm; - } - m_phase = phase; // copy the info to CRobotMain - m_phaseTime = 0.0f; - - dim.x = 32.0f/640.0f; - dim.y = 32.0f/480.0f; - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = (32.0f+2.0f)/640.0f; - sy = (32.0f+2.0f)/480.0f; - - if ( m_phase == PHASE_INIT ) - { - pos.x = 0.35f; - pos.y = 0.10f; - ddim.x = 0.30f; - ddim.y = 0.80f; -#if _TEEN - pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5); -#else - pw = m_interface->CreateWindows(pos, ddim, 10, EVENT_WINDOW5); -#endif - GetResource(RES_TEXT, RT_TITLE_INIT, name); - pw->SetName(name); - - pos.x = 0.35f; - pos.y = 0.60f; - ddim.x = 0.30f; - ddim.y = 0.30f; - pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner - pos.x = 0.35f; - pos.y = 0.10f; - ddim.x = 0.30f; - ddim.y = 0.30f; - pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner - -#if _SCHOOL - ddim.x = 0.20f; - ddim.y = dim.y*2.4f; - pos.x = 0.40f; - pos.y = oy+sy*7.9f; - pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // orange - pg->SetState(STATE_SHADOW); - pos.y = oy+sy*3.9f; - pg = pw->CreateGroup(pos, ddim, 25, EVENT_LABEL1); // orange - pg->SetState(STATE_SHADOW); - ddim.y = dim.y*1.2f; - pos.y = oy+sy*1.9f; - pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // red - pg->SetState(STATE_SHADOW); -#else - ddim.x = 0.20f; - ddim.y = dim.y*2.4f; - pos.x = 0.40f; - if ( m_accessEnable && m_accessMission ) - { - pos.y = oy+sy*9.1f; - pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // yellow - pg->SetState(STATE_SHADOW); - } - pos.y = oy+sy*6.8f; - pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // orange - pg->SetState(STATE_SHADOW); - pos.y = oy+sy*3.9f; - pg = pw->CreateGroup(pos, ddim, 25, EVENT_LABEL1); // orange - pg->SetState(STATE_SHADOW); - ddim.y = dim.y*1.2f; - pos.y = oy+sy*1.9f; - pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // red - pg->SetState(STATE_SHADOW); -#endif - -#if _SCHOOL - ddim.x = 0.18f; - ddim.y = dim.y*1; - pos.x = 0.41f; - pos.y = oy+sy*9.1f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_TRAINER); - pb->SetState(STATE_SHADOW); - - pos.y = oy+sy*8.0f; -#if _TEEN - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_TEEN); -#else - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_DEFI); -#endif -#if _CEEBOTDEMO - pb->ClearState(STATE_ENABLE); -#endif - pb->SetState(STATE_SHADOW); -#else - ddim.x = 0.18f; - ddim.y = dim.y*1; - pos.x = 0.41f; - - if ( m_accessEnable && m_accessMission ) - { - pos.y = oy+sy*10.3f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_MISSION); - pb->SetState(STATE_SHADOW); - - pos.y = oy+sy*9.2f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_FREE); - pb->SetState(STATE_SHADOW); - } - - pos.y = oy+sy*8.0f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_TRAINER); - pb->SetState(STATE_SHADOW); - - pos.y = oy+sy*6.9f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_DEFI); - pb->SetState(STATE_SHADOW); -#endif - - if ( m_engine->RetSetupMode() ) - { - pos.y = oy+sy*5.1f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUP); - pb->SetState(STATE_SHADOW); - } - - pos.y = oy+sy*4.0f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NAME); - pb->SetState(STATE_SHADOW); - - pos.y = oy+sy*2.0f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_QUIT); - pb->SetState(STATE_SHADOW); - -#if !_DEMO & !_SCHOOL - if ( m_accessEnable && m_accessUser ) - { - pos.x = 447.0f/640.0f; - pos.y = 313.0f/480.0f; - ddim.x = 0.09f; -#if _POLISH - pos.x -= 5.0f/640.0f; - ddim.x += 10.0f/640.0f; -#endif - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_USER); - pb->SetState(STATE_SHADOW); - } -#endif - - if ( m_engine->RetDebugMode() ) - { - pos.x = 139.0f/640.0f; - pos.y = 313.0f/480.0f; - ddim.x = 0.09f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PROTO); - pb->SetState(STATE_SHADOW); - } - - pos.x = 0.40f; - ddim.x = 0.20f; - pos.y = 26.0f/480.0f; - ddim.y = 12.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 1, EVENT_LABEL1); - pg->SetState(STATE_SHADOW); - pos.y -= 5.0f/480.0f; -#if _WG - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, " "); -#else -#if _NEWLOOK - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, "www.epsitec.ch"); -#else - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, "www.ceebot.com"); -#endif -#endif - pl->SetFontType(FONT_COURIER); - pl->SetFontSize(8.0f); - - m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE); - m_engine->SetBackForce(TRUE); - } - - if ( m_phase == PHASE_NAME ) - { - pos.x = 0.10f; - pos.y = 0.10f; - ddim.x = 0.80f; - ddim.y = 0.80f; - pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5); - GetResource(RES_TEXT, RT_TITLE_NAME, name); - pw->SetName(name); - -#if _NEWLOOK - pos.x = 80.0f/640.0f; - pos.y = 93.0f/480.0f; - ddim.x = 285.0f/640.0f; - ddim.y = 266.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue - pg->SetState(STATE_SHADOW); - pos.x = 372.0f/640.0f; - ddim.x = 188.0f/640.0f; - pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet - pg->SetState(STATE_SHADOW); -#endif - - pos.x = 0.10f; - pos.y = 0.40f; - ddim.x = 0.50f; - ddim.y = 0.50f; - pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner - pos.x = 0.40f; - pos.y = 0.10f; - ddim.x = 0.50f; - ddim.y = 0.50f; - pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner - - pos.x = 60.0f/640.0f; - pos.y = 313.0f/480.0f; - ddim.x = 120.0f/640.0f; - ddim.y = 32.0f/480.0f; - GetResource(RES_EVENT, EVENT_INTERFACE_NLABEL, name); - pl = pw->CreateLabel(pos, ddim, -1, EVENT_INTERFACE_NLABEL, name); - pl->SetJustif(-1); - - pos.x = 200.0f/640.0f; - pos.y = 320.0f/480.0f; - ddim.x = 160.0f/640.0f; - ddim.y = 32.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 7, EVENT_LABEL1); - pg->SetState(STATE_SHADOW); - - pos.x = 207.0f/640.0f; - pos.y = 328.0f/480.0f; - ddim.x = 144.0f/640.0f; - ddim.y = 18.0f/480.0f; - pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_NEDIT); - pe->SetMaxChar(15); - gamer = m_main->RetGamerName(); - if ( gamer[0] == 0 ) - { - GetResource(RES_TEXT, RT_NAME_DEFAULT, name); - } - else - { - strcpy(name, gamer); - } - pe->SetText(name); - pe->SetCursor(strlen(name), 0); - pe->SetFocus(TRUE); - - pos.x = 380.0f/640.0f; - pos.y = 320.0f/480.0f; - ddim.x =100.0f/640.0f; - ddim.y = 32.0f/480.0f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NOK); - pb->SetState(STATE_SHADOW); - -#if !_TEEN - pos.x = 380.0f/640.0f; - pos.y = 250.0f/480.0f; - ddim.x =100.0f/640.0f; - ddim.y = 52.0f/480.0f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PERSO); - pb->SetState(STATE_SHADOW); -#endif - - pos.x = 200.0f/640.0f; - pos.y = 150.0f/480.0f; - ddim.x = 160.0f/640.0f; - ddim.y = 160.0f/480.0f; - pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_NLIST); - pli->SetState(STATE_SHADOW); - - if ( m_bDeleteGamer ) - { - pos.x = 200.0f/640.0f; - pos.y = 100.0f/480.0f; - ddim.x = 160.0f/640.0f; - ddim.y = 32.0f/480.0f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NDELETE); - pb->SetState(STATE_SHADOW); - } - - pos.x = 380.0f/640.0f; - pos.y = 100.0f/480.0f; - ddim.x =100.0f/640.0f; - ddim.y = 32.0f/480.0f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NCANCEL); - pb->SetState(STATE_SHADOW); - - ReadNameList(); - UpdateNameList(); - UpdateNameControl(); - UpdateNameFace(); - - m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE); - m_engine->SetBackForce(TRUE); - } - - if ( m_phase == PHASE_PERSO ) - { - pos.x = 0.10f; - pos.y = 0.10f; - ddim.x = 0.80f; - ddim.y = 0.80f; - pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5); - GetResource(RES_TEXT, RT_TITLE_PERSO, name); - pw->SetName(name); - -#if _NEWLOOK - pos.x = 95.0f/640.0f; - pos.y = 66.0f/480.0f; - ddim.x = 443.0f/640.0f; - ddim.y = 42.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet - pg->SetState(STATE_SHADOW); -#endif - - pos.x = 0.10f; - pos.y = 0.40f; - ddim.x = 0.50f; - ddim.y = 0.50f; - pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner - pos.x = 0.40f; - pos.y = 0.10f; - ddim.x = 0.50f; - ddim.y = 0.50f; - pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner - - pos.x = 95.0f/640.0f; - pos.y = 108.0f/480.0f; - ddim.x = 220.0f/640.0f; - ddim.y = 274.0f/480.0f; - pw->CreateGroup(pos, ddim, 17, EVENT_NULL); // frame - - pos.x = 100.0f/640.0f; - pos.y = 364.0f/480.0f; - ddim.x = 210.0f/640.0f; - ddim.y = 14.0f/480.0f; - pw->CreateGroup(pos, ddim, 3, EVENT_NULL); // transparent -> gray - - pos.x = 120.0f/640.0f; - pos.y = 364.0f/480.0f; - ddim.x = 80.0f/640.0f; - ddim.y = 28.0f/480.0f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PHEAD); - pb->SetState(STATE_SHADOW); - pb->SetState(STATE_CARD); - - pos.x = 210.0f/640.0f; - pos.y = 364.0f/480.0f; - ddim.x = 80.0f/640.0f; - ddim.y = 28.0f/480.0f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PBODY); - pb->SetState(STATE_SHADOW); - pb->SetState(STATE_CARD); - - pos.x = 100.0f/640.0f; - pos.y = 354.0f/480.0f; - ddim.x = 210.0f/640.0f; - ddim.y = 10.0f/480.0f; - pw->CreateGroup(pos, ddim, 1, EVENT_INTERFACE_GLINTb); // orange bar - pos.x = 100.0f/640.0f; - pos.y = 154.0f/480.0f; - ddim.x = 210.0f/640.0f; - ddim.y = 200.0f/480.0f; - pw->CreateGroup(pos, ddim, 2, EVENT_INTERFACE_GLINTu); // orange -> transparent - - // Face - pos.x = 340.0f/640.0f; - pos.y = 356.0f/480.0f; - ddim.x = 200.0f/640.0f; - ddim.y = 16.0f/480.0f; - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL11, ""); - pl->SetJustif(1); - - pos.x = 340.0f/640.0f; - pos.y = 312.0f/480.0f; - ddim.x = 44.0f/640.0f; - ddim.y = 44.0f/480.0f; - pb = pw->CreateButton(pos, ddim, 43, EVENT_INTERFACE_PFACE1); - pb->SetState(STATE_SHADOW); - pos.x += 50.0f/640.0f; - pb = pw->CreateButton(pos, ddim, 46, EVENT_INTERFACE_PFACE4); - pb->SetState(STATE_SHADOW); - pos.x += 50.0f/640.0f; - pb = pw->CreateButton(pos, ddim, 45, EVENT_INTERFACE_PFACE3); - pb->SetState(STATE_SHADOW); - pos.x += 50.0f/640.0f; - pb = pw->CreateButton(pos, ddim, 44, EVENT_INTERFACE_PFACE2); - pb->SetState(STATE_SHADOW); - - // Glasses - pos.x = 340.0f/640.0f; - pos.y = 270.0f/480.0f; - ddim.x = 200.0f/640.0f; - ddim.y = 16.0f/480.0f; - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL12, ""); - pl->SetJustif(1); - - pos.x = 340.0f/640.0f; - pos.y = 240.0f/480.0f; - ddim.x = 30.0f/640.0f; - ddim.y = 30.0f/480.0f; - for ( i=0 ; i<6 ; i++ ) - { - int ti[6] = {11, 179, 180, 181, 182, 183}; - pb = pw->CreateButton(pos, ddim, ti[i], (EventMsg)(EVENT_INTERFACE_PGLASS0+i)); - pb->SetState(STATE_SHADOW); - pos.x += (30.0f+2.8f)/640.0f; - } - - // Color A - pos.x = 340.0f/640.0f; - pos.y = 300.0f/480.0f; - ddim.x = 200.0f/640.0f; - ddim.y = 16.0f/480.0f; - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL14, ""); - pl->SetJustif(1); - - pos.y = 282.0f/480.0f; - ddim.x = 18.0f/640.0f; - ddim.y = 18.0f/480.0f; - for ( j=0 ; j<3 ; j++ ) - { - pos.x = 340.0f/640.0f; - for ( i=0 ; i<3 ; i++ ) - { - pco = pw->CreateColor(pos, ddim, -1, (EventMsg)(EVENT_INTERFACE_PC0a+j*3+i)); - pco->SetState(STATE_SHADOW); - pos.x += 20.0f/640.0f; - } - pos.y -= 20.0f/480.0f; - } - - pos.x = 420.0f/640.0f; - pos.y = 282.0f/480.0f; - ddim.x = 100.0f/640.0f; - ddim.y = 18.0f/480.0f; - for ( i=0 ; i<3 ; i++ ) - { - psl = pw->CreateSlider(pos, ddim, 0, (EventMsg)(EVENT_INTERFACE_PCRa+i)); - psl->SetState(STATE_SHADOW); - psl->SetLimit(0.0f, 255.0f); - psl->SetArrowStep(16.0f); - pos.y -= 20.0f/480.0f; - } - - // Color B - pos.x = 340.0f/640.0f; - pos.y = 192.0f/480.0f; - ddim.x = 200.0f/640.0f; - ddim.y = 16.0f/480.0f; - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL13, ""); - pl->SetJustif(1); - - pos.y = 174.0f/480.0f; - ddim.x = 18.0f/640.0f; - ddim.y = 18.0f/480.0f; - for ( j=0 ; j<3 ; j++ ) - { - pos.x = 340.0f/640.0f; - for ( i=0 ; i<3 ; i++ ) - { - pco = pw->CreateColor(pos, ddim, -1, (EventMsg)(EVENT_INTERFACE_PC0b+j*3+i)); - pco->SetState(STATE_SHADOW); - pos.x += 20.0f/640.0f; - } - pos.y -= 20.0f/480.0f; - } - - pos.x = 420.0f/640.0f; - pos.y = 174.0f/480.0f; - ddim.x = 100.0f/640.0f; - ddim.y = 18.0f/480.0f; - for ( i=0 ; i<3 ; i++ ) - { - psl = pw->CreateSlider(pos, ddim, 0, (EventMsg)(EVENT_INTERFACE_PCRb+i)); - psl->SetState(STATE_SHADOW); - psl->SetLimit(0.0f, 255.0f); - psl->SetArrowStep(16.0f); - pos.y -= 20.0f/480.0f; - } - - // Rotation - pos.x = 100.0f/640.0f; - pos.y = 113.0f/480.0f; - ddim.x = 20.0f/640.0f; - ddim.y = 20.0f/480.0f; - pb = pw->CreateButton(pos, ddim, 55, EVENT_INTERFACE_PLROT); // < - pb->SetState(STATE_SHADOW); - pb->SetRepeat(TRUE); - - pos.x = 290.0f/640.0f; - pos.y = 113.0f/480.0f; - ddim.x = 20.0f/640.0f; - ddim.y = 20.0f/480.0f; - pb = pw->CreateButton(pos, ddim, 48, EVENT_INTERFACE_PRROT); // > - pb->SetState(STATE_SHADOW); - pb->SetRepeat(TRUE); - - pos.x = 100.0f/640.0f; - pos.y = 70.0f/480.0f; - ddim.x = 100.0f/640.0f; - ddim.y = 32.0f/480.0f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_POK); - pb->SetState(STATE_SHADOW); - - pos.x = 210.0f/640.0f; - pos.y = 70.0f/480.0f; - ddim.x =100.0f/640.0f; - ddim.y = 32.0f/480.0f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PCANCEL); - pb->SetState(STATE_SHADOW); - - pos.x = 340.0f/640.0f; - pos.y = 70.0f/480.0f; - ddim.x =194.0f/640.0f; - ddim.y = 32.0f/480.0f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PDEF); - pb->SetState(STATE_SHADOW); - - m_persoCopy = m_perso; - m_persoTab = 0; - m_persoAngle = -0.6f; - UpdatePerso(); - m_main->ScenePerso(); - CameraPerso(); - } - - if ( m_phase == PHASE_TRAINER || - m_phase == PHASE_DEFI || - m_phase == PHASE_MISSION || - m_phase == PHASE_FREE || - m_phase == PHASE_TEEN || - m_phase == PHASE_USER || - m_phase == PHASE_PROTO ) - { - if ( m_phase == PHASE_TRAINER ) m_index = 0; - if ( m_phase == PHASE_DEFI ) m_index = 1; - if ( m_phase == PHASE_MISSION ) m_index = 2; - if ( m_phase == PHASE_FREE ) m_index = 3; - if ( m_phase == PHASE_USER ) m_index = 4; - if ( m_phase == PHASE_PROTO ) m_index = 5; - if ( m_phase == PHASE_TEEN ) m_index = 6; - - if ( m_phase == PHASE_FREE ) - { - strcpy(m_sceneName, "scene"); - ReadGamerInfo(); - m_accessChap = RetChapPassed(); - } - - if ( m_phase == PHASE_TRAINER ) strcpy(m_sceneName, "train"); - if ( m_phase == PHASE_DEFI ) strcpy(m_sceneName, "defi" ); - if ( m_phase == PHASE_MISSION ) strcpy(m_sceneName, "scene"); - if ( m_phase == PHASE_FREE ) strcpy(m_sceneName, "free"); - if ( m_phase == PHASE_TEEN ) strcpy(m_sceneName, "teen"); - if ( m_phase == PHASE_USER ) strcpy(m_sceneName, "user"); - if ( m_phase == PHASE_PROTO ) strcpy(m_sceneName, "proto"); - - ReadGamerInfo(); - - pos.x = 0.10f; - pos.y = 0.10f; - ddim.x = 0.80f; - ddim.y = 0.80f; - pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5); - pw->SetClosable(TRUE); - if ( m_phase == PHASE_TRAINER ) res = RT_TITLE_TRAINER; - if ( m_phase == PHASE_DEFI ) res = RT_TITLE_DEFI; - if ( m_phase == PHASE_MISSION ) res = RT_TITLE_MISSION; - if ( m_phase == PHASE_FREE ) res = RT_TITLE_FREE; - if ( m_phase == PHASE_TEEN ) res = RT_TITLE_TEEN; - if ( m_phase == PHASE_USER ) res = RT_TITLE_USER; - if ( m_phase == PHASE_PROTO ) res = RT_TITLE_PROTO; - GetResource(RES_TEXT, res, name); - pw->SetName(name); - -#if _NEWLOOK - pos.x = 100.0f/640.0f; - pos.y = 226.0f/480.0f; - ddim.x = 216.0f/640.0f; - ddim.y = 160.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue - pg->SetState(STATE_SHADOW); - pos.x = 322.0f/640.0f; - pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // cyan - pg->SetState(STATE_SHADOW); - - pos.x = 100.0f/640.0f; - pos.y = 122.0f/480.0f; - ddim.x = 438.0f/640.0f; - ddim.y = 98.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 25, EVENT_LABEL1); // green - pg->SetState(STATE_SHADOW); - pos.y = 66.0f/480.0f; - ddim.y = 42.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet - pg->SetState(STATE_SHADOW); -#endif - - pos.x = 0.10f; - pos.y = 0.40f; - ddim.x = 0.50f; - ddim.y = 0.50f; - pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner - pos.x = 0.40f; - pos.y = 0.10f; - ddim.x = 0.50f; - ddim.y = 0.50f; - pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner - - // Displays a list of chapters: - pos.x = ox+sx*3; - pos.y = oy+sy*10.5f; - ddim.x = dim.x*7.5f; - ddim.y = dim.y*0.6f; - if ( m_phase == PHASE_TRAINER ) res = RT_PLAY_CHAPt; - if ( m_phase == PHASE_DEFI ) res = RT_PLAY_CHAPd; - if ( m_phase == PHASE_MISSION ) res = RT_PLAY_CHAPm; - if ( m_phase == PHASE_FREE ) res = RT_PLAY_CHAPf; - if ( m_phase == PHASE_TEEN ) res = RT_PLAY_CHAPte; - if ( m_phase == PHASE_USER ) res = RT_PLAY_CHAPu; - if ( m_phase == PHASE_PROTO ) res = RT_PLAY_CHAPp; - GetResource(RES_TEXT, res, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL11, name); - pl->SetJustif(1); - - pos.y = oy+sy*6.7f; - ddim.y = dim.y*4.5f; - ddim.x = dim.x*6.5f; - pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_CHAP); - pli->SetState(STATE_SHADOW); - UpdateSceneChap(m_chap[m_index]); - if ( m_phase != PHASE_USER ) pli->SetState(STATE_EXTEND); - - // Displays a list of missions: - pos.x = ox+sx*9.5f; - pos.y = oy+sy*10.5f; - ddim.x = dim.x*7.5f; - ddim.y = dim.y*0.6f; - if ( m_phase == PHASE_TRAINER ) res = RT_PLAY_LISTt; - if ( m_phase == PHASE_DEFI ) res = RT_PLAY_LISTd; - if ( m_phase == PHASE_MISSION ) res = RT_PLAY_LISTm; - if ( m_phase == PHASE_FREE ) res = RT_PLAY_LISTf; - if ( m_phase == PHASE_TEEN ) res = RT_PLAY_LISTk; - if ( m_phase == PHASE_USER ) res = RT_PLAY_LISTu; - if ( m_phase == PHASE_PROTO ) res = RT_PLAY_LISTp; - GetResource(RES_TEXT, res, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL12, name); - pl->SetJustif(1); - - pos.y = oy+sy*6.7f; - ddim.y = dim.y*4.5f; - ddim.x = dim.x*6.5f; - pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_LIST); - pli->SetState(STATE_SHADOW); - UpdateSceneList(m_chap[m_index], m_sel[m_index]); - if ( m_phase != PHASE_USER ) pli->SetState(STATE_EXTEND); - pos = pli->RetPos(); - ddim = pli->RetDim(); - - // Displays the summary: - pos.x = ox+sx*3; - pos.y = oy+sy*5.4f; - ddim.x = dim.x*6.5f; - ddim.y = dim.y*0.6f; - GetResource(RES_TEXT, RT_PLAY_RESUME, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL13, name); - pl->SetJustif(1); - - pos.x = ox+sx*3; - pos.y = oy+sy*3.6f; - ddim.x = dim.x*13.4f; - ddim.y = dim.y*1.9f; - pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_RESUME); - pe->SetState(STATE_SHADOW); - pe->SetMaxChar(500); - pe->SetEditCap(FALSE); // just to see - pe->SetHiliteCap(FALSE); - - // Button displays the "soluce": - if ( m_phase != PHASE_TRAINER && - m_phase != PHASE_FREE && - m_phase != PHASE_TEEN ) - { - pos.x = ox+sx*9.5f; - pos.y = oy+sy*5.8f; - ddim.x = dim.x*6.5f; - ddim.y = dim.y*0.5f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SOLUCE); - pc->SetState(STATE_SHADOW); - pc->ClearState(STATE_CHECK); - } - m_bSceneSoluce = FALSE; - - UpdateSceneResume((m_chap[m_index]+1)*100+(m_sel[m_index]+1)); - - if ( m_phase == PHASE_MISSION || - m_phase == PHASE_FREE || - m_phase == PHASE_USER ) - { - pos.x = ox+sx*9.5f; - pos.y = oy+sy*2; - ddim.x = dim.x*3.7f; - ddim.y = dim.y*1; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PLAY); - pb->SetState(STATE_SHADOW); - if ( m_maxList == 0 ) - { - pb->ClearState(STATE_ENABLE); - } - - pos.x += dim.x*4.0f; - ddim.x = dim.x*2.5f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_READ); - pb->SetState(STATE_SHADOW); - if ( !IsIOReadScene() ) // no file to read? - { - pb->ClearState(STATE_ENABLE); - } - } - else - { - pos.x = ox+sx*9.5f; - pos.y = oy+sy*2; - ddim.x = dim.x*6.5f; - ddim.y = dim.y*1; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PLAY); - pb->SetState(STATE_SHADOW); - if ( m_maxList == 0 ) - { - pb->ClearState(STATE_ENABLE); - } - } - - pos.x = ox+sx*3; - ddim.x = dim.x*4; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_BACK); - pb->SetState(STATE_SHADOW); - - m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE); - m_engine->SetBackForce(TRUE); - } - - if ( m_phase == PHASE_SETUPd || - m_phase == PHASE_SETUPg || - m_phase == PHASE_SETUPp || - m_phase == PHASE_SETUPc || - m_phase == PHASE_SETUPs || - m_phase == PHASE_SETUPds || - m_phase == PHASE_SETUPgs || - m_phase == PHASE_SETUPps || - m_phase == PHASE_SETUPcs || - m_phase == PHASE_SETUPss ) - { - if ( m_phase == PHASE_SETUPds ) - { - m_phaseSetup = PHASE_SETUPd; - m_bSimulSetup = TRUE; - } - else if ( m_phase == PHASE_SETUPgs ) - { - m_phaseSetup = PHASE_SETUPg; - m_bSimulSetup = TRUE; - } - else if ( m_phase == PHASE_SETUPps ) - { - m_phaseSetup = PHASE_SETUPp; - m_bSimulSetup = TRUE; - } - else if ( m_phase == PHASE_SETUPcs ) - { - m_phaseSetup = PHASE_SETUPc; - m_bSimulSetup = TRUE; - } - else if ( m_phase == PHASE_SETUPss ) - { - m_phaseSetup = PHASE_SETUPs; - m_bSimulSetup = TRUE; - } - else - { - m_phaseSetup = m_phase; - m_bSimulSetup = FALSE; - } - - pos.x = 0.10f; - pos.y = 0.10f; - ddim.x = 0.80f; - ddim.y = 0.80f; - pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5); - pw->SetClosable(TRUE); - GetResource(RES_TEXT, RT_TITLE_SETUP, name); - pw->SetName(name); - - pos.x = 0.70f; - pos.y = 0.10f; - ddim.x = 0.20f; - ddim.y = 0.20f; - pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner - - pos.x = 0.10f; - ddim.x = 0.80f; - pos.y = 0.76f; - ddim.y = 0.05f; - pw->CreateGroup(pos, ddim, 3, EVENT_NULL); // transparent -> gray - -#if _NEWLOOK - if ( m_phase == PHASE_SETUPd || // setup/display ? - m_phase == PHASE_SETUPds ) - { - pos.x = 100.0f/640.0f; - pos.y = 130.0f/480.0f; - ddim.x = 216.0f/640.0f; - ddim.y = 212.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue - pg->SetState(STATE_SHADOW); - pos.x = 324.0f/640.0f; - pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // cyan - pg->SetState(STATE_SHADOW); - } - if ( m_phase == PHASE_SETUPg || // setup/graphic ? - m_phase == PHASE_SETUPgs ) - { - pos.x = 100.0f/640.0f; - pos.y = 130.0f/480.0f; - ddim.x = 174.0f/640.0f; - ddim.y = 212.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue - pg->SetState(STATE_SHADOW); - pos.x = 282.0f/640.0f; - ddim.x = 258.0f/640.0f; - pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // cyan - pg->SetState(STATE_SHADOW); - } - if ( m_phase == PHASE_SETUPp || // setup/game ? - m_phase == PHASE_SETUPps ) - { - pos.x = 100.0f/640.0f; - pos.y = 130.0f/480.0f; - ddim.x = 226.0f/640.0f; - ddim.y = 212.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue - pg->SetState(STATE_SHADOW); - pos.x = 334.0f/640.0f; - ddim.x = 206.0f/640.0f; - pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // cyan - pg->SetState(STATE_SHADOW); - } - if ( m_phase == PHASE_SETUPc || // setup/command ? - m_phase == PHASE_SETUPcs ) - { - pos.x = 100.0f/640.0f; - pos.y = 125.0f/480.0f; - ddim.x = 440.0f/640.0f; - ddim.y = 222.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue - pg->SetState(STATE_SHADOW); - } - if ( m_phase == PHASE_SETUPs || // setup/sound ? - m_phase == PHASE_SETUPss ) - { - pos.x = 100.0f/640.0f; - pos.y = 130.0f/480.0f; - ddim.x = 216.0f/640.0f; - ddim.y = 212.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue - pg->SetState(STATE_SHADOW); - pos.x = 324.0f/640.0f; - pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // cyan - pg->SetState(STATE_SHADOW); - } - - pos.x = 100.0f/640.0f; - pos.y = 66.0f/480.0f; - ddim.x = 440.0f/640.0f; - ddim.y = 42.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet - pg->SetState(STATE_SHADOW); -#endif - - ddim.x = 0.78f/5-0.01f; - ddim.y = 0.06f; - pos.x = 0.115f; - pos.y = 0.76f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPd); - pb->SetState(STATE_SHADOW); - pb->SetState(STATE_CARD); - pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPd || m_phase == PHASE_SETUPds)); - - pos.x += ddim.x+0.01f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPg); - pb->SetState(STATE_SHADOW); - pb->SetState(STATE_CARD); - pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPg || m_phase == PHASE_SETUPgs)); - - pos.x += ddim.x+0.01f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPp); - pb->SetState(STATE_SHADOW); - pb->SetState(STATE_CARD); - pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPp || m_phase == PHASE_SETUPps)); - - pos.x += ddim.x+0.01f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPc); - pb->SetState(STATE_SHADOW); - pb->SetState(STATE_CARD); - pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPc || m_phase == PHASE_SETUPcs)); - - pos.x += ddim.x+0.01f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPs); - pb->SetState(STATE_SHADOW); - pb->SetState(STATE_CARD); - pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPs || m_phase == PHASE_SETUPss)); - - pos.x = 0.10f; - ddim.x = 0.80f; - pos.y = 0.34f; - ddim.y = 0.42f; - pw->CreateGroup(pos, ddim, 2, EVENT_INTERFACE_GLINTu); // orange -> transparent - pos.x = 0.10f+(6.0f/640.0f); - ddim.x = 0.80f-(11.0f/640.0f); - pos.y = 0.74f; - ddim.y = 0.02f; - pw->CreateGroup(pos, ddim, 1, EVENT_INTERFACE_GLINTb); // orange bar - - ddim.x = dim.x*4; - ddim.y = dim.y*1; - pos.x = ox+sx*3; - pos.y = oy+sy*2; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_BACK); - pb->SetState(STATE_SHADOW); - - if ( !m_bSimulSetup ) - { - m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE); - m_engine->SetBackForce(TRUE); - } - } - - if ( m_phase == PHASE_SETUPd || // setup/display ? - m_phase == PHASE_SETUPds ) - { - pos.x = ox+sx*3; - pos.y = oy+sy*9; - ddim.x = dim.x*6; - ddim.y = dim.y*1; - GetResource(RES_TEXT, RT_SETUP_DEVICE, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name); - pl->SetJustif(1); - - pos.x = ox+sx*3; - pos.y = oy+sy*5.2f; - ddim.x = dim.x*6; - ddim.y = dim.y*4.5f; - pli = pw->CreateList(pos, ddim, 0, EVENT_LIST1); - pli->SetState(STATE_SHADOW); - UpdateDisplayDevice(); - - pos.x = ox+sx*10; - pos.y = oy+sy*9; - ddim.x = dim.x*6; - ddim.y = dim.y*1; - GetResource(RES_TEXT, RT_SETUP_MODE, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL2, name); - pl->SetJustif(1); - - m_setupFull = m_engine->RetFullScreen(); - pos.x = ox+sx*10; - pos.y = oy+sy*5.2f; - ddim.x = dim.x*6; - ddim.y = dim.y*4.5f; - pli = pw->CreateList(pos, ddim, 0, EVENT_LIST2); - pli->SetState(STATE_SHADOW); - UpdateDisplayMode(); - pli->SetState(STATE_ENABLE, m_setupFull); - - ddim.x = dim.x*4; - ddim.y = dim.y*0.5f; - pos.x = ox+sx*3; - pos.y = oy+sy*4.1f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_FULL); - pc->SetState(STATE_SHADOW); - pc->SetState(STATE_CHECK, m_setupFull); - - ddim.x = dim.x*6; - ddim.y = dim.y*1; - pos.x = ox+sx*10; - pos.y = oy+sy*2; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_APPLY); - pb->SetState(STATE_SHADOW); - UpdateApply(); - } - - if ( m_phase == PHASE_SETUPg || // setup/graphic ? - m_phase == PHASE_SETUPgs ) - { - ddim.x = dim.x*6; - ddim.y = dim.y*0.5f; - pos.x = ox+sx*3; - pos.y = 0.65f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SHADOW); - pc->SetState(STATE_SHADOW); - pos.y -= 0.048f; - if ( !m_bSimulSetup ) - { - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_GROUND); - pc->SetState(STATE_SHADOW); - if ( m_engine->IsVideo8MB() ) pc->ClearState(STATE_ENABLE); - } - pos.y -= 0.048f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_DIRTY); - pc->SetState(STATE_SHADOW); - pos.y -= 0.048f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SKY); - pc->SetState(STATE_SHADOW); - if ( m_engine->IsVideo8MB() ) pc->ClearState(STATE_ENABLE); - pos.y -= 0.048f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_LENS); - pc->SetState(STATE_SHADOW); - pos.y -= 0.048f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_PLANET); - pc->SetState(STATE_SHADOW); - pos.y -= 0.048f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_FOG); - pc->SetState(STATE_SHADOW); - pos.y -= 0.048f; - if ( !m_bSimulSetup ) - { - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_LIGHT); - pc->SetState(STATE_SHADOW); - } - - pos.x = ox+sx*8.5f; - pos.y = 0.65f; - ddim.x = dim.x*2.2f; - ddim.y = 18.0f/480.0f; - pv = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_PARTI); - pv->SetState(STATE_SHADOW); - pv->SetMinValue(0.0f); - pv->SetMaxValue(2.0f); - pos.x += 0.13f; - pos.y -= 0.015f; - ddim.x = 0.40f; - GetResource(RES_EVENT, EVENT_INTERFACE_PARTI, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL10, name); - pl->SetJustif(1); - - pos.x = ox+sx*8.5f; - pos.y = 0.59f; - ddim.x = dim.x*2.2f; - ddim.y = 18.0f/480.0f; - pv = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_CLIP); - pv->SetState(STATE_SHADOW); - pv->SetMinValue(0.5f); - pv->SetMaxValue(2.0f); - pos.x += 0.13f; - pos.y -= 0.015f; - ddim.x = 0.40f; - GetResource(RES_EVENT, EVENT_INTERFACE_CLIP, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL11, name); - pl->SetJustif(1); - - pos.x = ox+sx*8.5f; - pos.y = 0.53f; - ddim.x = dim.x*2.2f; - ddim.y = 18.0f/480.0f; - pv = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_DETAIL); - pv->SetState(STATE_SHADOW); - pv->SetMinValue(0.0f); - pv->SetMaxValue(2.0f); - pos.x += 0.13f; - pos.y -= 0.015f; - ddim.x = 0.40f; - GetResource(RES_EVENT, EVENT_INTERFACE_DETAIL, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL12, name); - pl->SetJustif(1); - - if ( !m_bSimulSetup ) - { - pos.x = ox+sx*8.5f; - pos.y = 0.47f; - ddim.x = dim.x*2.2f; - ddim.y = 18.0f/480.0f; - pv = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_GADGET); - pv->SetState(STATE_SHADOW); - pv->SetMinValue(0.0f); - pv->SetMaxValue(1.0f); - pos.x += 0.13f; - pos.y -= 0.015f; - ddim.x = 0.40f; - GetResource(RES_EVENT, EVENT_INTERFACE_GADGET, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL13, name); - pl->SetJustif(1); - } - -#if 0 - if ( !m_bSimulSetup ) - { - pos.x = ox+sx*8.5f; - pos.y = 0.41f; - ddim.x = dim.x*2.2f; - ddim.y = 18.0f/480.0f; - pv = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_TEXTURE); - pv->SetState(STATE_SHADOW); - pv->SetType(EVT_INT); - pv->SetMinValue(0.0f); - pv->SetMaxValue(2.0f); - pv->SetStepValue(1.0f); - pos.x += 0.13f; - pos.y -= 0.015f; - ddim.x = 0.40f; - GetResource(RES_EVENT, EVENT_INTERFACE_TEXTURE, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL14, name); - pl->SetJustif(1); - } -#endif - - ddim.x = dim.x*2; - ddim.y = dim.y*1; - pos.x = ox+sx*10; - pos.y = oy+sy*2; -#if _POLISH - ddim.x += 20.0f/640.0f; - pos.x -= 20.0f/640.0f*3.0f; -#endif - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_MIN); - pb->SetState(STATE_SHADOW); - pos.x += ddim.x; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NORM); - pb->SetState(STATE_SHADOW); - pos.x += ddim.x; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_MAX); - pb->SetState(STATE_SHADOW); - - UpdateSetupButtons(); - } - - if ( m_phase == PHASE_SETUPp || // setup/game ? - m_phase == PHASE_SETUPps ) - { - ddim.x = dim.x*6; - ddim.y = dim.y*0.5f; - pos.x = ox+sx*3; - pos.y = 0.65f; -//? pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_TOTO); -//? pc->SetState(STATE_SHADOW); -//? pos.y -= 0.048f; -#if _SCHOOL - #if _EDU - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SOLUCE4); - pc->SetState(STATE_SHADOW); - pos.y -= 0.048f; - #endif -#else - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_MOVIES); - pc->SetState(STATE_SHADOW); - pos.y -= 0.048f; -#endif - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SCROLL); - pc->SetState(STATE_SHADOW); - pos.y -= 0.048f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_INVERTX); - pc->SetState(STATE_SHADOW); - pos.y -= 0.048f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_INVERTY); - pc->SetState(STATE_SHADOW); - pos.y -= 0.048f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_EFFECT); - pc->SetState(STATE_SHADOW); -//? pos.y -= 0.048f; -//? pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_NICERST); -//? pc->SetState(STATE_SHADOW); -//? pos.y -= 0.048f; -//? pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_HIMSELF); -//? pc->SetState(STATE_SHADOW); - - ddim.x = dim.x*6; - ddim.y = dim.y*0.5f; - pos.x = ox+sx*10; - pos.y = 0.65f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_TOOLTIP); - pc->SetState(STATE_SHADOW); - pos.y -= 0.048f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_GLINT); - pc->SetState(STATE_SHADOW); - pos.y -= 0.048f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_RAIN); - pc->SetState(STATE_SHADOW); - pos.y -= 0.048f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_MOUSE); - pc->SetState(STATE_SHADOW); - pos.y -= 0.048f; - pos.y -= 0.048f; - if ( !m_bSimulSetup ) - { - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_EDITMODE); - pc->SetState(STATE_SHADOW); - } - pos.y -= 0.048f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_EDITVALUE); - pc->SetState(STATE_SHADOW); - - UpdateSetupButtons(); - } - - if ( m_phase == PHASE_SETUPc || // setup/commands ? - m_phase == PHASE_SETUPcs ) - { - pos.x = ox+sx*3; - pos.y = 320.0f/480.0f; - ddim.x = dim.x*15.0f; - ddim.y = 18.0f/480.0f; - GetResource(RES_TEXT, RT_SETUP_KEY1, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_INTERFACE_KINFO1, name); - pl->SetJustif(1); - - pos.x = ox+sx*3; - pos.y = 302.0f/480.0f; - ddim.x = dim.x*15.0f; - ddim.y = 18.0f/480.0f; - GetResource(RES_TEXT, RT_SETUP_KEY2, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_INTERFACE_KINFO2, name); - pl->SetJustif(1); - - ddim.x = 428.0f/640.0f; - ddim.y = 128.0f/480.0f; - pos.x = 105.0f/640.0f; - pos.y = 164.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 0, EVENT_INTERFACE_KGROUP); - pg->ClearState(STATE_ENABLE); - pg->SetState(STATE_DEAD); - pg->SetState(STATE_SHADOW); - - ddim.x = 18.0f/640.0f; - ddim.y = (20.0f/480.0f)*KEY_VISIBLE; - pos.x = 510.0f/640.0f; - pos.y = 168.0f/480.0f; - ps = pw->CreateScroll(pos, ddim, -1, EVENT_INTERFACE_KSCROLL); - ps->SetVisibleRatio((float)KEY_VISIBLE/KEY_TOTAL); - ps->SetArrowStep(1.0f/((float)KEY_TOTAL-KEY_VISIBLE)); - UpdateKey(); - - ddim.x = dim.x*6; - ddim.y = dim.y*0.5f; - pos.x = ox+sx*3; - pos.y = 130.0f/480.0f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_JOYSTICK); - pc->SetState(STATE_SHADOW); - - ddim.x = dim.x*6; - ddim.y = dim.y*1; - pos.x = ox+sx*10; - pos.y = oy+sy*2; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_KDEF); - pb->SetState(STATE_SHADOW); - - UpdateSetupButtons(); - } - - if ( m_phase == PHASE_SETUPs || // setup/sound ? - m_phase == PHASE_SETUPss ) - { - pos.x = ox+sx*3; - pos.y = 0.55f; - ddim.x = dim.x*4.0f; - ddim.y = 18.0f/480.0f; - psl = pw->CreateSlider(pos, ddim, 0, EVENT_INTERFACE_VOLSOUND); - psl->SetState(STATE_SHADOW); - psl->SetLimit(0.0f, MAXVOLUME); - psl->SetArrowStep(1.0f); - pos.y += ddim.y; - GetResource(RES_EVENT, EVENT_INTERFACE_VOLSOUND, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name); - pl->SetJustif(1); - -#if (_FULL | _NET) & _SOUNDTRACKS - pos.x = ox+sx*3; - pos.y = 0.40f; - ddim.x = dim.x*4.0f; - ddim.y = 18.0f/480.0f; - psl = pw->CreateSlider(pos, ddim, 0, EVENT_INTERFACE_VOLMUSIC); - psl->SetState(STATE_SHADOW); - psl->SetLimit(0.0f, MAXVOLUME); - psl->SetArrowStep(1.0f); - pos.y += ddim.y; - GetResource(RES_EVENT, EVENT_INTERFACE_VOLMUSIC, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL2, name); - pl->SetJustif(1); -#endif - - ddim.x = dim.x*6; - ddim.y = dim.y*0.5f; - pos.x = ox+sx*10; - pos.y = 0.55f; - pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SOUND3D); - pc->SetState(STATE_SHADOW); - - ddim.x = dim.x*3; - ddim.y = dim.y*1; - pos.x = ox+sx*10; - pos.y = oy+sy*2; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SILENT); - pb->SetState(STATE_SHADOW); - pos.x += ddim.x; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NOISY); - pb->SetState(STATE_SHADOW); - - UpdateSetupButtons(); - } - - if ( m_phase == PHASE_WRITE || - m_phase == PHASE_WRITEs ) - { - pos.x = 0.10f; - pos.y = 0.10f; - ddim.x = 0.80f; - ddim.y = 0.80f; - pw = m_interface->CreateWindows(pos, ddim, 13, EVENT_WINDOW5); - pw->SetClosable(TRUE); - GetResource(RES_TEXT, RT_TITLE_WRITE, name); - pw->SetName(name); - - pos.x = 0.10f; - pos.y = 0.40f; - ddim.x = 0.50f; - ddim.y = 0.50f; - pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner - pos.x = 0.40f; - pos.y = 0.10f; - ddim.x = 0.50f; - ddim.y = 0.50f; - pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner - -#if _NEWLOOK - pos.x = 100.0f/640.0f; - pos.y = 66.0f/480.0f; - ddim.x = 438.0f/640.0f; - ddim.y = 42.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet - pg->SetState(STATE_SHADOW); -#endif - - pos.x = 290.0f/640.0f; - ddim.x = 245.0f/640.0f; - - pos.y = 146.0f/480.0f; - ddim.y = 18.0f/480.0f; - GetResource(RES_EVENT, EVENT_INTERFACE_IOLABEL, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_INTERFACE_IOLABEL, name); - pl->SetJustif(1); - - pos.y = 130.0f/480.0f; - ddim.y = 18.0f/480.0f; - pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_IONAME); - pe->SetState(STATE_SHADOW); - pe->SetFontType(FONT_COLOBOT); - pe->SetMaxChar(35); - IOReadName(); - - pos.y = 190.0f/480.0f; - ddim.y = 190.0f/480.0f; - pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_IOLIST); - pli->SetState(STATE_SHADOW); - - pos.y = oy+sy*2; - ddim.y = dim.y*1; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_IOWRITE); - pb->SetState(STATE_SHADOW); - - pos.x = 105.0f/640.0f; - pos.y = 190.0f/480.0f; - ddim.x = 170.0f/640.0f; - ddim.y = dim.y*1; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_IODELETE); - pb->SetState(STATE_SHADOW); - - pos.x = 105.0f/640.0f; - pos.y = 250.0f/480.0f; - ddim.x = 170.0f/640.0f; - ddim.y = 128.0f/480.0f; - pi = pw->CreateImage(pos, ddim, 0, EVENT_INTERFACE_IOIMAGE); - pi->SetState(STATE_SHADOW); - - ddim.x = dim.x*4; - ddim.y = dim.y*1; - pos.x = ox+sx*3; - pos.y = oy+sy*2; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_BACK); - pb->SetState(STATE_SHADOW); - - IOReadList(); - IOUpdateList(); - } - - if ( m_phase == PHASE_READ || - m_phase == PHASE_READs ) - { - pos.x = 0.10f; - pos.y = 0.10f; - ddim.x = 0.80f; - ddim.y = 0.80f; - pw = m_interface->CreateWindows(pos, ddim, 14, EVENT_WINDOW5); - pw->SetClosable(TRUE); - GetResource(RES_TEXT, RT_TITLE_READ, name); - pw->SetName(name); - - pos.x = 0.10f; - pos.y = 0.40f; - ddim.x = 0.50f; - ddim.y = 0.50f; - pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner - pos.x = 0.40f; - pos.y = 0.10f; - ddim.x = 0.50f; - ddim.y = 0.50f; - pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner - -#if _NEWLOOK - pos.x = 100.0f/640.0f; - pos.y = 66.0f/480.0f; - ddim.x = 438.0f/640.0f; - ddim.y = 42.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet - pg->SetState(STATE_SHADOW); -#endif - - pos.x = 290.0f/640.0f; - ddim.x = 245.0f/640.0f; - - pos.y = 160.0f/480.0f; - ddim.y = 190.0f/480.0f; - pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_IOLIST); - pli->SetState(STATE_SHADOW); - - pos.y = oy+sy*2; - ddim.y = dim.y*1; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_IOREAD); - pb->SetState(STATE_SHADOW); - if ( m_phase == PHASE_READs ) - { - pb->SetState(STATE_WARNING); - } - - pos.x = 105.0f/640.0f; - pos.y = 160.0f/480.0f; - ddim.x = 170.0f/640.0f; - ddim.y = dim.y*1; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_IODELETE); - pb->SetState(STATE_SHADOW); - - pos.x = 105.0f/640.0f; - pos.y = 220.0f/480.0f; - ddim.x = 170.0f/640.0f; - ddim.y = 128.0f/480.0f; - pi = pw->CreateImage(pos, ddim, 0, EVENT_INTERFACE_IOIMAGE); - pi->SetState(STATE_SHADOW); - - ddim.x = dim.x*4; - ddim.y = dim.y*1; - pos.x = ox+sx*3; - pos.y = oy+sy*2; - pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_BACK); - pb->SetState(STATE_SHADOW); - - IOReadList(); - IOUpdateList(); - - if ( m_phase == PHASE_READ ) - { - m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE); - m_engine->SetBackForce(TRUE); - } - } - - if ( m_phase == PHASE_LOADING ) - { - pos.x = 0.35f; - pos.y = 0.10f; - ddim.x = 0.30f; - ddim.y = 0.80f; -#if _TEEN - pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5); -#else - pw = m_interface->CreateWindows(pos, ddim, 10, EVENT_WINDOW5); -#endif - pw->SetName(" "); - - pos.x = 0.35f; - pos.y = 0.60f; - ddim.x = 0.30f; - ddim.y = 0.30f; - pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner - pos.x = 0.35f; - pos.y = 0.10f; - ddim.x = 0.30f; - ddim.y = 0.30f; - pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner - - pos.x = 254.0f/640.0f; - pos.y = 208.0f/480.0f; - ddim.x = 132.0f/640.0f; - ddim.y = 42.0f/480.0f; - pg = pw->CreateGroup(pos, ddim, 22, EVENT_NULL); - pg->SetState(STATE_SHADOW); - - pos.x = 220.0f/640.0f; - pos.y = 210.0f/480.0f; - ddim.x = 200.0f/640.0f; - ddim.y = 20.0f/480.0f; - GetResource(RES_TEXT, RT_DIALOG_LOADING, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name); - pl->SetFontSize(12.0f); - pl->SetJustif(0); - - m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE); - m_engine->SetBackForce(TRUE); - - m_loadingCounter = 1; // enough time to display! - } - - if ( m_phase == PHASE_WELCOME1 ) - { - m_sound->StopMusic(); - m_sound->PlayMusic(11, FALSE); - - pos.x = 0.0f; - pos.y = 0.0f; - ddim.x = 0.0f; - ddim.y = 0.0f; - pw = m_interface->CreateWindows(pos, ddim, -1, EVENT_WINDOW5); - - m_engine->SetOverColor(RetColor(1.0f), D3DSTATETCb); - m_engine->SetOverFront(TRUE); - -#if _FRENCH - m_engine->SetBackground("alsyd.tga", 0,0, 0,0, TRUE, FALSE); -#endif -#if _POLISH - m_engine->SetBackground("manta.tga", 0,0, 0,0, TRUE, FALSE); -#endif -#if _WG - m_engine->SetBackground("wg.tga", 0,0, 0,0, TRUE, FALSE); -#endif - m_engine->SetBackForce(TRUE); - } - if ( m_phase == PHASE_WELCOME2 ) - { -#if _ENGLISH - m_sound->StopMusic(); - m_sound->PlayMusic(11, FALSE); -#endif -#if _POLISH - m_sound->StopMusic(); - m_sound->PlayMusic(11, FALSE); -#endif - - pos.x = 0.0f; - pos.y = 0.0f; - ddim.x = 0.0f; - ddim.y = 0.0f; - pw = m_interface->CreateWindows(pos, ddim, -1, EVENT_WINDOW5); - - m_engine->SetOverColor(RetColor(1.0f), D3DSTATETCb); - m_engine->SetOverFront(TRUE); - - m_engine->SetBackground("colobot.tga", 0,0, 0,0, TRUE, FALSE); - m_engine->SetBackForce(TRUE); - } - if ( m_phase == PHASE_WELCOME3 ) - { - pos.x = 0.0f; - pos.y = 0.0f; - ddim.x = 0.0f; - ddim.y = 0.0f; - pw = m_interface->CreateWindows(pos, ddim, -1, EVENT_WINDOW5); - - m_engine->SetOverColor(RetColor(0.0f), D3DSTATETCw); - m_engine->SetOverFront(TRUE); - -#if _FRENCH - m_engine->SetBackground("epsitecf.tga", 0,0, 0,0, TRUE, FALSE); -#endif -#if _ENGLISH - m_engine->SetBackground("epsitece.tga", 0,0, 0,0, TRUE, FALSE); -#endif -#if _GERMAN | _WG - m_engine->SetBackground("epsitecd.tga", 0,0, 0,0, TRUE, FALSE); -#endif -#if _POLISH - m_engine->SetBackground("epsitecp.tga", 0,0, 0,0, TRUE, FALSE); -#endif - m_engine->SetBackForce(TRUE); - } - - if ( m_phase == PHASE_GENERIC ) - { - pos.x = 0.0f; - pos.y = 0.0f; - ddim.x = 0.0f; - ddim.y = 0.0f; - pw = m_interface->CreateWindows(pos, ddim, -1, EVENT_WINDOW5); - -#if _FULL | _NET - pos.x = 80.0f/640.0f; - pos.y = 240.0f/480.0f; - ddim.x = 490.0f/640.0f; - ddim.y = 110.0f/480.0f; - pe = pw->CreateEdit(pos, ddim, 0, EVENT_EDIT1); - pe->SetGenericMode(TRUE); - pe->SetEditCap(FALSE); - pe->SetHiliteCap(FALSE); - pe->SetFontType(FONT_COURIER); - pe->SetFontSize(8.0f); - pe->ReadText("help\\authors.txt"); - - pos.x = 80.0f/640.0f; - pos.y = 140.0f/480.0f; - ddim.x = 490.0f/640.0f; - ddim.y = 100.0f/480.0f; - pe = pw->CreateEdit(pos, ddim, 0, EVENT_EDIT2); - pe->SetGenericMode(TRUE); - pe->SetEditCap(FALSE); - pe->SetHiliteCap(FALSE); - pe->SetFontType(FONT_COURIER); - pe->SetFontSize(6.5f); - pe->ReadText("help\\licences.txt"); -#endif -#if _SCHOOL -#if _CEEBOTDEMO - pos.x = 80.0f/640.0f; - pos.y = 210.0f/480.0f; - ddim.x = 490.0f/640.0f; - ddim.y = 150.0f/480.0f; -#else - pos.x = 80.0f/640.0f; - pos.y = 200.0f/480.0f; - ddim.x = 490.0f/640.0f; - ddim.y = 150.0f/480.0f; -#endif - pe = pw->CreateEdit(pos, ddim, 0, EVENT_EDIT1); - pe->SetGenericMode(TRUE); - pe->SetEditCap(FALSE); - pe->SetHiliteCap(FALSE); - pe->SetFontType(FONT_COURIER); - pe->SetFontSize(8.0f); - pe->ReadText("help\\authors.txt"); -#endif -#if _DEMO -//? pos.x = 80.0f/640.0f; -//? pos.y = 240.0f/480.0f; -//? ddim.x = 490.0f/640.0f; -//? ddim.y = 110.0f/480.0f; -//? pe = pw->CreateEdit(pos, ddim, 0, EVENT_EDIT1); -//? pe->SetGenericMode(TRUE); -//? pe->SetEditCap(FALSE); -//? pe->SetHiliteCap(FALSE); -//? pe->SetFontType(FONT_COURIER); -//? pe->SetFontSize(8.0f); -//? pe->ReadText("help\\demo.txt"); - -//? pos.x = 80.0f/640.0f; -//? pos.y = 140.0f/480.0f; -//? ddim.x = 490.0f/640.0f; -//? ddim.y = 100.0f/480.0f; -//? pe = pw->CreateEdit(pos, ddim, 0, EVENT_EDIT2); -//? pe->SetGenericMode(TRUE); -//? pe->SetEditCap(FALSE); -//? pe->SetHiliteCap(FALSE); -//? pe->SetFontType(FONT_COURIER); -//? pe->SetFontSize(8.0f); -//? pe->ReadText("help\\authors.txt"); -#endif - -#if !_DEMO - pos.x = 40.0f/640.0f; - pos.y = 83.0f/480.0f; - ddim.x = 246.0f/640.0f; - ddim.y = 16.0f/480.0f; - GetResource(RES_TEXT, RT_GENERIC_DEV1, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name); - pl->SetFontType(FONT_COURIER); - pl->SetFontSize(8.0f); - - pos.y = 13.0f/480.0f; - GetResource(RES_TEXT, RT_GENERIC_DEV2, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL2, name); - pl->SetFontType(FONT_COURIER); - pl->SetFontSize(8.0f); - - pos.x = 355.0f/640.0f; - pos.y = 83.0f/480.0f; - ddim.x = 246.0f/640.0f; - ddim.y = 16.0f/480.0f; - GetResource(RES_TEXT, RT_GENERIC_EDIT1, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL3, name); - pl->SetFontType(FONT_COURIER); - pl->SetFontSize(8.0f); - - pos.y = 13.0f/480.0f; - GetResource(RES_TEXT, RT_GENERIC_EDIT2, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL4, name); - pl->SetFontType(FONT_COURIER); - pl->SetFontSize(8.0f); -#endif - -#if _DEMO - pos.x = 481.0f/640.0f; - pos.y = 51.0f/480.0f; - ddim.x = 30.0f/640.0f; - ddim.y = 30.0f/480.0f; - pb = pw->CreateButton(pos, ddim, 49, EVENT_INTERFACE_ABORT); - pb->SetState(STATE_SHADOW); -#else - pos.x = 306.0f/640.0f; - pos.y = 17.0f/480.0f; - ddim.x = 30.0f/640.0f; - ddim.y = 30.0f/480.0f; - pb = pw->CreateButton(pos, ddim, 49, EVENT_INTERFACE_ABORT); - pb->SetState(STATE_SHADOW); -#endif - -#if _NEWLOOK -#if _CEEBOTDEMO -#if _TEEN - m_engine->SetBackground("genedt.tga", 0,0, 0,0, TRUE, TRUE); -#else - m_engine->SetBackground("geneda.tga", 0,0, 0,0, TRUE, TRUE); -#endif -#else - m_engine->SetBackground("genern.tga", 0,0, 0,0, TRUE, TRUE); -#endif -#else -#if _FRENCH -#if _DEMO - m_engine->SetBackground("genedf.tga", 0,0, 0,0, TRUE, TRUE); -#else - m_engine->SetBackground("generf.tga", 0,0, 0,0, TRUE, TRUE); -#endif -#endif -#if _ENGLISH -#if _DEMO - m_engine->SetBackground("genede.tga", 0,0, 0,0, TRUE, TRUE); -#else - m_engine->SetBackground("genere.tga", 0,0, 0,0, TRUE, TRUE); -#endif -#endif -#if _GERMAN -#if _DEMO - m_engine->SetBackground("genedd.tga", 0,0, 0,0, TRUE, TRUE); -#else - m_engine->SetBackground("genere.tga", 0,0, 0,0, TRUE, TRUE); -#endif -#endif -#if _WG -#if _DEMO - m_engine->SetBackground("genedd.tga", 0,0, 0,0, TRUE, TRUE); -#else - m_engine->SetBackground("generd.tga", 0,0, 0,0, TRUE, TRUE); -#endif -#endif -#if _POLISH -#if _DEMO - m_engine->SetBackground("genedp.tga", 0,0, 0,0, TRUE, TRUE); -#else - m_engine->SetBackground("generp.tga", 0,0, 0,0, TRUE, TRUE); -#endif -#endif -#endif - m_engine->SetBackForce(TRUE); - } - - if ( m_phase == PHASE_INIT || - m_phase == PHASE_NAME || - m_phase == PHASE_TRAINER || - m_phase == PHASE_DEFI || - m_phase == PHASE_MISSION || - m_phase == PHASE_FREE || - m_phase == PHASE_TEEN || - m_phase == PHASE_USER || - m_phase == PHASE_PROTO || - m_phase == PHASE_SETUPd || - m_phase == PHASE_SETUPg || - m_phase == PHASE_SETUPp || - m_phase == PHASE_SETUPc || - m_phase == PHASE_SETUPs || - m_phase == PHASE_READ || - m_phase == PHASE_LOADING ) - { -#if _SCHOOL -#if _TEEN - pos.x = 50.0f/640.0f; - pos.y = 430.0f/480.0f; - ddim.x = 200.0f/640.0f; - ddim.y = 10.0f/480.0f; -#else - pos.x = 450.0f/640.0f; - pos.y = 0.0f/480.0f; - ddim.x = 170.0f/640.0f; - ddim.y = 9.0f/480.0f; -#endif -#else - pos.x = 540.0f/640.0f; - pos.y = 9.0f/480.0f; - ddim.x = 90.0f/640.0f; - ddim.y = 10.0f/480.0f; -#endif - GetResource(RES_TEXT, RT_VERSION_ID, name); - pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name); - pl->SetFontType(FONT_COURIER); - pl->SetFontSize(9.0f); - } - - m_engine->LoadAllTexture(); -} - - -// Processing an event. -// Returns FALSE if the event has been processed completely. - -BOOL CMainDialog::EventProcess(const Event &event) -{ - CWindow* pw; - CList* pl; - CButton* pb; - CCheck* pc; - Event newEvent; - float welcomeLength; - - if ( event.event == EVENT_FRAME ) - { - m_phaseTime += event.rTime; - -//? if ( m_phase == PHASE_WELCOME1 ) welcomeLength = WELCOME_LENGTH+2.0f; -//? else welcomeLength = WELCOME_LENGTH; - welcomeLength = WELCOME_LENGTH; - - if ( m_phase == PHASE_WELCOME1 || - m_phase == PHASE_WELCOME2 || - m_phase == PHASE_WELCOME3 ) - { - float intensity; - int mode = D3DSTATETCb; - - if ( m_phaseTime < 1.5f ) - { - intensity = 1.0f-(m_phaseTime-0.5f); - } - else if ( m_phaseTime < welcomeLength-1.0f ) - { - intensity = 0.0f; - } - else - { - intensity = m_phaseTime-(welcomeLength-1.0f); - } - if ( intensity < 0.0f ) intensity = 0.0f; - if ( intensity > 1.0f ) intensity = 1.0f; - - if ( (m_phase == PHASE_WELCOME2 && m_phaseTime > welcomeLength/2.0f) || - m_phase == PHASE_WELCOME3 ) - { - intensity = 1.0f-intensity; - mode = D3DSTATETCw; - } - - m_engine->SetOverColor(RetColor(intensity), mode); - } - - if ( m_phase == PHASE_WELCOME1 && m_phaseTime >= welcomeLength ) - { - ChangePhase(PHASE_WELCOME2); - return TRUE; - } - if ( m_phase == PHASE_WELCOME2 && m_phaseTime >= welcomeLength ) - { - ChangePhase(PHASE_WELCOME3); - return TRUE; - } - if ( m_phase == PHASE_WELCOME3 && m_phaseTime >= welcomeLength ) - { - ChangePhase(PHASE_NAME); - return TRUE; - } - - if ( m_shotDelay > 0 && !m_bDialog ) // screenshot done? - { - m_shotDelay --; - if ( m_shotDelay == 0 ) - { - m_engine->WriteScreenShot(m_shotName, 320, 240); -//? m_engine->WriteScreenShot(m_shotName, 160, 120); - } - } - - if ( m_phase == PHASE_LOADING ) - { - if ( m_loadingCounter == 0 ) - { - m_main->ChangePhase(PHASE_SIMUL); - } - m_loadingCounter --; - return FALSE; - } - - m_glintTime += event.rTime; - GlintMove(); // moves reflections - - FrameParticule(event.rTime); - - if ( m_bDialog ) // this dialogue? - { - FrameDialog(event.rTime); - } - - return TRUE; - } - - if ( event.event == EVENT_MOUSEMOVE ) - { - m_glintMouse = event.pos; - NiceParticule(event.pos, event.keyState&KS_MLEFT); - } - - if ( m_bDialog ) // this dialogue? - { - m_interface->EventProcess(event); - - if ( event.event == EVENT_DIALOG_OK || - (event.event == EVENT_KEYDOWN && event.param == VK_RETURN ) ) - { - StopDialog(); - if ( m_phase == PHASE_NAME ) - { - NameDelete(); - } - if ( m_phase == PHASE_INIT ) - { -//? m_event->MakeEvent(newEvent, EVENT_QUIT); -//? m_event->AddEvent(newEvent); - m_main->ChangePhase(PHASE_GENERIC); - } - if ( m_phase == PHASE_SIMUL ) - { - if ( m_bDialogDelete ) - { - m_main->DeleteObject(); - } - else - { - m_main->ChangePhase(PHASE_TERM); - } - } - } - if ( event.event == EVENT_DIALOG_CANCEL || - (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE ) ) - { - StopDialog(); - } - if ( event.event == EVENT_INTERFACE_SETUP ) - { - StopDialog(); - StartSuspend(); - if ( m_phaseSetup == PHASE_SETUPd ) ChangePhase(PHASE_SETUPds); - if ( m_phaseSetup == PHASE_SETUPg ) ChangePhase(PHASE_SETUPgs); - if ( m_phaseSetup == PHASE_SETUPp ) ChangePhase(PHASE_SETUPps); - if ( m_phaseSetup == PHASE_SETUPc ) ChangePhase(PHASE_SETUPcs); - if ( m_phaseSetup == PHASE_SETUPs ) ChangePhase(PHASE_SETUPss); - } - if ( event.event == EVENT_INTERFACE_AGAIN ) - { - StopDialog(); - m_main->ChangePhase(PHASE_LOADING); - } - if ( event.event == EVENT_INTERFACE_WRITE ) - { - StopDialog(); - StartSuspend(); - ChangePhase(PHASE_WRITEs); - } - if ( event.event == EVENT_INTERFACE_READ ) - { - StopDialog(); - StartSuspend(); - ChangePhase(PHASE_READs); - } - - return FALSE; - } - - if ( !m_engine->RetMouseHide() && - !m_interface->EventProcess(event) ) - { - return FALSE; - } - - if ( m_phase == PHASE_INIT ) - { - switch( event.event ) - { - case EVENT_KEYDOWN: - if ( event.param == VK_ESCAPE ) - { -//? StartQuit(); // would you leave? - m_sound->Play(SOUND_TZOING); - m_main->ChangePhase(PHASE_GENERIC); - } - break; - - case EVENT_INTERFACE_QUIT: -//? StartQuit(); // would you leave? - m_sound->Play(SOUND_TZOING); - m_main->ChangePhase(PHASE_GENERIC); - break; - - case EVENT_INTERFACE_TRAINER: - m_main->ChangePhase(PHASE_TRAINER); - break; - - case EVENT_INTERFACE_DEFI: - m_main->ChangePhase(PHASE_DEFI); - break; - - case EVENT_INTERFACE_MISSION: - m_main->ChangePhase(PHASE_MISSION); - break; - - case EVENT_INTERFACE_FREE: - m_main->ChangePhase(PHASE_FREE); - break; - - case EVENT_INTERFACE_TEEN: - m_main->ChangePhase(PHASE_TEEN); - break; - - case EVENT_INTERFACE_USER: - m_main->ChangePhase(PHASE_USER); - break; - - case EVENT_INTERFACE_PROTO: - m_main->ChangePhase(PHASE_PROTO); - break; - - case EVENT_INTERFACE_SETUP: - m_main->ChangePhase(m_phaseSetup); - break; - - case EVENT_INTERFACE_NAME: - m_main->ChangePhase(PHASE_NAME); - break; - } - return FALSE; - } - - if ( m_phase == PHASE_NAME ) - { - switch( event.event ) - { - case EVENT_KEYDOWN: - if ( event.param == VK_RETURN ) - { - NameSelect(); - } - if ( event.param == VK_ESCAPE ) - { - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) break; - pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_NCANCEL); - if ( pb == 0 ) break; - if ( pb->TestState(STATE_ENABLE) ) - { - m_main->ChangePhase(PHASE_INIT); - } - } - break; - - case EVENT_INTERFACE_NEDIT: - UpdateNameList(); - UpdateNameControl(); - break; - - case EVENT_INTERFACE_NLIST: - UpdateNameEdit(); - break; - - case EVENT_INTERFACE_NOK: - NameSelect(); - break; - - case EVENT_INTERFACE_PERSO: - NameSelect(); - m_main->ChangePhase(PHASE_PERSO); - break; - - case EVENT_INTERFACE_NCANCEL: - m_main->ChangePhase(PHASE_INIT); - break; - - case EVENT_INTERFACE_NDELETE: - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) break; - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); - if ( pl == 0 ) break; - StartDeleteGame(pl->RetName(pl->RetSelect())); - break; - } - } - - if ( m_phase == PHASE_PERSO ) - { - switch( event.event ) - { - case EVENT_KEYDOWN: - if ( event.param == VK_RETURN ) - { - m_main->ChangePhase(PHASE_INIT); - } - if ( event.param == VK_ESCAPE ) - { - m_main->ChangePhase(PHASE_NAME); - } - break; - - case EVENT_INTERFACE_PHEAD: - m_persoTab = 0; - UpdatePerso(); - m_main->ScenePerso(); - CameraPerso(); - break; - case EVENT_INTERFACE_PBODY: - m_persoTab = 1; - UpdatePerso(); - m_main->ScenePerso(); - CameraPerso(); - break; - - case EVENT_INTERFACE_PFACE1: - case EVENT_INTERFACE_PFACE2: - case EVENT_INTERFACE_PFACE3: - case EVENT_INTERFACE_PFACE4: - m_perso.face = event.event-EVENT_INTERFACE_PFACE1; - WriteGamerPerso(m_main->RetGamerName()); - UpdatePerso(); - m_main->ScenePerso(); - break; - - case EVENT_INTERFACE_PGLASS0: - case EVENT_INTERFACE_PGLASS1: - case EVENT_INTERFACE_PGLASS2: - case EVENT_INTERFACE_PGLASS3: - case EVENT_INTERFACE_PGLASS4: - case EVENT_INTERFACE_PGLASS5: - case EVENT_INTERFACE_PGLASS6: - case EVENT_INTERFACE_PGLASS7: - case EVENT_INTERFACE_PGLASS8: - case EVENT_INTERFACE_PGLASS9: - m_perso.glasses = event.event-EVENT_INTERFACE_PGLASS0; - WriteGamerPerso(m_main->RetGamerName()); - UpdatePerso(); - m_main->ScenePerso(); - break; - - case EVENT_INTERFACE_PC0a: - case EVENT_INTERFACE_PC1a: - case EVENT_INTERFACE_PC2a: - case EVENT_INTERFACE_PC3a: - case EVENT_INTERFACE_PC4a: - case EVENT_INTERFACE_PC5a: - case EVENT_INTERFACE_PC6a: - case EVENT_INTERFACE_PC7a: - case EVENT_INTERFACE_PC8a: - case EVENT_INTERFACE_PC9a: - FixPerso(event.event-EVENT_INTERFACE_PC0a, 0); - WriteGamerPerso(m_main->RetGamerName()); - UpdatePerso(); - m_main->ScenePerso(); - break; - - case EVENT_INTERFACE_PC0b: - case EVENT_INTERFACE_PC1b: - case EVENT_INTERFACE_PC2b: - case EVENT_INTERFACE_PC3b: - case EVENT_INTERFACE_PC4b: - case EVENT_INTERFACE_PC5b: - case EVENT_INTERFACE_PC6b: - case EVENT_INTERFACE_PC7b: - case EVENT_INTERFACE_PC8b: - case EVENT_INTERFACE_PC9b: - FixPerso(event.event-EVENT_INTERFACE_PC0b, 1); - WriteGamerPerso(m_main->RetGamerName()); - UpdatePerso(); - m_main->ScenePerso(); - break; - - case EVENT_INTERFACE_PCRa: - case EVENT_INTERFACE_PCGa: - case EVENT_INTERFACE_PCBa: - case EVENT_INTERFACE_PCRb: - case EVENT_INTERFACE_PCGb: - case EVENT_INTERFACE_PCBb: - ColorPerso(); - WriteGamerPerso(m_main->RetGamerName()); - UpdatePerso(); - m_main->ScenePerso(); - break; - - case EVENT_INTERFACE_PDEF: - DefPerso(); - WriteGamerPerso(m_main->RetGamerName()); - UpdatePerso(); - m_main->ScenePerso(); - break; - - case EVENT_INTERFACE_PLROT: - m_persoAngle += 0.2f; - break; - case EVENT_INTERFACE_PRROT: - m_persoAngle -= 0.2f; - break; - - case EVENT_INTERFACE_POK: - m_main->ChangePhase(PHASE_INIT); - break; - - case EVENT_INTERFACE_PCANCEL: - m_perso = m_persoCopy; - WriteGamerPerso(m_main->RetGamerName()); - m_main->ChangePhase(PHASE_NAME); - break; - } - } - - if ( m_phase == PHASE_TRAINER || - m_phase == PHASE_DEFI || - m_phase == PHASE_MISSION || - m_phase == PHASE_FREE || - m_phase == PHASE_TEEN || - m_phase == PHASE_USER || - m_phase == PHASE_PROTO ) - { - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return FALSE; - - if ( event.event == pw->RetEventMsgClose() || - event.event == EVENT_INTERFACE_BACK || - (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) ) - { - m_main->ChangePhase(PHASE_INIT); - return FALSE; - } - } - - if ( m_phase == PHASE_TRAINER || - m_phase == PHASE_DEFI || - m_phase == PHASE_MISSION || - m_phase == PHASE_FREE || - m_phase == PHASE_TEEN || - m_phase == PHASE_USER || - m_phase == PHASE_PROTO ) - { - switch( event.event ) - { - case EVENT_INTERFACE_CHAP: - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_CHAP); - if ( pl == 0 ) break; - m_chap[m_index] = pl->RetSelect(); - UpdateSceneList(m_chap[m_index], m_sel[m_index]); - UpdateSceneResume((m_chap[m_index]+1)*100+(m_sel[m_index]+1)); - break; - - case EVENT_INTERFACE_LIST: - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_LIST); - if ( pl == 0 ) break; - m_sel[m_index] = pl->RetSelect(); - UpdateSceneResume((m_chap[m_index]+1)*100+(m_sel[m_index]+1)); - break; - - case EVENT_INTERFACE_SOLUCE: - pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_SOLUCE); - if ( pb == 0 ) break; - m_bSceneSoluce = !m_bSceneSoluce; - pb->SetState(STATE_CHECK, m_bSceneSoluce); - break; - - case EVENT_INTERFACE_PLAY: - if ( m_phase == PHASE_PROTO && m_chap[m_index] == 0 && m_sel[m_index] == 0 ) - { - m_main->ChangePhase(PHASE_MODEL); - break; - } - m_sceneRank = (m_chap[m_index]+1)*100+(m_sel[m_index]+1); - m_phaseTerm = m_phase; - m_main->ChangePhase(PHASE_LOADING); - break; - - case EVENT_INTERFACE_READ: - m_phaseTerm = m_phase; - m_main->ChangePhase(PHASE_READ); - break; - } - return FALSE; - } - - if ( m_phase == PHASE_SETUPd || - m_phase == PHASE_SETUPg || - m_phase == PHASE_SETUPp || - m_phase == PHASE_SETUPc || - m_phase == PHASE_SETUPs ) - { - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return FALSE; - - if ( event.event == pw->RetEventMsgClose() || - event.event == EVENT_INTERFACE_BACK || - (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) ) - { - SetupMemorize(); - m_engine->ApplyChange(); - m_main->ChangePhase(PHASE_INIT); - return FALSE; - } - - switch( event.event ) - { - case EVENT_INTERFACE_SETUPd: - m_main->ChangePhase(PHASE_SETUPd); - break; - - case EVENT_INTERFACE_SETUPg: - m_main->ChangePhase(PHASE_SETUPg); - break; - - case EVENT_INTERFACE_SETUPp: - m_main->ChangePhase(PHASE_SETUPp); - break; - - case EVENT_INTERFACE_SETUPc: - m_main->ChangePhase(PHASE_SETUPc); - break; - - case EVENT_INTERFACE_SETUPs: - m_main->ChangePhase(PHASE_SETUPs); - break; - } - } - - if ( m_phase == PHASE_SETUPds || - m_phase == PHASE_SETUPgs || - m_phase == PHASE_SETUPps || - m_phase == PHASE_SETUPcs || - m_phase == PHASE_SETUPss ) - { - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return FALSE; - - if ( event.event == pw->RetEventMsgClose() || - event.event == EVENT_INTERFACE_BACK || - (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) ) - { - SetupMemorize(); - m_engine->ApplyChange(); - m_interface->DeleteControl(EVENT_WINDOW5); - ChangePhase(PHASE_SIMUL); - StopSuspend(); - return FALSE; - } - - switch( event.event ) - { - case EVENT_INTERFACE_SETUPd: - ChangePhase(PHASE_SETUPds); - break; - - case EVENT_INTERFACE_SETUPg: - ChangePhase(PHASE_SETUPgs); - break; - - case EVENT_INTERFACE_SETUPp: - ChangePhase(PHASE_SETUPps); - break; - - case EVENT_INTERFACE_SETUPc: - ChangePhase(PHASE_SETUPcs); - break; - - case EVENT_INTERFACE_SETUPs: - ChangePhase(PHASE_SETUPss); - break; - } - } - - if ( m_phase == PHASE_SETUPd || // setup/display ? - m_phase == PHASE_SETUPds ) - { - switch( event.event ) - { - case EVENT_LIST1: - case EVENT_LIST2: - UpdateApply(); - break; - - case EVENT_INTERFACE_FULL: - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) break; - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_FULL); - if ( pc == 0 ) break; - pl = (CList*)pw->SearchControl(EVENT_LIST2); - if ( pl == 0 ) break; - if ( pc->TestState(STATE_CHECK) ) - { - pc->ClearState(STATE_CHECK); // window - pl->ClearState(STATE_ENABLE); - } - else - { - pc->SetState(STATE_CHECK); // fullscreen - pl->SetState(STATE_ENABLE); - } - UpdateApply(); - break; - - case EVENT_INTERFACE_APPLY: - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) break; - pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_APPLY); - if ( pb == 0 ) break; - pb->ClearState(STATE_PRESS); - pb->ClearState(STATE_HILIGHT); - ChangeDisplay(); - UpdateApply(); - break; - } - return FALSE; - } - - if ( m_phase == PHASE_SETUPg || // setup/graphic ? - m_phase == PHASE_SETUPgs ) - { - switch( event.event ) - { - case EVENT_INTERFACE_SHADOW: - m_engine->SetShadow(!m_engine->RetShadow()); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_GROUND: - m_engine->SetGroundSpot(!m_engine->RetGroundSpot()); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_DIRTY: - m_engine->SetDirty(!m_engine->RetDirty()); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_FOG: - m_engine->SetFog(!m_engine->RetFog()); - m_camera->SetOverBaseColor(RetColor(RetColor(0.0f))); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_LENS: - m_engine->SetLensMode(!m_engine->RetLensMode()); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_SKY: - m_engine->SetSkyMode(!m_engine->RetSkyMode()); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_PLANET: - m_engine->SetPlanetMode(!m_engine->RetPlanetMode()); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_LIGHT: - m_engine->SetLightMode(!m_engine->RetLightMode()); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_PARTI: - case EVENT_INTERFACE_CLIP: - case EVENT_INTERFACE_DETAIL: - case EVENT_INTERFACE_GADGET: - case EVENT_INTERFACE_TEXTURE: - ChangeSetupButtons(); - break; - - case EVENT_INTERFACE_MIN: - ChangeSetupQuality(-1); - UpdateSetupButtons(); - break; - case EVENT_INTERFACE_NORM: - ChangeSetupQuality(0); - UpdateSetupButtons(); - break; - case EVENT_INTERFACE_MAX: - ChangeSetupQuality(1); - UpdateSetupButtons(); - break; - } - return FALSE; - } - - if ( m_phase == PHASE_SETUPp || // setup/game ? - m_phase == PHASE_SETUPps ) - { - switch( event.event ) - { - case EVENT_INTERFACE_TOTO: - m_engine->SetTotoMode(!m_engine->RetTotoMode()); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_TOOLTIP: - m_bTooltip = !m_bTooltip; - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_GLINT: - m_bGlint = !m_bGlint; - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_RAIN: - m_bRain = !m_bRain; - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_MOUSE: - m_engine->SetNiceMouse(!m_engine->RetNiceMouse()); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_EDITMODE: - m_engine->SetEditIndentMode(!m_engine->RetEditIndentMode()); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_EDITVALUE: - if ( m_engine->RetEditIndentValue() == 2 ) - { - m_engine->SetEditIndentValue(4); - } - else - { - m_engine->SetEditIndentValue(2); - } - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_SOLUCE4: - m_bSoluce4 = !m_bSoluce4; - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_MOVIES: - m_bMovies = !m_bMovies; - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_NICERST: - m_bNiceReset = !m_bNiceReset; - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_HIMSELF: - m_bHimselfDamage = !m_bHimselfDamage; - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_SCROLL: - m_bCameraScroll = !m_bCameraScroll; - m_camera->SetCameraScroll(m_bCameraScroll); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_INVERTX: - m_bCameraInvertX = !m_bCameraInvertX; - m_camera->SetCameraInvertX(m_bCameraInvertX); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_INVERTY: - m_bCameraInvertY = !m_bCameraInvertY; - m_camera->SetCameraInvertY(m_bCameraInvertY); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_EFFECT: - m_bEffect = !m_bEffect; - m_camera->SetEffect(m_bEffect); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - } - return FALSE; - } - - if ( m_phase == PHASE_SETUPc || // setup/commands ? - m_phase == PHASE_SETUPcs ) - { - switch( event.event ) - { - case EVENT_INTERFACE_KSCROLL: - UpdateKey(); - break; - - case EVENT_INTERFACE_KLEFT: - case EVENT_INTERFACE_KRIGHT: - case EVENT_INTERFACE_KUP: - case EVENT_INTERFACE_KDOWN: - case EVENT_INTERFACE_KGUP: - case EVENT_INTERFACE_KGDOWN: - case EVENT_INTERFACE_KCAMERA: - case EVENT_INTERFACE_KDESEL: - case EVENT_INTERFACE_KACTION: - case EVENT_INTERFACE_KNEAR: - case EVENT_INTERFACE_KAWAY: - case EVENT_INTERFACE_KNEXT: - case EVENT_INTERFACE_KHUMAN: - case EVENT_INTERFACE_KQUIT: - case EVENT_INTERFACE_KHELP: - case EVENT_INTERFACE_KPROG: - case EVENT_INTERFACE_KCBOT: - case EVENT_INTERFACE_KSPEED10: - case EVENT_INTERFACE_KSPEED15: - case EVENT_INTERFACE_KSPEED20: - case EVENT_INTERFACE_KSPEED30: - case EVENT_INTERFACE_KVISIT: - ChangeKey(event.event); - UpdateKey(); - break; - - case EVENT_INTERFACE_KDEF: - m_engine->ResetKey(); - UpdateKey(); - break; - - case EVENT_INTERFACE_JOYSTICK: - m_engine->SetJoystick(!m_engine->RetJoystick()); - UpdateSetupButtons(); - break; - } - return FALSE; - } - - if ( m_phase == PHASE_SETUPs || // setup/sound ? - m_phase == PHASE_SETUPss ) - { - switch( event.event ) - { - case EVENT_INTERFACE_VOLSOUND: - case EVENT_INTERFACE_VOLMUSIC: - ChangeSetupButtons(); - break; - - case EVENT_INTERFACE_SOUND3D: - m_sound->SetSound3D(!m_sound->RetSound3D()); - ChangeSetupButtons(); - UpdateSetupButtons(); - break; - - case EVENT_INTERFACE_SILENT: - m_sound->SetAudioVolume(0); - m_sound->SetMidiVolume(0); - UpdateSetupButtons(); - break; - case EVENT_INTERFACE_NOISY: - m_sound->SetAudioVolume(MAXVOLUME); - m_sound->SetMidiVolume(MAXVOLUME*3/4); - UpdateSetupButtons(); - break; - } - return FALSE; - } - - if ( m_phase == PHASE_READ ) - { - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return FALSE; - - if ( event.event == pw->RetEventMsgClose() || - event.event == EVENT_INTERFACE_BACK || - (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) ) - { - ChangePhase(m_phaseTerm); - } - - if ( event.event == EVENT_INTERFACE_IOLIST ) - { - IOUpdateList(); - } - if ( event.event == EVENT_INTERFACE_IODELETE ) - { - IODeleteScene(); - IOUpdateList(); - } - if ( event.event == EVENT_INTERFACE_IOREAD ) - { - if ( IOReadScene() ) - { - m_main->ChangePhase(PHASE_LOADING); - } - } - - return FALSE; - } - - if ( m_phase == PHASE_WRITEs || - m_phase == PHASE_READs ) - { - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return FALSE; - - if ( event.event == pw->RetEventMsgClose() || - event.event == EVENT_INTERFACE_BACK || - (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) ) - { - m_interface->DeleteControl(EVENT_WINDOW5); - ChangePhase(PHASE_SIMUL); - StopSuspend(); - } - - if ( event.event == EVENT_INTERFACE_IOLIST ) - { - IOUpdateList(); - } - if ( event.event == EVENT_INTERFACE_IODELETE ) - { - IODeleteScene(); - IOUpdateList(); - } - if ( event.event == EVENT_INTERFACE_IOWRITE ) - { - IOWriteScene(); - m_interface->DeleteControl(EVENT_WINDOW5); - ChangePhase(PHASE_SIMUL); - StopSuspend(); - } - if ( event.event == EVENT_INTERFACE_IOREAD ) - { - if ( IOReadScene() ) - { - m_interface->DeleteControl(EVENT_WINDOW5); - ChangePhase(PHASE_SIMUL); - StopSuspend(); - m_main->ChangePhase(PHASE_LOADING); - } - } - - return FALSE; - } - - if ( m_phase == PHASE_WELCOME1 ) - { - if ( event.event == EVENT_KEYDOWN || - event.event == EVENT_LBUTTONDOWN || - event.event == EVENT_RBUTTONDOWN ) - { - ChangePhase(PHASE_WELCOME2); - return TRUE; - } - } - if ( m_phase == PHASE_WELCOME2 ) - { - if ( event.event == EVENT_KEYDOWN || - event.event == EVENT_LBUTTONDOWN || - event.event == EVENT_RBUTTONDOWN ) - { - ChangePhase(PHASE_WELCOME3); - return TRUE; - } - } - if ( m_phase == PHASE_WELCOME3 ) - { - if ( event.event == EVENT_KEYDOWN || - event.event == EVENT_LBUTTONDOWN || - event.event == EVENT_RBUTTONDOWN ) - { - ChangePhase(PHASE_NAME); - return TRUE; - } - } - - if ( m_phase == PHASE_GENERIC ) - { - if ( event.event == EVENT_INTERFACE_ABORT ) - { - ChangePhase(PHASE_INIT); - } - - if ( event.event == EVENT_KEYDOWN ) - { - if ( event.param == VK_ESCAPE ) - { - ChangePhase(PHASE_INIT); - } - else - { - m_event->MakeEvent(newEvent, EVENT_QUIT); - m_event->AddEvent(newEvent); - } - } - - if ( event.event == EVENT_LBUTTONDOWN || - event.event == EVENT_RBUTTONDOWN ) - { - m_event->MakeEvent(newEvent, EVENT_QUIT); - m_event->AddEvent(newEvent); - } - } - - return TRUE; -} - - -// Moves the reflections. - -void CMainDialog::GlintMove() -{ - CWindow* pw; - CGroup* pg; - FPOINT pos, dim, zoom; - - if ( m_phase == PHASE_SIMUL ) return; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - - if ( m_phase == PHASE_INIT ) - { - pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTl); - if ( pg != 0 ) - { - zoom.x = sinf(m_glintTime*0.23f); - zoom.y = sinf(m_glintTime*0.37f); - pos.x = 0.35f; - pos.y = 0.90f; - dim.x = 0.30f-0.10f*(zoom.x+1.0f)/2.0f; - dim.y = 0.50f-0.30f*(zoom.y+1.0f)/2.0f; - pos.y -= dim.y; - pg->SetPos(pos); - pg->SetDim(dim); - } - - pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTr); - if ( pg != 0 ) - { - zoom.x = sinf(m_glintTime*0.21f); - zoom.y = sinf(m_glintTime*0.26f); - pos.x = 0.65f; - pos.y = 0.10f; - dim.x = 0.30f-0.10f*(zoom.x+1.0f)/2.0f; - dim.y = 0.50f-0.30f*(zoom.y+1.0f)/2.0f; - pos.x -= dim.x; - pg->SetPos(pos); - pg->SetDim(dim); - } - } - - if ( m_phase == PHASE_NAME || - m_phase == PHASE_TRAINER || - m_phase == PHASE_MISSION || - m_phase == PHASE_FREE || - m_phase == PHASE_TEEN || - m_phase == PHASE_USER || - m_phase == PHASE_PROTO ) - { - pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTl); - if ( pg != 0 ) - { - zoom.x = sinf(m_glintTime*0.22f); - zoom.y = sinf(m_glintTime*0.37f); - pos.x = 0.10f; - pos.y = 0.90f; - dim.x = 0.60f+0.30f*zoom.x; - dim.y = 0.60f+0.30f*zoom.y; - pos.y -= dim.y; - pg->SetPos(pos); - pg->SetDim(dim); - } - - pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTr); - if ( pg != 0 ) - { - zoom.x = sinf(m_glintTime*0.19f); - zoom.y = sinf(m_glintTime*0.28f); - pos.x = 0.90f; - pos.y = 0.10f; - dim.x = 0.60f+0.30f*zoom.x; - dim.y = 0.60f+0.30f*zoom.y; - pos.x -= dim.x; - pg->SetPos(pos); - pg->SetDim(dim); - } - } - - if ( m_phase == PHASE_SETUPd || - m_phase == PHASE_SETUPg || - m_phase == PHASE_SETUPp || - m_phase == PHASE_SETUPc || - m_phase == PHASE_SETUPs || - m_phase == PHASE_SETUPds || - m_phase == PHASE_SETUPgs || - m_phase == PHASE_SETUPps || - m_phase == PHASE_SETUPcs || - m_phase == PHASE_SETUPss ) - { - pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTu); - if ( pg != 0 ) - { - zoom.y = sinf(m_glintTime*0.27f); - pos.x = 0.10f; - pos.y = 0.76f; - dim.x = 0.80f; - dim.y = 0.32f+0.20f*zoom.y; - pos.y -= dim.y; - pg->SetPos(pos); - pg->SetDim(dim); - } - - pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTr); - if ( pg != 0 ) - { - zoom.x = sinf(m_glintTime*0.29f); - zoom.y = sinf(m_glintTime*0.14f); - pos.x = 0.90f; - pos.y = 0.10f; - dim.x = 0.40f+0.20f*zoom.x; - dim.y = 0.40f+0.20f*zoom.y; - pos.x -= dim.x; - pg->SetPos(pos); - pg->SetDim(dim); - } - } - - if ( m_phase == PHASE_WRITE || - m_phase == PHASE_READ || - m_phase == PHASE_WRITEs || - m_phase == PHASE_READs ) - { - pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTl); - if ( pg != 0 ) - { - zoom.x = sinf(m_glintTime*0.22f); - zoom.y = sinf(m_glintTime*0.37f); - pos.x = 0.10f; - pos.y = 0.90f; - dim.x = 0.60f+0.30f*zoom.x; - dim.y = 0.60f+0.30f*zoom.y; - pos.y -= dim.y; - pg->SetPos(pos); - pg->SetDim(dim); - } - - pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTr); - if ( pg != 0 ) - { - zoom.x = sinf(m_glintTime*0.19f); - zoom.y = sinf(m_glintTime*0.28f); - pos.x = 0.90f; - pos.y = 0.10f; - dim.x = 0.60f+0.30f*zoom.x; - dim.y = 0.60f+0.30f*zoom.y; - pos.x -= dim.x; - pg->SetPos(pos); - pg->SetDim(dim); - } - } -} - - -// Returns the position for a sound. - -D3DVECTOR SoundPos(FPOINT pos) -{ - D3DVECTOR s; - - s.x = (pos.x-0.5f)*2.0f; - s.y = (pos.y-0.5f)*2.0f; - s.z = 0.0f; - - return s; -} - -// Returns a random position for a sound. - -D3DVECTOR SoundRand() -{ - D3DVECTOR s; - - s.x = (Rand()-0.5f)*2.0f; - s.y = (Rand()-0.5f)*2.0f; - s.z = 0.0f; - - return s; -} - -// Makes pretty qq particles evolve. - -void CMainDialog::FrameParticule(float rTime) -{ -#if _NEWLOOK -#else - D3DVECTOR pos, speed; - FPOINT dim; - float *pParti, *pGlint; - int nParti, nGlint; - int i, r, ii; - - static float partiPosInit[1+5*12] = - { // x x t2 t2 type - 12.0f, - 607.0f, 164.0f, 0.2f, 0.8f, 1.0f, // upper cable - 604.0f, 205.0f, 0.1f, 0.3f, 1.0f, // middle cable - 603.0f, 247.0f, 0.1f, 0.3f, 1.0f, // lower cable - 119.0f, 155.0f, 0.2f, 0.4f, 2.0f, // left pipe - 366.0f, 23.0f, 0.5f, 1.5f, 4.0f, // upper pipe - 560.0f, 414.0f, 0.1f, 0.1f, 1.0f, // button lower/right - 20.0f, 413.0f, 0.1f, 0.1f, 2.0f, // button lower/left - 39.0f, 78.0f, 0.1f, 0.2f, 1.0f, // left pot - 39.0f, 78.0f, 0.5f, 0.9f, 1.0f, // left pot - 170.0f, 229.0f, 0.5f, 0.5f, 3.0f, // left smoke - 170.0f, 229.0f, 0.5f, 0.5f, 3.0f, // left smoke - 474.0f, 229.0f, 0.5f, 0.5f, 3.0f, // right smoke - }; - - static float glintPosInit[1+2*14] = - { - 14.0f, - 15.0f, 407.0f, - 68.0f, 417.0f, - 548.0f, 36.0f, - 611.0f, 37.0f, - 611.0f, 100.0f, - 611.0f, 395.0f, - 36.0f, 35.0f, - 166.0f, 55.0f, - 166.0f, 94.0f, - 477.0f, 56.0f, - 31.0f, 190.0f, - 32.0f, 220.0f, - 65.0f, 221.0f, - 65.0f, 250.0f, - }; - - static float partiPosBig[1+5*12] = - { // x x t2 t2 type - 12.0f, - 607.0f, 164.0f, 0.2f, 0.8f, 1.0f, // upper cable - 604.0f, 205.0f, 0.1f, 0.3f, 1.0f, // middle cable - 603.0f, 247.0f, 0.1f, 0.3f, 1.0f, // lower cable - 64.0f, 444.0f, 0.2f, 0.8f, 1.0f, // down the left cable - 113.0f, 449.0f, 0.1f, 0.3f, 1.0f, // down the left cable - 340.0f, 463.0f, 0.2f, 0.8f, 1.0f, // down the middle cable - 36.0f, 155.0f, 0.2f, 0.4f, 2.0f, // left pipe - 366.0f, 23.0f, 0.5f, 1.5f, 4.0f, // upper pipe - 612.0f, 414.0f, 0.1f, 0.1f, 1.0f, // button lower/right - 20.0f, 413.0f, 0.1f, 0.1f, 2.0f, // button lower/left - 39.0f, 78.0f, 0.1f, 0.2f, 1.0f, // left pot - 39.0f, 78.0f, 0.5f, 0.9f, 1.0f, // left pot - }; - - static float glintPosBig[1+2*12] = - { - 12.0f, - 15.0f, 407.0f, - 48.0f, 399.0f, - 611.0f, 37.0f, - 611.0f, 100.0f, - 611.0f, 395.0f, - 36.0f, 35.0f, - 31.0f, 190.0f, - 32.0f, 220.0f, - 31.0f, 221.0f, - 31.0f, 189.0f, - 255.0f, 18.0f, - 279.0f, 18.0f, - }; - - if ( m_bDialog || !m_bRain ) return; - - if ( m_phase == PHASE_INIT ) - { - pParti = partiPosInit; - pGlint = glintPosInit; - } - else if ( m_phase == PHASE_NAME || - m_phase == PHASE_TRAINER || - m_phase == PHASE_DEFI || - m_phase == PHASE_MISSION || - m_phase == PHASE_FREE || - m_phase == PHASE_TEEN || - m_phase == PHASE_USER || - m_phase == PHASE_PROTO || - m_phase == PHASE_SETUPd || - m_phase == PHASE_SETUPg || - m_phase == PHASE_SETUPp || - m_phase == PHASE_SETUPc || - m_phase == PHASE_SETUPs || - m_phase == PHASE_WRITE || - m_phase == PHASE_READ ) - { - pParti = partiPosBig; - pGlint = glintPosBig; - } - else - { - return; - } - - nParti = (int)(*pParti++); - nGlint = (int)(*pGlint++); - - for ( i=0 ; i<10 ; i++ ) - { - if ( m_partiPhase[i] == 0 ) // waiting? - { - m_partiTime[i] -= rTime; - if ( m_partiTime[i] <= 0.0f ) - { - r = rand()%3; - - if ( r == 0 ) - { - ii = rand()%nParti; - m_partiPos[i].x = pParti[ii*5+0]/640.0f; - m_partiPos[i].y = (480.0f-pParti[ii*5+1])/480.0f; - m_partiTime[i] = pParti[ii*5+2]+Rand()*pParti[ii*5+3]; - m_partiPhase[i] = (int)pParti[ii*5+4]; - if ( m_partiPhase[i] == 3 ) - { - m_sound->Play(SOUND_PSHHH, SoundPos(m_partiPos[i]), 0.3f+Rand()*0.3f); - } - else - { - m_sound->Play(SOUND_GGG, SoundPos(m_partiPos[i]), 0.1f+Rand()*0.4f); - } - } - - if ( r == 1 ) - { - ii = rand()%nGlint; - pos.x = pGlint[ii*2+0]/640.0f; - pos.y = (480.0f-pGlint[ii*2+1])/480.0f; - pos.z = 0.0f; - speed.x = 0.0f; - speed.y = 0.0f; - speed.z = 0.0f; - dim.x = 0.04f+Rand()*0.04f; - dim.y = dim.x/0.75f; - m_particule->CreateParticule(pos, speed, dim, - rand()%2?PARTIGLINT:PARTICONTROL, - Rand()*0.4f+0.4f, 0.0f, 0.0f, - SH_INTERFACE); - m_partiTime[i] = 0.5f+Rand()*0.5f; - } - - if ( r == 2 ) - { - ii = rand()%7; - if ( ii == 0 ) - { - m_sound->Play(SOUND_ENERGY, SoundRand(), 0.2f+Rand()*0.2f); - m_partiTime[i] = 1.0f+Rand()*1.0f; - } - if ( ii == 1 ) - { - m_sound->Play(SOUND_STATION, SoundRand(), 0.2f+Rand()*0.2f); - m_partiTime[i] = 1.0f+Rand()*2.0f; - } - if ( ii == 2 ) - { - m_sound->Play(SOUND_ALARM, SoundRand(), 0.1f+Rand()*0.1f); - m_partiTime[i] = 2.0f+Rand()*4.0f; - } - if ( ii == 3 ) - { - m_sound->Play(SOUND_INFO, SoundRand(), 0.1f+Rand()*0.1f); - m_partiTime[i] = 2.0f+Rand()*4.0f; - } - if ( ii == 4 ) - { - m_sound->Play(SOUND_RADAR, SoundRand(), 0.2f+Rand()*0.2f); - m_partiTime[i] = 0.5f+Rand()*1.0f; - } - if ( ii == 5 ) - { - m_sound->Play(SOUND_GFLAT, SoundRand(), 0.3f+Rand()*0.3f); - m_partiTime[i] = 2.0f+Rand()*4.0f; - } - if ( ii == 6 ) - { - m_sound->Play(SOUND_ALARMt, SoundRand(), 0.1f+Rand()*0.1f); - m_partiTime[i] = 2.0f+Rand()*4.0f; - } - } - } - } - - if ( m_partiPhase[i] != 0 ) // generates? - { - m_partiTime[i] -= rTime; - if ( m_partiTime[i] > 0.0f ) - { - if ( m_partiPhase[i] == 1 ) // sparks? - { - pos.x = m_partiPos[i].x; - pos.y = m_partiPos[i].y; - pos.z = 0.0f; - pos.x += (Rand()-0.5f)*0.01f; - pos.y += (Rand()-0.5f)*0.01f; - speed.x = (Rand()-0.5f)*0.2f; - speed.y = (Rand()-0.5f)*0.2f; - speed.z = 0.0f; - dim.x = 0.005f+Rand()*0.005f; - dim.y = dim.x/0.75f; - m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, - Rand()*0.2f+0.2f, 0.0f, 0.0f, - SH_INTERFACE); - pos.x = m_partiPos[i].x; - pos.y = m_partiPos[i].y; - pos.z = 0.0f; - speed.x = (Rand()-0.5f)*0.5f; - speed.y = (0.3f+Rand()*0.3f); - speed.z = 0.0f; - dim.x = 0.01f+Rand()*0.01f; - dim.y = dim.x/0.75f; - m_particule->CreateParticule(pos, speed, dim, - (ParticuleType)(PARTILENS1+rand()%3), - Rand()*0.5f+0.5f, 2.0f, 0.0f, - SH_INTERFACE); - } - if ( m_partiPhase[i] == 2 ) // sparks? - { - pos.x = m_partiPos[i].x; - pos.y = m_partiPos[i].y; - pos.z = 0.0f; - pos.x += (Rand()-0.5f)*0.01f; - pos.y += (Rand()-0.5f)*0.01f; - speed.x = (Rand()-0.5f)*0.2f; - speed.y = (Rand()-0.5f)*0.2f; - speed.z = 0.0f; - dim.x = 0.005f+Rand()*0.005f; - dim.y = dim.x/0.75f; - m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, - Rand()*0.2f+0.2f, 0.0f, 0.0f, - SH_INTERFACE); - pos.x = m_partiPos[i].x; - pos.y = m_partiPos[i].y; - pos.z = 0.0f; - speed.x = (Rand()-0.5f)*0.5f; - speed.y = (0.3f+Rand()*0.3f); - speed.z = 0.0f; - dim.x = 0.005f+Rand()*0.005f; - dim.y = dim.x/0.75f; - m_particule->CreateParticule(pos, speed, dim, PARTISCRAPS, - Rand()*0.5f+0.5f, 2.0f, 0.0f, - SH_INTERFACE); - } - if ( m_partiPhase[i] == 3 ) // smoke? - { - pos.x = m_partiPos[i].x; - pos.y = m_partiPos[i].y; - pos.z = 0.0f; - pos.x += (Rand()-0.5f)*0.03f; - pos.y += (Rand()-0.5f)*0.03f; - speed.x = (Rand()-0.5f)*0.2f; - speed.y = Rand()*0.5f; - speed.z = 0.0f; - dim.x = 0.03f+Rand()*0.07f; - dim.y = dim.x/0.75f; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, - Rand()*0.4f+0.4f, 0.0f, 0.0f, - SH_INTERFACE); - } - } - else - { - m_partiPhase[i] = 0; - m_partiTime[i] = 2.0f+Rand()*4.0f; - } - } - } -#endif -} - -// Some nice particles following the mouse. - -void CMainDialog::NiceParticule(FPOINT mouse, BOOL bPress) -{ - D3DVECTOR pos, speed; - FPOINT dim; - - if ( !m_bRain ) return; - if ( (m_phase == PHASE_SIMUL || - m_phase == PHASE_WIN || - m_phase == PHASE_LOST || - m_phase == PHASE_MODEL ) && - !m_bDialog ) return; - - if ( bPress ) - { - pos.x = mouse.x; - pos.y = mouse.y; - pos.z = 0.0f; - speed.x = (Rand()-0.5f)*0.5f; - speed.y = (0.3f+Rand()*0.3f); - speed.z = 0.0f; - dim.x = 0.005f+Rand()*0.005f; - dim.y = dim.x/0.75f; - m_particule->CreateParticule(pos, speed, dim, PARTISCRAPS, - Rand()*0.5f+0.5f, 2.0f, 0.0f, - SH_INTERFACE); - } - else - { - pos.x = mouse.x; - pos.y = mouse.y; - pos.z = 0.0f; - speed.x = (Rand()-0.5f)*0.5f; - speed.y = (0.3f+Rand()*0.3f); - speed.z = 0.0f; - dim.x = 0.01f+Rand()*0.01f; - dim.y = dim.x/0.75f; - m_particule->CreateParticule(pos, speed, dim, - (ParticuleType)(PARTILENS1+rand()%3), - Rand()*0.5f+0.5f, 2.0f, 0.0f, - SH_INTERFACE); - } -} - - - -// Specifies the special user folder if needed. - -void CMainDialog::SetUserDir(char *base, int rank) -{ - char dir[100]; - - if ( strcmp(base, "user") == 0 && rank >= 100 ) - { - sprintf(dir, "%s\\%s", m_userDir, m_userList[rank/100-1]); - UserDir(TRUE, dir); - } - else - { - UserDir(FALSE, ""); - } -} - -// Builds the file name of a mission. - -void CMainDialog::BuildSceneName(char *filename, char *base, int rank) -{ - if ( strcmp(base, "user") == 0 ) - { - sprintf(filename, "%s\\%s\\scene%.2d.txt", m_userDir, m_userList[rank/100-1], rank%100); - } - else - { - sprintf(filename, "%s\\%s%.3d.txt", m_sceneDir, base, rank); - } -} - -// Built the default descriptive name of a mission. - -void CMainDialog::BuildResumeName(char *filename, char *base, int rank) -{ - sprintf(filename, "Scene %s %d", base, rank); -} - -// Returns the name of the file or save the files. - -char* CMainDialog::RetFilesDir() -{ - return m_filesDir; -} - - -// Updates the list of players after checking the files on disk. - -void CMainDialog::ReadNameList() -{ - CWindow* pw; - CList* pl; - long hFile; - struct _finddata_t fBuffer; - BOOL bDo; - char dir[_MAX_FNAME]; - char temp[_MAX_FNAME]; - char filenames[_MAX_FNAME][100]; - int nbFilenames, i; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); - if ( pl == 0 ) return; - pl->Flush(); - - nbFilenames = 0; - sprintf(dir, "%s\\*", m_savegameDir); - hFile = _findfirst(dir, &fBuffer); - if ( hFile != -1 ) - { - do - { - if ( (fBuffer.attrib & _A_SUBDIR) && fBuffer.name[0] != '.' ) - { - strcpy(filenames[nbFilenames++], fBuffer.name); - } - } - while ( _findnext(hFile, &fBuffer) == 0 && nbFilenames < 100 ); - } - do // sorts all names: - { - bDo = FALSE; - for ( i=0 ; i 0 ) - { - strcpy(temp, filenames[i]); - strcpy(filenames[i], filenames[i+1]); - strcpy(filenames[i+1], temp); - bDo = TRUE; - } - } - } - while ( bDo ); - - for ( i=0 ; iSetName(i, filenames[i]); - } -} - -// Updates the controls of the players. - -void CMainDialog::UpdateNameControl() -{ - CWindow* pw; - CList* pl; - CButton* pb; - CEdit* pe; - char name[100]; - char* gamer; - int total, sel; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); - if ( pl == 0 ) return; - pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_NEDIT); - if ( pe == 0 ) return; - - gamer = m_main->RetGamerName(); - total = pl->RetTotal(); - sel = pl->RetSelect(); - pe->GetText(name, 100); - - pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_NCANCEL); - if ( pb != 0 ) - { - pb->SetState(STATE_ENABLE, gamer[0]!=0); - } - - pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_NDELETE); - if ( pb != 0 ) - { - pb->SetState(STATE_ENABLE, total>0 && sel!=-1); - } - - pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_NOK); - if ( pb != 0 ) - { - pb->SetState(STATE_ENABLE, name[0]!=0 || sel!=-1); - } - - pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_PERSO); - if ( pb != 0 ) - { - pb->SetState(STATE_ENABLE, name[0]!=0 || sel!=-1); - } -} - -// Updates the list of players by name frape. - -void CMainDialog::UpdateNameList() -{ - CWindow* pw; - CList* pl; - CEdit* pe; - char name[100]; - int total, sel, i; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); - if ( pl == 0 ) return; - pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_NEDIT); - if ( pe == 0 ) return; - - pe->GetText(name, 100); - total = pl->RetTotal(); - sel = pl->RetSelect(); - - for ( i=0 ; iRetName(i)) == 0 ) - { - pl->SetSelect(i); - pl->ShowSelect(FALSE); - return; - } - } - - pl->SetSelect(-1); -} - -// Updates the player's name and function of the selected list. - -void CMainDialog::UpdateNameEdit() -{ - CWindow* pw; - CList* pl; - CEdit* pe; - char* name; - int sel; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); - if ( pl == 0 ) return; - pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_NEDIT); - if ( pe == 0 ) return; - - sel = pl->RetSelect(); - if ( sel == -1 ) - { - pe->SetText(""); - pe->SetCursor(0, 0); - } - else - { - name = pl->RetName(sel); - pe->SetText(name); - pe->SetCursor(strlen(name), 0); - } - - UpdateNameControl(); -} - -// Updates the representation of the player depending on the selected list. - -void CMainDialog::UpdateNameFace() -{ - CWindow* pw; - CList* pl; - char* name; - int sel; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); - if ( pl == 0 ) return; - - sel = pl->RetSelect(); - if ( sel == -1 ) return; - name = pl->RetName(sel); - - ReadGamerPerso(name); -} - -// Selects a player. - -void CMainDialog::NameSelect() -{ - CWindow* pw; - CList* pl; - CEdit* pe; - char name[100]; - int sel; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); - if ( pl == 0 ) return; - pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_NEDIT); - if ( pe == 0 ) return; - - pe->GetText(name, 100); - sel = pl->RetSelect(); - - if ( sel == -1 ) - { - NameCreate(); - } - else - { - m_main->SetGamerName(pl->RetName(sel)); - m_main->ChangePhase(PHASE_INIT); - } - - RetGamerFace(m_main->RetGamerName()); - - SetProfileString("Gamer", "LastName", m_main->RetGamerName()); -} - -// Creates a new player. - -void CMainDialog::NameCreate() -{ - CWindow* pw; - CEdit* pe; - char name[100]; - char dir[100]; - char c; - int len, i, j; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_NEDIT); - if ( pe == 0 ) return; - - pe->GetText(name, 100); - if ( name[0] == 0 ) - { - m_sound->Play(SOUND_TZOING); - return; - } - - len = strlen(name); - j = 0; - for ( i=0 ; i= '0' && c <= '9') || - (c >= 'a' && c <= 'z') || - c == ' ' || - c == '-' || - c == '_' || - c == '.' || - c == ',' || - c == '\'' ) - { - name[j++] = name[i]; - } - } - name[j] = 0; - if ( j == 0 ) - { - m_sound->Play(SOUND_TZOING); - return; - } - - _mkdir(m_savegameDir); // if does not exist yet! - - sprintf(dir, "%s\\%s", m_savegameDir, name); - if ( _mkdir(dir) != 0 ) - { - m_sound->Play(SOUND_TZOING); - pe->SetText(name); - pe->SetCursor(strlen(name), 0); - pe->SetFocus(TRUE); - return; - } - - SetGamerFace(name, 0); - - m_main->SetGamerName(name); - m_main->ChangePhase(PHASE_INIT); -} - -// Deletes a folder and all its offspring. - -BOOL RemoveDir(char *dirname) -{ - long hFile; - struct _finddata_t fBuffer; - char filename[100]; - - sprintf(filename, "%s\\*", dirname); - hFile = _findfirst(filename, &fBuffer); - if ( hFile != -1 ) - { - do - { - if ( fBuffer.name[0] != '.' ) - { - if ( fBuffer.attrib & _A_SUBDIR ) - { - sprintf(filename, "%s\\%s", dirname, fBuffer.name); - RemoveDir(filename); - } - else - { - sprintf(filename, "%s\\%s", dirname, fBuffer.name); - remove(filename); - } - } - } - while ( _findnext(hFile, &fBuffer) == 0 ); - } - - if ( _rmdir(dirname) != 0 ) - { - return FALSE; - } - return TRUE; -} - -// Removes a player. - -void CMainDialog::NameDelete() -{ - CWindow* pw; - CList* pl; - int sel; - char* gamer; - char dir[100]; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); - if ( pl == 0 ) return; - - sel = pl->RetSelect(); - if ( sel == -1 ) - { - m_sound->Play(SOUND_TZOING); - return; - } - gamer = pl->RetName(sel); - - // Deletes all the contents of the file. - sprintf(dir, "%s\\%s", m_savegameDir, gamer); - if ( !RemoveDir(dir) ) - { - m_sound->Play(SOUND_TZOING); - return; - } - - m_main->SetGamerName(""); - pl->SetSelect(-1); - - ReadNameList(); - UpdateNameList(); - UpdateNameControl(); -} - - - -// ests whether two colors are equal or nearly are. - -BOOL EqColor(const D3DCOLORVALUE &c1, const D3DCOLORVALUE &c2) -{ - return (Abs(c1.r-c2.r) < 0.01f && - Abs(c1.g-c2.g) < 0.01f && - Abs(c1.b-c2.b) < 0.01f ); -} - -// Updates all the buttons for the character. - -void CMainDialog::UpdatePerso() -{ - CWindow* pw; - CLabel* pl; - CButton* pb; - CColor* pc; - CSlider* ps; - D3DCOLORVALUE color; - char name[100]; - int i; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - - pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_PHEAD); - if ( pb != 0 ) - { - pb->SetState(STATE_CHECK, m_persoTab==0); - } - pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_PBODY); - if ( pb != 0 ) - { - pb->SetState(STATE_CHECK, m_persoTab==1); - } - - pl = (CLabel*)pw->SearchControl(EVENT_LABEL11); - if ( pl != 0 ) - { - if ( m_persoTab == 0 ) - { - pl->SetState(STATE_VISIBLE); - GetResource(RES_TEXT, RT_PERSO_FACE, name); - pl->SetName(name); - } - else - { - pl->ClearState(STATE_VISIBLE); - } - } - - pl = (CLabel*)pw->SearchControl(EVENT_LABEL12); - if ( pl != 0 ) - { - if ( m_persoTab == 0 ) - { - pl->SetState(STATE_VISIBLE); - GetResource(RES_TEXT, RT_PERSO_GLASSES, name); - pl->SetName(name); - } - else - { - pl->ClearState(STATE_VISIBLE); - } - } - - pl = (CLabel*)pw->SearchControl(EVENT_LABEL13); - if ( pl != 0 ) - { - if ( m_persoTab == 0 ) GetResource(RES_TEXT, RT_PERSO_HAIR, name); - else GetResource(RES_TEXT, RT_PERSO_BAND, name); - pl->SetName(name); - } - - pl = (CLabel*)pw->SearchControl(EVENT_LABEL14); - if ( pl != 0 ) - { - if ( m_persoTab == 0 ) - { - pl->ClearState(STATE_VISIBLE); - } - else - { - pl->SetState(STATE_VISIBLE); - GetResource(RES_TEXT, RT_PERSO_COMBI, name); - pl->SetName(name); - } - } - - for ( i=0 ; i<4 ; i++ ) - { - pb = (CButton*)pw->SearchControl((EventMsg)(EVENT_INTERFACE_PFACE1+i)); - if ( pb == 0 ) break; - pb->SetState(STATE_VISIBLE, m_persoTab==0); - pb->SetState(STATE_CHECK, i==m_perso.face); - } - - for ( i=0 ; i<10 ; i++ ) - { - pb = (CButton*)pw->SearchControl((EventMsg)(EVENT_INTERFACE_PGLASS0+i)); - if ( pb == 0 ) break; - pb->SetState(STATE_VISIBLE, m_persoTab==0); - pb->SetState(STATE_CHECK, i==m_perso.glasses); - } - - for ( i=0 ; i<3*3 ; i++ ) - { - pc = (CColor*)pw->SearchControl((EventMsg)(EVENT_INTERFACE_PC0a+i)); - if ( pc == 0 ) break; - if ( m_persoTab == 0 ) - { - pc->ClearState(STATE_VISIBLE); - } - else - { - pc->SetState(STATE_VISIBLE); - color.r = perso_color[3*10*1+3*i+0]/255.0f; - color.g = perso_color[3*10*1+3*i+1]/255.0f; - color.b = perso_color[3*10*1+3*i+2]/255.0f; - color.a = 0.0f; - pc->SetColor(color); - pc->SetState(STATE_CHECK, EqColor(color, m_perso.colorCombi)); - } - - pc = (CColor*)pw->SearchControl((EventMsg)(EVENT_INTERFACE_PC0b+i)); - if ( pc == 0 ) break; - color.r = perso_color[3*10*2*m_persoTab+3*i+0]/255.0f; - color.g = perso_color[3*10*2*m_persoTab+3*i+1]/255.0f; - color.b = perso_color[3*10*2*m_persoTab+3*i+2]/255.0f; - color.a = 0.0f; - pc->SetColor(color); - pc->SetState(STATE_CHECK, EqColor(color, m_persoTab?m_perso.colorBand:m_perso.colorHair)); - } - - for ( i=0 ; i<3 ; i++ ) - { - ps = (CSlider*)pw->SearchControl((EventMsg)(EVENT_INTERFACE_PCRa+i)); - if ( ps == 0 ) break; - ps->SetState(STATE_VISIBLE, m_persoTab==1); - } - - if ( m_persoTab == 1 ) - { - color = m_perso.colorCombi; - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCRa); - if ( ps != 0 ) ps->SetVisibleValue(color.r*255.0f); - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCGa); - if ( ps != 0 ) ps->SetVisibleValue(color.g*255.0f); - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCBa); - if ( ps != 0 ) ps->SetVisibleValue(color.b*255.0f); - } - - if ( m_persoTab == 0 ) color = m_perso.colorHair; - else color = m_perso.colorBand; - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCRb); - if ( ps != 0 ) ps->SetVisibleValue(color.r*255.0f); - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCGb); - if ( ps != 0 ) ps->SetVisibleValue(color.g*255.0f); - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCBb); - if ( ps != 0 ) ps->SetVisibleValue(color.b*255.0f); -} - -// Updates the camera for the character. - -void CMainDialog::CameraPerso() -{ - if ( m_persoTab == 0 ) - { -//? m_camera->Init(D3DVECTOR(4.0f, 0.0f, 0.0f), -//? D3DVECTOR(0.0f, 0.0f, 1.0f), 0.0f); - m_camera->Init(D3DVECTOR(6.0f, 0.0f, 0.0f), - D3DVECTOR(0.0f, 0.2f, 1.5f), 0.0f); - } - else - { - m_camera->Init(D3DVECTOR(18.0f, 0.0f, 4.5f), - D3DVECTOR(0.0f, 1.6f, 4.5f), 0.0f); - } - - m_camera->SetType(CAMERA_SCRIPT); - m_camera->FixCamera(); -} - -// Sets a fixed color. - -void CMainDialog::FixPerso(int rank, int index) -{ - if ( m_persoTab == 0 ) - { - if ( index == 1 ) - { - m_perso.colorHair.r = perso_color[3*10*0+rank*3+0]/255.0f; - m_perso.colorHair.g = perso_color[3*10*0+rank*3+1]/255.0f; - m_perso.colorHair.b = perso_color[3*10*0+rank*3+2]/255.0f; - } - } - if ( m_persoTab == 1 ) - { - if ( index == 0 ) - { - m_perso.colorCombi.r = perso_color[3*10*1+rank*3+0]/255.0f; - m_perso.colorCombi.g = perso_color[3*10*1+rank*3+1]/255.0f; - m_perso.colorCombi.b = perso_color[3*10*1+rank*3+2]/255.0f; - } - if ( index == 1 ) - { - m_perso.colorBand.r = perso_color[3*10*2+rank*3+0]/255.0f; - m_perso.colorBand.g = perso_color[3*10*2+rank*3+1]/255.0f; - m_perso.colorBand.b = perso_color[3*10*2+rank*3+2]/255.0f; - } - } -} - -// Updates the color of the character. - -void CMainDialog::ColorPerso() -{ - CWindow* pw; - CSlider* ps; - D3DCOLORVALUE color; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - - color.a = 0.0f; - - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCRa); - if ( ps != 0 ) color.r = ps->RetVisibleValue()/255.0f; - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCGa); - if ( ps != 0 ) color.g = ps->RetVisibleValue()/255.0f; - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCBa); - if ( ps != 0 ) color.b = ps->RetVisibleValue()/255.0f; - if ( m_persoTab == 1 ) m_perso.colorCombi = color; - - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCRb); - if ( ps != 0 ) color.r = ps->RetVisibleValue()/255.0f; - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCGb); - if ( ps != 0 ) color.g = ps->RetVisibleValue()/255.0f; - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCBb); - if ( ps != 0 ) color.b = ps->RetVisibleValue()/255.0f; - if ( m_persoTab == 0 ) m_perso.colorHair = color; - else m_perso.colorBand = color; -} - -// Updates the default settings of the character. - -void CMainDialog::DefPerso() -{ - m_perso.colorCombi.r = 206.0f/256.0f; - m_perso.colorCombi.g = 206.0f/256.0f; - m_perso.colorCombi.b = 204.0f/256.0f; // ~white - m_perso.colorBand.r = 255.0f/256.0f; - m_perso.colorBand.g = 132.0f/256.0f; - m_perso.colorBand.b = 1.0f/256.0f; // orange - - if ( m_perso.face == 0 ) // normal ? - { - m_perso.glasses = 0; - m_perso.colorHair.r = 90.0f/256.0f; - m_perso.colorHair.g = 95.0f/256.0f; - m_perso.colorHair.b = 85.0f/256.0f; // black - } - if ( m_perso.face == 1 ) // bald ? - { - m_perso.glasses = 0; - m_perso.colorHair.r = 83.0f/256.0f; - m_perso.colorHair.g = 64.0f/256.0f; - m_perso.colorHair.b = 51.0f/256.0f; // brown - } - if ( m_perso.face == 2 ) // carlos ? - { - m_perso.glasses = 1; - m_perso.colorHair.r = 85.0f/256.0f; - m_perso.colorHair.g = 48.0f/256.0f; - m_perso.colorHair.b = 9.0f/256.0f; // brown - } - if ( m_perso.face == 3 ) // blond ? - { - m_perso.glasses = 4; - m_perso.colorHair.r = 255.0f/256.0f; - m_perso.colorHair.g = 255.0f/256.0f; - m_perso.colorHair.b = 181.0f/256.0f; // yellow - } - - m_perso.colorHair.a = 0.0f; - m_perso.colorCombi.a = 0.0f; - m_perso.colorBand.a = 0.0f; -} - - -// Indicates if there is at least one backup. - -BOOL CMainDialog::IsIOReadScene() -{ - FILE* file; - char filename[100]; - - sprintf(filename, "%s\\%s\\save%c%.3d\\data.sav", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], 0); - file = fopen(filename, "r"); - if ( file == NULL ) return FALSE; - fclose(file); - return TRUE; -} - -// Builds the file name by default. - -void CMainDialog::IOReadName() -{ - FILE* file; - CWindow* pw; - CEdit* pe; - char filename[_MAX_FNAME]; - char op[100]; - char line[500]; - char resume[100]; - char name[100]; - time_t now; - int i; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_IONAME); - if ( pe == 0 ) return; - - sprintf(resume, "%s %d", m_sceneName, m_chap[m_index]+1); - BuildSceneName(filename, m_sceneName, (m_chap[m_index]+1)*100); - file = fopen(filename, "r"); - if ( file != NULL ) - { - while ( fgets(line, 500, file) != NULL ) - { - for ( i=0 ; i<500 ; i++ ) - { - if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space - if ( line[i] == '/' && line[i+1] == '/' ) - { - line[i] = 0; - break; - } - } - - sprintf(op, "Title.%c", RetLanguageLetter()); - if ( Cmd(line, op) ) - { - OpString(line, "resume", resume); - break; - } - } - fclose(file); - } - - time(&now); - TimeToAscii(now, line); - sprintf(name, "%s %d - %s", resume, m_sel[m_index]+1, line); - pe->SetText(name); - pe->SetCursor(strlen(name), 0); - pe->SetFocus(TRUE); -} - -// Updates the list of games recorded on disk. - -void CMainDialog::IOReadList() -{ - FILE* file = NULL; - CWindow* pw; - CList* pl; - char filename[100]; - char line[500]; - char name[100]; - int i, j; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_IOLIST); - if ( pl == 0 ) return; - - pl->Flush(); - - for ( j=0 ; j<999 ; j++ ) - { - sprintf(filename, "%s\\%s\\save%c%.3d\\data.sav", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], j); - file = fopen(filename, "r"); - if ( file == NULL ) break; - - strcmp(name, filename); // default name - while ( fgets(line, 500, file) != NULL ) - { - for ( i=0 ; i<500 ; i++ ) - { - if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space - if ( line[i] == '/' && line[i+1] == '/' ) - { - line[i] = 0; - break; - } - } - - if ( Cmd(line, "Title") ) - { - OpString(line, "text", name); - break; - } - } - fclose(file); - - pl->SetName(j, name); - } - - if ( m_phase == PHASE_WRITE || - m_phase == PHASE_WRITEs ) - { - GetResource(RES_TEXT, RT_IO_NEW, name); - pl->SetName(j, name); - j ++; - } - - pl->SetSelect(j-1); - pl->ShowSelect(FALSE); // shows the selected columns -} - -// Updates the buttons according to the selected part in the list. - -void CMainDialog::IOUpdateList() -{ - FILE* file = NULL; - CWindow* pw; - CList* pl; - CButton* pb; - CImage* pi; - char filename[100]; - int sel, max; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_IOLIST); - if ( pl == 0 ) return; - pi = (CImage*)pw->SearchControl(EVENT_INTERFACE_IOIMAGE); - if ( pi == 0 ) return; - - sel = pl->RetSelect(); - max = pl->RetTotal(); - - sprintf(filename, "%s\\%s\\save%c%.3d\\screen.bmp", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); - - if ( m_phase == PHASE_WRITE || - m_phase == PHASE_WRITEs ) - { - if ( sel < max-1 ) - { - pi->SetFilenameImage(filename); - } - else - { - pi->SetFilenameImage(""); - } - - pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_IODELETE); - if ( pb != 0 ) - { - pb->SetState(STATE_ENABLE, sel < max-1); - } - } - else - { - pi->SetFilenameImage(filename); - } -} - -// Deletes the selected scene. - -void CMainDialog::IODeleteScene() -{ - CWindow* pw; - CList* pl; - char dir[100]; - char old[100]; - long hFile; - struct _finddata_t fBuffer; - int sel, max, i; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_IOLIST); - if ( pl == 0 ) return; - - sel = pl->RetSelect(); - if ( sel == -1 ) - { - m_sound->Play(SOUND_TZOING); - return; - } - - // Deletes all the contents of the file. - sprintf(dir, "%s\\%s\\save%c%.3d\\*", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); - hFile = _findfirst(dir, &fBuffer); - if ( hFile != -1 ) - { - do - { - if ( fBuffer.name[0] != '.' ) - { - sprintf(dir, "%s\\%s\\save%c%.3d\\%s", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel, fBuffer.name); - remove(dir); - } - } - while ( _findnext(hFile, &fBuffer) == 0 ); - } - - sprintf(dir, "%s\\%s\\save%c%.3d", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); - if ( _rmdir(dir) != 0 ) - { - m_sound->Play(SOUND_TZOING); - return; - } - - max = pl->RetTotal(); - for ( i=sel+1 ; iRetGamerName(), m_sceneName[0], i); - sprintf(dir, "%s\\%s\\save%c%.3d", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], i-1); - rename(old, dir); - } - IOReadList(); -} - -// Writes the scene. - -BOOL CMainDialog::IOWriteScene() -{ - CWindow* pw; - CList* pl; - CEdit* pe; - char filename[100]; - char filecbot[100]; - char info[100]; - int sel; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return FALSE; - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_IOLIST); - if ( pl == 0 ) return FALSE; - pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_IONAME); - if ( pe == 0 ) return FALSE; - - sel = pl->RetSelect(); - if ( sel == -1 ) return FALSE; - - _mkdir("Savegame"); // if doesn't exist yet! - sprintf(filename, "%s\\%s", m_savegameDir, m_main->RetGamerName()); - _mkdir(filename); - sprintf(filename, "%s\\%s\\save%c%.3d", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); - _mkdir(filename); - - sprintf(filename, "%s\\%s\\save%c%.3d\\data.sav", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); - sprintf(filecbot, "%s\\%s\\save%c%.3d\\cbot.run", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); - pe->GetText(info, 100); - m_main->IOWriteScene(filename, filecbot, info); - - m_shotDelay = 3; - sprintf(m_shotName, "%s\\%s\\save%c%.3d\\screen.bmp", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); - - return TRUE; -} - -// Reads the scene. - -BOOL CMainDialog::IOReadScene() -{ - FILE* file; - CWindow* pw; - CList* pl; - char filename[100]; - char filecbot[100]; - char line[500]; - char dir[100]; - int sel, i; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return FALSE; - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_IOLIST); - if ( pl == 0 ) return FALSE; - - sel = pl->RetSelect(); - if ( sel == -1 ) return FALSE; - - sprintf(filename, "%s\\%s\\save%c%.3d\\data.sav", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); - sprintf(filecbot, "%s\\%s\\save%c%.3d\\cbot.run", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); - - file = fopen(filename, "r"); - if ( file == NULL ) return FALSE; - - while ( fgets(line, 500, file) != NULL ) - { - for ( i=0 ; i<500 ; i++ ) - { - if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space - if ( line[i] == '/' && line[i+1] == '/' ) - { - line[i] = 0; - break; - } - } - - if ( Cmd(line, "Mission") ) - { - OpString(line, "base", m_sceneName); - m_sceneRank = OpInt(line, "rank", 0); - - if ( strcmp(m_sceneName, "user") == 0 ) - { - m_sceneRank = m_sceneRank%100; - OpString(line, "dir", dir); - for ( i=0 ; iRetShowAll() ) return 9; - - for ( j=0 ; j<9 ; j++ ) - { - if ( !RetGamerInfoPassed((j+1)*100) ) - { - return j; - } - } - return 9; -} - -// Updates the lists according to the cheat code. - -void CMainDialog::AllMissionUpdate() -{ - if ( m_phase == PHASE_TRAINER || - m_phase == PHASE_DEFI || - m_phase == PHASE_MISSION || - m_phase == PHASE_FREE || - m_phase == PHASE_TEEN || - m_phase == PHASE_USER || - m_phase == PHASE_PROTO ) - { - UpdateSceneChap(m_chap[m_index]); - UpdateSceneList(m_chap[m_index], m_sel[m_index]); - } -} - -// Updates the chapters of exercises or missions. - -void CMainDialog::UpdateSceneChap(int &chap) -{ - FILE* file = NULL; - CWindow* pw; - CList* pl; - long hFile; - struct _finddata_t fileBuffer; - char filename[_MAX_FNAME]; - char op[100]; - char line[500]; - char name[100]; - int i, j; - BOOL bPassed, bDo; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_CHAP); - if ( pl == 0 ) return; - - pl->Flush(); - - if ( m_phase == PHASE_USER ) - { - j = 0; - hFile = _findfirst("user\\*", &fileBuffer); - if ( hFile != -1 ) - { - do - { - if ( (fileBuffer.attrib & _A_SUBDIR) != 0 && - fileBuffer.name[0] != '.' ) - { - strcpy(m_userList[j++], fileBuffer.name); - } - } - while ( _findnext(hFile, &fileBuffer) == 0 && j < 100 ); - } - m_userTotal = j; - - do // sorts all names: - { - bDo = FALSE; - for ( i=0 ; i 0 ) - { - strcpy(name, m_userList[i]); - strcpy(m_userList[i], m_userList[i+1]); - strcpy(m_userList[i+1], name); - bDo = TRUE; - } - } - } - while ( bDo ); - - for ( j=0 ; jSetName(j, name); - pl->SetEnable(j, TRUE); - } - } - else - { - for ( j=0 ; j<9 ; j++ ) - { -#if _SCHOOL - if ( m_phase == PHASE_MISSION ) break; - if ( m_phase == PHASE_FREE ) break; -#if _CEEBOTDEMO - if ( m_phase == PHASE_TRAINER && j >= 2 ) break; -#endif -#endif -#if _DEMO - if ( m_phase == PHASE_MISSION && j >= 4 ) break; - if ( m_phase == PHASE_TRAINER && j >= 1 ) break; -#endif - BuildSceneName(filename, m_sceneName, (j+1)*100); - file = fopen(filename, "r"); - if ( file == NULL ) break; - - BuildResumeName(name, m_sceneName, j+1); // default name - while ( fgets(line, 500, file) != NULL ) - { - for ( i=0 ; i<500 ; i++ ) - { - if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space - if ( line[i] == '/' && line[i+1] == '/' ) - { - line[i] = 0; - break; - } - } - - sprintf(op, "Title.%c", RetLanguageLetter()); - if ( Cmd(line, op) ) - { - OpString(line, "text", name); - break; - } - } - fclose(file); - - bPassed = RetGamerInfoPassed((j+1)*100); - sprintf(line, "%d: %s", j+1, name); - pl->SetName(j, line); - pl->SetCheck(j, bPassed); - pl->SetEnable(j, TRUE); - - if ( m_phase == PHASE_MISSION && !m_main->RetShowAll() && !bPassed ) - { - j ++; - break; - } - -#if _TEEN - if ( m_phase == PHASE_TRAINER && !m_main->RetShowAll() && !bPassed ) - { - j ++; - break; - } -#endif - - if ( m_phase == PHASE_FREE && j == m_accessChap ) - { - j ++; - break; - } - } - } - - if ( chap > j-1 ) chap = j-1; - - pl->SetSelect(chap); - pl->ShowSelect(FALSE); // shows the selected columns -} - -// Updates the list of exercises or missions. - -void CMainDialog::UpdateSceneList(int chap, int &sel) -{ - FILE* file = NULL; - CWindow* pw; - CList* pl; - char filename[_MAX_FNAME]; - char op[100]; - char line[500]; - char name[100]; - int i, j; - BOOL bPassed; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_INTERFACE_LIST); - if ( pl == 0 ) return; - - pl->Flush(); - - for ( j=0 ; j<99 ; j++ ) - { -#if _SCHOOL - if ( m_phase == PHASE_MISSION ) break; - if ( m_phase == PHASE_FREE ) break; -#if _CEEBOTDEMO -#if _TEEN - if ( m_phase == PHASE_TRAINER && j >= 5 ) break; -#else - if ( m_phase == PHASE_TRAINER && j >= 3 ) break; -#endif -#endif -#endif -#if _DEMO - if ( m_phase == PHASE_MISSION && j >= 3 ) break; - if ( m_phase == PHASE_TRAINER && j >= 5 ) break; -#endif - BuildSceneName(filename, m_sceneName, (chap+1)*100+(j+1)); - file = fopen(filename, "r"); - if ( file == NULL ) break; - - BuildResumeName(name, m_sceneName, j+1); // default name - while ( fgets(line, 500, file) != NULL ) - { - for ( i=0 ; i<500 ; i++ ) - { - if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space - if ( line[i] == '/' && line[i+1] == '/' ) - { - line[i] = 0; - break; - } - } - - sprintf(op, "Title.%c", RetLanguageLetter()); - if ( Cmd(line, op) ) - { - OpString(line, "text", name); - break; - } - } - fclose(file); - - bPassed = RetGamerInfoPassed((chap+1)*100+(j+1)); - sprintf(line, "%d: %s", j+1, name); - pl->SetName(j, line); - pl->SetCheck(j, bPassed); - pl->SetEnable(j, TRUE); - - if ( m_phase == PHASE_MISSION && !m_main->RetShowAll() && !bPassed ) - { - j ++; - break; - } - -#if _TEEN - if ( m_phase == PHASE_TRAINER && !m_main->RetShowAll() && !bPassed ) - { - j ++; - break; - } -#endif - } - - BuildSceneName(filename, m_sceneName, (chap+1)*100+(j+1)); - file = fopen(filename, "r"); - if ( file == NULL ) - { - m_maxList = j; - } - else - { - m_maxList = j+1; // this is not the last! - fclose(file); - } - - if ( sel > j-1 ) sel = j-1; - - pl->SetSelect(sel); - pl->ShowSelect(FALSE); // shows the selected columns -} - -// Updates the button "solution" according to cheat code. - -void CMainDialog::ShowSoluceUpdate() -{ - CWindow* pw; - CEdit* pe; - CCheck* pc; - - if ( m_phase == PHASE_TRAINER || - m_phase == PHASE_DEFI || - m_phase == PHASE_MISSION || - m_phase == PHASE_FREE || - m_phase == PHASE_TEEN || - m_phase == PHASE_USER || - m_phase == PHASE_PROTO ) - { - m_bSceneSoluce = FALSE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_RESUME); - if ( pe == 0 ) return; - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SOLUCE); - if ( pc == 0 ) return; - - if ( m_main->RetShowSoluce() ) - { - pc->SetState(STATE_VISIBLE); - pc->SetState(STATE_CHECK); - m_bSceneSoluce = TRUE; - } - else - { - pc->ClearState(STATE_VISIBLE); - pc->ClearState(STATE_CHECK); - m_bSceneSoluce = FALSE; - } - } -} - -// Updates a summary of exercise or mission. - -void CMainDialog::UpdateSceneResume(int rank) -{ - FILE* file = NULL; - CWindow* pw; - CEdit* pe; - CCheck* pc; - char filename[_MAX_FNAME]; - char op[100]; - char line[500]; - char name[500]; - int i, numTry; - BOOL bPassed, bVisible; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_RESUME); - if ( pe == 0 ) return; - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SOLUCE); - - if ( pc == 0 ) - { - m_bSceneSoluce = FALSE; - } - else - { - numTry = RetGamerInfoTry(rank); - bPassed = RetGamerInfoPassed(rank); - bVisible = ( numTry > 2 || bPassed || m_main->RetShowSoluce() ); - if ( !RetSoluce4() ) bVisible = FALSE; - pc->SetState(STATE_VISIBLE, bVisible); - if ( !bVisible ) - { - pc->ClearState(STATE_CHECK); - m_bSceneSoluce = FALSE; - } - } - - BuildSceneName(filename, m_sceneName, rank); - file = fopen(filename, "r"); - if ( file == NULL ) return; - - name[0] = 0; - while ( fgets(line, 500, file) != NULL ) - { - for ( i=0 ; i<500 ; i++ ) - { - if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space - if ( line[i] == '/' && line[i+1] == '/' ) - { - line[i] = 0; - break; - } - } - - sprintf(op, "Resume.%c", RetLanguageLetter()); - if ( Cmd(line, op) ) - { - OpString(line, "text", name); - break; - } - } - fclose(file); - - pe->SetText(name); -} - -// Updates the list of devices. - -void CMainDialog::UpdateDisplayDevice() -{ - CWindow* pw; - CList* pl; - char bufDevices[1000]; - char bufModes[5000]; - int i, j, totalDevices, selectDevices, totalModes, selectModes; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_LIST1); - if ( pl == 0 ) return; - pl->Flush(); - - m_engine->EnumDevices(bufDevices, 1000, - bufModes, 5000, - totalDevices, selectDevices, - totalModes, selectModes); - - i = 0; - j = 0; - while ( bufDevices[i] != 0 ) - { - pl->SetName(j++, bufDevices+i); - while ( bufDevices[i++] != 0 ); - } - - pl->SetSelect(selectDevices); - pl->ShowSelect(FALSE); - - m_setupSelDevice = selectDevices; -} - -// Updates the list of modes. - -void CMainDialog::UpdateDisplayMode() -{ - CWindow* pw; - CList* pl; - char bufDevices[1000]; - char bufModes[5000]; - int i, j, totalDevices, selectDevices, totalModes, selectModes; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_LIST2); - if ( pl == 0 ) return; - pl->Flush(); - - m_engine->EnumDevices(bufDevices, 1000, - bufModes, 5000, - totalDevices, selectDevices, - totalModes, selectModes); - - i = 0; - j = 0; - while ( bufModes[i] != 0 ) - { - pl->SetName(j++, bufModes+i); - while ( bufModes[i++] != 0 ); - } - - pl->SetSelect(selectModes); - pl->ShowSelect(FALSE); - - m_setupSelMode = selectModes; -} - -// Change the graphics mode. - -void CMainDialog::ChangeDisplay() -{ - CWindow* pw; - CList* pl; - CCheck* pc; - char* device; - char* mode; - BOOL bFull; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - - pl = (CList*)pw->SearchControl(EVENT_LIST1); - if ( pl == 0 ) return; - m_setupSelDevice = pl->RetSelect(); - device = pl->RetName(m_setupSelDevice); - - pl = (CList*)pw->SearchControl(EVENT_LIST2); - if ( pl == 0 ) return; - m_setupSelMode = pl->RetSelect(); - mode = pl->RetName(m_setupSelMode); - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_FULL); - if ( pc == 0 ) return; - bFull = pc->TestState(STATE_CHECK); - m_setupFull = bFull; - - m_engine->ChangeDevice(device, mode, bFull); - - if ( m_bSimulSetup ) - { - m_main->ChangeColor(); - m_main->UpdateMap(); - } -} - - - -// Updates the "apply" button. - -void CMainDialog::UpdateApply() -{ - CWindow* pw; - CButton* pb; - CList* pl; - CCheck* pc; - int sel1, sel2; - BOOL bFull; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - - pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_APPLY); - if ( pb == 0 ) return; - - pl = (CList*)pw->SearchControl(EVENT_LIST1); - if ( pl == 0 ) return; - sel1 = pl->RetSelect(); - - pl = (CList*)pw->SearchControl(EVENT_LIST2); - if ( pl == 0 ) return; - sel2 = pl->RetSelect(); - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_FULL); - bFull = pc->TestState(STATE_CHECK); - - if ( sel1 == m_setupSelDevice && - sel2 == m_setupSelMode && - bFull == m_setupFull ) - { - pb->ClearState(STATE_ENABLE); - } - else - { - pb->SetState(STATE_ENABLE); - } -} - -// Updates the buttons during the setup phase. - -void CMainDialog::UpdateSetupButtons() -{ - CWindow* pw; - CCheck* pc; - CEditValue* pv; - CSlider* ps; - float value; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_TOTO); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_engine->RetTotoMode()); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_TOOLTIP); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_bTooltip); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_GLINT); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_bGlint); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_RAIN); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_bRain); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_MOUSE); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_engine->RetNiceMouse()); - pc->SetState(STATE_ENABLE, m_engine->RetNiceMouseCap()); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_EDITMODE); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_engine->RetEditIndentMode()); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_EDITVALUE); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_engine->RetEditIndentValue()>2); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SOLUCE4); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_bSoluce4); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_MOVIES); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_bMovies); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_NICERST); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_bNiceReset); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_HIMSELF); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_bHimselfDamage); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SCROLL); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_bCameraScroll); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_INVERTX); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_bCameraInvertX); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_INVERTY); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_bCameraInvertY); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_EFFECT); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_bEffect); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SHADOW); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_engine->RetShadow()); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_GROUND); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_engine->RetGroundSpot()); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_DIRTY); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_engine->RetDirty()); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_FOG); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_engine->RetFog()); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_LENS); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_engine->RetLensMode()); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SKY); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_engine->RetSkyMode()); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_PLANET); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_engine->RetPlanetMode()); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_LIGHT); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_engine->RetLightMode()); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_JOYSTICK); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_engine->RetJoystick()); - } - - pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_PARTI); - if ( pv != 0 ) - { - value = m_engine->RetParticuleDensity(); - pv->SetValue(value); - } - - pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_CLIP); - if ( pv != 0 ) - { - value = m_engine->RetClippingDistance(); - pv->SetValue(value); - } - - pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_DETAIL); - if ( pv != 0 ) - { - value = m_engine->RetObjectDetail(); - pv->SetValue(value); - } - - pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_GADGET); - if ( pv != 0 ) - { - value = m_engine->RetGadgetQuantity(); - pv->SetValue(value); - } - - pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_TEXTURE); - if ( pv != 0 ) - { - value = (float)m_engine->RetTextureQuality(); - pv->SetValue(value); - } - - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_VOLSOUND); - if ( ps != 0 ) - { - value = (float)m_sound->RetAudioVolume(); - ps->SetVisibleValue(value); - } - - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_VOLMUSIC); - if ( ps != 0 ) - { - value = (float)m_sound->RetMidiVolume(); - ps->SetVisibleValue(value); - } - - pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SOUND3D); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_sound->RetSound3D()); - pc->SetState(STATE_ENABLE, m_sound->RetSound3DCap()); - } -} - -// Updates the engine function of the buttons after the setup phase. - -void CMainDialog::ChangeSetupButtons() -{ - CWindow* pw; - CEditValue* pv; - CSlider* ps; - float value; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - - pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_PARTI); - if ( pv != 0 ) - { - value = pv->RetValue(); - m_engine->SetParticuleDensity(value); - } - - pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_CLIP); - if ( pv != 0 ) - { - value = pv->RetValue(); - m_engine->SetClippingDistance(value); - } - - pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_DETAIL); - if ( pv != 0 ) - { - value = pv->RetValue(); - m_engine->SetObjectDetail(value); - } - - pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_GADGET); - if ( pv != 0 ) - { - value = pv->RetValue(); - m_engine->SetGadgetQuantity(value); - } - - pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_TEXTURE); - if ( pv != 0 ) - { - value = pv->RetValue(); - m_engine->SetTextureQuality((int)value); - } - - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_VOLSOUND); - if ( ps != 0 ) - { - value = ps->RetVisibleValue(); - m_sound->SetAudioVolume((int)value); - } - - ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_VOLMUSIC); - if ( ps != 0 ) - { - value = ps->RetVisibleValue(); - m_sound->SetMidiVolume((int)value); - } -} - - -// Memorizes all the settings. - -void CMainDialog::SetupMemorize() -{ - float fValue; - int iValue, i, j; - char key[500]; - char num[10]; - - SetProfileString("Directory", "scene", m_sceneDir); - SetProfileString("Directory", "savegame", m_savegameDir); - SetProfileString("Directory", "public", m_publicDir); - SetProfileString("Directory", "user", m_userDir); - SetProfileString("Directory", "files", m_filesDir); - - iValue = m_engine->RetTotoMode(); - SetProfileInt("Setup", "TotoMode", iValue); - - iValue = m_bTooltip; - SetProfileInt("Setup", "Tooltips", iValue); - - iValue = m_bGlint; - SetProfileInt("Setup", "InterfaceGlint", iValue); - - iValue = m_bRain; - SetProfileInt("Setup", "InterfaceGlint", iValue); - - iValue = m_engine->RetNiceMouse(); - SetProfileInt("Setup", "NiceMouse", iValue); - - iValue = m_bSoluce4; - SetProfileInt("Setup", "Soluce4", iValue); - - iValue = m_bMovies; - SetProfileInt("Setup", "Movies", iValue); - - iValue = m_bNiceReset; - SetProfileInt("Setup", "NiceReset", iValue); - - iValue = m_bHimselfDamage; - SetProfileInt("Setup", "HimselfDamage", iValue); - - iValue = m_bCameraScroll; - SetProfileInt("Setup", "CameraScroll", iValue); - - iValue = m_bCameraInvertX; - SetProfileInt("Setup", "CameraInvertX", iValue); - - iValue = m_bEffect; - SetProfileInt("Setup", "InterfaceEffect", iValue); - - iValue = m_engine->RetShadow(); - SetProfileInt("Setup", "GroundShadow", iValue); - - iValue = m_engine->RetGroundSpot(); - SetProfileInt("Setup", "GroundSpot", iValue); - - iValue = m_engine->RetDirty(); - SetProfileInt("Setup", "ObjectDirty", iValue); - - iValue = m_engine->RetFog(); - SetProfileInt("Setup", "FogMode", iValue); - - iValue = m_engine->RetLensMode(); - SetProfileInt("Setup", "LensMode", iValue); - - iValue = m_engine->RetSkyMode(); - SetProfileInt("Setup", "SkyMode", iValue); - - iValue = m_engine->RetPlanetMode(); - SetProfileInt("Setup", "PlanetMode", iValue); - - iValue = m_engine->RetLightMode(); - SetProfileInt("Setup", "LightMode", iValue); - - iValue = m_engine->RetJoystick(); - SetProfileInt("Setup", "UseJoystick", iValue); - - fValue = m_engine->RetParticuleDensity(); - SetProfileFloat("Setup", "ParticuleDensity", fValue); - - fValue = m_engine->RetClippingDistance(); - SetProfileFloat("Setup", "ClippingDistance", fValue); - - fValue = m_engine->RetObjectDetail(); - SetProfileFloat("Setup", "ObjectDetail", fValue); - - fValue = m_engine->RetGadgetQuantity(); - SetProfileFloat("Setup", "GadgetQuantity", fValue); - - iValue = m_engine->RetTextureQuality(); - SetProfileInt("Setup", "TextureQuality", iValue); - - iValue = m_sound->RetAudioVolume(); - SetProfileInt("Setup", "AudioVolume", iValue); - - iValue = m_sound->RetMidiVolume(); - SetProfileInt("Setup", "MidiVolume", iValue); - - iValue = m_sound->RetSound3D(); - SetProfileInt("Setup", "Sound3D", iValue); - - iValue = m_engine->RetEditIndentMode(); - SetProfileInt("Setup", "EditIndentMode", iValue); - - iValue = m_engine->RetEditIndentValue(); - SetProfileInt("Setup", "EditIndentValue", iValue); - - key[0] = 0; - for ( i=0 ; i<100 ; i++ ) - { - if ( m_engine->RetKey(i, 0) == 0 ) break; - - for ( j=0 ; j<2 ; j++ ) - { - iValue = m_engine->RetKey(i, j); - sprintf(num, "%d%c", iValue, j==0?'+':' '); - strcat(key, num); - } - } - SetProfileString("Setup", "KeyMap", key); - -#if _NET - if ( m_accessEnable ) - { - iValue = m_accessMission; - SetProfileInt("Setup", "AccessMission", iValue); - - iValue = m_accessUser; - SetProfileInt("Setup", "AccessUser", iValue); - } -#endif - - iValue = m_bDeleteGamer; - SetProfileInt("Setup", "DeleteGamer", iValue); - - m_engine->WriteProfile(); -} - -// Remember all the settings. - -void CMainDialog::SetupRecall() -{ - float fValue; - int iValue, i, j; - char key[500]; - char* p; - - if ( GetProfileString("Directory", "scene", key, _MAX_FNAME) ) - { - strcpy(m_sceneDir, key); - } - - if ( GetProfileString("Directory", "savegame", key, _MAX_FNAME) ) - { - strcpy(m_savegameDir, key); - } - - if ( GetProfileString("Directory", "public", key, _MAX_FNAME) ) - { - strcpy(m_publicDir, key); - } - - if ( GetProfileString("Directory", "user", key, _MAX_FNAME) ) - { - strcpy(m_userDir, key); - } - - if ( GetProfileString("Directory", "files", key, _MAX_FNAME) ) - { - strcpy(m_filesDir, key); - } - - - if ( GetProfileInt("Setup", "TotoMode", iValue) ) - { - m_engine->SetTotoMode(iValue); - } - - if ( GetProfileInt("Setup", "Tooltips", iValue) ) - { - m_bTooltip = iValue; - } - - if ( GetProfileInt("Setup", "InterfaceGlint", iValue) ) - { - m_bGlint = iValue; - } - - if ( GetProfileInt("Setup", "InterfaceGlint", iValue) ) - { - m_bRain = iValue; - } - - if ( GetProfileInt("Setup", "NiceMouse", iValue) ) - { - m_engine->SetNiceMouse(iValue); - } - - if ( GetProfileInt("Setup", "Soluce4", iValue) ) - { - m_bSoluce4 = iValue; - } - - if ( GetProfileInt("Setup", "Movies", iValue) ) - { - m_bMovies = iValue; - } - - if ( GetProfileInt("Setup", "NiceReset", iValue) ) - { - m_bNiceReset = iValue; - } - - if ( GetProfileInt("Setup", "HimselfDamage", iValue) ) - { - m_bHimselfDamage = iValue; - } - - if ( GetProfileInt("Setup", "CameraScroll", iValue) ) - { - m_bCameraScroll = iValue; - m_camera->SetCameraScroll(m_bCameraScroll); - } - - if ( GetProfileInt("Setup", "CameraInvertX", iValue) ) - { - m_bCameraInvertX = iValue; - m_camera->SetCameraInvertX(m_bCameraInvertX); - } - - if ( GetProfileInt("Setup", "CameraInvertY", iValue) ) - { - m_bCameraInvertY = iValue; - m_camera->SetCameraInvertY(m_bCameraInvertY); - } - - if ( GetProfileInt("Setup", "InterfaceEffect", iValue) ) - { - m_bEffect = iValue; - } - - if ( GetProfileInt("Setup", "GroundShadow", iValue) ) - { - m_engine->SetShadow(iValue); - } - - if ( GetProfileInt("Setup", "GroundSpot", iValue) ) - { - m_engine->SetGroundSpot(iValue); - } - - if ( GetProfileInt("Setup", "ObjectDirty", iValue) ) - { - m_engine->SetDirty(iValue); - } - - if ( GetProfileInt("Setup", "FogMode", iValue) ) - { - m_engine->SetFog(iValue); - m_camera->SetOverBaseColor(RetColor(RetColor(0.0f))); - } - - if ( GetProfileInt("Setup", "LensMode", iValue) ) - { - m_engine->SetLensMode(iValue); - } - - if ( GetProfileInt("Setup", "SkyMode", iValue) ) - { - m_engine->SetSkyMode(iValue); - } - - if ( GetProfileInt("Setup", "PlanetMode", iValue) ) - { - m_engine->SetPlanetMode(iValue); - } - - if ( GetProfileInt("Setup", "LightMode", iValue) ) - { - m_engine->SetLightMode(iValue); - } - - if ( GetProfileInt("Setup", "UseJoystick", iValue) ) - { - m_engine->SetJoystick(iValue); - } - - if ( GetProfileFloat("Setup", "ParticuleDensity", fValue) ) - { - m_engine->SetParticuleDensity(fValue); - } - - if ( GetProfileFloat("Setup", "ClippingDistance", fValue) ) - { - m_engine->SetClippingDistance(fValue); - } - - if ( GetProfileFloat("Setup", "ObjectDetail", fValue) ) - { - m_engine->SetObjectDetail(fValue); - } - - if ( GetProfileFloat("Setup", "GadgetQuantity", fValue) ) - { - m_engine->SetGadgetQuantity(fValue); - } - - if ( GetProfileInt("Setup", "TextureQuality", iValue) ) - { - m_engine->SetTextureQuality(iValue); - } - - if ( GetProfileInt("Setup", "AudioVolume", iValue) ) - { - m_sound->SetAudioVolume(iValue); - } - - if ( GetProfileInt("Setup", "MidiVolume", iValue) ) - { - m_sound->SetMidiVolume(iValue); - } - - if ( GetProfileInt("Setup", "EditIndentMode", iValue) ) - { - m_engine->SetEditIndentMode(iValue); - } - - if ( GetProfileInt("Setup", "EditIndentValue", iValue) ) - { - m_engine->SetEditIndentValue(iValue); - } - - if ( GetProfileString("Setup", "KeyMap", key, 500) ) - { - p = key; - for ( i=0 ; i<100 ; i++ ) - { - if ( p[0] == 0 ) break; - - for ( j=0 ; j<2 ; j++ ) - { - sscanf(p, "%d", &iValue); - m_engine->SetKey(i, j, iValue); - while ( *p >= '0' && *p <= '9' ) p++; - while ( *p == ' ' || *p == '+' ) p++; - } - } - } - -#if _NET - if ( m_accessEnable ) - { - if ( GetProfileInt("Setup", "AccessMission", iValue) ) - { - m_accessMission = iValue; - } - - if ( GetProfileInt("Setup", "AccessUser", iValue) ) - { - m_accessUser = iValue; - } - } -#endif - - if ( GetProfileInt("Setup", "DeleteGamer", iValue) ) - { - m_bDeleteGamer = iValue; - } -} - - -// Changes the general level of quality. - -void CMainDialog::ChangeSetupQuality(int quality) -{ - BOOL bEnable; - float value; - int iValue; - - bEnable = (quality >= 0); - m_engine->SetShadow(bEnable); - m_engine->SetGroundSpot(bEnable); - m_engine->SetDirty(bEnable); - m_engine->SetFog(bEnable); - m_engine->SetLensMode(bEnable); - m_engine->SetSkyMode(bEnable); - m_engine->SetPlanetMode(bEnable); - m_engine->SetLightMode(bEnable); - m_camera->SetOverBaseColor(RetColor(RetColor(0.0f))); - - if ( quality < 0 ) value = 0.0f; - if ( quality == 0 ) value = 1.0f; - if ( quality > 0 ) value = 2.0f; - m_engine->SetParticuleDensity(value); - - if ( quality < 0 ) value = 0.5f; - if ( quality == 0 ) value = 1.0f; - if ( quality > 0 ) value = 2.0f; - m_engine->SetClippingDistance(value); - - if ( quality < 0 ) value = 0.0f; - if ( quality == 0 ) value = 1.0f; - if ( quality > 0 ) value = 2.0f; - m_engine->SetObjectDetail(value); - - if ( quality < 0 ) value = 0.5f; - if ( quality == 0 ) value = 1.0f; - if ( quality > 0 ) value = 1.0f; - m_engine->SetGadgetQuantity(value); - - if ( quality < 0 ) iValue = 0; - if ( quality == 0 ) iValue = 1; - if ( quality > 0 ) iValue = 2; - m_engine->SetTextureQuality(iValue); - - m_engine->FirstExecuteAdapt(FALSE); -} - - -// Redefinable keys: - -static int key_table[KEY_TOTAL] = -{ -#if _SCHOOL & _TEEN - KEYRANK_LEFT, - KEYRANK_RIGHT, - KEYRANK_UP, - KEYRANK_DOWN, - KEYRANK_CAMERA, - KEYRANK_NEAR, - KEYRANK_AWAY, - KEYRANK_HELP, - KEYRANK_PROG, - KEYRANK_SPEED10, - KEYRANK_SPEED15, - KEYRANK_SPEED20, - KEYRANK_QUIT, -#else - KEYRANK_LEFT, - KEYRANK_RIGHT, - KEYRANK_UP, - KEYRANK_DOWN, - KEYRANK_GUP, - KEYRANK_GDOWN, - KEYRANK_ACTION, - KEYRANK_CAMERA, - KEYRANK_VISIT, - KEYRANK_NEXT, - KEYRANK_HUMAN, - KEYRANK_DESEL, - KEYRANK_NEAR, - KEYRANK_AWAY, - KEYRANK_HELP, - KEYRANK_PROG, - KEYRANK_CBOT, - KEYRANK_SPEED10, - KEYRANK_SPEED15, - KEYRANK_SPEED20, - KEYRANK_QUIT, -#endif -}; - -static EventMsg key_event[KEY_TOTAL] = -{ -#if _SCHOOL & _TEEN - EVENT_INTERFACE_KLEFT, - EVENT_INTERFACE_KRIGHT, - EVENT_INTERFACE_KUP, - EVENT_INTERFACE_KDOWN, - EVENT_INTERFACE_KCAMERA, - EVENT_INTERFACE_KNEAR, - EVENT_INTERFACE_KAWAY, - EVENT_INTERFACE_KHELP, - EVENT_INTERFACE_KPROG, - EVENT_INTERFACE_KSPEED10, - EVENT_INTERFACE_KSPEED15, - EVENT_INTERFACE_KSPEED20, - EVENT_INTERFACE_KQUIT, -#else - EVENT_INTERFACE_KLEFT, - EVENT_INTERFACE_KRIGHT, - EVENT_INTERFACE_KUP, - EVENT_INTERFACE_KDOWN, - EVENT_INTERFACE_KGUP, - EVENT_INTERFACE_KGDOWN, - EVENT_INTERFACE_KACTION, - EVENT_INTERFACE_KCAMERA, - EVENT_INTERFACE_KVISIT, - EVENT_INTERFACE_KNEXT, - EVENT_INTERFACE_KHUMAN, - EVENT_INTERFACE_KDESEL, - EVENT_INTERFACE_KNEAR, - EVENT_INTERFACE_KAWAY, - EVENT_INTERFACE_KHELP, - EVENT_INTERFACE_KPROG, - EVENT_INTERFACE_KCBOT, - EVENT_INTERFACE_KSPEED10, - EVENT_INTERFACE_KSPEED15, - EVENT_INTERFACE_KSPEED20, - EVENT_INTERFACE_KQUIT, -#endif -}; - -// Updates the list of keys. - -void CMainDialog::UpdateKey() -{ - CWindow* pw; - CScroll* ps; - CKey* pk; - FPOINT pos, dim; - int first, i; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - - ps = (CScroll*)pw->SearchControl(EVENT_INTERFACE_KSCROLL); - if ( ps == 0 ) return; - - first = (int)(ps->RetVisibleValue()*(KEY_TOTAL-KEY_VISIBLE)); - - for ( i=0 ; iDeleteControl(key_event[i]); - } - - dim.x = 400.0f/640.0f; - dim.y = 20.0f/480.0f; - pos.x = 110.0f/640.0f; - pos.y = 168.0f/480.0f + dim.y*(KEY_VISIBLE-1); - for ( i=0 ; iCreateKey(pos, dim, -1, key_event[first+i]); - pk = (CKey*)pw->SearchControl(key_event[first+i]); - if ( pk == 0 ) break; - pk->SetKey(0, m_engine->RetKey(key_table[first+i], 0)); - pk->SetKey(1, m_engine->RetKey(key_table[first+i], 1)); - pos.y -= dim.y; - } -} - -// Change a key. - -void CMainDialog::ChangeKey(EventMsg event) -{ - CWindow* pw; - CScroll* ps; - CKey* pk; - int i; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw == 0 ) return; - - ps = (CScroll*)pw->SearchControl(EVENT_INTERFACE_KSCROLL); - if ( ps == 0 ) return; - - for ( i=0 ; iSearchControl(key_event[i]); - if ( pk == 0 ) break; - m_engine->SetKey(key_table[i], 0, pk->RetKey(0)); - m_engine->SetKey(key_table[i], 1, pk->RetKey(1)); - } - } -} - - - -// Do you want to quit the current mission? - -void CMainDialog::StartAbort() -{ - CWindow* pw; - CButton* pb; - FPOINT pos, dim; - char name[100]; - - StartDialog(FPOINT(0.3f, 0.8f), TRUE, FALSE, FALSE); - m_bDialogDelete = FALSE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); - if ( pw == 0 ) return; - - pos.x = 0.35f; - pos.y = 0.60f; - dim.x = 0.30f; - dim.y = 0.30f; - pw->CreateGroup(pos, dim, 5, EVENT_INTERFACE_GLINTl); // orange corner - pos.x = 0.35f; - pos.y = 0.10f; - dim.x = 0.30f; - dim.y = 0.30f; - pw->CreateGroup(pos, dim, 4, EVENT_INTERFACE_GLINTr); // blue corner - - pos.x = 0.40f; - dim.x = 0.20f; -#if _POLISH - pos.x -= 7.0f/640.0f; - dim.x += 14.0f/640.0f; -#endif - dim.y = 32.0f/480.0f; - - pos.y = 0.74f; - pb = pw->CreateButton(pos, dim, -1, EVENT_DIALOG_CANCEL); - pb->SetState(STATE_SHADOW); - GetResource(RES_TEXT, RT_DIALOG_NO, name); - pb->SetName(name); - - if ( m_index == 2 || // missions ? - m_index == 3 || // free games? - m_index == 4 ) // user ? - { - pos.y = 0.62f; - pb = pw->CreateButton(pos, dim, -1, EVENT_INTERFACE_WRITE); - pb->SetState(STATE_SHADOW); - if ( m_main->IsBusy() ) // current task? - { - pb->ClearState(STATE_ENABLE); - } - - pos.y = 0.53f; - pb = pw->CreateButton(pos, dim, -1, EVENT_INTERFACE_READ); - pb->SetState(STATE_SHADOW); - if ( !IsIOReadScene() ) // no file to read? - { - pb->ClearState(STATE_ENABLE); - } - pb->SetState(STATE_WARNING); - } - - if ( m_engine->RetSetupMode() ) - { - pos.y = 0.39f; - pb = pw->CreateButton(pos, dim, -1, EVENT_INTERFACE_SETUP); - pb->SetState(STATE_SHADOW); - } - - pos.y = 0.25f; - pb = pw->CreateButton(pos, dim, -1, EVENT_INTERFACE_AGAIN); - pb->SetState(STATE_SHADOW); - pb->SetState(STATE_WARNING); - - pos.y = 0.16f; - pb = pw->CreateButton(pos, dim, -1, EVENT_DIALOG_OK); - pb->SetState(STATE_SHADOW); - pb->SetState(STATE_WARNING); - GetResource(RES_TEXT, RT_DIALOG_YES, name); - pb->SetName(name); -} - -// Do you want to destroy the building? - -void CMainDialog::StartDeleteObject() -{ - CWindow* pw; - CButton* pb; - FPOINT pos, dim; - char name[100]; - - StartDialog(FPOINT(0.7f, 0.3f), FALSE, TRUE, TRUE); - m_bDialogDelete = TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); - if ( pw == 0 ) return; - - pos.x = 0.00f; - pos.y = 0.50f; - dim.x = 1.00f; - dim.y = 0.05f; - GetResource(RES_TEXT, RT_DIALOG_DELOBJ, name); - pw->CreateLabel(pos, dim, -1, EVENT_DIALOG_LABEL, name); - - pb = (CButton*)pw->SearchControl(EVENT_DIALOG_OK); - if ( pb == 0 ) return; - GetResource(RES_TEXT, RT_DIALOG_YESDEL, name); - pb->SetName(name); - pb->SetState(STATE_WARNING); - - pb = (CButton*)pw->SearchControl(EVENT_DIALOG_CANCEL); - if ( pb == 0 ) return; - GetResource(RES_TEXT, RT_DIALOG_NODEL, name); - pb->SetName(name); -} - -// Do you want to delete the player? - -void CMainDialog::StartDeleteGame(char *gamer) -{ - CWindow* pw; - CButton* pb; - FPOINT pos, dim; - char name[100]; - char text[100]; - - StartDialog(FPOINT(0.7f, 0.3f), FALSE, TRUE, TRUE); - m_bDialogDelete = TRUE; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); - if ( pw == 0 ) return; - - pos.x = 0.00f; - pos.y = 0.50f; - dim.x = 1.00f; - dim.y = 0.05f; - GetResource(RES_TEXT, RT_DIALOG_DELGAME, name); - sprintf(text, name, gamer); - pw->CreateLabel(pos, dim, -1, EVENT_DIALOG_LABEL, text); - - pb = (CButton*)pw->SearchControl(EVENT_DIALOG_OK); - if ( pb == 0 ) return; - GetResource(RES_TEXT, RT_DIALOG_YESDEL, name); - pb->SetName(name); - pb->SetState(STATE_WARNING); - - pb = (CButton*)pw->SearchControl(EVENT_DIALOG_CANCEL); - if ( pb == 0 ) return; - GetResource(RES_TEXT, RT_DIALOG_NODEL, name); - pb->SetName(name); -} - -// Would you quit the game? - -void CMainDialog::StartQuit() -{ - CWindow* pw; - CButton* pb; - FPOINT pos, dim; - char name[100]; - - StartDialog(FPOINT(0.6f, 0.3f), FALSE, TRUE, TRUE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); - if ( pw == 0 ) return; - - pos.x = 0.00f; - pos.y = 0.50f; - dim.x = 1.00f; - dim.y = 0.05f; - GetResource(RES_TEXT, RT_DIALOG_QUIT, name); - pw->CreateLabel(pos, dim, -1, EVENT_DIALOG_LABEL, name); - - pb = (CButton*)pw->SearchControl(EVENT_DIALOG_OK); - if ( pb == 0 ) return; - GetResource(RES_TEXT, RT_DIALOG_YESQUIT, name); - pb->SetName(name); - pb->SetState(STATE_WARNING); - - pb = (CButton*)pw->SearchControl(EVENT_DIALOG_CANCEL); - if ( pb == 0 ) return; - GetResource(RES_TEXT, RT_DIALOG_NOQUIT, name); - pb->SetName(name); -} - -// Beginning of displaying a dialog. - -void CMainDialog::StartDialog(FPOINT dim, BOOL bFire, BOOL bOK, BOOL bCancel) -{ - CWindow* pw; - CButton* pb; - FPOINT pos, ddim; - char name[100]; - - StartSuspend(); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW6); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW7); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW8); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); - if ( pb != 0 ) - { - pb->ClearState(STATE_VISIBLE); - } - - m_bDialogFire = bFire; - - pos.x = (1.0f-dim.x)/2.0f; - pos.y = (1.0f-dim.y)/2.0f; - pw = m_interface->CreateWindows(pos, dim, bFire?12:8, EVENT_WINDOW9); - pw->SetState(STATE_SHADOW); - GetResource(RES_TEXT, RT_TITLE_BASE, name); - pw->SetName(name); - - m_dialogPos = pos; - m_dialogDim = dim; - m_dialogTime = 0.0f; - m_dialogParti = 999.0f; - - if ( bOK ) - { - pos.x = 0.50f-0.15f-0.02f; - pos.y = 0.50f-dim.y/2.0f+0.03f; - ddim.x = 0.15f; - ddim.y = 0.06f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_DIALOG_OK); - pb->SetState(STATE_SHADOW); - GetResource(RES_EVENT, EVENT_DIALOG_OK, name); - pb->SetName(name); - } - - if ( bCancel ) - { - pos.x = 0.50f+0.02f; - pos.y = 0.50f-dim.y/2.0f+0.03f; - ddim.x = 0.15f; - ddim.y = 0.06f; - pb = pw->CreateButton(pos, ddim, -1, EVENT_DIALOG_CANCEL); - pb->SetState(STATE_SHADOW); - GetResource(RES_EVENT, EVENT_DIALOG_CANCEL, name); - pb->SetName(name); - } - - m_sound->Play(SOUND_TZOING); - m_bDialog = TRUE; -} - -// Animation of a dialog. - -void CMainDialog::FrameDialog(float rTime) -{ - CWindow* pw; - D3DVECTOR pos, speed; - FPOINT dim, dpos, ddim; - float zoom; - int i; - - dpos = m_dialogPos; - ddim = m_dialogDim; - - m_dialogTime += rTime; - if ( m_dialogTime < 1.0f ) - { - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); - if ( pw != 0 ) - { - if ( m_dialogTime < 0.50f ) - { - zoom = Bounce(m_dialogTime/0.50f); - } - else - { - zoom = 1.0f; - } - - dpos.x += ddim.x/2.0f; - dpos.y += ddim.y/2.0f; - - ddim.x *= zoom; -//? ddim.y *= zoom; - - dpos.x -= ddim.x/2.0f; - dpos.y -= ddim.y/2.0f; - - pw->SetPos(dpos); - pw->SetDim(ddim); - } - } - - if ( !m_bGlint ) return; - - m_dialogParti += rTime; - if ( m_dialogParti < m_engine->ParticuleAdapt(0.05f) ) return; - m_dialogParti = 0.0f; - - if ( !m_bDialogFire ) return; - - dpos = m_dialogPos; - ddim = m_dialogDim; - - pos.z = 0.0f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - - for ( i=0 ; i<2 ; i++ ) - { - // Bottom. - pos.x = dpos.x + ddim.x*Rand(); - pos.y = dpos.y; - pos.x += (Rand()-0.5f)*(6.0f/640.0f); - pos.y += Rand()*(16.0f/480.0f)-(10.0f/480.0f); - dim.x = 0.01f+Rand()*0.01f; - dim.y = dim.x/0.75f; - m_particule->CreateParticule(pos, speed, dim, - (ParticuleType)(PARTILENS1+rand()%3), - 1.0f, 0.0f, 0.0f, SH_INTERFACE); - - // Top. - pos.x = dpos.x + ddim.x*Rand(); - pos.y = dpos.y + ddim.y; - pos.x += (Rand()-0.5f)*(6.0f/640.0f); - pos.y -= Rand()*(16.0f/480.0f)-(10.0f/480.0f); - dim.x = 0.01f+Rand()*0.01f; - dim.y = dim.x/0.75f; - m_particule->CreateParticule(pos, speed, dim, - (ParticuleType)(PARTILENS1+rand()%3), - 1.0f, 0.0f, 0.0f, SH_INTERFACE); - - // Left. - pos.y = dpos.y + ddim.y*Rand(); - pos.x = dpos.x; - pos.x += Rand()*(16.0f/640.0f)-(10.0f/640.0f); - pos.y += (Rand()-0.5f)*(6.0f/480.0f); - dim.x = 0.01f+Rand()*0.01f; - dim.y = dim.x/0.75f; - m_particule->CreateParticule(pos, speed, dim, - (ParticuleType)(PARTILENS1+rand()%3), - 1.0f, 0.0f, 0.0f, SH_INTERFACE); - - // Right. - pos.y = dpos.y + ddim.y*Rand(); - pos.x = dpos.x + ddim.x; - pos.x -= Rand()*(16.0f/640.0f)-(10.0f/640.0f); - pos.y += (Rand()-0.5f)*(6.0f/480.0f); - dim.x = 0.01f+Rand()*0.01f; - dim.y = dim.x/0.75f; - m_particule->CreateParticule(pos, speed, dim, - (ParticuleType)(PARTILENS1+rand()%3), - 1.0f, 0.0f, 0.0f, SH_INTERFACE); - } -} - -// End of the display of a dialogue. - -void CMainDialog::StopDialog() -{ - CWindow* pw; - CButton* pb; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW6); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW7); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW8); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); - if ( pb != 0 ) - { - pb->SetState(STATE_VISIBLE); - } - - StopSuspend(); - m_interface->DeleteControl(EVENT_WINDOW9); - m_bDialog = FALSE; -} - -// Suspends the simulation for a dialog phase. - -void CMainDialog::StartSuspend() -{ - m_sound->MuteAll(TRUE); - m_main->ClearInterface(); - m_bInitPause = m_engine->RetPause(); - m_engine->SetPause(TRUE); - m_engine->SetOverFront(FALSE); // over flat behind - m_main->CreateShortcuts(); - m_main->StartSuspend(); - m_initCamera = m_camera->RetType(); - m_camera->SetType(CAMERA_DIALOG); -} - -// Resume the simulation after a period of dialog. - -void CMainDialog::StopSuspend() -{ - m_sound->MuteAll(FALSE); - m_main->ClearInterface(); - if ( !m_bInitPause ) m_engine->SetPause(FALSE); - m_engine->SetOverFront(TRUE); // over flat front - m_main->CreateShortcuts(); - m_main->StopSuspend(); - m_camera->SetType(m_initCamera); -} - - -// Whether to use tooltips. - -BOOL CMainDialog::RetTooltip() -{ - return m_bTooltip; -} - -// Specifies whether a dialog is displayed. - -BOOL CMainDialog::IsDialog() -{ - return m_bDialog; -} - - - - -// Specifies the name of the scene to read. - -void CMainDialog::SetSceneRead(char* name) -{ - strcpy(m_sceneRead, name); -} - -// Returns the name of the scene to read. - -char* CMainDialog::RetSceneRead() -{ - return m_sceneRead; -} - -// Specifies the name of the scene to read. - -void CMainDialog::SetStackRead(char* name) -{ - strcpy(m_stackRead, name); -} - -// Returns the name of the scene to read. - -char* CMainDialog::RetStackRead() -{ - return m_stackRead; -} - -// Specifies the name of the chosen to play scene. - -void CMainDialog::SetSceneName(char* name) -{ - strcpy(m_sceneName, name); -} - -// Returns the name of the chosen to play scene. - -char* CMainDialog::RetSceneName() -{ - return m_sceneName; -} - -// Specifies the rank of the chosen to play scene. - -void CMainDialog::SetSceneRank(int rank) -{ - m_sceneRank = rank; -} - -// Returns the rank of the chosen to play scene. - -int CMainDialog::RetSceneRank() -{ - return m_sceneRank; -} - -// Returns folder name of the scene that user selected to play. - -char* CMainDialog::RetSceneDir() -{ - int i; - - i = (m_sceneRank/100)-1; - - if ( i < 0 || i >= m_userTotal ) return 0; - return m_userList[i]; -} - -// Whether to show the solution. - -BOOL CMainDialog::RetSceneSoluce() -{ - return m_bSceneSoluce; -} - -// Returns the name of the folder to save. - -char* CMainDialog::RetSavegameDir() -{ - return m_savegameDir; -} - -// Returns the name of public folder. - -char* CMainDialog::RetPublicDir() -{ - return m_publicDir; -} - - -// Indicates if there are reflections on the buttons. - -BOOL CMainDialog::RetGlint() -{ - return m_bGlint; -} - -// Whether to show 4:solutions. - -BOOL CMainDialog::RetSoluce4() -{ - return m_bSoluce4; -} - -// Whether to show the cinematics. - -BOOL CMainDialog::RetMovies() -{ - return m_bMovies; -} - -// IWhether to make an animation in CTaskReset. - -BOOL CMainDialog::RetNiceReset() -{ - return m_bNiceReset; -} - -// Indicates whether the fire causes damage to its own units. - -BOOL CMainDialog::RetHimselfDamage() -{ - return m_bHimselfDamage; -} - - - -// Saves the personalized player. - -void CMainDialog::WriteGamerPerso(char *gamer) -{ - FILE* file; - char filename[100]; - char line[100]; - - sprintf(filename, "%s\\%s\\face.gam", m_savegameDir, gamer); - file = fopen(filename, "w"); - if ( file == NULL ) return; - - sprintf(line, "Head face=%d glasses=%d hair=%.2f;%.2f;%.2f;%.2f\n", - m_perso.face, m_perso.glasses, - m_perso.colorHair.r, m_perso.colorHair.g, m_perso.colorHair.b, m_perso.colorHair.a); - fputs(line, file); - - sprintf(line, "Body combi=%.2f;%.2f;%.2f;%.2f band=%.2f;%.2f;%.2f;%.2f\n", - m_perso.colorCombi.r, m_perso.colorCombi.g, m_perso.colorCombi.b, m_perso.colorCombi.a, - m_perso.colorBand.r, m_perso.colorBand.g, m_perso.colorBand.b, m_perso.colorBand.a); - fputs(line, file); - - fclose(file); -} - -// Reads the personalized player. - -void CMainDialog::ReadGamerPerso(char *gamer) -{ - FILE* file; - char filename[100]; - char line[100]; - D3DCOLORVALUE color; - - m_perso.face = 0; - DefPerso(); - - sprintf(filename, "%s\\%s\\face.gam", m_savegameDir, gamer); - file = fopen(filename, "r"); - if ( file == NULL ) return; - - while ( fgets(line, 100, file) != NULL ) - { - if ( Cmd(line, "Head") ) - { - m_perso.face = OpInt(line, "face", 0); - m_perso.glasses = OpInt(line, "glasses", 0); - - color.r = 0.0f; - color.g = 0.0f; - color.b = 0.0f; - color.a = 0.0f; - m_perso.colorHair = OpColorValue(line, "hair", color); - } - - if ( Cmd(line, "Body") ) - { - color.r = 0.0f; - color.g = 0.0f; - color.b = 0.0f; - color.a = 0.0f; - m_perso.colorCombi = OpColorValue(line, "combi", color); - - color.r = 0.0f; - color.g = 0.0f; - color.b = 0.0f; - color.a = 0.0f; - m_perso.colorBand = OpColorValue(line, "band", color); - } - } - - fclose(file); -} - -// Specifies the face of the player. - -void CMainDialog::SetGamerFace(char *gamer, int face) -{ - m_perso.face = face; - WriteGamerPerso(gamer); -} - -// Gives the face of the player. - -int CMainDialog::RetGamerFace(char *gamer) -{ - ReadGamerPerso(gamer); - return m_perso.face; -} - -// Gives the face of the player. - -int CMainDialog::RetGamerFace() -{ - return m_perso.face; -} - -int CMainDialog::RetGamerGlasses() -{ - return m_perso.glasses; -} - -BOOL CMainDialog::RetGamerOnlyHead() -{ - return (m_phase == PHASE_PERSO && m_persoTab == 0); -} - -float CMainDialog::RetPersoAngle() -{ - return m_persoAngle; -} - -D3DCOLORVALUE CMainDialog::RetGamerColorHair() -{ - return m_perso.colorHair; -} - -D3DCOLORVALUE CMainDialog::RetGamerColorCombi() -{ - return m_perso.colorCombi; -} - -D3DCOLORVALUE CMainDialog::RetGamerColorBand() -{ - return m_perso.colorBand; -} - - -// Reads the file of the player. - -BOOL CMainDialog::ReadGamerInfo() -{ - FILE* file; - char line[100]; - int chap, i, numTry, passed; - - for ( i=0 ; iRetGamerName(), m_sceneName); - file = fopen(line, "r"); - if ( file == NULL ) return FALSE; - - if ( fgets(line, 100, file) != NULL ) - { - sscanf(line, "CurrentChapter=%d CurrentSel=%d\n", &chap, &i); - m_chap[m_index] = chap-1; - m_sel[m_index] = i-1; - } - - while ( fgets(line, 100, file) != NULL ) - { - sscanf(line, "Chapter %d: Scene %d: numTry=%d passed=%d\n", - &chap, &i, &numTry, &passed); - - i += chap*100; - if ( i >= 0 && i < MAXSCENE ) - { - m_sceneInfo[i].numTry = numTry; - m_sceneInfo[i].bPassed = passed; - } - } - - fclose(file); - return TRUE; -} - -// Writes the file of the player. - -BOOL CMainDialog::WriteGamerInfo() -{ - FILE* file; - char line[100]; - int i; - - sprintf(line, "%s\\%s\\%s.gam", m_savegameDir, m_main->RetGamerName(), m_sceneName); - file = fopen(line, "w"); - if ( file == NULL ) return FALSE; - - sprintf(line, "CurrentChapter=%d CurrentSel=%d\n", - m_chap[m_index]+1, m_sel[m_index]+1); - fputs(line, file); - - for ( i=0 ; i= MAXSCENE ) return; - if ( numTry > 100 ) numTry = 100; - m_sceneInfo[rank].numTry = numTry; -} - -int CMainDialog::RetGamerInfoTry(int rank) -{ - if ( rank < 0 || rank >= MAXSCENE ) return 0; - return m_sceneInfo[rank].numTry; -} - -void CMainDialog::SetGamerInfoPassed(int rank, BOOL bPassed) -{ - int chap, i; - BOOL bAll; - - if ( rank < 0 || rank >= MAXSCENE ) return; - m_sceneInfo[rank].bPassed = bPassed; - - if ( bPassed ) - { - bAll = TRUE; - chap = rank/100; - for ( i=0 ; i= MAXSCENE ) return FALSE; - return m_sceneInfo[rank].bPassed; -} - - -// Passes to the next mission, and possibly in the next chapter. - -BOOL CMainDialog::NextMission() -{ - m_sel[m_index] ++; // next mission - - if ( m_sel[m_index] >= m_maxList ) // last mission of the chapter? - { - m_chap[m_index] ++; // next chapter - m_sel[m_index] = 0; // first mission - } - - return TRUE; -} - - diff --git a/src/maindialog.h b/src/maindialog.h deleted file mode 100644 index 21dca18..0000000 --- a/src/maindialog.h +++ /dev/null @@ -1,256 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// maindialog.h - -#ifndef _MAINDIALOG_H_ -#define _MAINDIALOG_H_ - -#include "struct.h" -#include "camera.h" -#include "robotmain.h" - - -class CInstanceManager; -class CEvent; -class CD3DEngine; -class CInterface; -class CWindow; -class CControl; -class CParticule; -class CSound; - - -#define USERLISTMAX 100 -#define MAXSCENE 1000 - -typedef struct -{ - char numTry; - char bPassed; -} -SceneInfo; - -typedef struct -{ - int face; // face - int glasses; // glasses - D3DCOLORVALUE colorHair; // hair color - D3DCOLORVALUE colorCombi; // spacesuit volor - D3DCOLORVALUE colorBand; // strips color -} -GamerPerso; - - - -class CMainDialog -{ -public: - CMainDialog(CInstanceManager* iMan); - ~CMainDialog(); - - BOOL EventProcess(const Event &event); - void ChangePhase(Phase phase); - - void SetSceneRead(char* name); - void SetStackRead(char* name); - void SetSceneName(char* name); - void SetSceneRank(int rank); - char* RetSceneRead(); - char* RetStackRead(); - char* RetSceneName(); - int RetSceneRank(); - char* RetSceneDir(); - BOOL RetSceneSoluce(); - char* RetSavegameDir(); - char* RetPublicDir(); - - BOOL RetTooltip(); - BOOL RetGlint(); - BOOL RetSoluce4(); - BOOL RetMovies(); - BOOL RetNiceReset(); - BOOL RetHimselfDamage(); - - void SetUserDir(char *base, int rank); - void BuildSceneName(char *filename, char *base, int rank); - void BuildResumeName(char *filename, char *base, int rank); - char* RetFilesDir(); - - void StartAbort(); - void StartDeleteObject(); - void StartDeleteGame(char *gamer); - void StartQuit(); - void StartDialog(FPOINT dim, BOOL bFire, BOOL bOK, BOOL bCancel); - void FrameDialog(float rTime); - void StopDialog(); - BOOL IsDialog(); - - void StartSuspend(); - void StopSuspend(); - - void SetupMemorize(); - void SetupRecall(); - - BOOL ReadGamerInfo(); - BOOL WriteGamerInfo(); - void SetGamerInfoTry(int rank, int numTry); - int RetGamerInfoTry(int rank); - void SetGamerInfoPassed(int rank, BOOL bPassed); - BOOL RetGamerInfoPassed(int rank); - BOOL NextMission(); - - void WriteGamerPerso(char *gamer); - void ReadGamerPerso(char *gamer); - void SetGamerFace(char *gamer, int face); - int RetGamerFace(char *gamer); - int RetGamerFace(); - int RetGamerGlasses(); - BOOL RetGamerOnlyHead(); - float RetPersoAngle(); - D3DCOLORVALUE RetGamerColorHair(); - D3DCOLORVALUE RetGamerColorCombi(); - D3DCOLORVALUE RetGamerColorBand(); - - void AllMissionUpdate(); - void ShowSoluceUpdate(); - -protected: - void GlintMove(); - void FrameParticule(float rTime); - void NiceParticule(FPOINT mouse, BOOL bPress); - void ReadNameList(); - void UpdateNameList(); - void UpdateNameEdit(); - void UpdateNameControl(); - void UpdateNameFace(); - void NameSelect(); - void NameCreate(); - void NameDelete(); - void UpdatePerso(); - void CameraPerso(); - void FixPerso(int rank, int index); - void ColorPerso(); - void DefPerso(); - BOOL IsIOReadScene(); - void IOReadName(); - void IOReadList(); - void IOUpdateList(); - void IODeleteScene(); - BOOL IOWriteScene(); - BOOL IOReadScene(); - int RetChapPassed(); - void UpdateSceneChap(int &chap); - void UpdateSceneList(int chap, int &sel); - void UpdateSceneResume(int rank); - void UpdateDisplayDevice(); - void UpdateDisplayMode(); - void ChangeDisplay(); - void UpdateApply(); - void UpdateSetupButtons(); - void ChangeSetupButtons(); - void ChangeSetupQuality(int quality); - void UpdateKey(); - void ChangeKey(EventMsg event); - -protected: - CInstanceManager* m_iMan; - CRobotMain* m_main; - CEvent* m_event; - CD3DEngine* m_engine; - CInterface* m_interface; - CParticule* m_particule; - CCamera* m_camera; - CSound* m_sound; - - Phase m_phase; // copy of CRobotMain - Phase m_phaseSetup; // tab selected - Phase m_phaseTerm; // phase trainer/scene/proto - float m_phaseTime; - - GamerPerso m_perso; // perso: description - GamerPerso m_persoCopy; // perso: copy for cancellation - int m_persoTab; // perso: tab selected - float m_persoAngle; // perso: angle of presentation - - char m_sceneDir[_MAX_FNAME]; // scene folder - char m_savegameDir[_MAX_FNAME]; // savegame folder - char m_publicDir[_MAX_FNAME]; // program folder - char m_userDir[_MAX_FNAME]; // user folder - char m_filesDir[_MAX_FNAME]; // case files - - int m_index; // 0..4 - int m_chap[10]; // selected chapter (0..8) - int m_sel[10]; // chosen mission (0..98) - int m_maxList; - int m_accessChap; - char m_sceneRead[100]; // name of the scene to read - char m_stackRead[100]; // name of the scene to read - char m_sceneName[20]; // name of the scene to play - int m_sceneRank; // rank of the scene to play - BOOL m_bSceneSoluce; // shows the solution - BOOL m_bSimulSetup; // adjustment during the game - BOOL m_accessEnable; - BOOL m_accessMission; - BOOL m_accessUser; - BOOL m_bDeleteGamer; - - int m_userTotal; - char m_userList[USERLISTMAX][100]; - - int m_shotDelay; // number of frames before copy - char m_shotName[100]; // generate a file name - - int m_setupSelDevice; - int m_setupSelMode; - BOOL m_setupFull; - - BOOL m_bTooltip; // tooltips to be displayed? - BOOL m_bGlint; // reflections on buttons? - BOOL m_bRain; // rain in the interface? - BOOL m_bSoluce4; // solutions in program 4? - BOOL m_bMovies; // cinematics? - BOOL m_bNiceReset; // for CTaskReset - BOOL m_bHimselfDamage; // for shots - BOOL m_bCameraScroll; // for CCamera - BOOL m_bCameraInvertX; // for CCamera - BOOL m_bCameraInvertY; // for CCamera - BOOL m_bEffect; // for CCamera - - FPOINT m_glintMouse; - float m_glintTime; - - int m_loadingCounter; - - BOOL m_bDialog; // this dialogue? - BOOL m_bDialogFire; // setting on fire? - BOOL m_bDialogDelete; - FPOINT m_dialogPos; - FPOINT m_dialogDim; - float m_dialogParti; - float m_dialogTime; - BOOL m_bInitPause; - CameraType m_initCamera; - - int m_partiPhase[10]; - float m_partiTime[10]; - FPOINT m_partiPos[10]; - - SceneInfo m_sceneInfo[MAXSCENE]; -}; - - -#endif //_MAINDIALOG_H_ diff --git a/src/mainmap.cpp b/src/mainmap.cpp deleted file mode 100644 index c66edf2..0000000 --- a/src/mainmap.cpp +++ /dev/null @@ -1,404 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// mainmap.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "global.h" -#include "event.h" -#include "iman.h" -#include "interface.h" -#include "map.h" -#include "image.h" -#include "group.h" -#include "slider.h" -#include "scroll.h" -#include "window.h" -#include "mainmap.h" - - - -#define ZOOM_MIN 1.0f -#define ZOOM_MAX 16.0f - - - -// Constructor of the application card. - -CMainMap::CMainMap(CInstanceManager* iMan) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_MAP, this); - - m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - - m_mapMode = 1; - m_bFixImage = FALSE; -} - -// Destructor of the application card. - -CMainMap::~CMainMap() -{ -} - - -// Created the mini-map and the corresponding buttons. - -void CMainMap::CreateMap() -{ - CWindow* pw; - FPOINT pos, dim; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw == 0 ) - { - pos.x = 0.0f; - pos.y = 0.0f; - dim.x = 0.0f; - dim.y = 0.0f; - pw = m_interface->CreateWindows(pos, dim, 10, EVENT_WINDOW1); - } - - dim.x = 10.0f/640.0f; - dim.y = 10.0f/480.0f; - pos.x = 10.0f/640.0f; - pos.y = 10.0f/480.0f; - pw->CreateMap (pos, dim, 2, EVENT_OBJECT_MAP); - pw->CreateSlider(pos, dim, 0, EVENT_OBJECT_MAPZOOM); - - DimMap(); -} - -// Indicates whether the mini-map should display a still image. - -void CMainMap::SetFixImage(char *filename) -{ - CWindow* pw; - CMap* pm; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw == 0 ) return; - - pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); - if ( pm == 0 ) return; - - pw->DeleteControl(EVENT_OBJECT_MAPZOOM); - m_bFixImage = TRUE; - - pm->SetFixImage(filename); -} - -// Choosing colors of soil and water for the mini-map. - -void CMainMap::FloorColorMap(D3DCOLORVALUE floor, D3DCOLORVALUE water) -{ - CWindow* pw; - CMap* pm; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw == 0 ) return; - - pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); - if ( pm != 0 ) - { - pm->SetFloorColor(floor); - pm->SetWaterColor(water); - } -} - -// Shows or hides the minimap. - -void CMainMap::ShowMap(BOOL bShow) -{ - CWindow* pw; - CMap* pm; - CSlider* ps; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw == 0 ) return; - - if ( bShow ) - { - DimMap(); - } - else - { - pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); - if ( pm != 0 ) - { - pm->ClearState(STATE_VISIBLE); - } - - ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM); - if ( ps != 0 ) - { - ps->ClearState(STATE_VISIBLE); - } - } -} - -// Dimensions of the mini-map. - -void CMainMap::DimMap() -{ - CWindow* pw; - CMap* pm; - CSlider* ps; - FPOINT pos, dim; - float value; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw == 0 ) return; - pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); - if ( pm == 0 ) return; - - pm->SetState(STATE_VISIBLE, (m_mapMode != 0)); - - dim.x = 100.0f/640.0f; - dim.y = 100.0f/480.0f; - pos.x = 540.0f/640.0f; - pos.y = 0.0f/480.0f; - pm->SetPos(pos); - pm->SetDim(dim); - - ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM); - if ( ps != 0 ) - { - ps->SetState(STATE_VISIBLE, (m_mapMode != 0)); - - dim.x = SCROLL_WIDTH; - dim.y = 66.0f/480.0f; - pos.x = 523.0f/640.0f; - pos.y = 3.0f/480.0f; - ps->SetPos(pos); - ps->SetDim(dim); - - value = pm->RetZoom(); - value = (value-ZOOM_MIN)/(ZOOM_MAX-ZOOM_MIN); - value = powf(value, 0.5f); - ps->SetVisibleValue(value); - ps->SetArrowStep(0.2f); - } -} - -// Returns the current zoom of the minimap. - -float CMainMap::RetZoomMap() -{ - CWindow* pw; - CMap* pm; - CSlider* ps; - - pw = (CWindow*)pw->SearchControl(EVENT_WINDOW1); - if ( pw == 0 ) return ZOOM_MIN; - - pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); - if ( pm == 0 ) return ZOOM_MIN; - - ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM); - if ( ps == 0 ) return ZOOM_MIN; - - return pm->RetZoom(); -} - -// Zoom the mini-map of any factor. - -void CMainMap::ZoomMap(float zoom) -{ - CWindow* pw; - CMap* pm; - CSlider* ps; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw == 0 ) return; - pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); - if ( pm == 0 ) return; - - ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM); - if ( ps == 0 ) return; - - if ( zoom < ZOOM_MIN ) zoom = ZOOM_MIN; - if ( zoom > ZOOM_MAX ) zoom = ZOOM_MAX; - pm->SetZoom(zoom); - - DimMap(); -} - -// The mini-map zoom depending on the slider. - -void CMainMap::ZoomMap() -{ - CWindow* pw; - CMap* pm; - CSlider* ps; - float zoom; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw == 0 ) return; - pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); - if ( pm == 0 ) return; - - ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM); - if ( ps == 0 ) return; - - zoom = ps->RetVisibleValue(); - zoom = powf(zoom, 2.0f); - zoom = ZOOM_MIN+zoom*(ZOOM_MAX-ZOOM_MIN); - pm->SetZoom(zoom); - - DimMap(); -} - -// Enables or disables the card. - -void CMainMap::MapEnable(BOOL bEnable) -{ - CWindow* pw; - CMap* pm; - CSlider* ps; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw == 0 ) return; - - pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); - if ( pm != 0 ) - { - pm->SetEnable(bEnable); - } - - ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM); - if ( ps != 0 ) - { - ps->SetState(STATE_ENABLE, bEnable); - } -} - -// Specifies the type of icon for the selected object. - -void CMainMap::SetToy(BOOL bToy) -{ - CWindow* pw; - CMap* pm; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw == 0 ) return; - - pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); - if ( pm == 0 ) return; - - pm->SetToy(bToy); -} - -// Specifies the parameters when using a still image. - -void CMainMap::SetFixParam(float zoom, float ox, float oy, float angle, - int mode, BOOL bDebug) -{ - CWindow* pw; - CMap* pm; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw == 0 ) return; - - pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); - if ( pm == 0 ) return; - - pm->SetZoom(zoom); - pm->SetOffset(ox, oy); - pm->SetAngle(angle); - pm->SetMode(mode); - pm->SetDebug(bDebug); -} - -// Updates the mini-map following to a change of terrain. - -void CMainMap::UpdateMap() -{ - CWindow* pw; - CMap* pm; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw == 0 ) return; - - pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); - if ( pm != 0 ) - { - pm->UpdateTerrain(); - } -} - -// Indicates if the mini-map is visible. - -BOOL CMainMap::RetShowMap() -{ - return ( m_mapMode != 0 ); -} - -// Indicates whether the mini-map displays a still image. - -BOOL CMainMap::RetFixImage() -{ - return m_bFixImage; -} - - -// The object is detected in the mini-map. - -CObject* CMainMap::DetectMap(FPOINT pos, BOOL &bInMap) -{ - CWindow* pw; - CMap* pm; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw == 0 ) return 0; - - bInMap = FALSE; - pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); - if ( pm == 0 ) return 0; - return pm->DetectObject(pos, bInMap); -} - - -// Indicates the object with the mouse hovers over. - -void CMainMap::SetHilite(CObject* pObj) -{ - CWindow* pw; - CMap* pm; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw == 0 ) return; - - pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); - if ( pm != 0 ) - { - pm->SetHilite(pObj); - } -} - - diff --git a/src/mainmap.h b/src/mainmap.h deleted file mode 100644 index f9fe0be..0000000 --- a/src/mainmap.h +++ /dev/null @@ -1,68 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// mainmap.h - -#ifndef _MAINMAP_H_ -#define _MAINMAP_H_ - - -class CInstanceManager; -class CEvent; -class CD3DEngine; -class CInterface; -class CObject; - - - -class CMainMap -{ -public: - CMainMap(CInstanceManager* iMan); - ~CMainMap(); - - void UpdateMap(); - void CreateMap(); - void SetFixImage(char *filename); - void FloorColorMap(D3DCOLORVALUE floor, D3DCOLORVALUE water); - void ShowMap(BOOL bShow); - void DimMap(); - float RetZoomMap(); - void ZoomMap(float zoom); - void ZoomMap(); - void MapEnable(BOOL bEnable); - BOOL RetShowMap(); - BOOL RetFixImage(); - CObject* DetectMap(FPOINT pos, BOOL &bInMap); - void SetHilite(CObject* pObj); - void SetToy(BOOL bToy); - void SetFixParam(float zoom, float ox, float oy, float angle, int mode, BOOL bDebug); - -protected: - void CenterMap(); - -protected: - CInstanceManager* m_iMan; - CEvent* m_event; - CD3DEngine* m_engine; - CInterface* m_interface; - - int m_mapMode; - BOOL m_bFixImage; -}; - - -#endif //_MAINMAP_H_ diff --git a/src/mainmovie.cpp b/src/mainmovie.cpp deleted file mode 100644 index 8205d16..0000000 --- a/src/mainmovie.cpp +++ /dev/null @@ -1,249 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// mainmovie.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "global.h" -#include "event.h" -#include "iman.h" -#include "math3d.h" -#include "camera.h" -#include "object.h" -#include "motion.h" -#include "motionhuman.h" -#include "interface.h" -#include "robotmain.h" -#include "sound.h" -#include "mainmovie.h" - - - - -// Constructor of the application card. - -CMainMovie::CMainMovie(CInstanceManager* iMan) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_SHORT, this); - - m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - - Flush(); -} - -// Destructor of the application card. - -CMainMovie::~CMainMovie() -{ -} - - -// Stops the current movie. - -void CMainMovie::Flush() -{ - m_type = MM_NONE; -} - - -// Start of a film. - -BOOL CMainMovie::Start(MainMovieType type, float time) -{ - D3DMATRIX* mat; - D3DVECTOR pos; - CObject* pObj; - CMotion* motion; - - m_type = type; - m_speed = 1.0f/time; - m_progress = 0.0f; - - if ( m_type == MM_SATCOMopen ) - { - pObj = m_main->SearchHuman(); - if ( pObj == 0 ) - { - m_type = MM_NONE; // it's over! - return TRUE; - } - - motion = pObj->RetMotion(); - if ( motion != 0 ) - { - motion->SetAction(MHS_SATCOM, 0.5f); // reads the SatCom - } - - m_camera->RetCamera(m_initialEye, m_initialLookat); - m_camera->SetType(CAMERA_SCRIPT); - m_camera->SetSmooth(CS_HARD); - m_camera->SetScriptEye(m_initialEye); - m_camera->SetScriptLookat(m_initialLookat); - m_camera->FixCamera(); - - mat = pObj->RetWorldMatrix(0); - m_finalLookat[0] = Transform(*mat, D3DVECTOR( 1.6f, 1.0f, 1.2f)); - m_finalEye[0] = Transform(*mat, D3DVECTOR(-1.5f, 5.0f, 3.0f)); - m_finalLookat[1] = Transform(*mat, D3DVECTOR( 1.6f, 1.0f, 1.2f)); - m_finalEye[1] = Transform(*mat, D3DVECTOR( 0.8f, 3.0f, 0.8f)); - } - - if ( m_type == MM_SATCOMclose ) - { - pObj = m_main->SearchHuman(); - if ( pObj != 0 ) - { - motion = pObj->RetMotion(); - if ( motion != 0 ) - { - motion->SetAction(-1); // finishes reading SatCom - } - } - - m_camera->SetType(CAMERA_BACK); - m_type = MM_NONE; // it's already over! - } - - return TRUE; -} - -// Stop a current movie. - -BOOL CMainMovie::Stop() -{ - CObject* pObj; - CMotion* motion; - - if ( m_type == MM_SATCOMopen ) - { - pObj = m_main->SearchHuman(); - if ( pObj != 0 ) - { - motion = pObj->RetMotion(); - if ( motion != 0 ) - { - motion->SetAction(-1); // finishes reading SatCom - } - } - } - - m_type = MM_NONE; - return TRUE; -} - -// Indicates whether a film is in progress. - -BOOL CMainMovie::IsExist() -{ - return (m_type != MM_NONE); -} - - -// Processing an event. - -BOOL CMainMovie::EventProcess(const Event &event) -{ - D3DVECTOR initialEye, initialLookat, finalEye, finalLookat, eye, lookat; - float progress; - - if ( m_type == MM_NONE ) return TRUE; - - m_progress += event.rTime*m_speed; - - if ( m_type == MM_SATCOMopen ) - { - if ( m_progress < 1.0f ) - { - progress = 1.0f-powf(1.0f-m_progress, 3.0f); - - if ( progress < 0.6f ) - { - progress = progress/0.6f; - initialEye = m_initialEye; - initialLookat = m_initialLookat; - finalEye = m_finalEye[0]; - finalLookat = m_finalLookat[0]; - } - else - { - progress = (progress-0.6f)/0.3f; - initialEye = m_finalEye[0]; - initialLookat = m_finalLookat[0]; - finalEye = m_finalEye[1]; - finalLookat = m_finalLookat[1]; - } - if ( progress > 1.0f ) progress = 1.0f; - - eye = (finalEye-initialEye)*progress+initialEye; - lookat = (finalLookat-initialLookat)*progress+initialLookat; - m_camera->SetScriptEye(eye); - m_camera->SetScriptLookat(lookat); -// m_camera->FixCamera(); - } - else - { - m_stopType = m_type; - Flush(); - return FALSE; - } - } - - if ( m_type == MM_SATCOMclose ) - { - if ( m_progress < 1.0f ) - { - } - else - { - m_stopType = m_type; - Flush(); - return FALSE; - } - } - - return TRUE; -} - - -// Returns the type of the current movie. - -MainMovieType CMainMovie::RetType() -{ - return m_type; -} - -// Returns the type of movie stop. - -MainMovieType CMainMovie::RetStopType() -{ - return m_stopType; -} - - diff --git a/src/mainmovie.h b/src/mainmovie.h deleted file mode 100644 index f31b3a9..0000000 --- a/src/mainmovie.h +++ /dev/null @@ -1,80 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// mainmovie.h - -#ifndef _MAINMOVIE_H_ -#define _MAINMOVIE_H_ - - -class CInstanceManager; -class CEvent; -class CD3DEngine; -class CInterface; -class CRobotMain; -class CCamera; -class CSound; -class CObject; - - - - -enum MainMovieType -{ - MM_NONE, - MM_SATCOMopen, - MM_SATCOMclose, -}; - - - -class CMainMovie -{ -public: - CMainMovie(CInstanceManager* iMan); - ~CMainMovie(); - - void Flush(); - BOOL Start(MainMovieType type, float time); - BOOL Stop(); - BOOL IsExist(); - BOOL EventProcess(const Event &event); - MainMovieType RetType(); - MainMovieType RetStopType(); - -protected: - -protected: - CInstanceManager* m_iMan; - CEvent* m_event; - CD3DEngine* m_engine; - CInterface* m_interface; - CRobotMain* m_main; - CCamera* m_camera; - CSound* m_sound; - - MainMovieType m_type; - MainMovieType m_stopType; - float m_speed; - float m_progress; - D3DVECTOR m_initialEye; - D3DVECTOR m_initialLookat; - D3DVECTOR m_finalEye[2]; - D3DVECTOR m_finalLookat[2]; -}; - - -#endif //_MAINMOVIE_H_ diff --git a/src/mainshort.cpp b/src/mainshort.cpp deleted file mode 100644 index 4e934e5..0000000 --- a/src/mainshort.cpp +++ /dev/null @@ -1,376 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// mainshort.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "global.h" -#include "event.h" -#include "iman.h" -#include "object.h" -#include "interface.h" -#include "map.h" -#include "button.h" -#include "robotmain.h" -#include "mainshort.h" - - - - -// Constructor of the application card. - -CMainShort::CMainShort(CInstanceManager* iMan) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_SHORT, this); - - m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - - FlushShortcuts(); -} - -// Destructor of the application card. - -CMainShort::~CMainShort() -{ -} - - - -void CMainShort::SetMode(BOOL bBuilding) -{ - m_bBuilding = bBuilding; -} - - - -// Reset all shortcuts. - -void CMainShort::FlushShortcuts() -{ - int i; - - for ( i=0 ; i<20 ; i++ ) - { - m_shortcuts[i] = 0; - } -} - -static EventMsg table_sc_em[20] = -{ - EVENT_OBJECT_SHORTCUT00, - EVENT_OBJECT_SHORTCUT01, - EVENT_OBJECT_SHORTCUT02, - EVENT_OBJECT_SHORTCUT03, - EVENT_OBJECT_SHORTCUT04, - EVENT_OBJECT_SHORTCUT05, - EVENT_OBJECT_SHORTCUT06, - EVENT_OBJECT_SHORTCUT07, - EVENT_OBJECT_SHORTCUT08, - EVENT_OBJECT_SHORTCUT09, - EVENT_OBJECT_SHORTCUT10, - EVENT_OBJECT_SHORTCUT11, - EVENT_OBJECT_SHORTCUT12, - EVENT_OBJECT_SHORTCUT13, - EVENT_OBJECT_SHORTCUT14, - EVENT_OBJECT_SHORTCUT15, - EVENT_OBJECT_SHORTCUT16, - EVENT_OBJECT_SHORTCUT17, - EVENT_OBJECT_SHORTCUT18, - EVENT_OBJECT_SHORTCUT19, -}; - -// Interface creates shortcuts to the units. - -BOOL CMainShort::CreateShortcuts() -{ - CObject* pObj; - CControl* pc; - ObjectType type; - FPOINT pos, dim; - int i, rank, icon; - char name[100]; - - if ( m_main->RetFixScene() ) return FALSE; - - m_interface->DeleteControl(EVENT_OBJECT_MOVIELOCK); - m_interface->DeleteControl(EVENT_OBJECT_EDITLOCK); - for ( i=0 ; i<20 ; i++ ) - { - if ( i != 0 && m_shortcuts[i] == 0 ) continue; - - m_interface->DeleteControl(table_sc_em[i]); - m_shortcuts[i] = 0; - } - - dim.x = 28.0f/640.0f; - dim.y = 28.0f/480.0f; - pos.x = 4.0f/640.0f; - pos.y = (480.0f-32.0f)/480.0f; - - if ( m_main->RetMovieLock() && - !m_main->RetEditLock() ) // hangs during film? - { - m_interface->CreateShortcut(pos, dim, 7, EVENT_OBJECT_MOVIELOCK); - return TRUE; - } - if ( !m_main->RetFreePhoto() && - (m_main->RetEditLock() || - m_engine->RetPause()) ) // hangs during edition? - { - m_interface->CreateShortcut(pos, dim, 6, EVENT_OBJECT_EDITLOCK); - return TRUE; - } - - rank = 0; - - m_interface->CreateShortcut(pos, dim, 2, table_sc_em[rank]); - pos.x += dim.x*1.2f; - m_shortcuts[rank] = 0; - rank ++; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetActif() ) continue; - if ( !pObj->RetSelectable() ) continue; - if ( pObj->RetProxyActivate() ) continue; - - type = pObj->RetType(); - icon = -1; - if ( m_bBuilding ) - { - if ( type == OBJECT_FACTORY ) icon = 32; - if ( type == OBJECT_DERRICK ) icon = 33; - if ( type == OBJECT_CONVERT ) icon = 34; - if ( type == OBJECT_RESEARCH ) icon = 35; - if ( type == OBJECT_STATION ) icon = 36; - if ( type == OBJECT_TOWER ) icon = 37; - if ( type == OBJECT_LABO ) icon = 38; - if ( type == OBJECT_ENERGY ) icon = 39; - if ( type == OBJECT_RADAR ) icon = 40; - if ( type == OBJECT_INFO ) icon = 44; - if ( type == OBJECT_REPAIR ) icon = 41; - if ( type == OBJECT_DESTROYER) icon = 41; - if ( type == OBJECT_NUCLEAR ) icon = 42; - if ( type == OBJECT_PARA ) icon = 46; - if ( type == OBJECT_SAFE ) icon = 47; - if ( type == OBJECT_HUSTON ) icon = 48; - if ( type == OBJECT_BASE ) icon = 43; - } - else - { - if ( type == OBJECT_HUMAN ) icon = 8; - if ( type == OBJECT_MOBILEfa ) icon = 11; - if ( type == OBJECT_MOBILEta ) icon = 10; - if ( type == OBJECT_MOBILEwa ) icon = 9; - if ( type == OBJECT_MOBILEia ) icon = 22; - if ( type == OBJECT_MOBILEfc ) icon = 17; - if ( type == OBJECT_MOBILEtc ) icon = 16; - if ( type == OBJECT_MOBILEwc ) icon = 15; - if ( type == OBJECT_MOBILEic ) icon = 23; - if ( type == OBJECT_MOBILEfi ) icon = 27; - if ( type == OBJECT_MOBILEti ) icon = 26; - if ( type == OBJECT_MOBILEwi ) icon = 25; - if ( type == OBJECT_MOBILEii ) icon = 28; - if ( type == OBJECT_MOBILEfs ) icon = 14; - if ( type == OBJECT_MOBILEts ) icon = 13; - if ( type == OBJECT_MOBILEws ) icon = 12; - if ( type == OBJECT_MOBILEis ) icon = 24; - if ( type == OBJECT_MOBILErt ) icon = 18; - if ( type == OBJECT_MOBILErc ) icon = 19; - if ( type == OBJECT_MOBILErr ) icon = 20; - if ( type == OBJECT_MOBILErs ) icon = 29; - if ( type == OBJECT_MOBILEsa ) icon = 21; - if ( type == OBJECT_MOBILEft ) icon = 30; - if ( type == OBJECT_MOBILEtt ) icon = 30; - if ( type == OBJECT_MOBILEwt ) icon = 30; - if ( type == OBJECT_MOBILEit ) icon = 30; - if ( type == OBJECT_MOBILEdr ) icon = 48; - if ( type == OBJECT_APOLLO2 ) icon = 49; - } - if ( icon == -1 ) continue; - - m_interface->CreateShortcut(pos, dim, icon, table_sc_em[rank]); - pos.x += dim.x; - m_shortcuts[rank] = pObj; - - pc = m_interface->SearchControl(table_sc_em[rank]); - if ( pc != 0 ) - { - pObj->GetTooltipName(name); - pc->SetTooltip(name); - } - rank ++; - - if ( rank >= 20 ) break; - } - - UpdateShortcuts(); - return TRUE; -} - -// Updates the interface shortcuts to the units. - -BOOL CMainShort::UpdateShortcuts() -{ - CControl* pc; - int i; - - for ( i=0 ; i<20 ; i++ ) - { - if ( m_shortcuts[i] == 0 ) continue; - - pc = m_interface->SearchControl(table_sc_em[i]); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_shortcuts[i]->RetSelect()); - pc->SetState(STATE_RUN, m_shortcuts[i]->IsProgram()); - } - } - return TRUE; -} - -// Selects an object through a shortcut. - -void CMainShort::SelectShortcut(EventMsg event) -{ - int i; - - for ( i=0 ; i<20 ; i++ ) - { - if ( event == table_sc_em[i] ) - { - if ( i != 0 && m_shortcuts[i] == 0 ) continue; - - if ( i == 0 ) // buildings <-> vehicles? - { - m_bBuilding = !m_bBuilding; - CreateShortcuts(); - } - else - { - m_main->SelectObject(m_shortcuts[i]); - } - return; - } - } -} - - -// Selects the next object. - -void CMainShort::SelectNext() -{ - CObject* pPrev; - int i; - - if ( m_main->RetMovieLock() || - m_main->RetEditLock() || - m_engine->RetPause() ) return; - - pPrev = m_main->DeselectAll(); - - for ( i=1 ; i<20 ; i++ ) - { - if ( m_shortcuts[i] == pPrev ) - { - if ( m_shortcuts[++i] == 0 ) i = 1; - break; - } - } - - if ( i == 20 || m_shortcuts[i] == 0 ) - { - m_main->SelectHuman(); - } - else - { - m_main->SelectObject(m_shortcuts[i]); - } -} - - -// The object detected by the mouse hovers over. - -CObject* CMainShort::DetectShort(FPOINT pos) -{ - CControl* pc; - FPOINT cpos, cdim; - int i; - - for ( i=0 ; i<20 ; i++ ) - { - if ( m_shortcuts[i] == 0 ) continue; - - pc = m_interface->SearchControl(table_sc_em[i]); - if ( pc != 0 ) - { - cpos = pc->RetPos(); - cdim = pc->RetDim(); - - if ( pos.x >= cpos.x && - pos.x <= cpos.x+cdim.x && - pos.y >= cpos.y && - pos.y <= cpos.y+cdim.y ) - { - return m_shortcuts[i]; - } - } - } - return 0; -} - -// Reports the object with the mouse hovers over. - -void CMainShort::SetHilite(CObject* pObj) -{ - CControl* pc; - int i; - - for ( i=0 ; i<20 ; i++ ) - { - if ( m_shortcuts[i] == 0 ) continue; - - pc = m_interface->SearchControl(table_sc_em[i]); - if ( pc == 0 ) continue; - - if ( m_shortcuts[i] == pObj ) - { - pc->SetState(STATE_HILIGHT); - pc->SetState(STATE_FRAME); - } - else - { - pc->ClearState(STATE_HILIGHT); - pc->ClearState(STATE_FRAME); - } - } -} - diff --git a/src/mainshort.h b/src/mainshort.h deleted file mode 100644 index 648dbbc..0000000 --- a/src/mainshort.h +++ /dev/null @@ -1,61 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// mainshort.h - -#ifndef _MAINSHORT_H_ -#define _MAINSHORT_H_ - - -class CInstanceManager; -class CEvent; -class CD3DEngine; -class CInterface; -class CRobotMain; -class CObject; - - - -class CMainShort -{ -public: - CMainShort(CInstanceManager* iMan); - ~CMainShort(); - - void SetMode(BOOL bBuilding); - void FlushShortcuts(); - BOOL CreateShortcuts(); - BOOL UpdateShortcuts(); - void SelectShortcut(EventMsg event); - void SelectNext(); - CObject* DetectShort(FPOINT pos); - void SetHilite(CObject* pObj); - -protected: - -protected: - CInstanceManager* m_iMan; - CEvent* m_event; - CD3DEngine* m_engine; - CInterface* m_interface; - CRobotMain* m_main; - - CObject* m_shortcuts[20]; - BOOL m_bBuilding; -}; - - -#endif //_MAINSHORT_H_ diff --git a/src/map.cpp b/src/map.cpp deleted file mode 100644 index c44a218..0000000 --- a/src/map.cpp +++ /dev/null @@ -1,1342 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// map.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "event.h" -#include "math3d.h" -#include "terrain.h" -#include "water.h" -#include "object.h" -#include "event.h" -#include "misc.h" -#include "robotmain.h" -#include "iman.h" -#include "map.h" - - - - -// Object's constructor. - -CMap::CMap(CInstanceManager* iMan) : CControl(iMan) -{ - CControl::CControl(iMan); - - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - - m_bEnable = TRUE; - m_time = 0.0f; - m_zoom = 2.0f; - m_offset.x = 0.0f; - m_offset.y = 0.0f; - m_angle = 0.0f; - - m_floorColor.r = 1.00f; - m_floorColor.g = 0.50f; - m_floorColor.b = 0.00f; // orange - - m_waterColor.r = 0.00f; - m_waterColor.g = 0.80f; - m_waterColor.b = 1.00f; // blue - - m_half = m_terrain->RetMosaic()*m_terrain->RetBrick()*m_terrain->RetSize()/2.0f; - - m_hiliteRank = -1; - FlushObject(); - - m_fixImage[0] = 0; - m_mode = 0; - m_bToy = FALSE; - m_bDebug = FALSE; -} - -// Object's destructor. - -CMap::~CMap() -{ -} - - -// Creates a new button. - -BOOL CMap::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - CControl::Create(pos, dim, icon, eventMsg); - return TRUE; -} - - -// Choice of the offset, when image is displayed. - -void CMap::SetOffset(float ox, float oy) -{ - m_offset.x = ox; - m_offset.y = oy; - m_half = m_terrain->RetMosaic()*m_terrain->RetBrick()*m_terrain->RetSize()/2.0f; -} - -// Choice of the global angle of rotation. - -void CMap::SetAngle(float angle) -{ - m_angle = angle; -} - -// Specifies the alternate mode. - -void CMap::SetMode(int mode) -{ - m_mode = mode; -} - -// Specifies the type of icon for the selected object. - -void CMap::SetToy(BOOL bToy) -{ - m_bToy = bToy; -} - -void CMap::SetDebug(BOOL bDebug) -{ - m_bDebug = bDebug; -} - - -//Choice of magnification of the map. - -void CMap::SetZoom(float value) -{ - m_zoom = value; - m_half = m_terrain->RetMosaic()*m_terrain->RetBrick()*m_terrain->RetSize()/2.0f; -} - -float CMap::RetZoom() -{ - return m_zoom; -} - -// Choosing a fixed offset. - -// Enables or disables the card. - -void CMap::SetEnable(BOOL bEnable) -{ - m_bEnable = bEnable; - SetState(STATE_DEAD, !bEnable); -} - -BOOL CMap::RetEnable() -{ - return m_bEnable; -} - - -// Choosing the color of the soil. - -void CMap::SetFloorColor(D3DCOLORVALUE color) -{ - m_floorColor = color; -} - -// Choosing the color of the water. - -void CMap::SetWaterColor(D3DCOLORVALUE color) -{ - m_waterColor = color; -} - - -// Specifies a fixed image in place of the drawing of the relief. - -void CMap::SetFixImage(char *filename) -{ - strcpy(m_fixImage, filename); -} - -// Whether to use a still image. - -BOOL CMap::RetFixImage() -{ - return (m_fixImage[0] != 0); -} - - -// Management of an event. - -BOOL CMap::EventProcess(const Event &event) -{ - BOOL bInMap; - - if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; - - CControl::EventProcess(event); - - if ( event.event == EVENT_FRAME ) - { - m_time += event.rTime; - } - - if ( event.event == EVENT_MOUSEMOVE && Detect(event.pos) ) - { - m_engine->SetMouseType(D3DMOUSENORM); - if ( DetectObject(event.pos, bInMap) != 0 ) - { - m_engine->SetMouseType(D3DMOUSEHAND); - } - } - - if ( event.event == EVENT_LBUTTONDOWN ) - { - if ( CControl::Detect(event.pos) ) - { - SelectObject(event.pos); - return FALSE; - } - } - - return TRUE; -} - -// Adjusts the offset to not exceed the card. - -FPOINT CMap::AdjustOffset(FPOINT offset) -{ - float limit; - - limit = m_half - m_half/m_zoom; - if ( offset.x < -limit ) offset.x = -limit; - if ( offset.x > limit ) offset.x = limit; - if ( offset.y < -limit ) offset.y = -limit; - if ( offset.y > limit ) offset.y = limit; - - return offset; -} - -// Indicates the object with the mouse hovers over. - -void CMap::SetHilite(CObject* pObj) -{ - int i; - - m_hiliteRank = -1; - if ( m_bToy || m_fixImage[0] != 0 ) return; // card with still image? - if ( pObj == 0 ) return; - - for ( i=0 ; i m_pos.x+m_dim.x || - pos.y > m_pos.y+m_dim.y ) return 0; - - bInMap = TRUE; - - pos.x = (pos.x-m_pos.x)/m_dim.x*256.0f; - pos.y = (pos.y-m_pos.y)/m_dim.y*256.0f; // 0..256 - pos.x = (pos.x-128.0f)*m_half/(m_zoom*128.0f)+m_offset.x; - pos.y = (pos.y-128.0f)*m_half/(m_zoom*128.0f)+m_offset.y; - - min = 10000.0f; - best = -1; - for ( i=MAPMAXOBJECT-1 ; i>=0 ; i-- ) - { - if ( !m_map[i].bUsed ) continue; - if ( m_map[i].color == MAPCOLOR_BBOX && !m_bRadar ) continue; - if ( m_map[i].color == MAPCOLOR_ALIEN && !m_bRadar ) continue; - - dist = Length(m_map[i].pos.x-pos.x, m_map[i].pos.y-pos.y); - if ( dist > m_half/m_zoom*8.0f/100.0f ) continue; // too far? - if ( dist < min ) - { - min = dist; - best = i; - } - } - if ( best == -1 ) return 0; - return m_map[best].object; -} - -// Selects an object. - -void CMap::SelectObject(FPOINT pos) -{ - CObject *pObj; - BOOL bInMap; - - pObj = DetectObject(pos, bInMap); - if ( pObj != 0 ) - { - m_main->SelectObject(pObj); - } -} - - -// Draw the map. - -void CMap::Draw() -{ - FPOINT uv1, uv2; - int i; - - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - CControl::Draw(); // draws the bottom (button) - - if ( !m_bEnable ) return; - - if ( m_fixImage[0] == 0 && m_map[MAPMAXOBJECT-1].bUsed ) - { - m_offset = AdjustOffset(m_map[MAPMAXOBJECT-1].pos); - } - - if ( m_fixImage[0] == 0 ) // drawing of the relief? - { - m_engine->SetTexture("map.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 0.5f+(m_offset.x-(m_half/m_zoom))/(m_half*2.0f); - uv1.y = 0.5f-(m_offset.y+(m_half/m_zoom))/(m_half*2.0f); - uv2.x = 0.5f+(m_offset.x+(m_half/m_zoom))/(m_half*2.0f); - uv2.y = 0.5f-(m_offset.y-(m_half/m_zoom))/(m_half*2.0f); - DrawVertex(uv1, uv2, 0.97f); // drawing the map - } - else // still image? - { - m_engine->LoadTexture(m_fixImage); - m_engine->SetTexture(m_fixImage); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 0.0f; - uv1.y = 0.0f; - uv2.x = 1.0f; - uv2.y = 1.0f; - DrawVertex(uv1, uv2, 0.97f); // drawing the map - } - - i = MAPMAXOBJECT-1; - if ( m_map[i].bUsed ) // selection: - { - DrawFocus(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color); - } - - for ( i=0 ; im_totalMove ; i-- ) // moving objects: - { - if ( i == m_hiliteRank ) continue; - DrawObject(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color, FALSE, FALSE); - } - - i = MAPMAXOBJECT-1; - if ( m_map[i].bUsed && i != m_hiliteRank ) // selection: - { - DrawObject(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color, TRUE, FALSE); - } - - if ( m_hiliteRank != -1 && m_map[m_hiliteRank].bUsed ) - { - i = m_hiliteRank; - DrawObject(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color, FALSE, TRUE); - DrawHilite(m_map[i].pos); - } -} - -// Computing a point for drawFocus. - -FPOINT CMap::MapInter(FPOINT pos, float dir) -{ - FPOINT p1; - float limit; - - p1.x = pos.x+1.0f; - p1.y = pos.y; - p1 = RotatePoint(pos, dir, p1); - - p1.x -= pos.x; - p1.y -= pos.y; - - limit = m_mapPos.x+m_mapDim.x-pos.x; - if ( p1.x > limit ) // exceeds the right? - { - p1.y = limit*p1.y/p1.x; - p1.x = limit; - } - limit = m_mapPos.y*0.75f+m_mapDim.y*0.75f-pos.y; - if ( p1.y > limit ) // exceeds the top? - { - p1.x = limit*p1.x/p1.y; - p1.y = limit; - } - limit = m_mapPos.x-pos.x; - if ( p1.x < limit ) // exceeds the left? - { - p1.y = limit*p1.y/p1.x; - p1.x = limit; - } - limit = m_mapPos.y*0.75f-pos.y; - if ( p1.y < limit ) // exceeds the bottom? - { - p1.x = limit*p1.x/p1.y; - p1.y = limit; - } - - p1.x += pos.x; - p1.y += pos.y; - return p1; -} - -// Draw the field of vision of the selected object. - -void CMap::DrawFocus(FPOINT pos, float dir, ObjectType type, MapColor color) -{ - FPOINT p0, p1, p2, uv1, uv2, rel; - float aMin, aMax, aOct, focus, a; - float limit[5]; - BOOL bEnding; - int quart; - - if ( m_bToy || m_fixImage[0] != 0 ) return; // map with still image? - if ( color != MAPCOLOR_MOVE ) return; - - pos.x = (pos.x-m_offset.x)*(m_zoom*0.5f)/m_half+0.5f; - pos.y = (pos.y-m_offset.y)*(m_zoom*0.5f)/m_half+0.5f; - - if ( pos.x < 0.0f || pos.x > 1.0f || - pos.y < 0.0f || pos.y > 1.0f ) return; - - rel.x = pos.x*2.0f-1.0f; - rel.y = pos.y*2.0f-1.0f; // rel [-1..1] - - pos.x = m_mapPos.x+m_mapDim.x*pos.x; - pos.y = m_mapPos.y*0.75f+m_mapDim.y*pos.y*0.75f; - - focus = m_engine->RetFocus(); - dir += PI/2.0f; - aMin = NormAngle(dir-PI/4.0f*focus); - aMax = NormAngle(dir+PI/4.0f*focus); - - if ( aMin > aMax ) - { - aMax += PI*2.0f; // aMax always after aMin - } - - limit[0] = RotateAngle( 1.0f-rel.x, 1.0f-rel.y); // upper/right - limit[1] = RotateAngle(-1.0f-rel.x, 1.0f-rel.y); // upper/left - limit[2] = RotateAngle(-1.0f-rel.x, -1.0f-rel.y); // lower/left - limit[3] = RotateAngle( 1.0f-rel.x, -1.0f-rel.y); // lower/right - limit[4] = limit[0]+PI*2.0f; - - a = NormAngle(aMin); - for ( quart=0 ; quart<4 ; quart++ ) - { - if ( a >= limit[quart+0] && - a <= limit[quart+1] ) break; - } - if ( quart == 4 ) quart = -1; - - uv1.x = 113.0f/256.0f; // degrade green - uv1.y = 240.5f/256.0f; - uv2.x = 126.0f/256.0f; - uv2.y = 255.0f/256.0f; - - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTw); - - bEnding = FALSE; - do - { - quart ++; - aOct = limit[quart%4]; - if ( quart >= 4 ) aOct += PI*2.0f; - if ( aOct >= aMax-CHOUIA ) - { - aOct = aMax; - bEnding = TRUE; - } - - p0 = pos; - p1 = MapInter(pos, aMin); - p2 = MapInter(pos, aOct); - p0.y /= 0.75f; - p1.y /= 0.75f; - p2.y /= 0.75f; - DrawTriangle(p0, p2, p1, uv1, uv2); - - aMin = aOct; - } - while ( !bEnding ); -} - -// Draw an object. - -void CMap::DrawObject(FPOINT pos, float dir, ObjectType type, MapColor color, - BOOL bSelect, BOOL bHilite) -{ - FPOINT p1, p2, p3, p4, p5, dim, uv1, uv2; - BOOL bOut, bUp, bDown, bLeft, bRight; - - pos.x = (pos.x-m_offset.x)*(m_zoom*0.5f)/m_half+0.5f; - pos.y = (pos.y-m_offset.y)*(m_zoom*0.5f)/m_half+0.5f; - - bOut = bUp = bDown = bLeft = bRight = FALSE; - if ( pos.x < 0.06f ) { pos.x = 0.02f; bOut = bLeft = TRUE; } - if ( pos.y < 0.06f ) { pos.y = 0.02f; bOut = bDown = TRUE; } - if ( pos.x > 0.94f ) { pos.x = 0.98f; bOut = bRight = TRUE; } - if ( pos.y > 0.94f ) { pos.y = 0.98f; bOut = bUp = TRUE; } - - pos.x = m_mapPos.x+m_mapDim.x*pos.x; - pos.y = m_mapPos.y+m_mapDim.y*pos.y; - dim.x = 2.0f/128.0f*0.75f; - dim.y = 2.0f/128.0f; - - if ( bOut ) // outside the map? - { - if ( color == MAPCOLOR_BBOX && !m_bRadar ) return; - if ( color == MAPCOLOR_ALIEN && !m_bRadar ) return; - - if ( Mod(m_time+(pos.x+pos.y)*4.0f, 0.6f) > 0.2f ) - { - return; // flashes - } - - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - if ( bUp ) - { - uv1.x = 160.5f/256.0f; // yellow triangle ^ - uv1.y = 240.5f/256.0f; - uv2.x = 175.0f/256.0f; - uv2.y = 255.0f/256.0f; - } - if ( bDown ) - { - uv1.x = 160.5f/256.0f; // yellow triangle v - uv1.y = 255.0f/256.0f; - uv2.x = 175.0f/256.0f; - uv2.y = 240.5f/256.0f; - } - if ( bRight ) - { - uv1.x = 176.5f/256.0f; // yellow triangle > - uv1.y = 240.5f/256.0f; - uv2.x = 191.0f/256.0f; - uv2.y = 255.0f/256.0f; - } - if ( bLeft ) - { - uv1.x = 191.0f/256.0f; // yellow triangle < - uv1.y = 240.5f/256.0f; - uv2.x = 176.5f/256.0f; - uv2.y = 255.0f/256.0f; - } - pos.x -= dim.x/2.0f; - pos.y -= dim.y/2.0f; - DrawIcon(pos, dim, uv1, uv2); - return; - } - - if ( bSelect ) - { - if ( m_bToy ) - { - dim.x *= 1.2f+sinf(m_time*8.0f)*0.1f; - dim.y *= 1.2f+sinf(m_time*8.0f)*0.1f; - } - else - { - dim.x *= 1.2f+sinf(m_time*8.0f)*0.3f; - dim.y *= 1.2f+sinf(m_time*8.0f)*0.3f; - } - } - if ( color == MAPCOLOR_BASE || - color == MAPCOLOR_FIX || - color == MAPCOLOR_MOVE ) - { - if ( bHilite ) - { - dim.x *= 2.2f; - dim.y *= 2.2f; - } - else - { - dim.x *= 0.6f; - dim.y *= 0.6f; - } - } - if ( color == MAPCOLOR_ALIEN ) - { - dim.x *= 1.4f; - dim.y *= 1.4f; - } - if ( type == OBJECT_TEEN28 ) // bottle? - { - dim.x *= 3.0f; - dim.y *= 3.0f; - bHilite = TRUE; - } - if ( type == OBJECT_TEEN34 ) // stone? - { - dim.x *= 2.0f; - dim.y *= 2.0f; - bHilite = TRUE; - } - - if ( color == MAPCOLOR_MOVE && bSelect ) - { - if ( m_bToy ) - { - p1.x = pos.x; - p1.y = pos.y+dim.y*1.4f; - p1 = RotatePoint(pos, dir, p1); - p1.x = pos.x+(p1.x-pos.x)*0.75f; - - p2.x = pos.x+dim.x*1.2f; - p2.y = pos.y+dim.y*0.8f; - p2 = RotatePoint(pos, dir, p2); - p2.x = pos.x+(p2.x-pos.x)*0.75f; - - p3.x = pos.x+dim.x*1.2f; - p3.y = pos.y-dim.y*1.0f; - p3 = RotatePoint(pos, dir, p3); - p3.x = pos.x+(p3.x-pos.x)*0.75f; - - p4.x = pos.x-dim.x*1.2f; - p4.y = pos.y-dim.y*1.0f; - p4 = RotatePoint(pos, dir, p4); - p4.x = pos.x+(p4.x-pos.x)*0.75f; - - p5.x = pos.x-dim.x*1.2f; - p5.y = pos.y+dim.y*0.8f; - p5 = RotatePoint(pos, dir, p5); - p5.x = pos.x+(p5.x-pos.x)*0.75f; - } - else - { - p1.x = pos.x; - p1.y = pos.y+dim.y*2.4f; - p1 = RotatePoint(pos, dir, p1); - p1.x = pos.x+(p1.x-pos.x)*0.75f; - - p2.x = pos.x+dim.x*1.0f; - p2.y = pos.y-dim.y*1.6f; - p2 = RotatePoint(pos, dir, p2); - p2.x = pos.x+(p2.x-pos.x)*0.75f; - - p3.x = pos.x-dim.x*1.0f; - p3.y = pos.y-dim.y*1.6f; - p3 = RotatePoint(pos, dir, p3); - p3.x = pos.x+(p3.x-pos.x)*0.75f; - } - } - - pos.x -= dim.x/2.0f; - pos.y -= dim.y/2.0f; - - if ( color == MAPCOLOR_BASE || - color == MAPCOLOR_FIX ) - { - DrawObjectIcon(pos, dim, color, type, bHilite); - } - - if ( color == MAPCOLOR_MOVE ) - { - if ( bSelect ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - if ( m_bToy ) - { - uv1.x = 164.5f/256.0f; // black pentagon - uv1.y = 228.5f/256.0f; - uv2.x = 172.0f/256.0f; - uv2.y = 236.0f/256.0f; - DrawPenta(p1, p2, p3, p4, p5, uv1, uv2); - } - else - { - uv1.x = 144.5f/256.0f; // red triangle - uv1.y = 240.5f/256.0f; - uv2.x = 159.0f/256.0f; - uv2.y = 255.0f/256.0f; - DrawTriangle(p1, p2, p3, uv1, uv2); - } - } - DrawObjectIcon(pos, dim, color, type, bHilite); - } - - if ( color == MAPCOLOR_BBOX ) - { - if ( m_bRadar ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTw); - uv1.x = 64.5f/256.0f; // blue triangle - uv1.y = 240.5f/256.0f; - uv2.x = 79.0f/256.0f; - uv2.y = 255.0f/256.0f; - DrawIcon(pos, dim, uv1, uv2); - } - } - - if ( color == MAPCOLOR_ALIEN ) - { - if ( m_bRadar ) - { - DrawObjectIcon(pos, dim, color, type, TRUE); - } - } - - if ( color == MAPCOLOR_WAYPOINTb ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 192.5f/256.0f; // blue cross - uv1.y = 240.5f/256.0f; - uv2.x = 207.0f/256.0f; - uv2.y = 255.0f/256.0f; - DrawIcon(pos, dim, uv1, uv2); - } - if ( color == MAPCOLOR_WAYPOINTr ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 208.5f/256.0f; // red cross - uv1.y = 240.5f/256.0f; - uv2.x = 223.0f/256.0f; - uv2.y = 255.0f/256.0f; - DrawIcon(pos, dim, uv1, uv2); - } - if ( color == MAPCOLOR_WAYPOINTg ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 224.5f/256.0f; // green cross - uv1.y = 240.5f/256.0f; - uv2.x = 239.0f/256.0f; - uv2.y = 255.0f/256.0f; - DrawIcon(pos, dim, uv1, uv2); - } - if ( color == MAPCOLOR_WAYPOINTy ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 240.5f/256.0f; // yellow cross - uv1.y = 240.5f/256.0f; - uv2.x = 255.0f/256.0f; - uv2.y = 255.0f/256.0f; - DrawIcon(pos, dim, uv1, uv2); - } - if ( color == MAPCOLOR_WAYPOINTv ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 192.5f/256.0f; // violet cross - uv1.y = 224.5f/256.0f; - uv2.x = 207.0f/256.0f; - uv2.y = 239.0f/256.0f; - DrawIcon(pos, dim, uv1, uv2); - } -} - -// Draws the icon of an object. - -void CMap::DrawObjectIcon(FPOINT pos, FPOINT dim, MapColor color, - ObjectType type, BOOL bHilite) -{ - FPOINT ppos, ddim, uv1, uv2; - float dp; - int icon; - - dp = 0.5f/256.0f; - - m_engine->SetTexture("button3.tga"); - m_engine->SetState(D3DSTATENORMAL); - if ( color == MAPCOLOR_MOVE ) - { - uv1.x = 160.0f/256.0f; // blue - uv1.y = 224.0f/256.0f; - } - else if ( color == MAPCOLOR_ALIEN ) - { - uv1.x = 224.0f/256.0f; // green - uv1.y = 224.0f/256.0f; - } - else - { - uv1.x = 192.0f/256.0f; // yellow - uv1.y = 224.0f/256.0f; - } - uv2.x = uv1.x+32.0f/256.0f; - uv2.y = uv1.y+32.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2); // background colors - - if ( bHilite ) - { - icon = -1; - if ( type == OBJECT_FACTORY ) icon = 32; - if ( type == OBJECT_DERRICK ) icon = 33; - if ( type == OBJECT_CONVERT ) icon = 34; - if ( type == OBJECT_RESEARCH ) icon = 35; - if ( type == OBJECT_STATION ) icon = 36; - if ( type == OBJECT_TOWER ) icon = 37; - if ( type == OBJECT_LABO ) icon = 38; - if ( type == OBJECT_ENERGY ) icon = 39; - if ( type == OBJECT_RADAR ) icon = 40; - if ( type == OBJECT_INFO ) icon = 44; - if ( type == OBJECT_REPAIR ) icon = 41; - if ( type == OBJECT_DESTROYER) icon = 41; - if ( type == OBJECT_NUCLEAR ) icon = 42; - if ( type == OBJECT_PARA ) icon = 46; - if ( type == OBJECT_SAFE ) icon = 47; - if ( type == OBJECT_HUSTON ) icon = 48; - if ( type == OBJECT_TARGET1 ) icon = 45; - if ( type == OBJECT_BASE ) icon = 43; - if ( type == OBJECT_HUMAN ) icon = 8; - if ( type == OBJECT_MOBILEfa ) icon = 11; - if ( type == OBJECT_MOBILEta ) icon = 10; - if ( type == OBJECT_MOBILEwa ) icon = 9; - if ( type == OBJECT_MOBILEia ) icon = 22; - if ( type == OBJECT_MOBILEfc ) icon = 17; - if ( type == OBJECT_MOBILEtc ) icon = 16; - if ( type == OBJECT_MOBILEwc ) icon = 15; - if ( type == OBJECT_MOBILEic ) icon = 23; - if ( type == OBJECT_MOBILEfi ) icon = 27; - if ( type == OBJECT_MOBILEti ) icon = 26; - if ( type == OBJECT_MOBILEwi ) icon = 25; - if ( type == OBJECT_MOBILEii ) icon = 28; - if ( type == OBJECT_MOBILEfs ) icon = 14; - if ( type == OBJECT_MOBILEts ) icon = 13; - if ( type == OBJECT_MOBILEws ) icon = 12; - if ( type == OBJECT_MOBILEis ) icon = 24; - if ( type == OBJECT_MOBILErt ) icon = 18; - if ( type == OBJECT_MOBILErc ) icon = 19; - if ( type == OBJECT_MOBILErr ) icon = 20; - if ( type == OBJECT_MOBILErs ) icon = 29; - if ( type == OBJECT_MOBILEsa ) icon = 21; - if ( type == OBJECT_MOBILEft ) icon = 30; - if ( type == OBJECT_MOBILEtt ) icon = 30; - if ( type == OBJECT_MOBILEwt ) icon = 30; - if ( type == OBJECT_MOBILEit ) icon = 30; - if ( type == OBJECT_MOBILEtg ) icon = 45; - if ( type == OBJECT_MOBILEdr ) icon = 48; - if ( type == OBJECT_APOLLO2 ) icon = 49; - if ( type == OBJECT_MOTHER ) icon = 31; - if ( type == OBJECT_ANT ) icon = 31; - if ( type == OBJECT_SPIDER ) icon = 31; - if ( type == OBJECT_BEE ) icon = 31; - if ( type == OBJECT_WORM ) icon = 31; - if ( type == OBJECT_TEEN28 ) icon = 48; // bottle - if ( type == OBJECT_TEEN34 ) icon = 48; // stone - if ( icon == -1 ) return; - - m_engine->SetState(D3DSTATETTw); - uv1.x = (32.0f/256.0f)*(icon%8); - uv1.y = (32.0f/256.0f)*(icon/8); - uv2.x = uv1.x+32.0f/256.0f; - uv2.y = uv1.y+32.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2); // icon - } -} - -// Draw the object with the mouse hovers over. - -void CMap::DrawHilite(FPOINT pos) -{ - FPOINT dim, uv1, uv2; - BOOL bOut, bUp, bDown, bLeft, bRight; - - if ( m_bToy || m_fixImage[0] != 0 ) return; // map with still image? - - pos.x = (pos.x-m_offset.x)*(m_zoom*0.5f)/m_half+0.5f; - pos.y = (pos.y-m_offset.y)*(m_zoom*0.5f)/m_half+0.5f; - - bOut = bUp = bDown = bLeft = bRight = FALSE; - if ( pos.x < 0.06f ) { pos.x = 0.02f; bOut = bLeft = TRUE; } - if ( pos.y < 0.06f ) { pos.y = 0.02f; bOut = bDown = TRUE; } - if ( pos.x > 0.94f ) { pos.x = 0.98f; bOut = bRight = TRUE; } - if ( pos.y > 0.94f ) { pos.y = 0.98f; bOut = bUp = TRUE; } - - pos.x = m_mapPos.x+m_mapDim.x*pos.x; - pos.y = m_mapPos.y+m_mapDim.y*pos.y; - dim.x = 2.0f/128.0f*0.75f; - dim.y = 2.0f/128.0f; - dim.x *= 2.0f+cosf(m_time*8.0f)*0.5f; - dim.y *= 2.0f+cosf(m_time*8.0f)*0.5f; - - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 160.5f/256.0f; // hilite - uv1.y = 224.5f/256.0f; - uv2.x = 175.0f/256.0f; - uv2.y = 239.0f/256.0f; - pos.x -= dim.x/2.0f; - pos.y -= dim.y/2.0f; - DrawIcon(pos, dim, uv1, uv2); -} - -// Draws a triangular icon. - -void CMap::DrawTriangle(FPOINT p1, FPOINT p2, FPOINT p3, FPOINT uv1, FPOINT uv2) -{ - LPDIRECT3DDEVICE7 device; - D3DVERTEX2 vertex[3]; // 1 triangle - D3DVECTOR n; - - device = m_engine->RetD3DDevice(); - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal - - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv1.y); - vertex[1] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv1.x,uv2.y); - vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv2.x,uv2.y); - - device->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_VERTEX2, vertex, 3, NULL); - m_engine->AddStatisticTriangle(1); -} - -// Draw a pentagon icon (a 5 rating, what!). - -void CMap::DrawPenta(FPOINT p1, FPOINT p2, FPOINT p3, FPOINT p4, FPOINT p5, FPOINT uv1, FPOINT uv2) -{ - LPDIRECT3DDEVICE7 device; - D3DVERTEX2 vertex[5]; // 1 pentagon - D3DVECTOR n; - - device = m_engine->RetD3DDevice(); - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal - -#if 1 - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv1.y); - vertex[1] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv1.x,uv2.y); - vertex[2] = D3DVERTEX2(D3DVECTOR(p5.x, p5.y, 0.0f), n, uv2.x,uv2.y); - vertex[3] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv2.x,uv2.y); - vertex[4] = D3DVERTEX2(D3DVECTOR(p4.x, p4.y, 0.0f), n, uv2.x,uv2.y); - - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 5, NULL); -#else - vertex[0] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv1.x,uv1.y); - vertex[1] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv1.x,uv2.y); - vertex[2] = D3DVERTEX2(D3DVECTOR(p4.x, p4.y, 0.0f), n, uv2.x,uv2.y); - - device->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_VERTEX2, vertex, 3, NULL); -#endif - m_engine->AddStatisticTriangle(3); -} - -// Draw the vertex array. - -void CMap::DrawVertex(FPOINT uv1, FPOINT uv2, float zoom) -{ - LPDIRECT3DDEVICE7 device; - D3DVERTEX2 vertex[4]; // 2 triangles - FPOINT p1, p2, c; - D3DVECTOR n; - - device = m_engine->RetD3DDevice(); - - p1.x = m_pos.x; - p1.y = m_pos.y; - p2.x = m_pos.x + m_dim.x; - p2.y = m_pos.y + m_dim.y; - - c.x = (p1.x+p2.x)/2.0f; - c.y = (p1.y+p2.y)/2.0f; // center - - p1.x = (p1.x-c.x)*zoom + c.x; - p1.y = (p1.y-c.y)*zoom + c.y; - - p2.x = (p2.x-c.x)*zoom + c.x; - p2.y = (p2.y-c.y)*zoom + c.y; - - m_mapPos = p1; - m_mapDim.x = p2.x-p1.x; - m_mapDim.y = p2.y-p1.y; - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal - - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x,uv1.y); - vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y); - vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv2.x,uv1.y); - - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); -} - - -// Updates the field in the map. - -void CMap::UpdateTerrain() -{ - D3DCOLORVALUE color; - D3DVECTOR pos; - float scale, water, level, intensity; - int x, y; - - if ( m_fixImage[0] != 0 ) return; // still image? - if ( !m_engine->OpenImage("map.tga") ) return; - - scale = m_terrain->RetScaleRelief(); - water = m_water->RetLevel(); - color.a = 0.0f; - - for ( y=0 ; y<256 ; y++ ) - { - for ( x=0 ; x<256 ; x++ ) - { - pos.x = ((float)x-128.0f)*m_half/128.0f; - pos.z = -((float)y-128.0f)*m_half/128.0f; - pos.y = 0.0f; - - if ( pos.x >= -m_half && pos.x <= m_half && - pos.z >= -m_half && pos.z <= m_half ) - { - level = m_terrain->RetFloorLevel(pos, TRUE)/scale; - } - else - { - level = 1000.0f; - } - - intensity = level/256.0f; - if ( intensity < 0.0f ) intensity = 0.0f; - if ( intensity > 1.0f ) intensity = 1.0f; - - if ( level >= water ) // on water? - { - color.r = m_floorColor.r + (intensity-0.5f); - color.g = m_floorColor.g + (intensity-0.5f); - color.b = m_floorColor.b + (intensity-0.5f); - } - else // underwater? - { - color.r = m_waterColor.r + (intensity-0.5f); - color.g = m_waterColor.g + (intensity-0.5f); - color.b = m_waterColor.b + (intensity-0.5f); - } - - m_engine->SetDot(x, y, color); - } - } - - m_engine->CopyImage(); // copy the ground drawing - m_engine->CloseImage(); -} - -// Updates the field in the map. - -void CMap::UpdateTerrain(int bx, int by, int ex, int ey) -{ - D3DCOLORVALUE color; - D3DVECTOR pos; - float scale, water, level, intensity; - int x, y; - - if ( m_fixImage[0] != 0 ) return; // still image? - if ( !m_engine->OpenImage("map.tga") ) return; - m_engine->LoadImage(); - - scale = m_terrain->RetScaleRelief(); - water = m_water->RetLevel(); - color.a = 0.0f; - - for ( y=by ; y= -m_half && pos.x <= m_half && - pos.z >= -m_half && pos.z <= m_half ) - { - level = m_terrain->RetFloorLevel(pos, TRUE)/scale; - } - else - { - level = 1000.0f; - } - - intensity = level/256.0f; - if ( intensity < 0.0f ) intensity = 0.0f; - if ( intensity > 1.0f ) intensity = 1.0f; - - if ( level > water ) // on water? - { - color.r = m_floorColor.r + (intensity-0.5f); - color.g = m_floorColor.g + (intensity-0.5f); - color.b = m_floorColor.b + (intensity-0.5f); - } - else // underwater? - { - color.r = m_waterColor.r + (intensity-0.5f); - color.g = m_waterColor.g + (intensity-0.5f); - color.b = m_waterColor.b + (intensity-0.5f); - } - - m_engine->SetDot(x, y, color); - } - } - - m_engine->CopyImage(); // copy the ground drawing - m_engine->CloseImage(); -} - - -// Empty all objects. - -void CMap::FlushObject() -{ - int i; - - m_totalFix = 0; // object index fixed - m_totalMove = MAPMAXOBJECT-2; // moving vehicles index - m_bRadar = m_main->RetCheatRadar(); // no radar - - for ( i=0 ; i= m_totalMove ) return; // full table? - - if ( !pObj->RetActif() ) return; - if ( !pObj->RetSelectable() ) return; - if ( pObj->RetProxyActivate() ) return; - if ( pObj->RetTruck() != 0 ) return; - - type = pObj->RetType(); - pos = pObj->RetPosition(0); - dir = -(pObj->RetAngleY(0)+PI/2.0f); - - if ( m_angle != 0.0f ) - { - ppos = RotatePoint(m_angle, FPOINT(pos.x, pos.z)); - pos.x = ppos.x; - pos.z = ppos.y; - dir += m_angle; - } - - if ( type == OBJECT_RADAR ) - { - m_bRadar = TRUE; // radar exists - } - - color = MAPCOLOR_NULL; - if ( type == OBJECT_BASE ) - { - color = MAPCOLOR_BASE; - } - if ( type == OBJECT_DERRICK || - type == OBJECT_FACTORY || - type == OBJECT_STATION || - type == OBJECT_CONVERT || - type == OBJECT_REPAIR || - type == OBJECT_DESTROYER|| - type == OBJECT_TOWER || - type == OBJECT_RESEARCH || - type == OBJECT_RADAR || - type == OBJECT_INFO || - type == OBJECT_ENERGY || - type == OBJECT_LABO || - type == OBJECT_NUCLEAR || - type == OBJECT_PARA || - type == OBJECT_SAFE || - type == OBJECT_HUSTON || - type == OBJECT_TARGET1 || - type == OBJECT_START || - type == OBJECT_END || // stationary object? - type == OBJECT_TEEN28 || // bottle? - type == OBJECT_TEEN34 ) // stone? - { - color = MAPCOLOR_FIX; - } - if ( type == OBJECT_BBOX || - type == OBJECT_KEYa || - type == OBJECT_KEYb || - type == OBJECT_KEYc || - type == OBJECT_KEYd ) - { - color = MAPCOLOR_BBOX; - } - if ( type == OBJECT_HUMAN || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEia || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs || - type == OBJECT_MOBILEsa || - type == OBJECT_MOBILEtg || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEtt || - type == OBJECT_MOBILEft || - type == OBJECT_MOBILEit || - type == OBJECT_MOBILEdr || - type == OBJECT_APOLLO2 ) // moving vehicle? - { - color = MAPCOLOR_MOVE; - } - if ( type == OBJECT_ANT || - type == OBJECT_BEE || - type == OBJECT_WORM || - type == OBJECT_SPIDER ) // mobile enemy? - { - color = MAPCOLOR_ALIEN; - } - if ( type == OBJECT_WAYPOINT || - type == OBJECT_FLAGb ) - { - color = MAPCOLOR_WAYPOINTb; - } - if ( type == OBJECT_FLAGr ) - { - color = MAPCOLOR_WAYPOINTr; - } - if ( type == OBJECT_FLAGg ) - { - color = MAPCOLOR_WAYPOINTg; - } - if ( type == OBJECT_FLAGy ) - { - color = MAPCOLOR_WAYPOINTy; - } - if ( type == OBJECT_FLAGv ) - { - color = MAPCOLOR_WAYPOINTv; - } - - if ( color == MAPCOLOR_NULL ) return; - - if ( m_fixImage[0] != 0 && !m_bDebug ) // map with still image? - { - if ( (type == OBJECT_TEEN28 || - type == OBJECT_TEEN34 ) && - m_mode == 0 ) return; - - if ( type != OBJECT_TEEN28 && - type != OBJECT_TEEN34 && - color != MAPCOLOR_MOVE ) return; - } - - if ( pObj->RetSelect() ) - { - m_map[MAPMAXOBJECT-1].type = type; - m_map[MAPMAXOBJECT-1].object = pObj; - m_map[MAPMAXOBJECT-1].color = color; - m_map[MAPMAXOBJECT-1].pos.x = pos.x; - m_map[MAPMAXOBJECT-1].pos.y = pos.z; - m_map[MAPMAXOBJECT-1].dir = dir; - m_map[MAPMAXOBJECT-1].bUsed = TRUE; - } - else - { - if ( color == MAPCOLOR_BASE || - color == MAPCOLOR_FIX ) - { - m_map[m_totalFix].type = type; - m_map[m_totalFix].object = pObj; - m_map[m_totalFix].color = color; - m_map[m_totalFix].pos.x = pos.x; - m_map[m_totalFix].pos.y = pos.z; - m_map[m_totalFix].dir = dir; - m_map[m_totalFix].bUsed = TRUE; - m_totalFix ++; - } - else - { - m_map[m_totalMove].type = type; - m_map[m_totalMove].object = pObj; - m_map[m_totalMove].color = color; - m_map[m_totalMove].pos.x = pos.x; - m_map[m_totalMove].pos.y = pos.z; - m_map[m_totalMove].dir = dir; - m_map[m_totalMove].bUsed = TRUE; - m_totalMove --; - } - } -} - diff --git a/src/map.h b/src/map.h deleted file mode 100644 index 4b1f793..0000000 --- a/src/map.h +++ /dev/null @@ -1,141 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// map.h - -#ifndef _MAP_H_ -#define _MAP_H_ - - -#include "control.h" -#include "struct.h" -#include "object.h" - - -class CD3DEngine; -class CTerrain; -class CWater; -class CRobotMain; - - - -#define MAPMAXOBJECT 100 - -enum MapColor -{ - MAPCOLOR_NULL, - MAPCOLOR_BASE, - MAPCOLOR_FIX, - MAPCOLOR_MOVE, - MAPCOLOR_ALIEN, - MAPCOLOR_WAYPOINTb, - MAPCOLOR_WAYPOINTr, - MAPCOLOR_WAYPOINTg, - MAPCOLOR_WAYPOINTy, - MAPCOLOR_WAYPOINTv, - MAPCOLOR_BBOX, -}; - -typedef struct -{ - char bUsed; - CObject* object; - MapColor color; - ObjectType type; - FPOINT pos; - float dir; -} -MapObject; - - - -class CMap : public CControl -{ -public: - CMap(CInstanceManager* iMan); - ~CMap(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - BOOL EventProcess(const Event &event); - void Draw(); - - void UpdateTerrain(); - void UpdateTerrain(int bx, int by, int ex, int ey); - - void SetFixImage(char *filename); - BOOL RetFixImage(); - - void SetOffset(float ox, float oy); - void SetAngle(float angle); - void SetMode(int mode); - void SetToy(BOOL bToy); - void SetDebug(BOOL bDebug); - - void SetZoom(float value); - float RetZoom(); - - void SetEnable(BOOL bEnable); - BOOL RetEnable(); - - void SetFloorColor(D3DCOLORVALUE color); - void SetWaterColor(D3DCOLORVALUE color); - - void FlushObject(); - void UpdateObject(CObject* pObj); - - CObject* DetectObject(FPOINT pos, BOOL &bInMap); - void SetHilite(CObject* pObj); - -protected: - FPOINT AdjustOffset(FPOINT offset); - void SelectObject(FPOINT pos); - FPOINT MapInter(FPOINT pos, float dir); - void DrawFocus(FPOINT pos, float dir, ObjectType type, MapColor color); - void DrawObject(FPOINT pos, float dir, ObjectType type, MapColor color, BOOL bSelect, BOOL bHilite); - void DrawObjectIcon(FPOINT pos, FPOINT dim, MapColor color, ObjectType type, BOOL bHilite); - void DrawHilite(FPOINT pos); - void DrawTriangle(FPOINT p1, FPOINT p2, FPOINT p3, FPOINT uv1, FPOINT uv2); - void DrawPenta(FPOINT p1, FPOINT p2, FPOINT p3, FPOINT p4, FPOINT p5, FPOINT uv1, FPOINT uv2); - void DrawVertex(FPOINT uv1, FPOINT uv2, float zoom); - -protected: - CTerrain* m_terrain; - CWater* m_water; - CRobotMain* m_main; - - BOOL m_bEnable; - float m_time; - float m_half; - float m_zoom; - FPOINT m_offset; - float m_angle; - D3DCOLORVALUE m_floorColor; - D3DCOLORVALUE m_waterColor; - MapObject m_map[MAPMAXOBJECT]; - int m_totalFix; - int m_totalMove; - int m_hiliteRank; - FPOINT m_mapPos; - FPOINT m_mapDim; - BOOL m_bRadar; - char m_fixImage[100]; - int m_mode; - BOOL m_bToy; - BOOL m_bDebug; -}; - - -#endif //_MAP_H_ diff --git a/src/math/README.txt b/src/math/README.txt new file mode 100644 index 0000000..1a5ce93 --- /dev/null +++ b/src/math/README.txt @@ -0,0 +1,3 @@ +src/math + +Contains common mathematical structures and functions. diff --git a/src/math/d3dmath.cpp b/src/math/d3dmath.cpp new file mode 100644 index 0000000..2686215 --- /dev/null +++ b/src/math/d3dmath.cpp @@ -0,0 +1,343 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +//----------------------------------------------------------------------------- +// File: D3DMath.cpp +// +// Desc: Shortcut macros and functions for using DX objects +// +// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved +//----------------------------------------------------------------------------- +#define D3D_OVERLOADS +#define STRICT +#include +#include +#include "d3dmath.h" + + + + +//----------------------------------------------------------------------------- +// Name: D3DMath_MatrixMultiply() +// Desc: Does the matrix operation: [Q] = [A] * [B]. Note that the order of +// this operation was changed from the previous version of the DXSDK. +//----------------------------------------------------------------------------- +VOID D3DMath_MatrixMultiply( D3DMATRIX& q, D3DMATRIX& a, D3DMATRIX& b ) +{ + FLOAT* pA = (FLOAT*)&a; + FLOAT* pB = (FLOAT*)&b; + FLOAT pM[16]; + + ZeroMemory( pM, sizeof(D3DMATRIX) ); + + for( WORD i=0; i<4; i++ ) + for( WORD j=0; j<4; j++ ) + for( WORD k=0; k<4; k++ ) + pM[4*i+j] += pA[4*i+k] * pB[4*k+j]; + + memcpy( &q, pM, sizeof(D3DMATRIX) ); +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DMath_MatrixInvert() +// Desc: Does the matrix operation: [Q] = inv[A]. Note: this function only +// works for matrices with [0 0 0 1] for the 4th column. +//----------------------------------------------------------------------------- +HRESULT D3DMath_MatrixInvert( D3DMATRIX& q, D3DMATRIX& a ) +{ + if( fabs(a._44 - 1.0f) > .001f) + return E_INVALIDARG; + if( fabs(a._14) > .001f || fabs(a._24) > .001f || fabs(a._34) > .001f ) + return E_INVALIDARG; + + FLOAT fDetInv = 1.0f / ( a._11 * ( a._22 * a._33 - a._23 * a._32 ) - + a._12 * ( a._21 * a._33 - a._23 * a._31 ) + + a._13 * ( a._21 * a._32 - a._22 * a._31 ) ); + + q._11 = fDetInv * ( a._22 * a._33 - a._23 * a._32 ); + q._12 = -fDetInv * ( a._12 * a._33 - a._13 * a._32 ); + q._13 = fDetInv * ( a._12 * a._23 - a._13 * a._22 ); + q._14 = 0.0f; + + q._21 = -fDetInv * ( a._21 * a._33 - a._23 * a._31 ); + q._22 = fDetInv * ( a._11 * a._33 - a._13 * a._31 ); + q._23 = -fDetInv * ( a._11 * a._23 - a._13 * a._21 ); + q._24 = 0.0f; + + q._31 = fDetInv * ( a._21 * a._32 - a._22 * a._31 ); + q._32 = -fDetInv * ( a._11 * a._32 - a._12 * a._31 ); + q._33 = fDetInv * ( a._11 * a._22 - a._12 * a._21 ); + q._34 = 0.0f; + + q._41 = -( a._41 * q._11 + a._42 * q._21 + a._43 * q._31 ); + q._42 = -( a._41 * q._12 + a._42 * q._22 + a._43 * q._32 ); + q._43 = -( a._41 * q._13 + a._42 * q._23 + a._43 * q._33 ); + q._44 = 1.0f; + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DMath_VectorMatrixMultiply() +// Desc: Multiplies a vector by a matrix +//----------------------------------------------------------------------------- +HRESULT D3DMath_VectorMatrixMultiply( D3DVECTOR& vDest, D3DVECTOR& vSrc, + D3DMATRIX& mat) +{ + FLOAT x = vSrc.x*mat._11 + vSrc.y*mat._21 + vSrc.z* mat._31 + mat._41; + FLOAT y = vSrc.x*mat._12 + vSrc.y*mat._22 + vSrc.z* mat._32 + mat._42; + FLOAT z = vSrc.x*mat._13 + vSrc.y*mat._23 + vSrc.z* mat._33 + mat._43; + FLOAT w = vSrc.x*mat._14 + vSrc.y*mat._24 + vSrc.z* mat._34 + mat._44; + + if( fabs( w ) < g_EPSILON ) + return E_INVALIDARG; + + vDest.x = x/w; + vDest.y = y/w; + vDest.z = z/w; + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DMath_VertexMatrixMultiply() +// Desc: Multiplies a vertex by a matrix +//----------------------------------------------------------------------------- +HRESULT D3DMath_VertexMatrixMultiply( D3DVERTEX& vDest, D3DVERTEX& vSrc, + D3DMATRIX& mat ) +{ + HRESULT hr; + D3DVECTOR* pSrcVec = (D3DVECTOR*)&vSrc.x; + D3DVECTOR* pDestVec = (D3DVECTOR*)&vDest.x; + + if( SUCCEEDED( hr = D3DMath_VectorMatrixMultiply( *pDestVec, *pSrcVec, + mat ) ) ) + { + pSrcVec = (D3DVECTOR*)&vSrc.nx; + pDestVec = (D3DVECTOR*)&vDest.nx; + hr = D3DMath_VectorMatrixMultiply( *pDestVec, *pSrcVec, mat ); + } + return hr; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DMath_QuaternionFromRotation() +// Desc: Converts a normalized axis and angle to a unit quaternion. +//----------------------------------------------------------------------------- +VOID D3DMath_QuaternionFromRotation( FLOAT& x, FLOAT& y, FLOAT& z, FLOAT& w, + D3DVECTOR& v, FLOAT fTheta ) +{ + x = sinf( fTheta/2.0f ) * v.x; + y = sinf( fTheta/2.0f ) * v.y; + z = sinf( fTheta/2.0f ) * v.z; + w = cosf( fTheta/2.0f ); +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DMath_RotationFromQuaternion() +// Desc: Converts a normalized axis and angle to a unit quaternion. +//----------------------------------------------------------------------------- +VOID D3DMath_RotationFromQuaternion( D3DVECTOR& v, FLOAT& fTheta, + FLOAT x, FLOAT y, FLOAT z, FLOAT w ) + +{ + fTheta = acosf(w) * 2.0f; + v.x = x / sinf( fTheta/2.0f ); + v.y = y / sinf( fTheta/2.0f ); + v.z = z / sinf( fTheta/2.0f ); +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DMath_QuaternionFromAngles() +// Desc: Converts euler angles to a unit quaternion. +//----------------------------------------------------------------------------- +VOID D3DMath_QuaternionFromAngles( FLOAT& x, FLOAT& y, FLOAT& z, FLOAT& w, + FLOAT fYaw, FLOAT fPitch, FLOAT fRoll ) + +{ + FLOAT fSinYaw = sinf( fYaw/2.0f ); + FLOAT fSinPitch = sinf( fPitch/2.0f ); + FLOAT fSinRoll = sinf( fRoll/2.0f ); + FLOAT fCosYaw = cosf( fYaw/2.0f ); + FLOAT fCosPitch = cosf( fPitch/2.0f ); + FLOAT fCosRoll = cosf( fRoll/2.0f ); + + x = fSinRoll * fCosPitch * fCosYaw - fCosRoll * fSinPitch * fSinYaw; + y = fCosRoll * fSinPitch * fCosYaw + fSinRoll * fCosPitch * fSinYaw; + z = fCosRoll * fCosPitch * fSinYaw - fSinRoll * fSinPitch * fCosYaw; + w = fCosRoll * fCosPitch * fCosYaw + fSinRoll * fSinPitch * fSinYaw; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DMath_MatrixFromQuaternion() +// Desc: Converts a unit quaternion into a rotation matrix. +//----------------------------------------------------------------------------- +VOID D3DMath_MatrixFromQuaternion( D3DMATRIX& mat, FLOAT x, FLOAT y, FLOAT z, + FLOAT w ) +{ + FLOAT xx = x*x; FLOAT yy = y*y; FLOAT zz = z*z; + FLOAT xy = x*y; FLOAT xz = x*z; FLOAT yz = y*z; + FLOAT wx = w*x; FLOAT wy = w*y; FLOAT wz = w*z; + + mat._11 = 1 - 2 * ( yy + zz ); + mat._12 = 2 * ( xy - wz ); + mat._13 = 2 * ( xz + wy ); + + mat._21 = 2 * ( xy + wz ); + mat._22 = 1 - 2 * ( xx + zz ); + mat._23 = 2 * ( yz - wx ); + + mat._31 = 2 * ( xz - wy ); + mat._32 = 2 * ( yz + wx ); + mat._33 = 1 - 2 * ( xx + yy ); + + mat._14 = mat._24 = mat._34 = 0.0f; + mat._41 = mat._42 = mat._43 = 0.0f; + mat._44 = 1.0f; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DMath_QuaternionFromMatrix() +// Desc: Converts a rotation matrix into a unit quaternion. +//----------------------------------------------------------------------------- +VOID D3DMath_QuaternionFromMatrix( FLOAT& x, FLOAT& y, FLOAT& z, FLOAT& w, + D3DMATRIX& mat ) +{ + if( mat._11 + mat._22 + mat._33 > 0.0f ) + { + FLOAT s = sqrtf( mat._11 + mat._22 + mat._33 + mat._44 ); + + x = (mat._23-mat._32) / (2*s); + y = (mat._31-mat._13) / (2*s); + z = (mat._12-mat._21) / (2*s); + w = 0.5f * s; + } + else + { + + + } + FLOAT xx = x*x; FLOAT yy = y*y; FLOAT zz = z*z; + FLOAT xy = x*y; FLOAT xz = x*z; FLOAT yz = y*z; + FLOAT wx = w*x; FLOAT wy = w*y; FLOAT wz = w*z; + + mat._11 = 1 - 2 * ( yy + zz ); + mat._12 = 2 * ( xy - wz ); + mat._13 = 2 * ( xz + wy ); + + mat._21 = 2 * ( xy + wz ); + mat._22 = 1 - 2 * ( xx + zz ); + mat._23 = 2 * ( yz - wx ); + + mat._31 = 2 * ( xz - wy ); + mat._32 = 2 * ( yz + wx ); + mat._33 = 1 - 2 * ( xx + yy ); + + mat._14 = mat._24 = mat._34 = 0.0f; + mat._41 = mat._42 = mat._43 = 0.0f; + mat._44 = 1.0f; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DMath_QuaternionMultiply() +// Desc: Mulitples two quaternions together as in {Q} = {A} * {B}. +//----------------------------------------------------------------------------- +VOID D3DMath_QuaternionMultiply( FLOAT& Qx, FLOAT& Qy, FLOAT& Qz, FLOAT& Qw, + FLOAT Ax, FLOAT Ay, FLOAT Az, FLOAT Aw, + FLOAT Bx, FLOAT By, FLOAT Bz, FLOAT Bw ) +{ + FLOAT Dx = Ax*Bw + Ay*Bz - Az*By + Aw*Bx; + FLOAT Dy = -Ax*Bz + Ay*Bw + Az*Bx + Aw*By; + FLOAT Dz = Ax*By - Ay*Bx + Az*Bw + Aw*Bz; + FLOAT Dw = -Ax*Bx - Ay*By - Az*Bz + Aw*Bw; + + Qx = Dx; Qy = Dy; Qz = Dz; Qw = Dw; +} + + + + +//----------------------------------------------------------------------------- +// Name: D3DMath_SlerpQuaternions() +// Desc: Compute a quaternion which is the spherical linear interpolation +// between two other quaternions by dvFraction. +//----------------------------------------------------------------------------- +VOID D3DMath_QuaternionSlerp( FLOAT& Qx, FLOAT& Qy, FLOAT& Qz, FLOAT& Qw, + FLOAT Ax, FLOAT Ay, FLOAT Az, FLOAT Aw, + FLOAT Bx, FLOAT By, FLOAT Bz, FLOAT Bw, + FLOAT fAlpha ) +{ + // Compute dot product (equal to cosine of the angle between quaternions) + FLOAT fCosTheta = Ax*Bx + Ay*By + Az*Bz + Aw*Bw; + + // Check angle to see if quaternions are in opposite hemispheres + if( fCosTheta < 0.0f ) + { + // If so, flip one of the quaterions + fCosTheta = -fCosTheta; + Bx = -Bx; By = -By; Bz = -Bz; Bw = -Bw; + } + + // Set factors to do linear interpolation, as a special case where the + // quaternions are close together. + FLOAT fBeta = 1.0f - fAlpha; + + // If the quaternions aren't close, proceed with spherical interpolation + if( 1.0f - fCosTheta > 0.001f ) + { + FLOAT fTheta = acosf( fCosTheta ); + + fBeta = sinf( fTheta*fBeta ) / sinf( fTheta); + fAlpha = sinf( fTheta*fAlpha ) / sinf( fTheta); + } + + // Do the interpolation + Qx = fBeta*Ax + fAlpha*Bx; + Qy = fBeta*Ay + fAlpha*By; + Qz = fBeta*Az + fAlpha*Bz; + Qw = fBeta*Aw + fAlpha*Bw; +} + + + + diff --git a/src/math/d3dmath.h b/src/math/d3dmath.h new file mode 100644 index 0000000..d28707d --- /dev/null +++ b/src/math/d3dmath.h @@ -0,0 +1,97 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +//----------------------------------------------------------------------------- +// File: D3DMath.h +// +// Desc: Math functions and shortcuts for Direct3D programming. +// +// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved +//----------------------------------------------------------------------------- +#ifndef D3DMATH_H +#define D3DMATH_H +#include +#include + + +//----------------------------------------------------------------------------- +// Useful Math constants +//----------------------------------------------------------------------------- +const FLOAT g_PI = 3.14159265358979323846f; // Pi +const FLOAT g_2_PI = 6.28318530717958623200f; // 2 * Pi +const FLOAT g_PI_DIV_2 = 1.57079632679489655800f; // Pi / 2 +const FLOAT g_PI_DIV_4 = 0.78539816339744827900f; // Pi / 4 +const FLOAT g_INV_PI = 0.31830988618379069122f; // 1 / Pi +const FLOAT g_DEGTORAD = 0.01745329251994329547f; // Degrees to Radians +const FLOAT g_RADTODEG = 57.29577951308232286465f; // Radians to Degrees +const FLOAT g_HUGE = 1.0e+38f; // Huge number for FLOAT +const FLOAT g_EPSILON = 1.0e-5f; // Tolerance for FLOATs + + + + +//----------------------------------------------------------------------------- +// Fuzzy compares (within tolerance) +//----------------------------------------------------------------------------- +inline BOOL D3DMath_IsZero( FLOAT a, FLOAT fTol = g_EPSILON ) +{ return ( a <= 0.0f ) ? ( a >= -fTol ) : ( a <= fTol ); } + + + + +//----------------------------------------------------------------------------- +// Matrix functions +//----------------------------------------------------------------------------- +VOID D3DMath_MatrixMultiply( D3DMATRIX& q, D3DMATRIX& a, D3DMATRIX& b ); +HRESULT D3DMath_MatrixInvert( D3DMATRIX& q, D3DMATRIX& a ); + + + + +//----------------------------------------------------------------------------- +// Vector functions +//----------------------------------------------------------------------------- +HRESULT D3DMath_VectorMatrixMultiply( D3DVECTOR& vDest, D3DVECTOR& vSrc, + D3DMATRIX& mat); +HRESULT D3DMath_VertexMatrixMultiply( D3DVERTEX& vDest, D3DVERTEX& vSrc, + D3DMATRIX& mat ); + + + + +//----------------------------------------------------------------------------- +// Quaternion functions +//----------------------------------------------------------------------------- +VOID D3DMath_QuaternionFromRotation( FLOAT& x, FLOAT& y, FLOAT& z, FLOAT& w, + D3DVECTOR& v, FLOAT fTheta ); +VOID D3DMath_RotationFromQuaternion( D3DVECTOR& v, FLOAT& fTheta, + FLOAT x, FLOAT y, FLOAT z, FLOAT w ); +VOID D3DMath_QuaternionFromAngles( FLOAT& x, FLOAT& y, FLOAT& z, FLOAT& w, + FLOAT fYaw, FLOAT fPitch, FLOAT fRoll ); +VOID D3DMath_MatrixFromQuaternion( D3DMATRIX& mat, FLOAT x, FLOAT y, FLOAT z, + FLOAT w ); +VOID D3DMath_QuaternionFromMatrix( FLOAT &x, FLOAT &y, FLOAT &z, FLOAT &w, + D3DMATRIX& mat ); +VOID D3DMath_QuaternionMultiply( FLOAT& Qx, FLOAT& Qy, FLOAT& Qz, FLOAT& Qw, + FLOAT Ax, FLOAT Ay, FLOAT Az, FLOAT Aw, + FLOAT Bx, FLOAT By, FLOAT Bz, FLOAT Bw ); +VOID D3DMath_QuaternionSlerp( FLOAT& Qx, FLOAT& Qy, FLOAT& Qz, FLOAT& Qw, + FLOAT Ax, FLOAT Ay, FLOAT Az, FLOAT Aw, + FLOAT Bx, FLOAT By, FLOAT Bz, FLOAT Bw, + FLOAT fAlpha ); + + +#endif // D3DMATH_H diff --git a/src/math/math3d.cpp b/src/math/math3d.cpp new file mode 100644 index 0000000..9aa5f89 --- /dev/null +++ b/src/math/math3d.cpp @@ -0,0 +1,1035 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// math3d.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "d3dutil.h" +#include "math3d.h" + + + +// Returns TRUE if two numbers are nearly equal. + +BOOL IsEqual(float a, float b) +{ + return Abs(a-b) < CHOUIA; +} + + +// Returns the minimum value. + +float Min(float a, float b) +{ + if ( a <= b ) return a; + else return b; +} + +float Min(float a, float b, float c) +{ + return Min( Min(a,b), c ); +} + +float Min(float a, float b, float c, float d) +{ + return Min( Min(a,b), Min(c,d) ); +} + +float Min(float a, float b, float c, float d, float e) +{ + return Min( Min(a,b), Min(c,d), e ); +} + + +// Returns the maximum value. + +float Max(float a, float b) +{ + if ( a >= b ) return a; + else return b; +} + +float Max(float a, float b, float c) +{ + return Max( Max(a,b), c ); +} + +float Max(float a, float b, float c, float d) +{ + return Max( Max(a,b), Max(c,d) ); +} + +float Max(float a, float b, float c, float d, float e) +{ + return Max( Max(a,b), Max(c,d), e ); +} + + +// Returns the normalized value (0 .. 1). + +float Norm(float a) +{ + if ( a < 0.0f ) return 0.0f; + if ( a > 1.0f ) return 1.0f; + return a; +} + + +// Returns the absolute value of a number. + +float Abs(float a) +{ + return (float)fabs(a); +} + + +// Swaps two integers. + +void Swap(int &a, int &b) +{ + int c; + + c = a; + a = b; + b = c; +} + +// Swaps two real numbers. + +void Swap(float &a, float &b) +{ + float c; + + c = a; + a = b; + b = c; +} + +// Permutes two points. + +void Swap(FPOINT &a, FPOINT &b) +{ + FPOINT c; + + c = a; + a = b; + b = c; +} + +// Returns the modulo of a floating point number. +// Mod(8.1, 4) = 0.1 +// Mod(n, 1) = fractional part of n + +float Mod(float a, float m) +{ + return a - ((int)(a/m))*m; +} + +// Returns a normalized angle, that is in other words between 0 and 2 * PI. + +float NormAngle(float angle) +{ + angle = Mod(angle, PI*2.0f); + if ( angle < 0.0f ) + { + return PI*2.0f + angle; + } + else + { + return angle; + } +} + +// Test if a angle is between two terminals. + +BOOL TestAngle(float angle, float min, float max) +{ + angle = NormAngle(angle); + min = NormAngle(min); + max = NormAngle(max); + + if ( min > max ) + { + return ( angle <= max || angle >= min ); + } + else + { + return ( angle >= min && angle <= max ); + } +} + + +// Calculates the angle to rotate the angle a to the angle g. +// A positive angle is counterclockwise (CCW). + +float Direction(float a, float g) +{ + a = NormAngle(a); + g = NormAngle(g); + + if ( a < g ) + { + if ( a+PI*2.0f-g < g-a ) a += PI*2.0f; + } + else + { + if ( g+PI*2.0f-a < a-g ) g += PI*2.0f; + } + return (g-a); +} + + +// Rotates a point around a center. +// The angle is in radians. +// A positive angle is counterclockwise (CCW). + +FPOINT RotatePoint(FPOINT center, float angle, FPOINT p) +{ + FPOINT a, b; + + a.x = p.x-center.x; + a.y = p.y-center.y; + + b.x = a.x*cosf(angle) - a.y*sinf(angle); + b.y = a.x*sinf(angle) + a.y*cosf(angle); + + b.x += center.x; + b.y += center.y; + return b; +} + +// Rotates a point around the origin. +// The angle is in radians. +// A positive angle is counterclockwise (CCW). + +FPOINT RotatePoint(float angle, FPOINT p) +{ + FPOINT a; + + a.x = p.x*cosf(angle) - p.y*sinf(angle); + a.y = p.x*sinf(angle) + p.y*cosf(angle); + + return a; +} + +// Rotates a vector (dist, 0). +// The angle is in radians. +// A positive angle is counterclockwise (CCW). + +FPOINT RotatePoint(float angle, float dist) +{ + FPOINT a; + + a.x = dist*cosf(angle); + a.y = dist*sinf(angle); + + return a; +} + +// Calculates the angle of a right triangle. +// The angle is counterclockwise (CCW), between 0 and 2 * PI. +// For an angle clockwise (CW), just go ahead. +// +// ^ +// | +// y o----o +// | / | +// |/)a | +// ----o----o--> +// | x +// | + +float RotateAngle(float x, float y) +{ +#if 1 + if ( x == 0.0f && y == 0.0f ) return 0.0f; + + if ( x >= 0.0f ) + { + if ( y >= 0.0f ) + { + if ( x > y ) return atanf(y/x); + else return PI*0.5f - atanf(x/y); + } + else + { + if ( x > -y ) return PI*2.0f + atanf(y/x); + else return PI*1.5f - atanf(x/y); + } + } + else + { + if ( y >= 0.0f ) + { + if ( -x > y ) return PI*1.0f + atanf(y/x); + else return PI*0.5f - atanf(x/y); + } + else + { + if ( -x > -y ) return PI*1.0f + atanf(y/x); + else return PI*1.5f - atanf(x/y); + } + } +#else + float angle; + + if ( x == 0.0f ) + { + if ( y > 0.0f ) + { + return 90.0f*PI/180.0f; + } + else + { + return 270.0f*PI/180.0f; + } + } + else + { + angle = atanf(y/x); + if ( x < 0.0f ) + { + angle += PI; + } + return angle; + } +#endif +} + +// Calculates the angle between two points and one center. +// The angle is in radians. +// A positive angle is counterclockwise (CCW). + +float RotateAngle(FPOINT center, FPOINT p1, FPOINT p2) +{ + float a1, a2, a; + + if ( p1.x == center.x && + p1.y == center.y ) return 0; + + if ( p2.x == center.x && + p2.y == center.y ) return 0; + + a1 = asinf((p1.y-center.y)/Length(p1,center)); + a2 = asinf((p2.y-center.y)/Length(p2,center)); + + if ( p1.x < center.x ) a1 = PI-a1; + if ( p2.x < center.x ) a2 = PI-a2; + + a = a2-a1; + if ( a < 0 ) a += PI*2; + return a; +} + +// Returns py up on the line ab. + +float MidPoint(FPOINT a, FPOINT b, float px) +{ + if ( Abs(a.x-b.x) < CHOUIA ) + { + if ( a.y < b.y ) return BEAUCOUP; + else return -BEAUCOUP; + } + return (b.y-a.y)*(px-a.x)/(b.x-a.x)+a.y; +} + +// Advance "dist" along the segment p1-p2. + +D3DVECTOR SegmentDist(const D3DVECTOR &p1, const D3DVECTOR &p2, float dist) +{ + return p1+Normalize(p2-p1)*dist; +} + +// Check if a point is inside a triangle. + +BOOL IsInsideTriangle(FPOINT a, FPOINT b, FPOINT c, FPOINT p) +{ + float n, m; + + if ( p.x < a.x && p.x < b.x && p.x < c.x ) return FALSE; + if ( p.x > a.x && p.x > b.x && p.x > c.x ) return FALSE; + if ( p.y < a.y && p.y < b.y && p.y < c.y ) return FALSE; + if ( p.y > a.y && p.y > b.y && p.y > c.y ) return FALSE; + + if ( a.x > b.x ) Swap(a,b); + if ( a.x > c.x ) Swap(a,c); + if ( c.x < a.x ) Swap(c,a); + if ( c.x < b.x ) Swap(c,b); + + n = MidPoint(a, b, p.x); + m = MidPoint(a, c, p.x); + if ( (n>p.y||p.y>m) && (np.y||p.y>m) && (n= 100 ) break; + } + } + + sum.x = 0; + sum.y = 0; + sum.z = 0; + for ( j=0 ; j 0.1f || + Abs(n1.y-n2.y) > 0.1f || + Abs(n1.z-n2.z) > 0.1f ) return FALSE; + + dist = DistancePlanPoint(plan1[0], plan1[1], plan1[2], plan2[0]); + if ( dist > 0.1f ) return FALSE; + + return TRUE; +} + + +// Calculates the matrix to make three rotations in the X, Y and Z +// >>>>>> OPTIMIZING!!! + +void MatRotateXZY(D3DMATRIX &mat, D3DVECTOR angle) +{ + D3DMATRIX temp; + + D3DUtil_SetRotateXMatrix(temp, angle.x); + D3DUtil_SetRotateZMatrix(mat, angle.z); + D3DMath_MatrixMultiply(mat, mat, temp); + D3DUtil_SetRotateYMatrix(temp, angle.y); + D3DMath_MatrixMultiply(mat, mat, temp); // X-Z-Y +} + +// Calculates the matrix to make three rotations in the order Z, X and Y. +// >>>>>> OPTIMIZING!!! + +void MatRotateZXY(D3DMATRIX &mat, D3DVECTOR angle) +{ + D3DMATRIX temp; + + D3DUtil_SetRotateZMatrix(temp, angle.z); + D3DUtil_SetRotateXMatrix(mat, angle.x); + D3DMath_MatrixMultiply(mat, mat, temp); + D3DUtil_SetRotateYMatrix(temp, angle.y); + D3DMath_MatrixMultiply(mat, mat, temp); // Z-X-Y +} + + +// Returns a random value between 0 and 1. + +float Rand() +{ + return (float)rand()/RAND_MAX; +} + + +// Managing the dead zone of a joystick. + +// in: -1 0 1 +// --|-------|----o----|-------|--> +// <----> +// dead +// out: -1 0 0 1 + +float Neutral(float value, float dead) +{ + if ( Abs(value) <= dead ) + { + return 0.0f; + } + else + { + if ( value > 0.0f ) return (value-dead)/(1.0f-dead); + else return (value+dead)/(1.0f-dead); + } +} + + +// Calculates a value (radians) proportional between a and b (degrees). + +float Prop(int a, int b, float p) +{ + float aa, bb; + + aa = (float)a*PI/180.0f; + bb = (float)b*PI/180.0f; + + return aa+p*(bb-aa); +} + +// Gently advanced a desired value from its current value. +// Over time, the greater the progression is rapid. + +float Smooth(float actual, float hope, float time) +{ + float futur; + + futur = actual + (hope-actual)*time; + + if ( hope > actual ) + { + if ( futur > hope ) futur = hope; + } + if ( hope < actual ) + { + if ( futur < hope ) futur = hope; + } + + return futur; +} + + +// Bounces any movement. + +// out +// | +// 1+------o-------o--- +// | o | o o | | bounce +// | o | o---|--- +// | o | | +// | o | | +// -o------|-------+----> progress +// 0| | 1 +// |<---->|middle + +float Bounce(float progress, float middle, float bounce) +{ + if ( progress < middle ) + { + progress = progress/middle; // 0..1 + return 0.5f+sinf(progress*PI-PI/2.0f)/2.0f; + } + else + { + progress = (progress-middle)/(1.0f-middle); // 0..1 + return (1.0f-bounce/2.0f)+sinf((0.5f+progress*2.0f)*PI)*(bounce/2.0f); + } +} + + +// Returns the color corresponding D3DCOLOR. + +D3DCOLOR RetColor(float intensity) +{ + D3DCOLOR color; + + if ( intensity <= 0.0f ) return 0x00000000; + if ( intensity >= 1.0f ) return 0xffffffff; + + color = (int)(intensity*255.0f)<<24; + color |= (int)(intensity*255.0f)<<16; + color |= (int)(intensity*255.0f)<<8; + color |= (int)(intensity*255.0f); + + return color; +} + +// Returns the color corresponding D3DCOLOR. + +D3DCOLOR RetColor(D3DCOLORVALUE intensity) +{ + D3DCOLOR color; + + color = (int)(intensity.a*255.0f)<<24; + color |= (int)(intensity.r*255.0f)<<16; + color |= (int)(intensity.g*255.0f)<<8; + color |= (int)(intensity.b*255.0f); + + return color; +} + +// Returns the color corresponding D3DCOLORVALUE. + +D3DCOLORVALUE RetColor(D3DCOLOR intensity) +{ + D3DCOLORVALUE color; + + color.r = (float)((intensity>>16)&0xff)/256.0f; + color.g = (float)((intensity>>8 )&0xff)/256.0f; + color.b = (float)((intensity>>0 )&0xff)/256.0f; + color.a = (float)((intensity>>24)&0xff)/256.0f; + + return color; +} + + +// RGB to HSV conversion. + +void RGB2HSV(D3DCOLORVALUE src, ColorHSV &dest) +{ + float min, max, delta; + + min = Min(src.r, src.g, src.b); + max = Max(src.r, src.g, src.b); + + dest.v = max; // intensity + + if ( max == 0.0f ) + { + dest.s = 0.0f; // saturation + dest.h = 0.0f; // undefined color! + } + else + { + delta = max-min; + dest.s = delta/max; // saturation + + if ( src.r == max ) // between yellow & magenta + { + dest.h = (src.g-src.b)/delta; + } + else if ( src.g == max ) // between cyan & yellow + { + dest.h = 2.0f+(src.b-src.r)/delta; + } + else // between magenta & cyan + { + dest.h = 4.0f+(src.r-src.g)/delta; + } + + dest.h *= 60.0f; // in degrees + if ( dest.h < 0.0f ) dest.h += 360.0f; + dest.h /= 360.0f; // 0..1 + } +} + +// HSV to RGB conversion. + +void HSV2RGB(ColorHSV src, D3DCOLORVALUE &dest) +{ + int i; + float f,v,p,q,t; + + src.h = Norm(src.h)*360.0f; + src.s = Norm(src.s); + src.v = Norm(src.v); + + if ( src.s == 0.0f ) // zero saturation? + { + dest.r = src.v; + dest.g = src.v; + dest.b = src.v; // gray + } + else + { + if ( src.h == 360.0f ) src.h = 0.0f; + src.h /= 60.0f; + i = (int)src.h; // integer part (0 .. 5) + f = src.h-i; // fractional part + + v = src.v; + p = src.v*(1.0f-src.s); + q = src.v*(1.0f-(src.s*f)); + t = src.v*(1.0f-(src.s*(1.0f-f))); + + switch (i) + { + case 0: dest.r=v; dest.g=t; dest.b=p; break; + case 1: dest.r=q; dest.g=v; dest.b=p; break; + case 2: dest.r=p; dest.g=v; dest.b=t; break; + case 3: dest.r=p; dest.g=q; dest.b=v; break; + case 4: dest.r=t; dest.g=p; dest.b=v; break; + case 5: dest.r=v; dest.g=p; dest.b=q; break; + } + } +} + diff --git a/src/math/math3d.h b/src/math/math3d.h new file mode 100644 index 0000000..ce7eee3 --- /dev/null +++ b/src/math/math3d.h @@ -0,0 +1,106 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// math3d.h + +#ifndef _MATH3D_H_ +#define _MATH3D_H_ + + +#define STRICT +#define D3D_OVERLOADS +#include + + +#define PI 3.14159265358979323846f +#define CHOUIA 1e-6f +#define BEAUCOUP 1e6f + + + +BOOL IsEqual(float a, float b); + +float Min(float a, float b); +float Min(float a, float b, float c); +float Min(float a, float b, float c, float d); +float Min(float a, float b, float c, float d, float e); + +float Max(float a, float b); +float Max(float a, float b, float c); +float Max(float a, float b, float c, float d); +float Max(float a, float b, float c, float d, float e); + +float Norm(float a); +float Abs(float a); + +void Swap(int &a, int &b); +void Swap(float &a, float &b); +void Swap(FPOINT &a, FPOINT &b); + +float Mod(float a, float m); +float NormAngle(float angle); +BOOL TestAngle(float angle, float min, float max); + +float Direction(float a, float g); +FPOINT RotatePoint(FPOINT center, float angle, FPOINT p); +FPOINT RotatePoint(float angle, FPOINT p); +FPOINT RotatePoint(float angle, float dist); +float RotateAngle(float x, float y); +float RotateAngle(FPOINT center, FPOINT p1, FPOINT p2); +float MidPoint(FPOINT a, FPOINT b, float px); +D3DVECTOR SegmentDist(const D3DVECTOR &p1, const D3DVECTOR &p2, float dist); +BOOL IsInsideTriangle(FPOINT a, FPOINT b, FPOINT c, FPOINT p); +BOOL Intersect(D3DVECTOR a, D3DVECTOR b, D3DVECTOR c, D3DVECTOR d, D3DVECTOR e, D3DVECTOR &i); +BOOL IntersectY(D3DVECTOR a, D3DVECTOR b, D3DVECTOR c, D3DVECTOR &p); +void RotatePoint(float cx, float cy, float angle, float &px, float &py); +void RotatePoint(D3DVECTOR center, float angleH, float angleV, D3DVECTOR &p); +void RotatePoint2(D3DVECTOR center, float angleH, float angleV, D3DVECTOR &p); +D3DVECTOR RotateView(D3DVECTOR center, float angleH, float angleV, float dist); +D3DVECTOR LookatPoint( D3DVECTOR eye, float angleH, float angleV, float length ); +float Length(FPOINT a, FPOINT b); +float Length(float x, float y); +float Length(const D3DVECTOR &u); +float Length(const D3DVECTOR &a, const D3DVECTOR &b); +float Length2d(const D3DVECTOR &a, const D3DVECTOR &b); +float Angle( D3DVECTOR u, D3DVECTOR v ); +D3DVECTOR Cross( D3DVECTOR u, D3DVECTOR v ); +D3DVECTOR ComputeNormal( D3DVECTOR p1, D3DVECTOR p2, D3DVECTOR p3 ); +D3DVECTOR Transform(const D3DMATRIX &m, D3DVECTOR p); +D3DVECTOR Projection(const D3DVECTOR &a, const D3DVECTOR &b, const D3DVECTOR &p); + +void MappingObject( D3DVERTEX2* pVertices, int nb, float scale ); +void SmoothObject( D3DVERTEX2* pVertices, int nb ); +BOOL LineFunction(FPOINT p1, FPOINT p2, float &a, float &b); +float DistancePlanPoint(const D3DVECTOR &a, const D3DVECTOR &b, const D3DVECTOR &c, const D3DVECTOR &p); +BOOL IsSamePlane(D3DVECTOR *plan1, D3DVECTOR *plan2); +void MatRotateXZY(D3DMATRIX &mat, D3DVECTOR angle); +void MatRotateZXY(D3DMATRIX &mat, D3DVECTOR angle); + +float Rand(); +float Neutral(float value, float dead); + +float Prop(int a, int b, float p); +float Smooth(float actual, float hope, float time); +float Bounce(float progress, float middle=0.3f, float bounce=0.4f); + +D3DCOLOR RetColor(float intensity); +D3DCOLOR RetColor(D3DCOLORVALUE intensity); +D3DCOLORVALUE RetColor(D3DCOLOR intensity); + +void RGB2HSV(D3DCOLORVALUE src, ColorHSV &dest); +void HSV2RGB(ColorHSV src, D3DCOLORVALUE &dest); + +#endif //_MATH3D_H_ diff --git a/src/math3d.cpp b/src/math3d.cpp deleted file mode 100644 index 9aa5f89..0000000 --- a/src/math3d.cpp +++ /dev/null @@ -1,1035 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// math3d.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "d3dutil.h" -#include "math3d.h" - - - -// Returns TRUE if two numbers are nearly equal. - -BOOL IsEqual(float a, float b) -{ - return Abs(a-b) < CHOUIA; -} - - -// Returns the minimum value. - -float Min(float a, float b) -{ - if ( a <= b ) return a; - else return b; -} - -float Min(float a, float b, float c) -{ - return Min( Min(a,b), c ); -} - -float Min(float a, float b, float c, float d) -{ - return Min( Min(a,b), Min(c,d) ); -} - -float Min(float a, float b, float c, float d, float e) -{ - return Min( Min(a,b), Min(c,d), e ); -} - - -// Returns the maximum value. - -float Max(float a, float b) -{ - if ( a >= b ) return a; - else return b; -} - -float Max(float a, float b, float c) -{ - return Max( Max(a,b), c ); -} - -float Max(float a, float b, float c, float d) -{ - return Max( Max(a,b), Max(c,d) ); -} - -float Max(float a, float b, float c, float d, float e) -{ - return Max( Max(a,b), Max(c,d), e ); -} - - -// Returns the normalized value (0 .. 1). - -float Norm(float a) -{ - if ( a < 0.0f ) return 0.0f; - if ( a > 1.0f ) return 1.0f; - return a; -} - - -// Returns the absolute value of a number. - -float Abs(float a) -{ - return (float)fabs(a); -} - - -// Swaps two integers. - -void Swap(int &a, int &b) -{ - int c; - - c = a; - a = b; - b = c; -} - -// Swaps two real numbers. - -void Swap(float &a, float &b) -{ - float c; - - c = a; - a = b; - b = c; -} - -// Permutes two points. - -void Swap(FPOINT &a, FPOINT &b) -{ - FPOINT c; - - c = a; - a = b; - b = c; -} - -// Returns the modulo of a floating point number. -// Mod(8.1, 4) = 0.1 -// Mod(n, 1) = fractional part of n - -float Mod(float a, float m) -{ - return a - ((int)(a/m))*m; -} - -// Returns a normalized angle, that is in other words between 0 and 2 * PI. - -float NormAngle(float angle) -{ - angle = Mod(angle, PI*2.0f); - if ( angle < 0.0f ) - { - return PI*2.0f + angle; - } - else - { - return angle; - } -} - -// Test if a angle is between two terminals. - -BOOL TestAngle(float angle, float min, float max) -{ - angle = NormAngle(angle); - min = NormAngle(min); - max = NormAngle(max); - - if ( min > max ) - { - return ( angle <= max || angle >= min ); - } - else - { - return ( angle >= min && angle <= max ); - } -} - - -// Calculates the angle to rotate the angle a to the angle g. -// A positive angle is counterclockwise (CCW). - -float Direction(float a, float g) -{ - a = NormAngle(a); - g = NormAngle(g); - - if ( a < g ) - { - if ( a+PI*2.0f-g < g-a ) a += PI*2.0f; - } - else - { - if ( g+PI*2.0f-a < a-g ) g += PI*2.0f; - } - return (g-a); -} - - -// Rotates a point around a center. -// The angle is in radians. -// A positive angle is counterclockwise (CCW). - -FPOINT RotatePoint(FPOINT center, float angle, FPOINT p) -{ - FPOINT a, b; - - a.x = p.x-center.x; - a.y = p.y-center.y; - - b.x = a.x*cosf(angle) - a.y*sinf(angle); - b.y = a.x*sinf(angle) + a.y*cosf(angle); - - b.x += center.x; - b.y += center.y; - return b; -} - -// Rotates a point around the origin. -// The angle is in radians. -// A positive angle is counterclockwise (CCW). - -FPOINT RotatePoint(float angle, FPOINT p) -{ - FPOINT a; - - a.x = p.x*cosf(angle) - p.y*sinf(angle); - a.y = p.x*sinf(angle) + p.y*cosf(angle); - - return a; -} - -// Rotates a vector (dist, 0). -// The angle is in radians. -// A positive angle is counterclockwise (CCW). - -FPOINT RotatePoint(float angle, float dist) -{ - FPOINT a; - - a.x = dist*cosf(angle); - a.y = dist*sinf(angle); - - return a; -} - -// Calculates the angle of a right triangle. -// The angle is counterclockwise (CCW), between 0 and 2 * PI. -// For an angle clockwise (CW), just go ahead. -// -// ^ -// | -// y o----o -// | / | -// |/)a | -// ----o----o--> -// | x -// | - -float RotateAngle(float x, float y) -{ -#if 1 - if ( x == 0.0f && y == 0.0f ) return 0.0f; - - if ( x >= 0.0f ) - { - if ( y >= 0.0f ) - { - if ( x > y ) return atanf(y/x); - else return PI*0.5f - atanf(x/y); - } - else - { - if ( x > -y ) return PI*2.0f + atanf(y/x); - else return PI*1.5f - atanf(x/y); - } - } - else - { - if ( y >= 0.0f ) - { - if ( -x > y ) return PI*1.0f + atanf(y/x); - else return PI*0.5f - atanf(x/y); - } - else - { - if ( -x > -y ) return PI*1.0f + atanf(y/x); - else return PI*1.5f - atanf(x/y); - } - } -#else - float angle; - - if ( x == 0.0f ) - { - if ( y > 0.0f ) - { - return 90.0f*PI/180.0f; - } - else - { - return 270.0f*PI/180.0f; - } - } - else - { - angle = atanf(y/x); - if ( x < 0.0f ) - { - angle += PI; - } - return angle; - } -#endif -} - -// Calculates the angle between two points and one center. -// The angle is in radians. -// A positive angle is counterclockwise (CCW). - -float RotateAngle(FPOINT center, FPOINT p1, FPOINT p2) -{ - float a1, a2, a; - - if ( p1.x == center.x && - p1.y == center.y ) return 0; - - if ( p2.x == center.x && - p2.y == center.y ) return 0; - - a1 = asinf((p1.y-center.y)/Length(p1,center)); - a2 = asinf((p2.y-center.y)/Length(p2,center)); - - if ( p1.x < center.x ) a1 = PI-a1; - if ( p2.x < center.x ) a2 = PI-a2; - - a = a2-a1; - if ( a < 0 ) a += PI*2; - return a; -} - -// Returns py up on the line ab. - -float MidPoint(FPOINT a, FPOINT b, float px) -{ - if ( Abs(a.x-b.x) < CHOUIA ) - { - if ( a.y < b.y ) return BEAUCOUP; - else return -BEAUCOUP; - } - return (b.y-a.y)*(px-a.x)/(b.x-a.x)+a.y; -} - -// Advance "dist" along the segment p1-p2. - -D3DVECTOR SegmentDist(const D3DVECTOR &p1, const D3DVECTOR &p2, float dist) -{ - return p1+Normalize(p2-p1)*dist; -} - -// Check if a point is inside a triangle. - -BOOL IsInsideTriangle(FPOINT a, FPOINT b, FPOINT c, FPOINT p) -{ - float n, m; - - if ( p.x < a.x && p.x < b.x && p.x < c.x ) return FALSE; - if ( p.x > a.x && p.x > b.x && p.x > c.x ) return FALSE; - if ( p.y < a.y && p.y < b.y && p.y < c.y ) return FALSE; - if ( p.y > a.y && p.y > b.y && p.y > c.y ) return FALSE; - - if ( a.x > b.x ) Swap(a,b); - if ( a.x > c.x ) Swap(a,c); - if ( c.x < a.x ) Swap(c,a); - if ( c.x < b.x ) Swap(c,b); - - n = MidPoint(a, b, p.x); - m = MidPoint(a, c, p.x); - if ( (n>p.y||p.y>m) && (np.y||p.y>m) && (n= 100 ) break; - } - } - - sum.x = 0; - sum.y = 0; - sum.z = 0; - for ( j=0 ; j 0.1f || - Abs(n1.y-n2.y) > 0.1f || - Abs(n1.z-n2.z) > 0.1f ) return FALSE; - - dist = DistancePlanPoint(plan1[0], plan1[1], plan1[2], plan2[0]); - if ( dist > 0.1f ) return FALSE; - - return TRUE; -} - - -// Calculates the matrix to make three rotations in the X, Y and Z -// >>>>>> OPTIMIZING!!! - -void MatRotateXZY(D3DMATRIX &mat, D3DVECTOR angle) -{ - D3DMATRIX temp; - - D3DUtil_SetRotateXMatrix(temp, angle.x); - D3DUtil_SetRotateZMatrix(mat, angle.z); - D3DMath_MatrixMultiply(mat, mat, temp); - D3DUtil_SetRotateYMatrix(temp, angle.y); - D3DMath_MatrixMultiply(mat, mat, temp); // X-Z-Y -} - -// Calculates the matrix to make three rotations in the order Z, X and Y. -// >>>>>> OPTIMIZING!!! - -void MatRotateZXY(D3DMATRIX &mat, D3DVECTOR angle) -{ - D3DMATRIX temp; - - D3DUtil_SetRotateZMatrix(temp, angle.z); - D3DUtil_SetRotateXMatrix(mat, angle.x); - D3DMath_MatrixMultiply(mat, mat, temp); - D3DUtil_SetRotateYMatrix(temp, angle.y); - D3DMath_MatrixMultiply(mat, mat, temp); // Z-X-Y -} - - -// Returns a random value between 0 and 1. - -float Rand() -{ - return (float)rand()/RAND_MAX; -} - - -// Managing the dead zone of a joystick. - -// in: -1 0 1 -// --|-------|----o----|-------|--> -// <----> -// dead -// out: -1 0 0 1 - -float Neutral(float value, float dead) -{ - if ( Abs(value) <= dead ) - { - return 0.0f; - } - else - { - if ( value > 0.0f ) return (value-dead)/(1.0f-dead); - else return (value+dead)/(1.0f-dead); - } -} - - -// Calculates a value (radians) proportional between a and b (degrees). - -float Prop(int a, int b, float p) -{ - float aa, bb; - - aa = (float)a*PI/180.0f; - bb = (float)b*PI/180.0f; - - return aa+p*(bb-aa); -} - -// Gently advanced a desired value from its current value. -// Over time, the greater the progression is rapid. - -float Smooth(float actual, float hope, float time) -{ - float futur; - - futur = actual + (hope-actual)*time; - - if ( hope > actual ) - { - if ( futur > hope ) futur = hope; - } - if ( hope < actual ) - { - if ( futur < hope ) futur = hope; - } - - return futur; -} - - -// Bounces any movement. - -// out -// | -// 1+------o-------o--- -// | o | o o | | bounce -// | o | o---|--- -// | o | | -// | o | | -// -o------|-------+----> progress -// 0| | 1 -// |<---->|middle - -float Bounce(float progress, float middle, float bounce) -{ - if ( progress < middle ) - { - progress = progress/middle; // 0..1 - return 0.5f+sinf(progress*PI-PI/2.0f)/2.0f; - } - else - { - progress = (progress-middle)/(1.0f-middle); // 0..1 - return (1.0f-bounce/2.0f)+sinf((0.5f+progress*2.0f)*PI)*(bounce/2.0f); - } -} - - -// Returns the color corresponding D3DCOLOR. - -D3DCOLOR RetColor(float intensity) -{ - D3DCOLOR color; - - if ( intensity <= 0.0f ) return 0x00000000; - if ( intensity >= 1.0f ) return 0xffffffff; - - color = (int)(intensity*255.0f)<<24; - color |= (int)(intensity*255.0f)<<16; - color |= (int)(intensity*255.0f)<<8; - color |= (int)(intensity*255.0f); - - return color; -} - -// Returns the color corresponding D3DCOLOR. - -D3DCOLOR RetColor(D3DCOLORVALUE intensity) -{ - D3DCOLOR color; - - color = (int)(intensity.a*255.0f)<<24; - color |= (int)(intensity.r*255.0f)<<16; - color |= (int)(intensity.g*255.0f)<<8; - color |= (int)(intensity.b*255.0f); - - return color; -} - -// Returns the color corresponding D3DCOLORVALUE. - -D3DCOLORVALUE RetColor(D3DCOLOR intensity) -{ - D3DCOLORVALUE color; - - color.r = (float)((intensity>>16)&0xff)/256.0f; - color.g = (float)((intensity>>8 )&0xff)/256.0f; - color.b = (float)((intensity>>0 )&0xff)/256.0f; - color.a = (float)((intensity>>24)&0xff)/256.0f; - - return color; -} - - -// RGB to HSV conversion. - -void RGB2HSV(D3DCOLORVALUE src, ColorHSV &dest) -{ - float min, max, delta; - - min = Min(src.r, src.g, src.b); - max = Max(src.r, src.g, src.b); - - dest.v = max; // intensity - - if ( max == 0.0f ) - { - dest.s = 0.0f; // saturation - dest.h = 0.0f; // undefined color! - } - else - { - delta = max-min; - dest.s = delta/max; // saturation - - if ( src.r == max ) // between yellow & magenta - { - dest.h = (src.g-src.b)/delta; - } - else if ( src.g == max ) // between cyan & yellow - { - dest.h = 2.0f+(src.b-src.r)/delta; - } - else // between magenta & cyan - { - dest.h = 4.0f+(src.r-src.g)/delta; - } - - dest.h *= 60.0f; // in degrees - if ( dest.h < 0.0f ) dest.h += 360.0f; - dest.h /= 360.0f; // 0..1 - } -} - -// HSV to RGB conversion. - -void HSV2RGB(ColorHSV src, D3DCOLORVALUE &dest) -{ - int i; - float f,v,p,q,t; - - src.h = Norm(src.h)*360.0f; - src.s = Norm(src.s); - src.v = Norm(src.v); - - if ( src.s == 0.0f ) // zero saturation? - { - dest.r = src.v; - dest.g = src.v; - dest.b = src.v; // gray - } - else - { - if ( src.h == 360.0f ) src.h = 0.0f; - src.h /= 60.0f; - i = (int)src.h; // integer part (0 .. 5) - f = src.h-i; // fractional part - - v = src.v; - p = src.v*(1.0f-src.s); - q = src.v*(1.0f-(src.s*f)); - t = src.v*(1.0f-(src.s*(1.0f-f))); - - switch (i) - { - case 0: dest.r=v; dest.g=t; dest.b=p; break; - case 1: dest.r=q; dest.g=v; dest.b=p; break; - case 2: dest.r=p; dest.g=v; dest.b=t; break; - case 3: dest.r=p; dest.g=q; dest.b=v; break; - case 4: dest.r=t; dest.g=p; dest.b=v; break; - case 5: dest.r=v; dest.g=p; dest.b=q; break; - } - } -} - diff --git a/src/math3d.h b/src/math3d.h deleted file mode 100644 index ce7eee3..0000000 --- a/src/math3d.h +++ /dev/null @@ -1,106 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// math3d.h - -#ifndef _MATH3D_H_ -#define _MATH3D_H_ - - -#define STRICT -#define D3D_OVERLOADS -#include - - -#define PI 3.14159265358979323846f -#define CHOUIA 1e-6f -#define BEAUCOUP 1e6f - - - -BOOL IsEqual(float a, float b); - -float Min(float a, float b); -float Min(float a, float b, float c); -float Min(float a, float b, float c, float d); -float Min(float a, float b, float c, float d, float e); - -float Max(float a, float b); -float Max(float a, float b, float c); -float Max(float a, float b, float c, float d); -float Max(float a, float b, float c, float d, float e); - -float Norm(float a); -float Abs(float a); - -void Swap(int &a, int &b); -void Swap(float &a, float &b); -void Swap(FPOINT &a, FPOINT &b); - -float Mod(float a, float m); -float NormAngle(float angle); -BOOL TestAngle(float angle, float min, float max); - -float Direction(float a, float g); -FPOINT RotatePoint(FPOINT center, float angle, FPOINT p); -FPOINT RotatePoint(float angle, FPOINT p); -FPOINT RotatePoint(float angle, float dist); -float RotateAngle(float x, float y); -float RotateAngle(FPOINT center, FPOINT p1, FPOINT p2); -float MidPoint(FPOINT a, FPOINT b, float px); -D3DVECTOR SegmentDist(const D3DVECTOR &p1, const D3DVECTOR &p2, float dist); -BOOL IsInsideTriangle(FPOINT a, FPOINT b, FPOINT c, FPOINT p); -BOOL Intersect(D3DVECTOR a, D3DVECTOR b, D3DVECTOR c, D3DVECTOR d, D3DVECTOR e, D3DVECTOR &i); -BOOL IntersectY(D3DVECTOR a, D3DVECTOR b, D3DVECTOR c, D3DVECTOR &p); -void RotatePoint(float cx, float cy, float angle, float &px, float &py); -void RotatePoint(D3DVECTOR center, float angleH, float angleV, D3DVECTOR &p); -void RotatePoint2(D3DVECTOR center, float angleH, float angleV, D3DVECTOR &p); -D3DVECTOR RotateView(D3DVECTOR center, float angleH, float angleV, float dist); -D3DVECTOR LookatPoint( D3DVECTOR eye, float angleH, float angleV, float length ); -float Length(FPOINT a, FPOINT b); -float Length(float x, float y); -float Length(const D3DVECTOR &u); -float Length(const D3DVECTOR &a, const D3DVECTOR &b); -float Length2d(const D3DVECTOR &a, const D3DVECTOR &b); -float Angle( D3DVECTOR u, D3DVECTOR v ); -D3DVECTOR Cross( D3DVECTOR u, D3DVECTOR v ); -D3DVECTOR ComputeNormal( D3DVECTOR p1, D3DVECTOR p2, D3DVECTOR p3 ); -D3DVECTOR Transform(const D3DMATRIX &m, D3DVECTOR p); -D3DVECTOR Projection(const D3DVECTOR &a, const D3DVECTOR &b, const D3DVECTOR &p); - -void MappingObject( D3DVERTEX2* pVertices, int nb, float scale ); -void SmoothObject( D3DVERTEX2* pVertices, int nb ); -BOOL LineFunction(FPOINT p1, FPOINT p2, float &a, float &b); -float DistancePlanPoint(const D3DVECTOR &a, const D3DVECTOR &b, const D3DVECTOR &c, const D3DVECTOR &p); -BOOL IsSamePlane(D3DVECTOR *plan1, D3DVECTOR *plan2); -void MatRotateXZY(D3DMATRIX &mat, D3DVECTOR angle); -void MatRotateZXY(D3DMATRIX &mat, D3DVECTOR angle); - -float Rand(); -float Neutral(float value, float dead); - -float Prop(int a, int b, float p); -float Smooth(float actual, float hope, float time); -float Bounce(float progress, float middle=0.3f, float bounce=0.4f); - -D3DCOLOR RetColor(float intensity); -D3DCOLOR RetColor(D3DCOLORVALUE intensity); -D3DCOLORVALUE RetColor(D3DCOLOR intensity); - -void RGB2HSV(D3DCOLORVALUE src, ColorHSV &dest); -void HSV2RGB(ColorHSV src, D3DCOLORVALUE &dest); - -#endif //_MATH3D_H_ diff --git a/src/metafile.cpp b/src/metafile.cpp deleted file mode 100644 index d7e260e..0000000 --- a/src/metafile.cpp +++ /dev/null @@ -1,418 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// metafile.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include - -#include "language.h" -#include "metafile.h" - - - - -#if _FULL | _NET -static unsigned char table_codec[23] = -{ - 0x85, 0x91, 0x73, 0xcf, 0xa2, 0xbb, 0xf4, 0x77, - 0x58, 0x39, 0x37, 0xfd, 0x2a, 0xcc, 0x5f, 0x55, - 0x96, 0x90, 0x07, 0xcd, 0x11, 0x88, 0x21, -}; - -void Codec(void* buffer, int len, int start) -{ - unsigned char *b = (unsigned char*)buffer; - int i; - - for ( i=0 ; i - - -#define METAMAX 5 - -typedef struct -{ - char name[14]; // file name (8.3 max) - int start; // position from the beginning of the metafile - int len; // length of the file -} -MetaHeader; - -typedef struct -{ - char name[50]; // name of the metafile - FILE* stream; // channel - int total; // number of files - MetaHeader* headers; // headers of files -} -MetaFile; - - - -class CMetaFile -{ -public: - CMetaFile(); - ~CMetaFile(); - - BOOL IsExist(char *metaname, char *filename); - int Open(char *metaname, char *filename); - int RetLength(); - int Seek(int offset); - int Read(void *buffer, int size); - int GetByte(); - int GetWord(); - int Close(); - int MetaClose(); - -protected: - int MetaOpen(char *metaname); - int MetaSearch(char *metaname); - -protected: - MetaFile m_list[METAMAX]; // metafile open - BOOL m_bOpen; // open file - BOOL m_bMeta; // metafile open - FILE* m_stream; // channel - int m_start; // position from the beginning - int m_pos; // current position - int m_len; // length of the file -}; - - -#endif //_METAFILE_H_ diff --git a/src/micent2.txt b/src/micent2.txt deleted file mode 100644 index c77d91b..0000000 --- a/src/micent2.txt +++ /dev/null @@ -1,13 +0,0 @@ -\b;Rapport du satellite -\c; -\s;-> SURFACE\c; -\tab;Température: 25.4 degrés -\tab;Atmosphère: oxygène, azote, ammoniaque -\tab;Vent: 0.7 m/s -\tab;Minerai titanium: aucun -\tab;Minerai uranium: aucun - -\s;-> SOUS-SOL\c; -\tab;Energie: aucune -\tab;Minerai titanium: aucun -\tab;Minerai uranium: aucun diff --git a/src/misc.cpp b/src/misc.cpp deleted file mode 100644 index ce42de0..0000000 --- a/src/misc.cpp +++ /dev/null @@ -1,443 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// misc.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include -#include -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "d3dutil.h" -#include "language.h" -#include "event.h" -#include "misc.h" - - - -CMetaFile g_metafile; - -static EventMsg g_uniqueEventMsg = EVENT_USER; -static BOOL g_bUserDir = FALSE; -static char g_userDir[100] = ""; - - - -// Gives a single user event. - -EventMsg GetUniqueEventMsg() -{ - int i; - - i = (int)g_uniqueEventMsg+1; - g_uniqueEventMsg = (EventMsg)i; - return g_uniqueEventMsg; -} - - - -// Returns a non-accented letter. - -char RetNoAccent(char letter) -{ - if ( letter < 0 ) - { - if ( letter == 'á' || - letter == 'à' || - letter == 'â' || - letter == 'ä' || - letter == 'ã' ) return 'a'; - - if ( letter == 'é' || - letter == 'è' || - letter == 'ê' || - letter == 'ë' ) return 'e'; - - if ( letter == 'í' || - letter == 'ì' || - letter == 'î' || - letter == 'ï' ) return 'i'; - - if ( letter == 'ó' || - letter == 'ò' || - letter == 'ô' || - letter == 'ö' || - letter == 'õ' ) return 'o'; - - if ( letter == 'ú' || - letter == 'ù' || - letter == 'û' || - letter == 'ü' ) return 'u'; - - if ( letter == 'ç' ) return 'c'; - - if ( letter == 'ñ' ) return 'n'; - - if ( letter == 'Á' || - letter == 'À' || - letter == 'Â' || - letter == 'Ä' || - letter == 'Ã' ) return 'A'; - - if ( letter == 'É' || - letter == 'È' || - letter == 'Ê' || - letter == 'Ë' ) return 'E'; - - if ( letter == 'Í' || - letter == 'Ì' || - letter == 'Î' || - letter == 'Ï' ) return 'I'; - - if ( letter == 'Ó' || - letter == 'Ò' || - letter == 'Ô' || - letter == 'Ö' || - letter == 'Õ' ) return 'O'; - - if ( letter == 'Ú' || - letter == 'Ù' || - letter == 'Û' || - letter == 'Ü' ) return 'U'; - - if ( letter == 'Ç' ) return 'C'; - - if ( letter == 'Ñ' ) return 'N'; - } - - return letter; -} - -// Returns an uppercase letter. - -char RetToUpper(char letter) -{ - if ( letter < 0 ) - { - if ( letter == 'á' ) return 'Á'; - if ( letter == 'à' ) return 'À'; - if ( letter == 'â' ) return 'Â'; - if ( letter == 'ä' ) return 'Ä'; - if ( letter == 'ã' ) return 'Ã'; - - if ( letter == 'é' ) return 'É'; - if ( letter == 'è' ) return 'È'; - if ( letter == 'ê' ) return 'Ê'; - if ( letter == 'ë' ) return 'Ë'; - - if ( letter == 'í' ) return 'Í'; - if ( letter == 'ì' ) return 'Ì'; - if ( letter == 'î' ) return 'Î'; - if ( letter == 'ï' ) return 'Ï'; - - if ( letter == 'ó' ) return 'Ó'; - if ( letter == 'ò' ) return 'Ò'; - if ( letter == 'ô' ) return 'Ô'; - if ( letter == 'ö' ) return 'Ö'; - if ( letter == 'õ' ) return 'Õ'; - - if ( letter == 'ú' ) return 'Ú'; - if ( letter == 'ù' ) return 'Ù'; - if ( letter == 'û' ) return 'Û'; - if ( letter == 'ü' ) return 'Ü'; - - if ( letter == 'ç' ) return 'Ç'; - - if ( letter == 'ñ' ) return 'Ñ'; - } - - return toupper(letter); -} - -// Returns a lowercase letter. - -char RetToLower(char letter) -{ - if ( letter < 0 ) - { - if ( letter == 'Á' ) return 'á'; - if ( letter == 'À' ) return 'à'; - if ( letter == 'Â' ) return 'â'; - if ( letter == 'Ä' ) return 'ä'; - if ( letter == 'Ã' ) return 'ã'; - - if ( letter == 'É' ) return 'é'; - if ( letter == 'È' ) return 'è'; - if ( letter == 'Ê' ) return 'ê'; - if ( letter == 'Ë' ) return 'ë'; - - if ( letter == 'Í' ) return 'í'; - if ( letter == 'Ì' ) return 'ì'; - if ( letter == 'Î' ) return 'î'; - if ( letter == 'Ï' ) return 'ï'; - - if ( letter == 'Ó' ) return 'ó'; - if ( letter == 'Ò' ) return 'ò'; - if ( letter == 'Ô' ) return 'ô'; - if ( letter == 'Ö' ) return 'ö'; - if ( letter == 'Õ' ) return 'õ'; - - if ( letter == 'Ú' ) return 'ú'; - if ( letter == 'Ù' ) return 'ù'; - if ( letter == 'Û' ) return 'û'; - if ( letter == 'Ü' ) return 'ü'; - - if ( letter == 'Ç' ) return 'ç'; - - if ( letter == 'Ñ' ) return 'ñ'; - } - - return tolower(letter); -} - - -// Converting time to string. - -void TimeToAscii(time_t time, char *buffer) -{ - struct tm when; - int year; - - when = *localtime(&time); - year = when.tm_year+1900; - if ( year < 2000 ) year -= 1900; - else year -= 2000; -#if _FRENCH - sprintf(buffer, "%.2d.%.2d.%.2d %.2d:%.2d", - when.tm_mday, when.tm_mon+1, year, - when.tm_hour, when.tm_min); -#endif -#if _GERMAN | _WG - sprintf(buffer, "%.2d.%.2d.%.2d %.2d:%.2d", - when.tm_mday, when.tm_mon+1, year, - when.tm_hour, when.tm_min); -#endif -#if _ENGLISH - char format[10]; - int hour; - - hour = when.tm_hour; // 0..23 - if ( hour < 12 ) // morning? - { - strcpy(format, "am"); - } - else // afternoon? - { - strcpy(format, "pm"); - hour -= 12; // 0..11 - } - if ( hour == 0 ) hour = 12; - - sprintf(buffer, "%.2d.%.2d.%.2d %.2d:%.2d %s", - when.tm_mon+1, when.tm_mday, year, - hour, when.tm_min, format); -#endif -#if _POLISH - sprintf(buffer, "%.2d.%.2d.%.2d %.2d:%.2d", - when.tm_mday, when.tm_mon+1, year, - when.tm_hour, when.tm_min); -#endif -} - - -// Makes a copy of a file. - -BOOL Xfer(char* src, char* dst) -{ - FILE *fs, *fd; - char *buffer; - int len; - - fs = fopen(src, "rb"); - if ( fs == 0 ) - { - return FALSE; - } - - fd = fopen(dst, "wb"); - if ( fd == 0 ) - { - fclose(fs); - return FALSE; - } - - buffer = (char*)malloc(10000); - - while ( TRUE ) - { - len = fread(buffer, 1, 10000, fs); - if ( len == 0 ) break; - fwrite(buffer, 1, len, fd); - } - - free(buffer); - fclose(fs); - fclose(fd); - return TRUE; -} - -// Copy a file into the temporary folder. - -BOOL CopyFileToTemp(char* filename) -{ - char src[100]; - char dst[100]; - char save[100]; - - UserDir(src, filename, "textures"); - - strcpy(save, g_userDir); - strcpy(g_userDir, "temp"); - UserDir(dst, filename, "textures"); - strcpy(g_userDir, save); - - _mkdir("temp"); - if ( !Xfer(src, dst) ) return FALSE; - - strcpy(filename, dst); - return TRUE; -} - -// Copy a list of numbered files into the temporary folder. - -BOOL CopyFileListToTemp(char* filename, int* list, int total) -{ - char name[100]; - char ext[10]; - char file[100]; - char save[100]; - char* p; - int i; - - strcpy(name, filename); - p = strchr(name, '.'); - if ( p == 0 ) - { - strcpy(ext, ".tga"); - } - else - { - strcpy(ext, p); - *p = 0; - } - - for ( i=0 ; i - - -#include "metafile.h" -#include "event.h" - - -extern CMetaFile g_metafile; - - - -// Existing classes. - -enum ClassType -{ - CLASS_EVENT = 1, - CLASS_INTERFACE = 2, - CLASS_MAIN = 3, - CLASS_ENGINE = 4, - CLASS_TERRAIN = 5, - CLASS_OBJECT = 6, - CLASS_PHYSICS = 7, - CLASS_BRAIN = 8, - CLASS_CAMERA = 9, - CLASS_LIGHT = 10, - CLASS_PARTICULE = 11, - CLASS_AUTO = 12, - CLASS_DISPLAYTEXT = 13, - CLASS_PYRO = 14, - CLASS_SCRIPT = 15, - CLASS_TEXT = 16, - CLASS_STUDIO = 17, - CLASS_WATER = 18, - CLASS_CLOUD = 19, - CLASS_MOTION = 20, - CLASS_SOUND = 21, - CLASS_PLANET = 22, - CLASS_TASKMANAGER = 23, - CLASS_DIALOG = 24, - CLASS_MAP = 25, - CLASS_SHORT = 26, - CLASS_BLITZ = 27, -}; - -#define CLASS_MAX 30 - - - -enum Error -{ - ERR_OK = 0, // ok - ERR_GENERIC = 1, // any error - ERR_CONTINUE = 2, // continues - ERR_STOP = 3, // stops - ERR_CMD = 4, // unknown command - ERR_INSTALL = 20, // incorrectly installed program - ERR_NOCD = 21, // CD not found - ERR_MANIP_VEH = 100, // inappropriate vehicle - ERR_MANIP_FLY = 101, // impossible in flight - ERR_MANIP_BUSY = 102, // taking: hands already occupied - ERR_MANIP_NIL = 103, // taking: nothing has to take - ERR_MANIP_MOTOR = 105, // busy: impossible to move - ERR_MANIP_OCC = 106, // busy: location already occupied - ERR_MANIP_FRIEND = 107, // no other vehicle - ERR_MANIP_RADIO = 108, // impossible because radioactive - ERR_MANIP_WATER = 109, // not possible under water - ERR_MANIP_EMPTY = 110, // nothing to deposit - ERR_BUILD_FLY = 120, // not possible in flight - ERR_BUILD_WATER = 121, // not possible under water - ERR_BUILD_ENERGY = 122, // not enough energy - ERR_BUILD_METALAWAY = 123, // lack of metal (too far) - ERR_BUILD_METALNEAR = 124, // lack of metal (too close) - ERR_BUILD_METALINEX = 125, // lack of metal - ERR_BUILD_FLAT = 126, // not enough flat ground - ERR_BUILD_FLATLIT = 127, // not enough flat ground space - ERR_BUILD_BUSY = 128, // location occupied - ERR_BUILD_BASE = 129, // too close to the rocket - ERR_BUILD_NARROW = 130, // buildings too close - ERR_BUILD_MOTOR = 131, // built: not possible in movement - ERR_SEARCH_FLY = 140, // not possible in flight - ERR_SEARCH_VEH = 141, // inappropriate vehicle - ERR_SEARCH_MOTOR = 142, // impossible in movement - ERR_TERRA_VEH = 150, // inappropriate vehicle - ERR_TERRA_ENERGY = 151, // not enough energy - ERR_TERRA_FLOOR = 152, // inappropriate ground - ERR_TERRA_BUILDING = 153, // building too close - ERR_TERRA_OBJECT = 154, // object too close - ERR_FIRE_VEH = 160, // inappropriate vehicle - ERR_FIRE_ENERGY = 161, // not enough energy - ERR_FIRE_FLY = 162, // not possible in flight - ERR_RECOVER_VEH = 170, // inappropriate vehicle - ERR_RECOVER_ENERGY = 171, // not enough energy - ERR_RECOVER_NULL = 172, // lack of ruin - ERR_CONVERT_EMPTY = 180, // no stone was transformed - ERR_SHIELD_VEH = 190, // inappropriate vehicle - ERR_SHIELD_ENERGY = 191, // not enough energy - ERR_MOVE_IMPOSSIBLE = 200, // move impossible - ERR_FIND_IMPOSSIBLE = 201, // find impossible - ERR_GOTO_IMPOSSIBLE = 210, // goto impossible - ERR_GOTO_ITER = 211, // goto too complicated - ERR_GOTO_BUSY = 212, // goto destination occupied - ERR_DERRICK_NULL = 300, // no ore underground - ERR_STATION_NULL = 301, // no energy underground - ERR_TOWER_POWER = 310, // no battery - ERR_TOWER_ENERGY = 311, // more energy - ERR_RESEARCH_POWER = 320, // no battery - ERR_RESEARCH_ENERGY = 321, // more energy - ERR_RESEARCH_TYPE = 322, // the wrong type of battery - ERR_RESEARCH_ALREADY = 323, // research already done - ERR_ENERGY_NULL = 330, // no energy underground - ERR_ENERGY_LOW = 331, // not enough energy - ERR_ENERGY_EMPTY = 332, // lack of metal - ERR_ENERGY_BAD = 333, // transforms only the metal - ERR_BASE_DLOCK = 340, // doors locked - ERR_BASE_DHUMAN = 341, // you must be on spaceship - ERR_LABO_NULL = 350, // nothing to analyze - ERR_LABO_BAD = 351, // analyzes only organic ball - ERR_LABO_ALREADY = 352, // analysis already made - ERR_NUCLEAR_NULL = 360, // no energy underground - ERR_NUCLEAR_LOW = 361, // not enough energy - ERR_NUCLEAR_EMPTY = 362, // lack of uranium - ERR_NUCLEAR_BAD = 363, // transforms only uranium - ERR_FACTORY_NULL = 370, // no metal - ERR_FACTORY_NEAR = 371, // vehicle too close - ERR_RESET_NEAR = 380, // vehicle too close - ERR_INFO_NULL = 390, // no information terminal - ERR_VEH_VIRUS = 400, // vehicle infected by a virus - ERR_BAT_VIRUS = 401, // building infected by a virus - ERR_VEH_POWER = 500, // no battery - ERR_VEH_ENERGY = 501, // more energy - ERR_FLAG_FLY = 510, // impossible in flight - ERR_FLAG_WATER = 511, // impossible during swimming - ERR_FLAG_MOTOR = 512, // impossible in movement - ERR_FLAG_BUSY = 513, // taking: already creating flag - ERR_FLAG_CREATE = 514, // too many flags - ERR_FLAG_PROXY = 515, // too close - ERR_FLAG_DELETE = 516, // nothing to remove - ERR_MISSION_NOTERM = 600, // Mission not completed - ERR_DELETEMOBILE = 700, // vehicle destroyed - ERR_DELETEBUILDING = 701, // building destroyed - ERR_TOOMANY = 702, // too many objects - ERR_OBLIGATORYTOKEN = 800, // compulsory instruction missing - ERR_PROHIBITEDTOKEN = 801, // instruction prohibited - - INFO_FIRST = 10000, // first information - INFO_BUILD = 10001, // construction builded - INFO_CONVERT = 10002, // metal available - INFO_RESEARCH = 10003, // search ended - INFO_FACTORY = 10004, // vehicle manufactured - INFO_LABO = 10005, // analysis ended - INFO_ENERGY = 10006, // battery available - INFO_NUCLEAR = 10007, // nuclear battery available - INFO_FINDING = 10008, // nuclear battery available - INFO_MARKPOWER = 10020, // location for station found - INFO_MARKURANIUM = 10021, // location for derrick found - INFO_MARKSTONE = 10022, // location for derrick found - INFO_MARKKEYa = 10023, // location for derrick found - INFO_MARKKEYb = 10024, // location for derrick found - INFO_MARKKEYc = 10025, // location for derrick found - INFO_MARKKEYd = 10026, // location for derrick found - INFO_RESEARCHTANK = 10030, // research ended - INFO_RESEARCHFLY = 10031, // research ended - INFO_RESEARCHTHUMP = 10032, // research ended - INFO_RESEARCHCANON = 10033, // research ended - INFO_RESEARCHTOWER = 10034, // research ended - INFO_RESEARCHPHAZER = 10035, // research ended - INFO_RESEARCHSHIELD = 10036, // research ended - INFO_RESEARCHATOMIC = 10037, // research ended - INFO_WIN = 10040, // win - INFO_LOST = 10041, // lost - INFO_LOSTq = 10042, // lost immediately - INFO_WRITEOK = 10043, // record done - INFO_DELETEPATH = 10050, // way mark deleted - INFO_DELETEMOTHER = 10100, // insect killed - INFO_DELETEANT = 10101, // insect killed - INFO_DELETEBEE = 10102, // insect killed - INFO_DELETEWORM = 10103, // insect killed - INFO_DELETESPIDER = 10104, // insect killed - INFO_BEGINSATCOM = 10105, // use your SatCom -}; - - -// Keyboard state. - -#define KS_PAGEUP (1<<4) -#define KS_PAGEDOWN (1<<5) -#define KS_SHIFT (1<<6) -#define KS_CONTROL (1<<7) -#define KS_MLEFT (1<<8) -#define KS_MRIGHT (1<<9) -#define KS_NUMUP (1<<10) -#define KS_NUMDOWN (1<<11) -#define KS_NUMLEFT (1<<12) -#define KS_NUMRIGHT (1<<13) -#define KS_NUMPLUS (1<<14) -#define KS_NUMMINUS (1<<15) - - -// Procedures. - -extern EventMsg GetUniqueEventMsg(); - -extern char RetNoAccent(char letter); -extern char RetToUpper(char letter); -extern char RetToLower(char letter); - -extern void TimeToAscii(time_t time, char *buffer); - -extern BOOL CopyFileToTemp(char* filename); -extern BOOL CopyFileListToTemp(char* filename, int* list, int total); -extern void AddExt(char* filename, char* ext); -extern void UserDir(BOOL bUser, char* dir); -extern void UserDir(char* buffer, char* dir, char* def); - -extern char RetLanguageLetter(); - - - -#endif //_MISC_H_ diff --git a/src/mixer.txt b/src/mixer.txt deleted file mode 100644 index 2009c2a..0000000 --- a/src/mixer.txt +++ /dev/null @@ -1,486 +0,0 @@ -Several people have asked me for the sample code I use to program -the mixer in Windows. Since it's a fairly short sample and there's -clearly some interest, I thought I'd post it directly to the newsgroup. -Here it is ... enjoy! (?) - -Julian - -// Example routine that manipulates the mixer controls for Win32 -// This code is not a stand-alone application ... -// -// It's also not very pretty ... -// -// But then, neither is the API ... -// -// Julian Bunn, 1998, julianb@altavista.net - - -#include -#include - - -MIXERCONTROLDETAILS mixDetailsMic,mixDetailsSpk,mixDetailsLin; -LONG -lMaximumSpk,lMaximumMic,lMaximumLin,lMinimumMic,lMinimumSpk,lMinimumLin; - -int nMixerDevs; -int nMicMixID; - -LPHMIXER hMixer; -UINT IdMixer; - - -/**************************************************************************** - - Function: ProgramInitMixer() - - PURPOSE : Initialises the mixer -*****************************************************************************/ - -LONG WINAPI ProgramInitMixer() -{ - UINT iS,iD,iDC,iC, itype; - UINT volume; - MMRESULT mmres; - MIXERCAPS mixCaps; - MIXERLINE mixLine; - MIXERLINECONTROLS mixControls; - MIXERCONTROL mixClist[50]; - MIXERCONTROLDETAILS mixDetails; - MIXERCONTROLDETAILS_UNSIGNED mixValue; - MIXERCONTROLDETAILS_BOOLEAN mixMute; - MIXERCONTROLDETAILS_BOOLEAN mixBoolean[50]; - MIXERCONTROLDETAILS_LISTTEXT mixList[50]; - BOOL bDoneMike = FALSE; - BOOL bDoneSpkr = FALSE; - UINT LineID = 0; - - if(!bMixerOpened) { -// check first if we have a mixer - if((nMixerDevs = mixerGetNumDevs()) < 1) { - return (Program_ERROR); - } - -// really need to pop up a chooser for which mixer device, in -// cases where there is more than one. -// In the meantime, I select the last one listed - - IdMixer = nMixerDevs-1; - - mmres = mixerOpen((LPHMIXER) &hMixer, IdMixer, (DWORD) 0, (DWORD) -NULL, - MIXER_OBJECTF_MIXER); - if(mmres != MMSYSERR_NOERROR) { - return (Program_ERROR); - } - - bMixerOpened = TRUE; - } - - mmres = mixerGetDevCaps(IdMixer, (LPMIXERCAPS) &mixCaps, -sizeof(MIXERCAPS)); - if(mmres != MMSYSERR_NOERROR) { - return (Program_ERROR); - } -// Set the manufacturer's name for the mixer ... - SetDlgItemText(hWndDialogBox,IDC_MIXERNAME,mixCaps.szPname); - if(nMixerDevs>1) { - DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_INFOMESSAGE1), -hWndDialogBox, DialogBoxCallback); - } - - -// Loop over the destination mixer lines - for (iD=0;iD -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "water.h" -#include "robotmain.h" -#include "interface.h" -#include "edit.h" -#include "button.h" -#include "cmdtoken.h" -#include "modfile.h" -#include "model.h" - - - -#define MAX_COLORS 9 - -static float table_color[MAX_COLORS*3] = -{ - 1.0f, 1.0f, 1.0f, // white - 1.0f, 0.0f, 0.0f, // red - 0.0f, 1.0f, 0.0f, // green - 0.0f, 0.6f, 1.0f, // blue - 1.0f, 1.0f, 0.0f, // yellow - 0.0f, 1.0f, 1.0f, // cyan - 1.0f, 0.0f, 1.0f, // magenta - 0.3f, 0.3f, 0.3f, // grey - 0.0f, 0.0f, 0.0f, // black -}; - - -#define MAX_STATES 10 - -static int table_state[MAX_STATES] = -{ - D3DSTATENORMAL, - D3DSTATEPART1, - D3DSTATEPART2, - D3DSTATEPART3, - D3DSTATEPART4, - D3DSTATE2FACE, // #5 - D3DSTATETTw, - D3DSTATETTb, - D3DSTATETTw|D3DSTATE2FACE, // #8 - D3DSTATETTb|D3DSTATE2FACE, // #9 -}; - - -#define MAX_NAMES 23 - - - - -// Object's constructor. - -CModel::CModel(CInstanceManager* iMan) -{ - m_iMan = iMan; - - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - - m_modFile = new CModFile(m_iMan); - m_triangleTable = m_modFile->RetTriangleList(); - - m_textureRank = 0; - strcpy(m_textureName, "lemt.tga"); - m_color = 0; - m_state = 0; - m_textureMode = 0; - m_textureRotate = 0; - m_bTextureMirrorX = FALSE; - m_bTextureMirrorY = FALSE; - m_texturePart = 0; - TexturePartUpdate(); - - m_bDisplayTransparent = FALSE; - m_bDisplayOnlySelection = FALSE; - InitView(); - - m_triangleSel1 = 0; - m_triangleSel2 = 0; - - m_mode = 1; - m_oper = 'P'; - - m_secondTexNum = 0; - m_secondSubdiv = 1; - m_secondOffsetU = 0; - m_secondOffsetV = 0; - - m_min = 0.0f; - m_max = 1000000.0f; -} - -// Object's destructor. - -CModel::~CModel() -{ - delete m_modFile; -} - - -// You must call this procedure before changing the model interactively. - -void CModel::StartUserAction() -{ - Event event; - FPOINT pos, dim; - CButton* pb; - - dim.x = 105.0f/640.0f; - dim.y = 18.0f/480.0f; - pos.x = 10.0f/640.0f; - pos.y = 450.0f/480.0f; - m_interface->CreateEdit(pos, dim, 0, EVENT_EDIT1); - - dim.x = 50.0f/640.0f; - pos.x = 125.0f/640.0f; - pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON1); - pb->SetState(STATE_SIMPLY); - pb->SetName("Load"); - pos.x = 185.0f/640.0f; - pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON2); - pb->SetState(STATE_SIMPLY); - pb->SetName("Script"); - pos.x = 245.0f/640.0f; - pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON3); - pb->SetState(STATE_SIMPLY); - pb->SetName("Read"); - pos.x = 305.0f/640.0f; - pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON4); - pb->SetState(STATE_SIMPLY); - pb->SetName("Add"); - pos.x = 365.0f/640.0f; - pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON5); - pb->SetState(STATE_SIMPLY); - pb->SetName("Write"); - - dim.x = 50.0f/640.0f; - dim.y = 18.0f/480.0f; - pos.x = 10.0f/640.0f; - pos.y = 425.0f/480.0f; - m_interface->CreateEdit(pos, dim, 0, EVENT_EDIT2); - pos.x = 65.0f/640.0f; - pos.y = 425.0f/480.0f; - m_interface->CreateEdit(pos, dim, 0, EVENT_EDIT3); - pos.x = 10.0f/640.0f; - pos.y = 400.0f/480.0f; - m_interface->CreateEdit(pos, dim, 0, EVENT_EDIT4); - pos.x = 65.0f/640.0f; - pos.y = 400.0f/480.0f; - m_interface->CreateEdit(pos, dim, 0, EVENT_EDIT5); - - dim.x = 20.0f/640.0f; - dim.y = 20.0f/480.0f; - pos.y = 370.0f/480.0f; - pos.x = 10.0f/640.0f; - pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON10); - pb->SetState(STATE_SIMPLY); - pb->SetName("P"); - pos.x = 30.0f/640.0f; - pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON11); - pb->SetState(STATE_SIMPLY); - pb->SetName("R"); - pos.x = 50.0f/640.0f; - pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON12); - pb->SetState(STATE_SIMPLY); - pb->SetName("Z"); - pos.y = 350.0f/480.0f; - pos.x = 10.0f/640.0f; - pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON13); - pb->SetState(STATE_SIMPLY); - pb->SetName("+X"); - pos.x = 30.0f/640.0f; - pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON14); - pb->SetState(STATE_SIMPLY); - pb->SetName("+Y"); - pos.x = 50.0f/640.0f; - pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON15); - pb->SetState(STATE_SIMPLY); - pb->SetName("+Z"); - pos.y = 330.0f/480.0f; - pos.x = 10.0f/640.0f; - pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON16); - pb->SetState(STATE_SIMPLY); - pb->SetName("-X"); - pos.x = 30.0f/640.0f; - pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON17); - pb->SetState(STATE_SIMPLY); - pb->SetName("-Y"); - pos.x = 50.0f/640.0f; - pb = m_interface->CreateButton(pos, dim, 0, EVENT_BUTTON18); - pb->SetState(STATE_SIMPLY); - pb->SetName("-Z"); - -//? m_modFile->ReadModel("objects\\io.mod"); - DeselectAll(); - CurrentInit(); - - ZeroMemory(&event, sizeof(Event)); - EventFrame(event); - - m_engine->LoadAllTexture(); - UpdateInfoText(); -} - -// You must call this procedure after modifing the model interactively. - -void CModel::StopUserAction() -{ - m_interface->DeleteControl(EVENT_EDIT1); - m_interface->DeleteControl(EVENT_EDIT2); - m_interface->DeleteControl(EVENT_EDIT3); - m_interface->DeleteControl(EVENT_EDIT4); - m_interface->DeleteControl(EVENT_EDIT5); - m_interface->DeleteControl(EVENT_BUTTON1); - m_interface->DeleteControl(EVENT_BUTTON2); - m_interface->DeleteControl(EVENT_BUTTON3); - m_interface->DeleteControl(EVENT_BUTTON4); - m_interface->DeleteControl(EVENT_BUTTON5); - m_interface->DeleteControl(EVENT_BUTTON10); - m_interface->DeleteControl(EVENT_BUTTON11); - m_interface->DeleteControl(EVENT_BUTTON12); - m_interface->DeleteControl(EVENT_BUTTON13); - m_interface->DeleteControl(EVENT_BUTTON14); - m_interface->DeleteControl(EVENT_BUTTON15); - m_interface->DeleteControl(EVENT_BUTTON16); - m_interface->DeleteControl(EVENT_BUTTON17); - m_interface->DeleteControl(EVENT_BUTTON18); - - m_engine->SetInfoText(0, ""); - m_engine->SetInfoText(1, ""); -} - - -// Updates the​editable values for mapping textures. - -void CModel::PutTextureValues() -{ - CEdit* pe; - char s[100]; - int value; - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT2); - if ( pe != 0 ) - { - value = (int)(m_textureSup.x*256.0f+0.5f); - sprintf(s, "%d", value); - pe->SetText(s); - } - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT3); - if ( pe != 0 ) - { - value = (int)(m_textureSup.y*256.0f+0.5f); - sprintf(s, "%d", value); - pe->SetText(s); - } - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT4); - if ( pe != 0 ) - { - value = (int)(m_textureInf.x*256.0f-0.5f); - sprintf(s, "%d", value); - pe->SetText(s); - } - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT5); - if ( pe != 0 ) - { - value = (int)(m_textureInf.y*256.0f-0.5f); - sprintf(s, "%d", value); - pe->SetText(s); - } -} - -// Takes the editable values for mapping textures. - -void CModel::GetTextureValues() -{ - CEdit* pe; - char s[100]; - int value; - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT2); - if ( pe != 0 ) - { - pe->GetText(s, 100); - sscanf(s, "%d", &value); - m_textureSup.x = ((float)value-0.5f)/256.0f; - } - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT3); - if ( pe != 0 ) - { - pe->GetText(s, 100); - sscanf(s, "%d", &value); - m_textureSup.y = ((float)value-0.5f)/256.0f; - } - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT4); - if ( pe != 0 ) - { - pe->GetText(s, 100); - sscanf(s, "%d", &value); - m_textureInf.x = ((float)value+0.5f)/256.0f; - } - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT5); - if ( pe != 0 ) - { - pe->GetText(s, 100); - sscanf(s, "%d", &value); - m_textureInf.y = ((float)value+0.5f)/256.0f; - } -} - - -// Gives the model name. - -void CModel::GetModelName(char *buffer) -{ - CEdit* pe; - char s[100]; - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT1); - if ( pe == 0 ) - { - strcpy(buffer, "objects\\io.mod"); - } - else - { - pe->GetText(s, 100); - sprintf(buffer, "objects\\%s.mod", s); - } -} - -// Gives the model name. - -void CModel::GetDXFName(char *buffer) -{ - CEdit* pe; - char s[100]; - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT1); - if ( pe == 0 ) - { - strcpy(buffer, "models\\import.dxf"); - } - else - { - pe->GetText(s, 100); - sprintf(buffer, "models\\%s.dxf", s); - } -} - -// Gives the model name. - -void CModel::GetScriptName(char *buffer) -{ - CEdit* pe; - char s[100]; - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT1); - if ( pe == 0 ) - { - strcpy(buffer, "objects\\script.txt"); - } - else - { - pe->GetText(s, 100); - sprintf(buffer, "objects\\%s.txt", s); - } -} - -// Indicates whether the edition name has focus. - -BOOL CModel::IsEditFocus() -{ - CEdit* pe; - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT1); - if ( pe != 0 ) - { - if ( pe->RetFocus() ) return TRUE; - } - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT2); - if ( pe != 0 ) - { - if ( pe->RetFocus() ) return TRUE; - } - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT3); - if ( pe != 0 ) - { - if ( pe->RetFocus() ) return TRUE; - } - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT4); - if ( pe != 0 ) - { - if ( pe->RetFocus() ) return TRUE; - } - - pe = (CEdit*)m_interface->SearchControl(EVENT_EDIT5); - if ( pe != 0 ) - { - if ( pe->RetFocus() ) return TRUE; - } - - return FALSE; -} - - -// Management of an event. - -BOOL CModel::EventProcess(const Event &event) -{ - char s[100]; - int first, last; - - switch( event.event ) - { - case EVENT_FRAME: - EventFrame(event); - break; - - case EVENT_KEYDOWN: - if ( IsEditFocus() ) - break; - - if ( event.param == '1' ) - { - m_mode = 1; - UpdateInfoText(); - } - if ( event.param == '2' ) - { - m_mode = 2; - UpdateInfoText(); - } - if ( event.param == '3' ) - { - m_mode = 3; - UpdateInfoText(); - } - if ( event.param == VK_ADD ) // numpad? - { - if ( event.keyState & KS_SHIFT ) CurrentSelect(TRUE); - CurrentSearchNext(+1, (event.keyState & KS_CONTROL)); - } - if ( event.param == VK_SUBTRACT ) // least numpad? - { - if ( event.keyState & KS_SHIFT ) CurrentSelect(TRUE); - CurrentSearchNext(-1, (event.keyState & KS_CONTROL)); - } - if ( event.param == VK_NUMPAD0 ) - { - CurrentSelect(FALSE); - } - if ( event.param == VK_DECIMAL ) - { - CurrentSelect(TRUE); - } - if ( event.param == VK_END ) - { - DeselectAll(); - } - if ( event.param == VK_INSERT ) - { - SelectAll(); - } - if ( event.param == VK_BACK ) // Delete normal ? - { - SelectDelete(); - } - if ( event.param == VK_SPACE ) - { - m_bDisplayTransparent = !m_bDisplayTransparent; - m_bDisplayOnlySelection = FALSE; - } - if ( event.param == 'H' ) - { - m_bDisplayOnlySelection = !m_bDisplayOnlySelection; - m_bDisplayTransparent = FALSE; - } - if ( m_mode == 1 ) - { - if ( event.param == 'S' ) - { - SmoothSelect(); - } - if ( event.param == 'N' ) - { - PlaneSelect(); - } - if ( event.param == 'C' ) - { - ColorSelect(); - } - if ( event.param == 'V' ) - { - m_color ++; - if ( m_color >= MAX_COLORS ) m_color = 0; - UpdateInfoText(); - ColorSelect(); - } - if ( event.param == 'J' ) - { - StateSelect(); - } - if ( event.param == 'K' ) - { - m_state ++; - if ( m_state >= MAX_STATES ) m_state = 0; - UpdateInfoText(); - StateSelect(); - } - if ( event.param == 'M' ) - { - m_textureMode ++; - if ( m_textureMode > 3 ) m_textureMode = 0; - UpdateInfoText(); - GetTextureValues(); - MappingSelect(m_textureMode, m_textureRotate, - m_bTextureMirrorX, m_bTextureMirrorY, - m_textureInf, m_textureSup, m_textureName); - } - if ( event.param == 'Z' ) - { - m_textureRotate ++; - if ( m_textureRotate > 2 ) m_textureRotate = 0; - UpdateInfoText(); - GetTextureValues(); - MappingSelect(m_textureMode, m_textureRotate, - m_bTextureMirrorX, m_bTextureMirrorY, - m_textureInf, m_textureSup, m_textureName); - } - if ( event.param == 'X' ) - { - m_bTextureMirrorX = !m_bTextureMirrorX; - UpdateInfoText(); - GetTextureValues(); - MappingSelect(m_textureMode, m_textureRotate, - m_bTextureMirrorX, m_bTextureMirrorY, - m_textureInf, m_textureSup, m_textureName); - } - if ( event.param == 'Y' ) - { - m_bTextureMirrorY = !m_bTextureMirrorY; - UpdateInfoText(); - GetTextureValues(); - MappingSelect(m_textureMode, m_textureRotate, - m_bTextureMirrorX, m_bTextureMirrorY, - m_textureInf, m_textureSup, m_textureName); - } - if ( event.param == 'O' ) - { - TextureRankChange(+1); - UpdateInfoText(); - } - if ( event.param == 'P' ) - { - TexturePartChange(+1); - UpdateInfoText(); - GetTextureValues(); - MappingSelect(m_textureMode, m_textureRotate, - m_bTextureMirrorX, m_bTextureMirrorY, - m_textureInf, m_textureSup, m_textureName); - } - if ( event.param == 'T' ) - { - GetTextureValues(); - MappingSelect(m_textureMode, m_textureRotate, - m_bTextureMirrorX, m_bTextureMirrorY, - m_textureInf, m_textureSup, m_textureName); - } - if ( event.param == 'E' ) - { - FPOINT ti, ts; - ti.x = 0.00f; - ti.y = 0.00f; - ts.x = 0.00f; - ts.y = 0.00f; - MappingSelect(m_textureMode, m_textureRotate, - m_bTextureMirrorX, m_bTextureMirrorY, - ti, ts, ""); - } - } - if ( m_mode == 2 ) - { - if ( event.param == 'E' ) - { - m_secondTexNum = 0; - UpdateInfoText(); - MappingSelect2(m_secondTexNum, m_secondSubdiv, m_secondOffsetU, m_secondOffsetV, m_bTextureMirrorX, m_bTextureMirrorY); - } - if ( event.param == 'O' ) - { - m_secondTexNum ++; - if ( m_secondTexNum > 10 ) m_secondTexNum = 1; - UpdateInfoText(); - } - if ( event.param == 'T' ) - { - MappingSelect2(m_secondTexNum, m_secondSubdiv, m_secondOffsetU, m_secondOffsetV, m_bTextureMirrorX, m_bTextureMirrorY); - m_engine->LoadAllTexture(); - } - if ( event.param == 'U' ) - { - m_secondOffsetU += 45; - if ( m_secondOffsetU >= 360 ) m_secondOffsetU = 0; - MappingSelect2(m_secondTexNum, m_secondSubdiv, m_secondOffsetU, m_secondOffsetV, m_bTextureMirrorX, m_bTextureMirrorY); - UpdateInfoText(); - } - if ( event.param == 'V' ) - { - m_secondOffsetV += 45; - if ( m_secondOffsetV >= 360 ) m_secondOffsetV = 0; - MappingSelect2(m_secondTexNum, m_secondSubdiv, m_secondOffsetU, m_secondOffsetV, m_bTextureMirrorX, m_bTextureMirrorY); - UpdateInfoText(); - } - if ( event.param == 'X' ) - { - m_bTextureMirrorX = !m_bTextureMirrorX; - MappingSelect2(m_secondTexNum, m_secondSubdiv, m_secondOffsetU, m_secondOffsetV, m_bTextureMirrorX, m_bTextureMirrorY); - UpdateInfoText(); - } - if ( event.param == 'Y' ) - { - m_bTextureMirrorY = !m_bTextureMirrorY; - MappingSelect2(m_secondTexNum, m_secondSubdiv, m_secondOffsetU, m_secondOffsetV, m_bTextureMirrorX, m_bTextureMirrorY); - UpdateInfoText(); - } - if ( event.param == 'S' ) - { - m_secondSubdiv ++; - if ( m_secondSubdiv > 7 ) m_secondSubdiv = 1; - MappingSelect2(m_secondTexNum, m_secondSubdiv, m_secondOffsetU, m_secondOffsetV, m_bTextureMirrorX, m_bTextureMirrorY); - UpdateInfoText(); - } - } - if ( m_mode == 3 ) - { - if ( event.param == 'M' ) - { - if ( m_min == 0.0f && m_max == 1000000.0f ) - { - m_min = 0.0f; m_max = 100.0f; - } - else if ( m_min == 0.0f && m_max == 100.0f ) - { - m_min = 100.0f; m_max = 200.0f; - } - else if ( m_min == 100.0f && m_max == 200.0f ) - { - m_min = 200.0f; m_max = 1000000.0f; - } - else if ( m_min == 200.0f && m_max == 1000000.0f ) - { - m_min = 0.0f; m_max = 1000000.0f; - } - UpdateInfoText(); - } - if ( event.param == 'C' ) - { - MinMaxChange(); - } - } - break; - - case EVENT_BUTTON1: // import ? - GetDXFName(s); - m_modFile->ReadDXF(s, m_min, m_max); - DeselectAll(); - CurrentInit(); - EventFrame(event); - m_engine->LoadAllTexture(); - break; - - case EVENT_BUTTON2: // script ? - GetScriptName(s); - ReadScript(s); - DeselectAll(); - CurrentInit(); - EventFrame(event); - m_engine->LoadAllTexture(); - break; - - case EVENT_BUTTON3: // read ? - GetModelName(s); - m_modFile->ReadModel(s, TRUE, FALSE); // standard read with borders - DeselectAll(); - CurrentInit(); - EventFrame(event); - m_engine->LoadAllTexture(); - break; - - case EVENT_BUTTON4: // add ? - GetModelName(s); - first = m_modFile->RetTriangleUsed(); - m_modFile->AddModel(s, first, TRUE, FALSE); // standard read with borders - last = m_modFile->RetTriangleUsed(); - SelectZone(first, last); - EventFrame(event); - break; - - case EVENT_BUTTON5: // write ? - GetModelName(s); - DeselectAll(); - m_modFile->WriteModel(s); - break; - - case EVENT_BUTTON10: // pos ? - m_oper = 'P'; - break; - case EVENT_BUTTON11: // rotate ? - m_oper = 'R'; - break; - case EVENT_BUTTON12: // zoom ? - m_oper = 'Z'; - break; - - case EVENT_BUTTON13: // +X ? - MoveSelect(D3DVECTOR(1.0f, 0.0f, 0.0f)); - break; - case EVENT_BUTTON16: // -X ? - MoveSelect(D3DVECTOR(-1.0f, 0.0f, 0.0f)); - break; - case EVENT_BUTTON14: // +Y ? - MoveSelect(D3DVECTOR(0.0f, 1.0f, 0.0f)); - break; - case EVENT_BUTTON17: // -Y ? - MoveSelect(D3DVECTOR(0.0f, -1.0f, 0.0f)); - break; - case EVENT_BUTTON15: // +Z ? - MoveSelect(D3DVECTOR(0.0f, 0.0f, 1.0f)); - break; - case EVENT_BUTTON18: // -Z ? - MoveSelect(D3DVECTOR(0.0f, 0.0f, -1.0f)); - break; - } - - return 0; -} - - -// Drives the model. - -BOOL CModel::EventFrame(const Event &event) -{ - D3DMATERIAL7 matCurrent, matCurrenti, matCurrents, matTrans; - D3DMATERIAL7* pMat; - D3DVERTEX2 vertex[3]; - char texName2[20]; - int i, used, objRank, state; - - m_time += event.rTime; - - m_engine->FlushObject(); - objRank = m_engine->CreateObject(); - - ZeroMemory(&matCurrent, sizeof(D3DMATERIAL7)); - matCurrent.diffuse.r = 1.0f; - matCurrent.diffuse.g = 0.0f; - matCurrent.diffuse.b = 0.0f; // red - matCurrent.ambient.r = 0.5f; - matCurrent.ambient.g = 0.5f; - matCurrent.ambient.b = 0.5f; - - ZeroMemory(&matCurrents, sizeof(D3DMATERIAL7)); - matCurrents.diffuse.r = 1.0f; - matCurrents.diffuse.g = 1.0f; - matCurrents.diffuse.b = 0.0f; // yellow - matCurrents.ambient.r = 0.5f; - matCurrents.ambient.g = 0.5f; - matCurrents.ambient.b = 0.5f; - - ZeroMemory(&matCurrenti, sizeof(D3DMATERIAL7)); - matCurrenti.diffuse.r = 0.0f; - matCurrenti.diffuse.g = 0.0f; - matCurrenti.diffuse.b = 1.0f; // blue - matCurrenti.ambient.r = 0.5f; - matCurrenti.ambient.g = 0.5f; - matCurrenti.ambient.b = 0.5f; - - used = m_modFile->RetTriangleUsed(); - for ( i=0 ; i= m_triangleSel1 && - i <= m_triangleSel2 && - (int)(m_time*10.0f)%2 == 0 ) - { - pMat = &matCurrent; - } - else if ( m_triangleTable[i].bSelect && - (int)(m_time*10.0f)%2 == 0 ) - { - pMat = &matCurrents; - } - else - { - if ( m_bDisplayOnlySelection ) continue; - if ( m_bDisplayTransparent ) - { - matTrans = m_triangleTable[i].material; - matTrans.diffuse.a = 0.1f; // very transparent - pMat = &matTrans; - state = D3DSTATETD; - } - } - - if ( m_triangleTable[i].texNum2 == 0 ) - { - m_engine->AddTriangle(objRank, &m_triangleTable[i].p1, 3, - *pMat, state, - m_triangleTable[i].texName, "", - 0.0f, 1000000.0f, FALSE); - } - else - { - sprintf(texName2, "dirty%.2d.tga", m_triangleTable[i].texNum2); - m_engine->AddTriangle(objRank, &m_triangleTable[i].p1, 3, - *pMat, state|D3DSTATEDUALb, - m_triangleTable[i].texName, texName2, - 0.0f, 1000000.0f, FALSE); - } - - if ( m_bDisplayTransparent && // draws inside? - i >= m_triangleSel1 && - i <= m_triangleSel2 ) - { - vertex[0] = m_triangleTable[i].p3; - vertex[1] = m_triangleTable[i].p2; - vertex[2] = m_triangleTable[i].p1; - - m_engine->AddTriangle(objRank, vertex, 3, - matCurrenti, D3DSTATENORMAL, - m_triangleTable[i].texName, "", - 0.0f, 1000000.0f, FALSE); - } - } - - return TRUE; -} - - -// Gives a vertex. - -BOOL CModel::GetVertex(int rank, D3DVERTEX2 &vertex) -{ - if ( rank < 0 || rank/3 >= m_modFile->RetTriangleUsed() ) return FALSE; - if ( !m_triangleTable[rank/3].bUsed ) return FALSE; - - if ( !m_triangleTable[rank/3].bSelect ) return FALSE; - - if ( rank%3 == 0 ) - { - vertex = m_triangleTable[rank/3].p1; - return TRUE; - } - if ( rank%3 == 1 ) - { - vertex = m_triangleTable[rank/3].p2; - return TRUE; - } - if ( rank%3 == 2 ) - { - vertex = m_triangleTable[rank/3].p3; - return TRUE; - } - return FALSE; -} - -// Modifies a vertex. - -BOOL CModel::SetVertex(int rank, D3DVERTEX2 &vertex) -{ - if ( rank < 0 || rank/3 >= m_modFile->RetTriangleUsed() ) return FALSE; - if ( !m_triangleTable[rank/3].bUsed ) return FALSE; - - if ( !m_triangleTable[rank/3].bSelect ) return FALSE; - - if ( rank%3 == 0 ) - { - m_triangleTable[rank/3].p1 = vertex; - return TRUE; - } - if ( rank%3 == 1 ) - { - m_triangleTable[rank/3].p2 = vertex; - return TRUE; - } - if ( rank%3 == 2 ) - { - m_triangleTable[rank/3].p3 = vertex; - return TRUE; - } - return FALSE; -} - -// Smoothed normals selected triangles. - -void CModel::SmoothSelect() -{ - char* bDone; - int index[100]; - int used, i, j, rank; - D3DVERTEX2 vi, vj; - D3DVECTOR sum; - - used = m_modFile->RetTriangleUsed(); - - bDone = (char*)malloc(used*3*sizeof(char)); - for ( i=0 ; i= 100 ) break; - } - } - - sum.x = 0; - sum.y = 0; - sum.z = 0; - for ( j=0 ; jRetTriangleUsed(); - - for ( i=0 ; iRetTriangleUsed(); - for ( i=0 ; iRetTriangleUsed(); - for ( i=0 ; iRetTriangleUsed(); - for ( i=0 ; iReadModel(buffer, TRUE, TRUE); - last = m_modFile->RetTriangleUsed(); - SelectZone(0, last); - } - else - { - first = m_modFile->RetTriangleUsed(); - m_modFile->AddModel(buffer, first, TRUE, FALSE); - last = m_modFile->RetTriangleUsed(); - SelectZone(first, last); - } - bFirst = FALSE; - - move = OpDir(line, "zoom"); - OperSelect(move, 'Z'); - - move = OpDir(line, "rot"); - move *= PI/180.0f; // degrees -> radians - OperSelect(move, 'R'); - - move = OpDir(line, "pos"); - OperSelect(move, 'P'); - } - } - - fclose(file); -} - - - -// Computes the bbox of selected triangles. - -void CModel::BBoxCompute(D3DVECTOR &min, D3DVECTOR &max) -{ - D3DVERTEX2 vertex; - int used, i; - - min.x = 1000000.0f; - min.y = 1000000.0f; - min.z = 1000000.0f; - max.x = -1000000.0f; - max.y = -1000000.0f; - max.z = -1000000.0f; - - used = m_modFile->RetTriangleUsed(); - - for ( i=0 ; i max.x ) max.x = vertex.x; - if ( vertex.y > max.y ) max.y = vertex.y; - if ( vertex.z > max.z ) max.z = vertex.z; - } -} - -// Returns the gravity center of the selection. - -D3DVECTOR CModel::RetSelectCDG() -{ - D3DVECTOR min, max, cdg; - - BBoxCompute(min, max); - - cdg.x = (min.x+max.x)/2.0f; - cdg.y = (min.y+max.y)/2.0f; - cdg.z = (min.z+max.z)/2.0f; - - return cdg; -} - -// Returns the normal vector of the selection. - -D3DVECTOR CModel::RetSelectNormal() -{ - D3DVECTOR p1, p2, p3, n; - - p1.x = m_triangleTable[m_triangleSel1].p1.nx; - p1.y = m_triangleTable[m_triangleSel1].p1.ny; - p1.z = m_triangleTable[m_triangleSel1].p1.nz; - - p2.x = m_triangleTable[m_triangleSel1].p2.nx; - p2.y = m_triangleTable[m_triangleSel1].p2.ny; - p2.z = m_triangleTable[m_triangleSel1].p2.nz; - - p3.x = m_triangleTable[m_triangleSel1].p3.nx; - p3.y = m_triangleTable[m_triangleSel1].p3.ny; - p3.z = m_triangleTable[m_triangleSel1].p3.nz; - - n = Normalize(p1+p2+p3); - - return n; -} - -// Maps a texture onto the selected triangles. - -BOOL CModel::IsMappingSelectPlausible(D3DMaping D3Dmode) -{ - D3DVERTEX2 vertex[3]; - D3DVECTOR min, max; - FPOINT a, b, ti, ts; - float au, bu, av, bv; - int used, i, j; - - ti.x = 0.0f; - ti.y = 0.0f; - ts.x = 1.0f; - ts.y = 1.0f; - - BBoxCompute(min, max); - - if ( D3Dmode == D3DMAPPINGX ) - { - a.x = min.z; - a.y = min.y; - b.x = max.z; - b.y = max.y; - } - if ( D3Dmode == D3DMAPPINGY ) - { - a.x = min.x; - a.y = min.z; - b.x = max.x; - b.y = max.z; - } - if ( D3Dmode == D3DMAPPINGZ ) - { - a.x = min.x; - a.y = min.y; - b.x = max.x; - b.y = max.y; - } - - au = (ts.x-ti.x)/(b.x-a.x); - bu = ts.x-b.x*(ts.x-ti.x)/(b.x-a.x); - - av = (ts.y-ti.y)/(b.y-a.y); - bv = ts.y-b.y*(ts.y-ti.y)/(b.y-a.y); - - used = m_modFile->RetTriangleUsed(); - for ( i=0 ; iRetTriangleUsed(); - for ( i=0 ; iRetTriangleUsed(); - for ( i=0 ; iRetTriangleUsed(); - for ( i=0 ; iRetTriangleUsed(); - for ( i=0 ; iRetTriangleUsed(); - for ( i=0 ; i 1.0f ) u[j] -= 1.0f; -#else - u[j] = RotateAngle(p.x, p.z)/PI; -//? if ( u[j] > 1.0f ) u[j] = 2.0f-u[j]; - if ( u[j] > 1.0f ) u[j] -= 1.0f; -#endif - - v[j] = p.y/dim.y/2.0f + 0.5f; - - if ( u[j] < 0.5f ) m[j] = u[j]; - else m[j] = u[j]-1.0f; - } - - avg = (m[0]+m[1]+m[2])/3.0f; - - for ( j=0 ; j<3 ; j++ ) - { - if ( u[j] < 0.05f || u[j] > 0.95f ) - { - if ( avg > 0.0f ) u[j] = 0.0f; - else u[j] = 1.0f; - } - - vertex[j].tu = ti.x+(ts.x-ti.x)*u[j]; - vertex[j].tv = ti.y+(ts.y-ti.y)*v[j]; - - SetVertex(i*3+j, vertex[j]); - } - } - - SelectTerm(); -} - - -// Maps a secondary texture on selected triangles. - -void CModel::MappingSelect2(int texNum2, int subdiv, - int offsetU, int offsetV, - BOOL bMirrorX, BOOL bMirrorY) -{ - D3DVERTEX2 vertex; - D3DVECTOR min, max, center, p; - float u ,v; - int used, i; - - DefaultSelect(); - - used = m_modFile->RetTriangleUsed(); - for ( i=0 ; i 2 ) - { - MappingSelectPlane2(subdiv-3, bMirrorX, bMirrorY); - return; - } - - BBoxCompute(min, max); - center = (min+max)/2.0f; - - for ( i=0 ; iRetTriangleUsed(); - for ( i=0 ; iRetTriangleUsed(); - for ( i=0 ; iRetTriangleUsed(); - for ( i=0 ; i= Max(n.y, n.z) ) mode = 0; - if ( n.y >= Max(n.x, n.z) ) mode = 1; - if ( n.z >= Max(n.x, n.y) ) mode = 2; - } - - if ( !GetVertex(i, vertex) ) continue; - - if ( mode == 0 ) - { - vertex.tu2 = vertex.z*au.z+bu.z; - vertex.tv2 = vertex.y*av.y+bv.y; - } - if ( mode == 1 ) - { - vertex.tu2 = vertex.x*au.x+bu.x; - vertex.tv2 = vertex.z*av.z+bv.z; - } - if ( mode == 2 ) - { - vertex.tu2 = vertex.x*au.x+bu.x; - vertex.tv2 = vertex.y*av.y+bv.y; - } - - SetVertex(i, vertex); - } - - SelectTerm(); -} - - -// Seeks the next triangle. - -int CModel::SearchNext(int rank, int step) -{ - int max, i; - - max = m_modFile->RetTriangleUsed(); - - for ( i=0 ; i= max ) rank = 0; - - if ( m_triangleTable[rank].min != m_min || - m_triangleTable[rank].max != m_max ) continue; - - if ( m_triangleTable[rank].bUsed ) break; - } - return rank; -} - -// Seeks all the triangles belonging to the same plane. - -int CModel::SearchSamePlane(int first, int step) -{ - D3DVECTOR vFirst[3], vNext[3]; - int last, i; - - vFirst[0].x = m_triangleTable[first].p1.x; - vFirst[0].y = m_triangleTable[first].p1.y; - vFirst[0].z = m_triangleTable[first].p1.z; - vFirst[1].x = m_triangleTable[first].p2.x; - vFirst[1].y = m_triangleTable[first].p2.y; - vFirst[1].z = m_triangleTable[first].p2.z; - vFirst[2].x = m_triangleTable[first].p3.x; - vFirst[2].y = m_triangleTable[first].p3.y; - vFirst[2].z = m_triangleTable[first].p3.z; - - for ( i=0 ; i<1000 ; i++ ) - { - last = first; - first = SearchNext(first, step); - - vNext[0].x = m_triangleTable[first].p1.x; - vNext[0].y = m_triangleTable[first].p1.y; - vNext[0].z = m_triangleTable[first].p1.z; - vNext[1].x = m_triangleTable[first].p2.x; - vNext[1].y = m_triangleTable[first].p2.y; - vNext[1].z = m_triangleTable[first].p2.z; - vNext[2].x = m_triangleTable[first].p3.x; - vNext[2].y = m_triangleTable[first].p3.y; - vNext[2].z = m_triangleTable[first].p3.z; - - if ( !IsSamePlane(vFirst, vNext) ) // other plan? - { - return last; - } - } - return first; -} - -// Seeks the next triangle. - -void CModel::CurrentSearchNext(int step, BOOL bControl) -{ - if ( step > 0 ) // forward? - { - m_triangleSel1 = SearchNext(m_triangleSel2, step); - if ( bControl ) - { - m_triangleSel2 = m_triangleSel1; - } - else - { - m_triangleSel2 = SearchSamePlane(m_triangleSel1, step); - } - } - if ( step < 0 ) // back? - { - m_triangleSel2 = SearchNext(m_triangleSel1, step); - if ( bControl ) - { - m_triangleSel1 = m_triangleSel2; - } - else - { - m_triangleSel1 = SearchSamePlane(m_triangleSel2, step); - } - } - -#if 0 - char s[100]; - sprintf(s, "(%.2f;%.2f;%.2f) (%.2f;%.2f;%.2f) (%.2f;%.2f;%.2f)", - m_triangleTable[m_triangleSel1].p1.x, - m_triangleTable[m_triangleSel1].p1.y, - m_triangleTable[m_triangleSel1].p1.z, - m_triangleTable[m_triangleSel1].p2.x, - m_triangleTable[m_triangleSel1].p2.y, - m_triangleTable[m_triangleSel1].p2.z, - m_triangleTable[m_triangleSel1].p3.x, - m_triangleTable[m_triangleSel1].p3.y, - m_triangleTable[m_triangleSel1].p3.z); - m_engine->SetInfoText(2, s); - sprintf(s, "(%.2f;%.2f) (%.2f;%.2f) (%.2f;%.2f)", - m_triangleTable[m_triangleSel1].p1.tu2, - m_triangleTable[m_triangleSel1].p1.tv2, - m_triangleTable[m_triangleSel1].p2.tu2, - m_triangleTable[m_triangleSel1].p2.tv2, - m_triangleTable[m_triangleSel1].p3.tu2, - m_triangleTable[m_triangleSel1].p3.tv2); - m_engine->SetInfoText(3, s); -#endif - - InitViewFromSelect(); - UpdateInfoText(); -} - -// Initializes the current triangles. - -void CModel::CurrentInit() -{ - m_triangleSel1 = 0; - m_triangleSel2 = SearchSamePlane(m_triangleSel1, +1); - - InitViewFromSelect(); - UpdateInfoText(); -} - -// Selects the current triangles. - -void CModel::CurrentSelect(BOOL bSelect) -{ - int i; - - for ( i=m_triangleSel1 ; i<=m_triangleSel2 ; i++ ) - { - m_triangleTable[i].bSelect = bSelect; - } -} - - -// Deselects all triangles. - -void CModel::DeselectAll() -{ - int used, i; - - used = m_modFile->RetTriangleUsed(); - for ( i=0 ; iRetTriangleUsed(); - for ( i=0 ; i= first && i < last ) - { - m_triangleTable[i].bSelect = TRUE; - } - } - m_triangleSel1 = first; - m_triangleSel2 = last-1; -} - -// Selects all triangles. - -void CModel::SelectAll() -{ - int used, i; - - used = m_modFile->RetTriangleUsed(); - for ( i=0 ; iRetTriangleUsed(); - for ( i=0 ; i= m_triangleSel1 && i <= m_triangleSel2 ) - { - if ( !m_triangleTable[i].bSelect ) return; - } - else - { - if ( m_triangleTable[i].bSelect ) return; - } - } - - DeselectAll(); -} - -// Selects the triangles currents. - -void CModel::DefaultSelect() -{ - int used, i; - - used = m_modFile->RetTriangleUsed(); - for ( i=m_triangleSel1 ; i<=m_triangleSel2 ; i++ ) - { - m_triangleTable[i].bSelect = TRUE; - } -} - - - -// Removes all selected triangles. - -void CModel::SelectDelete() -{ - int used ,i; - - DefaultSelect(); - - used = m_modFile->RetTriangleUsed(); - for ( i=0 ; iRetTriangleUsed(); - for ( i=0 ; iSetTriangleUsed(j); - CurrentInit(); -} - - -// Change the min / max of all selected triangles. - -void CModel::MinMaxChange() -{ - int used, i; - - DefaultSelect(); - - used = m_modFile->RetTriangleUsed(); - for ( i=0 ; i= PI ) - { - m_viewAngleV -= PI; - m_viewAngleH -= PI; - } - m_viewAngleV *= 0.75f; - - char s[100]; - sprintf(s, "angle=%f %f -> %f %f\n", h,v, m_viewAngleH, m_viewAngleV); - OutputDebugString(s); -#endif -} - -// Updates the parameters for the point of view. - -void CModel::UpdateView() -{ - D3DVECTOR eye, lookat, vUpVec; - -//? lookat = RetSelectCDG(); - lookat = D3DVECTOR(0.0f, m_viewHeight, 0.0f); - eye = RotateView(lookat, m_viewAngleH, m_viewAngleV, m_viewDist); - - vUpVec = D3DVECTOR(0.0f, 1.0f, 0.0f); - m_engine->SetViewParams(eye, lookat, vUpVec, 10.0f); - m_engine->SetRankView(0); -} - -// Moves the point of view. - -void CModel::ViewMove(const Event &event, float speed) -{ - if ( IsEditFocus() ) return; - - // Up/Down. - if ( event.axeY > 0.5f ) - { - if ( event.keyState & KS_CONTROL ) - { - m_viewHeight += event.rTime*10.0f*speed; - if ( m_viewHeight > 100.0f ) m_viewHeight = 100.0f; - } - else - { - m_viewAngleV -= event.rTime*1.0f*speed; - if ( m_viewAngleV < -PI*0.49f ) m_viewAngleV = -PI*0.49f; - } - } - if ( event.axeY < -0.5f ) - { - if ( event.keyState & KS_CONTROL ) - { - m_viewHeight -= event.rTime*10.0f*speed; - if ( m_viewHeight < -100.0f ) m_viewHeight = -100.0f; - } - else - { - m_viewAngleV += event.rTime*1.0f*speed; - if ( m_viewAngleV > PI*0.49f ) m_viewAngleV = PI*0.49f; - } - } - - // Left/Right. - if ( event.axeX < -0.5f ) - { - m_viewAngleH -= event.rTime*1.0f*speed; - } - if ( event.axeX > 0.5f ) - { - m_viewAngleH += event.rTime*1.0f*speed; - } - - // PageUp/PageDown. - if ( event.keyState & KS_PAGEUP ) - { - m_viewDist -= event.rTime*30.0f*speed; - if ( m_viewDist < 1.0f ) m_viewDist = 1.0f; - } - if ( event.keyState & KS_PAGEDOWN ) - { - m_viewDist += event.rTime*30.0f*speed; - if ( m_viewDist > 300.0f ) m_viewDist = 300.0f; - } -} - - - -// Updates the text information. - -void CModel::UpdateInfoText() -{ - char info[100]; - - if ( m_mode == 1 ) - { - sprintf(info, "[1] V:color=%d K:state=%d Sel=%d..%d (T=%d)", - m_color, m_state, - m_triangleSel1, m_triangleSel2, - m_triangleSel2-m_triangleSel1+1); - m_engine->SetInfoText(0, info); - - sprintf(info, "M:mode=%d Z:rot=%d XY:mir=%d;%d P:part=%d O:name=%s", - m_textureMode, m_textureRotate, - m_bTextureMirrorX, m_bTextureMirrorY, - m_texturePart, m_textureName); - m_engine->SetInfoText(1, info); - } - - if ( m_mode == 2 ) - { - sprintf(info, "[2] Sel=%d..%d (T=%d)", - m_triangleSel1, m_triangleSel2, - m_triangleSel2-m_triangleSel1+1); - m_engine->SetInfoText(0, info); - - sprintf(info, "O:dirty=%d UV:offset=%d;%d XY:mir=%d;%d S:subdiv=%d", - m_secondTexNum, - m_secondOffsetU, m_secondOffsetV, - m_bTextureMirrorX, m_bTextureMirrorY, - m_secondSubdiv); - m_engine->SetInfoText(1, info); - } - - if ( m_mode == 3 ) - { - sprintf(info, "[3] LOD Min/max=%d..%d Sel=%d..%d (T=%d)", - (int)m_min, (int)m_max, - m_triangleSel1, m_triangleSel2, - m_triangleSel2-m_triangleSel1+1); - m_engine->SetInfoText(0, info); - - sprintf(info, "[Change]"); - m_engine->SetInfoText(1, info); - } -} - - - -static int tablePartT[] = // lemt.tga -{ - 192, 0, 256, 32, // track profile - 0, 64, 128, 128, // wheels for track - 0, 0, 128, 64, // profile - 90, 0, 128, 28, // pivot trainer - 128, 0, 192, 44, // chest front - 128, 44, 192, 58, // shell - 128, 58, 192, 87, // back chest - 128, 87, 192, 128, // back shell - 128, 128, 192, 144, // sub back shell - 0, 128, 32, 152, // rear fender - 0, 152, 32, 182, // fender middle - 0, 182, 32, 256, // front fender - 32, 128, 112, 176, // wing - 224, 48, 232, 64, // thrust tunnel - 192, 32, 224, 64, // fire under reactor - 224, 32, 256, 48, // foot - 192, 64, 256, 128, // sensor - 192, 128, 224, 176, // battery holder - 192, 216, 248, 248, // cannon board - 220, 216, 222, 245, // cannon board - 64, 176, 128, 224, // top cannon - 128, 152, 192, 160, // external cannon - 128, 144, 192, 152, // interior cannon - 192, 176, 224, 192, // small cannon - 128, 236, 192, 256, // cannon organic - 214, 192, 224, 216, // crosshair - 224, 128, 248, 152, // articulation - 128, 192, 192, 214, // piston board - 128, 214, 192, 236, // piston front - 192, 192, 214, 214, // piston edge - 128, 192, 161, 214, // small piston board - 32, 176, 64, 198, // radar piston - 128, 160, 160, 192, // wheel - 232, 48, 255, 56, // tire profile - 240, 152, 248, 216, // vertical hatching - 248, 192, 256, 256, // battery - 224, 152, 240, 168, // rock - 144, 80, 176, 112, // nuclear - 140, 76, 180, 116, // large nuclear - 144, 80, 152, 88, // yellow nuclear - 224, 168, 240, 192, // cap resolution C - 224, 192, 240, 210, // back resolution C - 32, 224, 96, 235, // arm resolution C - 32, 235, 96, 246, // arm resolution C - 161, 1, 164, 4, // blank - 168, 1, 171, 4, // medium gray - 154, 1, 157, 4, // dark gray uniform - 147, 1, 150, 4, // blue unifrom - 114, 130, 118, 134, // red unifrom - 121, 130, 125, 134, // green uniform - 114, 137, 118, 141, // yellow uniform - 121, 137, 125, 141, // violet uniform - -1 -}; - -static int tablePartR[] = // roller.tga -{ - 0, 0, 128, 52, // wheels for track - 48, 137, 128, 201, // catalytic radiator - 0, 52, 32, 84, // front radiator - 32, 52, 43, 84, // back radiator - 0, 84, 96, 137, // large catalytic - 128, 0, 192, 85, // front - 128, 173, 192, 256, // back - 192, 0, 256, 42, // over - 128, 85, 192, 109, // catalytic pillon - 128, 109, 192, 173, // top pillon - 192, 85, 240, 109, // catalytic gate pillon - 0, 137, 24, 256, // catalytic verrin - 24, 137, 48, 256, // catalytic verrin - 48, 201, 128, 233, // medium cannon - 192, 109, 256, 173, // bottom cannon - 192, 173, 240, 205, // cannon 1 - 192, 173, 240, 177, // cannon 2 - 43, 52, 75, 84, // front cannon - 48, 233, 128, 247, // piston - 96, 105, 128, 137, // front phazer - 96, 97, 128, 105, // phazer cannon - 75, 52, 107, 84, // exhaust pipe - 192, 205, 243, 256, // nuclear power plant instruction - 192, 42, 256, 85, // reflection glass - -1 -}; - -static int tablePartW[] = // subm.tga -{ - 0, 0, 128, 26, // chenilles - 0, 26, 22, 114, // portique 1 - 0, 114, 22, 202, // portique 2 - 22, 26, 82, 56, // c�t� hublot - 22, 56, 82, 86, // c�t� ligne rouge - 22, 86, 82, 116, // c�t� simple - 22, 116, 82, 146, // avant/arri�re - 22, 146, 82, 176, // avant/arri�re + phare - 132, 82, 196, 166, // capot trainer - 132, 166, 196, 177, // capot trainer - 132, 177, 196, 188, // capot trainer - 0, 224, 96, 256, // c�t� trainer - 30, 224, 48, 256, // arri�re trainer - 136, 240, 216, 256, // barri�re courte - 96, 240, 256, 256, // barri�re longue - 128, 0, 160, 32, // black-box 1 - 160, 0, 192, 32, // black-box 2 - 192, 0, 224, 32, // black-box 3 - 224, 105, 256, 137, // TNT 1 - 224, 137, 256, 169, // TNT 2 - 82, 32, 146, 82, // factory r�solution C - 146, 32, 210, 82, // factory r�solution C - 224, 0, 256, 105, // tower r�solution C - 82, 82, 132, 150, // research r�solution C - 199, 169, 256, 233, // sac r�solution C - 106, 150, 130, 214, // cl� A - 82, 150, 106, 214, // cl� B - 132, 188, 196, 212, // cl� C - 132, 212, 196, 236, // cl� D - 210, 32, 224, 46, // gris - 56, 176, 82, 224, // sol coffre-fort - -1 -}; - -static int tablePartDr[] = // drawer.tga -{ - 128, 0, 134, 6, // bleu - 128, 6, 134, 12, // gris fonc� - 128, 12, 134, 18, // gris clair - 0, 0, 128, 32, // roues chenille - 192, 0, 256, 32, // profil chenille - 140, 0, 160, 8, // profil phare - 160, 0, 192, 32, // face phare - 0, 32, 160, 48, // hachure - 160, 32, 192, 48, // c�t� - 0, 48, 96, 96, // tableau de bord - 96, 48, 192, 112, // radiateur - 192, 32, 256, 112, // grille lat�rale - 192, 112, 256, 128, // capot - 0, 96, 8, 160, // chassis - 8, 96, 96, 104, // axe chenilles - 8, 104, 16, 160, // axe carrousel - 16, 128, 24, 160, // flan support - 224, 128, 256, 160, // rotule - 24, 104, 32, 160, // bocal (18) - 32, 104, 40, 160, // bocal - 40, 104, 48, 160, // bocal - 24, 152, 48, 160, // bocal fond - 0, 240, 32, 256, // crayon 1: couleur (22) - 0, 160, 32, 192, // crayon 1: dessus - 0, 192, 32, 256, // crayon 1: pointe - 32, 240, 64, 256, // crayon 2: couleur - 32, 160, 64, 192, // crayon 2: dessus - 32, 192, 64, 256, // crayon 2: pointe - 64, 240, 96, 256, // crayon 3: couleur - 64, 160, 96, 192, // crayon 3: dessus - 64, 192, 96, 256, // crayon 3: pointe - 96, 240, 128, 256, // crayon 4: couleur - 96, 160, 128, 192, // crayon 4: dessus - 96, 192, 128, 256, // crayon 4: pointe - 128, 240, 160, 256, // crayon 5: couleur - 128, 160, 160, 192, // crayon 5: dessus - 128, 192, 160, 256, // crayon 5: pointe - 160, 240, 192, 256, // crayon 6: couleur - 160, 160, 192, 192, // crayon 6: dessus - 160, 192, 192, 256, // crayon 6: pointe - 192, 240, 224, 256, // crayon 7: couleur - 192, 160, 224, 192, // crayon 7: dessus - 192, 192, 224, 256, // crayon 7: pointe - 224, 240, 256, 256, // crayon 8: couleur - 224, 160, 256, 192, // crayon 8: dessus - 224, 192, 256, 256, // crayon 8: pointe - -1 -}; - -static int tablePartKi[] = // kid.tga -{ - 0, 0, 128, 53, // ciseaux - 128, 0, 256, 128, // CD - 0, 0, 8, 8, // livre 1: fond - 8, 0, 16, 8, // livre 2: fond - 16, 0, 24, 8, // livre: fond - 24, 0, 32, 8, // livre: fond - 32, 0, 40, 8, // livre: fond - 40, 0, 48, 8, // livre: fond - 0, 53, 22, 138, // livre 1: tranche - 22, 53, 86, 138, // livre 1: face - 0, 138, 22, 224, // livre 2: tranche - 22, 138, 86, 224, // livre 2: face - 86, 53, 94, 85, // livre: pages - 94, 53, 110, 139, // livre: tranche - 110, 53, 126, 139, // livre: tranche - 86, 139, 102, 225, // livre: tranche - 102, 139, 118, 225, // livre: tranche - 118, 139, 134, 225, // livre: tranche - 64, 0, 72, 8, // fauille: fond - 155, 155, 256, 256, // feuille: carreaux - 72, 0, 80, 8, // lampe - 80, 0, 88, 8, // lampe - 80, 8, 88, 16, // ampoule - 72, 8, 80, 16, // rayons (23) - 86, 85, 94, 139, // lampe - 0, 224, 32, 256, // lampe rotule - 64, 8, 72, 16, // arrosoir: fond - 134, 128, 142, 256, // arrosoir: corps - 142, 128, 150, 256, // arrosoir: tuyau - 128, 225, 134, 256, // arrosoir: int�rieur - 32, 224, 64, 256, // arrosoir: ponneau - 56, 8, 64, 16, // skate: roues (31) - 48, 8, 56, 16, // skate: axes - 40, 8, 48, 16, // skate: grip - 32, 8, 40, 16, // skate: tranche - 24, 8, 32, 16, // skate: dessous - 150, 128, 200, 256, // skate: motif 1 - 200, 128, 250, 256, // skate: motif 2 - 64, 224, 96, 256, // skate: roue (38) - 96, 225, 104, 256, // skate: amortisseur - -1 -}; - -static int tablePartKi2[] = // kid2.tga -{ - 2, 2, 62, 62, // coca: dessus - 0, 64, 8, 192, // coca: flan - 8, 64, 96, 192, // coca: logo - 128, 0, 256, 85, // carton - 128, 85, 256, 91, // carton tranche - 128, 128, 256, 256, // roue - 192, 96, 256, 128, // pneu - 184, 96, 192, 128, // jante - 128, 96, 160, 128, // int�rieur - 160, 96, 168, 104, // porte bois - 160, 104, 168, 112, // porte m�tal - 160, 112, 184, 128, // vitre - 96, 0, 128, 256, // bouteille: corps (12) - 64, 0, 96, 32, // bouteille: bouchon - 168, 96, 176, 104, // bouteille: vert - 0, 192, 96, 224, // bois clair - 0, 224, 96, 256, // bois fonc� - 64, 32, 96, 64, // bateau - 168, 104, 176, 112, // ballon (18) - 176, 104, 184, 112, // ballon - 176, 96, 184, 104, // int�rieur caisse - -1 -}; - -static int tablePartKi3[] = // kid3.tga -{ - 0, 0, 32, 28, // �crou: flan - 0, 28, 32, 44, // �crou: profil - 0, 44, 32, 60, // �crou: pas de vis - 0, 60, 32, 64, // tuyau - 0, 64, 32, 68, // tuyau - 0, 68, 8, 76, // tuyau - 0, 76, 32, 108, // plastic - 8, 68, 16, 76, // saut: gris clair (7) - 16, 68, 24, 76, // saut: gris fonc� - 24, 68, 32, 76, // saut: gris bois - 0, 108, 32, 140, // saut: rotule - 0, 140, 32, 144, // saut: axe - 128, 0, 256, 128, // saut: flan - 0, 144, 8, 152, // basket: gris fonc� (13) - 8, 144, 16, 152, // basket: gris clair - 16, 144, 24, 152, // basket: gris lacets - 24, 144, 32, 152, // basket: gris semelle - 0, 152, 8, 181, // basket: int�rieur - 0, 181, 192, 256, // basket: c�t� - 192, 181, 226, 256, // basket: arri�re - 32, 135, 96, 181, // basket: dessus (20) - 96, 168, 128, 181, // basket: avant - 8, 152, 16, 160, // chaise: plastique - 16, 152, 24, 160, // chaise: m�tal - 32, 0, 64, 32, // chaise: roue - 8, 177, 24, 181, // chaise: roue - 226, 181, 234, 256, // chaise: piston (26) - 64, 96, 128, 128, // chaise: relief - 96, 135, 128, 167, // chaise: dessous - 32, 128, 250, 135, // paille 1 - 38, 128, 256, 135, // paille 2 - 234, 181, 242, 256, // allumette - 8, 160, 16, 168, // allumette (dessus) - 128, 135, 224, 181, // panneau - 242, 135, 256, 256, // poteau (34) - 24, 152, 32, 160, // clou - 16, 160, 24, 168, // tuyau m�talique - 112, 181, 192, 185, // tuyau int�rieur - 32, 32, 48, 80, // pas de vis - 24, 160, 32, 168, // ventillateur: plastique (39) - 40, 80, 56, 96, // ventillateur: plastique d�grad� - 8, 168, 16, 176, // ventillateur: m�tal - 32, 80, 40, 112, // ventillateur: socle 1 - 64, 0, 96, 16, // ventillateur: socle 2 - 48, 32, 56, 80, // ventillateur: socle 3 - 64, 16, 96, 32, // ventillateur: moteur flan - 96, 0, 128, 32, // ventillateur: moteur face - 102, 6, 122, 26, // ventillateur: socle dessus - 16, 168, 24, 176, // pot: uni (48) - 56, 32, 64, 64, // pot: haut - 56, 64, 64, 96, // pot: bas - 64, 32, 128, 96, // pot: terre - -1 -}; - -static int tablePartF[] = // factory.tga -{ - 0, 0, 152, 152, // plancher octogonal fabrique - 50, 50, 102, 102, // dessus pile - 0, 152, 128, 252, // avant - 128, 152, 256, 252, // arri�re - 152, 28, 225, 128, // c�t� - 152, 28, 176, 128, // c�t� partiel - 152, 0, 216, 16, // hachures - 236, 0, 256, 40, // axe - 152, 128, 224, 152, // support cible - -1 -}; - -static int tablePartD[] = // derrick.tga -{ - 0, 0, 64, 32, // grand c�t� - 64, 0, 96, 24, // petit c�t� - 96, 0, 136, 24, // attention - 0, 32, 8, 160, // tube 1 - 8, 32, 16, 96, // tube 2 - 16, 32, 24, 160, // pilier - 24, 32, 32, 160, // tige foret - 32, 32, 40, 160, // tige destructeur - 8, 96, 16, 128, // foret - 136, 0, 256, 120, // plancher octogonal station de recharge - 40, 32, 64, 56, // cube m�tal - 64, 24, 128, 48, // c�t� tour haut - 64, 48, 128, 229, // c�t� tour bas - 136, 120, 256, 240, // int�rieur usine - 0, 160, 64, 224, // to�t usine - -1 -}; - -static int tablePartC[] = // convert.tga -{ - 0, 0, 120, 120, // plancher octogonal convertisseur - 0, 120, 128, 176, // grand c�t� - 128, 120, 192, 176, // petit c�t� - 192, 120, 256, 184, // couvercle convertisseur - 120, 0, 216, 64, // face trianble - 216, 0, 248, 64, // c�t� triangle - 120, 64, 160, 84, // axe - 0, 141, 128, 176, // recherche: base - 0, 176, 128, 214, // recherche: haut - 0, 214, 128, 252, // recherche: haut (!) - 174, 64, 190, 120, // recherche: montant - 190, 64, 206, 120, // recherche: montant - 206, 64, 254, 85, // radar - 192, 168, 256, 232, // hachures carr�es - 248, 0, 256, 64, // c�ne fabrique de piles - 128, 176, 192, 240, // dessus centrale nucl�aire - 120, 85, 174, 120, // technicien, visage - 206, 106, 256, 120, // technicien, casquette - 160, 64, 174, 78, // technicien, visi�re - -1 -}; - -static int tablePartS[] = // search.tga -{ - 0, 0, 128, 128, // usine 1 - 128, 0, 256, 128, // usine 2 - 0, 128, 128, 256, // pile - 128, 128, 228, 240, // support pile - 228, 128, 256, 184, // antenne - 128, 128, 192, 160, // contr�le 1 - 128, 160, 192, 192, // contr�le 2 - 128, 192, 192, 224, // contr�le 3 - 128, 224, 192, 256, // contr�le 4 - -1 -}; - -static int tablePartP[] = // plant.tga -{ - 0, 160, 48, 256, // feuille 1 - 0, 0, 94, 100, // feuille 2 - 48, 156, 108, 256, // feuille 3 - 94, 0, 104, 100, // tige 1 - 185, 0, 195, 100, // tige 2 - 108, 100, 182, 256, // foug�re - 104, 0, 144, 100, // courge - 203, 0, 256, 83, // armature derrick r�solution C - -1 -}; - -static int tablePartV[] = // vegetal.tga -{ - 0, 0, 94, 100, // racine - 186, 0, 256, 256, // tronc - 162, 0, 168, 128, // mat drapeau bleu - 168, 0, 174, 128, // mat drapeau rouge - 174, 0, 180, 128, // mat drapeau vert - 180, 0, 186, 128, // mat drapeau jaune - 180, 128, 186, 256, // mat drapeau violet - 94, 0, 107, 32, // drapeau bleu - 107, 0, 120, 32, // drapeau rouge - 120, 0, 133, 32, // drapeau vert - 133, 0, 146, 32, // drapeau jaune - 146, 0, 159, 32, // drapeau violet - 94, 64, 126, 96, // verre 1 - 126, 64, 158, 86, // verre 2 - 128, 128, 180, 144, // verre 3a - 128, 144, 180, 160, // verre 3b - 128, 94, 162, 128, // verre 4 - 0, 100, 32, 228, // champignon 1 - 32, 100, 48, 228, // champignon 1 - 48, 100, 112, 228, // champignon 2 - 112, 100, 128, 228, // champignon 2 - 128, 160, 180, 212, // tronc (21) - -1 -}; - -static int tablePartM[] = // mother.tga -{ - 0, 0, 128, 128, // corps arri�re - 128, 0, 192, 128, // corps avant - 0, 128, 64, 192, // t�te - 64, 128, 192, 160, // pince ext. - 64, 160, 192, 192, // pince int. - 0, 192, 64, 256, // mire - -1 -}; - -static int tablePartA[] = // ant.tga -{ - 0, 0, 64, 64, // queue - 0, 96, 128, 160, // queue abeille - 64, 0, 128, 64, // corps - 128, 0, 192, 64, // t�te - 0, 64, 64, 72, // patte - 0, 72, 64, 80, // antenne - 64, 64, 150, 96, // queue ver - 150, 64, 182, 96, // corps ver - 182, 64, 256, 96, // t�te ver - 224, 32, 256, 64, // articulation ver - 128, 96, 220, 160, // aile - 0, 80, 16, 96, // oeil - 200, 0, 208, 8, // vert clair - 200, 8, 208, 16, // vert fonc� - 0, 160, 64, 224, // corps araign�e - 64, 160, 128, 192, // t�te araign�e - 208, 0, 216, 64, // patte araign�e - 216, 0, 224, 32, // patte araign�e - 224, 0, 256, 8, // antenne araign�e - 192, 0, 200, 8, // brun clair - 192, 8, 200, 16, // brun fonc� - 128, 160, 256, 256, // SatCom - -1 -}; - -static int tablePartH[] = // human.tga -{ - 0, 0, 64, 64, // vissi�re - 64, 0, 96, 64, // cuisse - 96, 0, 128, 64, // jambe - 128, 0, 192, 32, // bras - 128, 32, 192, 64, // avant-bras - 0, 64, 128, 224, // ventre - 128, 64, 256, 224, // dos - 64, 224, 112, 256, // dessus pied - 144, 224, 168, 240, // dessous pied - 112, 224, 144, 240, // c�t� pied - 112, 224, 128, 240, // c�t� pied - 0, 224, 64, 256, // gant - 168, 224, 200, 256, // oreille - 112, 240, 144, 256, // ligne casque - 200, 224, 208, 256, // int�rieur coup - 240, 0, 244, 64, // bombone orange - 244, 0, 248, 64, // bombone orange (reflet) - 248, 0, 252, 64, // bombone bleu - 252, 0, 256, 64, // bombone bleu (reflet) - 144, 240, 156, 256, // gris habit - 156, 240, 168, 256, // gris articulation -//? 208, 224, 256, 256, // SatCom - 192, 0, 240, 64, // quartz - -1 -}; - -static int tablePartG[] = // apollo.tga -{ - 0, 0, 64, 64, // rev�tement LEM - 64, 0, 128, 64, // rev�tement LEM - 128, 8, 136, 128, // pied - 0, 64, 64, 128, // roue - 136, 24, 152, 44, // profil pneu - 136, 8, 160, 24, // garde boue - 64, 64, 128, 128, // si�ge - 64, 128, 128, 192, // si�ge - 64, 192, 128, 212, // si�ge - 128, 128, 240, 192, // moteur - 0, 192, 28, 256, // moteur - 32, 128, 60, 256, // moteur - 224, 0, 256, 128, // avant - 206, 0, 224, 128, // avant - 136, 44, 168, 62, // avant - 64, 212, 108, 256, // panneau de commande - 198, 0, 206, 128, // mat - 190, 64, 198, 128, // mat - 160, 8, 176, 24, // cam�ra - 176, 8, 192, 24, // moyeu - 136, 64, 168, 96, // module - 168, 64, 190, 96, // module - 136, 96, 168, 128, // module - 128, 192, 230, 252, // drapeau - 0, 128, 32, 192, // antenne - 128, 0, 136, 8, // jaune - 136, 0, 144, 8, // beige - 144, 0, 152, 8, // brun - 168, 0, 176, 8, // gris tr�s clair - 152, 0, 160, 8, // gris clair - 160, 0, 168, 8, // gris fonc� - -1 -}; - -static int tablePartB[] = // base1.tga -{ - 0, 0, 80, 256, // int�rieur porte - 80, 0, 88, 256, // tranche porte - 116, 0, 180, 64, // coiffe 1 - 116, 64, 180, 102, // coiffe 2 - 180, 0, 244, 37, // base - 180, 37, 196, 101, // support - 88, 0, 116, 256, // colonne - 212, 37, 256, 128, // suppl�ment - 128, 128, 256, 256, // 1/4 du sol - 196, 37, 212, 53, // gris fonc� - 196, 53, 212, 69, // gris clair - -1 -}; - -static int tablePartCe[] = // cellar01.tga -{ - 0, 128, 64, 192, // briques - 64, 128, 128, 192, // briques - 128, 128, 192, 192, // briques - 192, 128, 256, 192, // briques - -1 -}; - -static int tablePartFa[] = // face01.tga -{ - 0, 0, 256, 256, // visage - -1 -}; - -// Retourne le pointeur la table. - -int* CModel::RetTextureTable() -{ - if ( m_textureRank == 0 ) return tablePartT; - if ( m_textureRank == 1 ) return tablePartR; - if ( m_textureRank == 2 ) return tablePartW; - if ( m_textureRank == 3 ) return tablePartDr; - if ( m_textureRank == 4 ) return tablePartKi; - if ( m_textureRank == 5 ) return tablePartKi2; - if ( m_textureRank == 6 ) return tablePartKi3; - if ( m_textureRank == 7 ) return tablePartF; - if ( m_textureRank == 8 ) return tablePartD; - if ( m_textureRank == 9 ) return tablePartC; - if ( m_textureRank == 10 ) return tablePartS; - if ( m_textureRank == 11 ) return tablePartP; - if ( m_textureRank == 12 ) return tablePartV; - if ( m_textureRank == 13 ) return tablePartM; - if ( m_textureRank == 14 ) return tablePartA; - if ( m_textureRank == 15 ) return tablePartH; - if ( m_textureRank == 16 ) return tablePartG; - if ( m_textureRank == 17 ) return tablePartB; - if ( m_textureRank == 18 ) return tablePartCe; - if ( m_textureRank == 19 ) return tablePartFa; - if ( m_textureRank == 20 ) return tablePartFa; - if ( m_textureRank == 21 ) return tablePartFa; - if ( m_textureRank == 22 ) return tablePartFa; - return 0; -} - -// Updates the part of texture. - -void CModel::TexturePartUpdate() -{ - int *table; - - table = RetTextureTable(); - if ( table == 0 ) return; - - m_textureInf.x = (table[m_texturePart*4+0]+0.5f)/256.0f; - m_textureInf.y = (table[m_texturePart*4+1]+0.5f)/256.0f; - m_textureSup.x = (table[m_texturePart*4+2]-0.5f)/256.0f; - m_textureSup.y = (table[m_texturePart*4+3]-0.5f)/256.0f; - - PutTextureValues(); -} - -// Changes the texture. - -void CModel::TextureRankChange(int step) -{ - m_textureRank += step; - - if ( m_textureRank >= MAX_NAMES ) m_textureRank = 0; - if ( m_textureRank < 0 ) m_textureRank = MAX_NAMES-1; - - if ( m_textureRank == 0 ) strcpy(m_textureName, "lemt.tga"); - if ( m_textureRank == 1 ) strcpy(m_textureName, "roller.tga"); - if ( m_textureRank == 2 ) strcpy(m_textureName, "subm.tga"); - if ( m_textureRank == 3 ) strcpy(m_textureName, "drawer.tga"); - if ( m_textureRank == 4 ) strcpy(m_textureName, "kid.tga"); - if ( m_textureRank == 5 ) strcpy(m_textureName, "kid2.tga"); - if ( m_textureRank == 6 ) strcpy(m_textureName, "kid3.tga"); - if ( m_textureRank == 7 ) strcpy(m_textureName, "factory.tga"); - if ( m_textureRank == 8 ) strcpy(m_textureName, "derrick.tga"); - if ( m_textureRank == 9 ) strcpy(m_textureName, "convert.tga"); - if ( m_textureRank == 10 ) strcpy(m_textureName, "search.tga"); - if ( m_textureRank == 11 ) strcpy(m_textureName, "plant.tga"); - if ( m_textureRank == 12 ) strcpy(m_textureName, "vegetal.tga"); - if ( m_textureRank == 13 ) strcpy(m_textureName, "mother.tga"); - if ( m_textureRank == 14 ) strcpy(m_textureName, "ant.tga"); - if ( m_textureRank == 15 ) strcpy(m_textureName, "human.tga"); - if ( m_textureRank == 16 ) strcpy(m_textureName, "apollo.tga"); - if ( m_textureRank == 17 ) strcpy(m_textureName, "base1.tga"); - if ( m_textureRank == 18 ) strcpy(m_textureName, "cellar01.tga"); - if ( m_textureRank == 19 ) strcpy(m_textureName, "face01.tga"); - if ( m_textureRank == 20 ) strcpy(m_textureName, "face02.tga"); - if ( m_textureRank == 21 ) strcpy(m_textureName, "face03.tga"); - if ( m_textureRank == 22 ) strcpy(m_textureName, "face04.tga"); - - m_texturePart = 0; -} - -// Changes the part of texture. - -void CModel::TexturePartChange(int step) -{ - int *table; - - table = RetTextureTable(); - if ( table == 0 ) return; - - m_texturePart ++; - - if ( table[m_texturePart*4] == -1 ) - { - m_texturePart = 0; - } - - TexturePartUpdate(); -} - - diff --git a/src/model.h b/src/model.h deleted file mode 100644 index 35b48b6..0000000 --- a/src/model.h +++ /dev/null @@ -1,137 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// model.h - -#ifndef _MODEL_H_ -#define _MODEL_H_ - - -#include "struct.h" - - -class CInstanceManager; -class CD3DEngine; -class CModFile; -class CInterface; - - - -class CModel -{ -public: - CModel(CInstanceManager* iMan); - ~CModel(); - - void StartUserAction(); - void StopUserAction(); - - BOOL EventProcess(const Event &event); - - void InitView(); - void InitViewFromSelect(); - void UpdateView(); - void ViewMove(const Event &event, float speed); - -protected: - BOOL EventFrame(const Event &event); - BOOL GetVertex(int rank, D3DVERTEX2 &vertex); - BOOL SetVertex(int rank, D3DVERTEX2 &vertex); - D3DVECTOR RetSelectCDG(); - D3DVECTOR RetSelectNormal(); - void SmoothSelect(); - void PlaneSelect(); - void ColorSelect(); - void StateSelect(); - void MoveSelect(D3DVECTOR move); - void OperSelect(D3DVECTOR move, char oper); - void ReadScript(char *filename); - void BBoxCompute(D3DVECTOR &min, D3DVECTOR &max); - BOOL IsMappingSelectPlausible(D3DMaping D3Dmode); - void MappingSelect(int mode, int rotate, BOOL bMirrorX, BOOL bMirrorY, FPOINT ti, FPOINT ts, char *texName); - void MappingSelectSpherical(int mode, int rotate, BOOL bMirrorX, BOOL bMirrorY, FPOINT ti, FPOINT ts, char *texName); - D3DVECTOR RetMappingCenter(D3DVECTOR pos, D3DVECTOR min); - void MappingSelectCylindrical(int mode, int rotate, BOOL bMirrorX, BOOL bMirrorY, FPOINT ti, FPOINT ts, char *texName); - void MappingSelectFace(int mode, int rotate, BOOL bMirrorX, BOOL bMirrorY, FPOINT ti, FPOINT ts, char *texName); - void MappingSelect2(int texNum2, int subdiv, int offsetU, int offsetV, BOOL bMirrorX, BOOL bMirrorY); - void MappingSelectPlane2(int mode, BOOL bMirrorX, BOOL bMirrorY); - void MappingSelectSpherical2(BOOL bMirrorX, BOOL bMirrorY); - void MappingSelectMagic2(BOOL bMirrorX, BOOL bMirrorY); - int SearchNext(int rank, int step); - int SearchSamePlane(int first, int step); - void CurrentSearchNext(int step, BOOL bControl); - void CurrentInit(); - void CurrentSelect(BOOL bSelect); - void DeselectAll(); - void SelectAll(); - void SelectZone(int first, int last); - void SelectTerm(); - void DefaultSelect(); - void SelectDelete(); - void Compress(); - void MinMaxSelect(); - void MinMaxChange(); - void UpdateInfoText(); - int* RetTextureTable(); - void TexturePartUpdate(); - void TextureRankChange(int step); - void TexturePartChange(int step); - void PutTextureValues(); - void GetTextureValues(); - void GetModelName(char *buffer); - void GetDXFName(char *buffer); - void GetScriptName(char *buffer); - BOOL IsEditFocus(); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CModFile* m_modFile; - CInterface* m_interface; - - float m_time; - ModelTriangle* m_triangleTable; - int m_triangleSel1; - int m_triangleSel2; - int m_mode; - int m_textureMode; - int m_textureRotate; - BOOL m_bTextureMirrorX; - BOOL m_bTextureMirrorY; - FPOINT m_textureInf; - FPOINT m_textureSup; - int m_texturePart; - int m_textureRank; - char m_textureName[20]; - BOOL m_bDisplayTransparent; - BOOL m_bDisplayOnlySelection; - float m_viewHeight; - float m_viewDist; - float m_viewAngleH; - float m_viewAngleV; - int m_color; - int m_state; - int m_secondTexNum; - int m_secondSubdiv; - int m_secondOffsetU; - int m_secondOffsetV; - char m_oper; - float m_min; - float m_max; -}; - - -#endif //_MODEL_H_ diff --git a/src/modfile.cpp b/src/modfile.cpp deleted file mode 100644 index 08fb89d..0000000 --- a/src/modfile.cpp +++ /dev/null @@ -1,697 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// modfile.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "language.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "modfile.h" - - - -#define MAX_VERTICES 2000 - - - -// Object's constructor. - -CModFile::CModFile(CInstanceManager* iMan) -{ - m_iMan = iMan; - - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - - m_triangleUsed = 0; - m_triangleTable = (ModelTriangle*)malloc(sizeof(ModelTriangle)*MAX_VERTICES); - ZeroMemory(m_triangleTable, sizeof(ModelTriangle)*MAX_VERTICES); -} - -// Object's destructor. - -CModFile::~CModFile() -{ - free(m_triangleTable); -} - - - - -// Creates a triangle in the internal structure. - -BOOL CModFile::CreateTriangle(D3DVECTOR p1, D3DVECTOR p2, D3DVECTOR p3, - float min, float max) -{ - D3DVECTOR n; - int i; - - if ( m_triangleUsed >= MAX_VERTICES ) - { - OutputDebugString("ERROR: CreateTriangle::Too many triangles\n"); - return FALSE; - } - - i = m_triangleUsed++; - - ZeroMemory(&m_triangleTable[i], sizeof(ModelTriangle)); - - m_triangleTable[i].bUsed = TRUE; - m_triangleTable[i].bSelect = FALSE; - - n = ComputeNormal(p3, p2, p1); - m_triangleTable[i].p1 = D3DVERTEX2( p1, n); - m_triangleTable[i].p2 = D3DVERTEX2( p2, n); - m_triangleTable[i].p3 = D3DVERTEX2( p3, n); - - m_triangleTable[i].material.diffuse.r = 1.0f; - m_triangleTable[i].material.diffuse.g = 1.0f; - m_triangleTable[i].material.diffuse.b = 1.0f; // white - m_triangleTable[i].material.ambient.r = 0.5f; - m_triangleTable[i].material.ambient.g = 0.5f; - m_triangleTable[i].material.ambient.b = 0.5f; - - m_triangleTable[i].min = min; - m_triangleTable[i].max = max; - - return TRUE; -} - -// Reads a DXF file. - -BOOL CModFile::ReadDXF(char *filename, float min, float max) -{ - FILE* file = NULL; - char line[100]; - int command, rankSommet, nbSommet, nbFace; - D3DVECTOR table[MAX_VERTICES]; - BOOL bWaitNbSommet; - BOOL bWaitNbFace; - BOOL bWaitSommetX; - BOOL bWaitSommetY; - BOOL bWaitSommetZ; - BOOL bWaitFaceX; - BOOL bWaitFaceY; - BOOL bWaitFaceZ; - float x,y,z; - int p1,p2,p3; - - file = fopen(filename, "r"); - if ( file == NULL ) return FALSE; - - m_triangleUsed = 0; - - rankSommet = 0; - bWaitNbSommet = FALSE; - bWaitNbFace = FALSE; - bWaitSommetX = FALSE; - bWaitSommetY = FALSE; - bWaitSommetZ = FALSE; - bWaitFaceX = FALSE; - bWaitFaceY = FALSE; - bWaitFaceZ = FALSE; - - while ( fgets(line, 100, file) != NULL ) - { - sscanf(line, "%d", &command); - if ( fgets(line, 100, file) == NULL ) break; - - if ( command == 66 ) - { - bWaitNbSommet = TRUE; - } - - if ( command == 71 && bWaitNbSommet ) - { - bWaitNbSommet = FALSE; - sscanf(line, "%d", &nbSommet); - if ( nbSommet > MAX_VERTICES ) nbSommet = MAX_VERTICES; - rankSommet = 0; - bWaitNbFace = TRUE; - -//? sprintf(s, "Waiting for %d sommets\n", nbSommet); -//? OutputDebugString(s); - } - - if ( command == 72 && bWaitNbFace ) - { - bWaitNbFace = FALSE; - sscanf(line, "%d", &nbFace); - bWaitSommetX = TRUE; - -//? sprintf(s, "Waiting for %d faces\n", nbFace); -//? OutputDebugString(s); - } - - if ( command == 10 && bWaitSommetX ) - { - bWaitSommetX = FALSE; - sscanf(line, "%f", &x); - bWaitSommetY = TRUE; - } - - if ( command == 20 && bWaitSommetY ) - { - bWaitSommetY = FALSE; - sscanf(line, "%f", &y); - bWaitSommetZ = TRUE; - } - - if ( command == 30 && bWaitSommetZ ) - { - bWaitSommetZ = FALSE; - sscanf(line, "%f", &z); - - nbSommet --; - if ( nbSommet >= 0 ) - { - D3DVECTOR p(x,z,y); // permutation of Y and Z! - table[rankSommet++] = p; - bWaitSommetX = TRUE; - -//? sprintf(s, "Sommet[%d]=%f;%f;%f\n", rankSommet, p.x,p.y,p.z); -//? OutputDebugString(s); - } - else - { - bWaitFaceX = TRUE; - } - } - - if ( command == 71 && bWaitFaceX ) - { - bWaitFaceX = FALSE; - sscanf(line, "%d", &p1); - if ( p1 < 0 ) p1 = -p1; - bWaitFaceY = TRUE; - } - - if ( command == 72 && bWaitFaceY ) - { - bWaitFaceY = FALSE; - sscanf(line, "%d", &p2); - if ( p2 < 0 ) p2 = -p2; - bWaitFaceZ = TRUE; - } - - if ( command == 73 && bWaitFaceZ ) - { - bWaitFaceZ = FALSE; - sscanf(line, "%d", &p3); - if ( p3 < 0 ) p3 = -p3; - - nbFace --; - if ( nbFace >= 0 ) - { - CreateTriangle( table[p3-1], table[p2-1], table[p1-1], min,max ); - bWaitFaceX = TRUE; - -//? sprintf(s, "Face=%d;%d;%d\n", p1,p2,p3); -//? OutputDebugString(s); - } - } - - } - - fclose(file); - return TRUE; -} - - - -typedef struct -{ - int rev; - int vers; - int total; - int reserve[10]; -} -InfoMOD; - - -// Change nom.bmp to nom.tga - -void ChangeBMPtoTGA(char *filename) -{ - char* p; - - p = strstr(filename, ".bmp"); - if ( p != 0 ) strcpy(p, ".tga"); -} - - -// Reads a MOD file. - -BOOL CModFile::AddModel(char *filename, int first, BOOL bEdit, BOOL bMeta) -{ - FILE* file; - InfoMOD info; - float limit[2]; - int i, nb, err; - char* p; - - if ( m_engine->RetDebugMode() ) - { - bMeta = FALSE; - } - - if ( bMeta ) - { - p = strchr(filename, '\\'); - if ( p == 0 ) - { -#if _SCHOOL - err = g_metafile.Open("ceebot2.dat", filename); -#else - err = g_metafile.Open("colobot2.dat", filename); -#endif - } - else - { -#if _SCHOOL - err = g_metafile.Open("ceebot2.dat", p+1); -#else - err = g_metafile.Open("colobot2.dat", p+1); -#endif - } - if ( err != 0 ) bMeta = FALSE; - } - if ( !bMeta ) - { - file = fopen(filename, "rb"); - if ( file == NULL ) return FALSE; - } - - if ( bMeta ) - { - g_metafile.Read(&info, sizeof(InfoMOD)); - } - else - { - fread(&info, sizeof(InfoMOD), 1, file); - } - nb = info.total; - m_triangleUsed += nb; - - if ( info.rev == 1 && info.vers == 0 ) - { - OldModelTriangle1 old; - - for ( i=first ; iRetLimitLOD(0); // frontier AB as config - limit[1] = m_engine->RetLimitLOD(1); // frontier BC as config - - // Standard frontiers -> config. - for ( i=first ; iRetSecondTexture(); - } - else - { - texNum = m_triangleTable[i].texNum2; - } - - if ( texNum >= 1 && texNum <= 10 ) - { - state = m_triangleTable[i].state|D3DSTATEDUALb; - } - if ( texNum >= 11 && texNum <= 20 ) - { - state = m_triangleTable[i].state|D3DSTATEDUALw; - } - sprintf(texName2, "dirty%.2d.bmp", texNum); - } - - m_engine->AddTriangle(objRank, &m_triangleTable[i].p1, 3, - m_triangleTable[i].material, - state+addState, - m_triangleTable[i].texName, texName2, - m_triangleTable[i].min, - m_triangleTable[i].max, FALSE); - } - return TRUE; -#else - char texName1[20]; - char texName2[20]; - int texNum, i, state; - - for ( i=0 ; iRetSecondTexture(); - } - else - { - texNum = m_triangleTable[i].texNum2; - } - - if ( texNum >= 1 && texNum <= 10 ) - { - state |= D3DSTATEDUALb; - } - if ( texNum >= 11 && texNum <= 20 ) - { - state |= D3DSTATEDUALw; - } - sprintf(texName2, "dirty%.2d.tga", texNum); - } - - m_engine->AddTriangle(objRank, &m_triangleTable[i].p1, 3, - m_triangleTable[i].material, - state+addState, - texName1, texName2, - m_triangleTable[i].min, - m_triangleTable[i].max, FALSE); - } - return TRUE; -#endif -} - - -// Performs a mirror according to Z. - -void CModFile::Mirror() -{ - D3DVERTEX2 t; - int i; - - for ( i=0 ; i using - char bSelect; // TRUE -> selected - D3DVERTEX p1; - D3DVERTEX p2; - D3DVERTEX p3; - D3DMATERIAL7 material; - char texName[20]; - float min; - float max; -} -OldModelTriangle1; // length = 196 bytes - -typedef struct -{ - char bUsed; // TRUE -> used - char bSelect; // TRUE -> selected - D3DVERTEX p1; - D3DVERTEX p2; - D3DVERTEX p3; - D3DMATERIAL7 material; - char texName[20]; - float min; - float max; - long state; - short reserve1; - short reserve2; - short reserve3; - short reserve4; -} -OldModelTriangle2; - -typedef struct -{ - char bUsed; // TRUE -> used - char bSelect; // TRUE -> selected - D3DVERTEX2 p1; - D3DVERTEX2 p2; - D3DVERTEX2 p3; - D3DMATERIAL7 material; - char texName[20]; - float min; - float max; - long state; - short texNum2; - short reserve2; - short reserve3; - short reserve4; -} -ModelTriangle; // length = 208 bytes - - - - -class CModFile -{ -public: - CModFile(CInstanceManager* iMan); - ~CModFile(); - - BOOL ReadDXF(char *filename, float min, float max); - BOOL AddModel(char *filename, int first, BOOL bEdit=FALSE, BOOL bMeta=TRUE); - BOOL ReadModel(char *filename, BOOL bEdit=FALSE, BOOL bMeta=TRUE); - BOOL WriteModel(char *filename); - - BOOL CreateEngineObject(int objRank, int addState=0); - void Mirror(); - - void SetTriangleUsed(int total); - int RetTriangleUsed(); - int RetTriangleMax(); - ModelTriangle* RetTriangleList(); - - float RetHeight(D3DVECTOR pos); - -protected: - BOOL CreateTriangle(D3DVECTOR p1, D3DVECTOR p2, D3DVECTOR p3, float min, float max); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - - ModelTriangle* m_triangleTable; - int m_triangleUsed; -}; - - -#endif //_MODFILE_H_ diff --git a/src/motion.cpp b/src/motion.cpp deleted file mode 100644 index 642108b..0000000 --- a/src/motion.cpp +++ /dev/null @@ -1,257 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motion.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "light.h" -#include "particule.h" -#include "terrain.h" -#include "water.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "robotmain.h" -#include "sound.h" -#include "cmdtoken.h" -#include "motion.h" - - - - -// Object's constructor. - -CMotion::CMotion(CInstanceManager* iMan, CObject* object) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_MOTION, this, 100); - - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - - m_object = object; - m_physics = 0; - m_brain = 0; - - m_actionType = -1; - m_actionTime = 0.0f; - m_progress = 0.0f; - - m_linVibration = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_cirVibration = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_inclinaison = D3DVECTOR(0.0f, 0.0f, 0.0f); -} - -// Object's destructor. - -CMotion::~CMotion() -{ - m_iMan->DeleteInstance(CLASS_MOTION, this); -} - -// Deletes the object. - -void CMotion::DeleteObject(BOOL bAll) -{ -} - - -void CMotion::SetPhysics(CPhysics* physics) -{ - m_physics = physics; -} - -void CMotion::SetBrain(CBrain* brain) -{ - m_brain = brain; -} - - -// Creates. - -BOOL CMotion::Create(D3DVECTOR pos, float angle, ObjectType type, float power) -{ - return TRUE; -} - -// Management of an event. - -BOOL CMotion::EventProcess(const Event &event) -{ - D3DVECTOR pos, dir; - float time; - - if ( m_object->RetType() != OBJECT_TOTO && - m_engine->RetPause() ) return TRUE; - - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_actionTime; - if ( m_progress > 1.0f ) m_progress = 1.0f; // (*) - - pos = m_object->RetPosition(0); - if ( pos.y < m_water->RetLevel(m_object) ) // underwater? - { - time = event.rTime*3.0f; // everything is slower - } - else - { - time = event.rTime*10.0f; - } - - dir = m_object->RetLinVibration(); - dir.x = Smooth(dir.x, m_linVibration.x, time); - dir.y = Smooth(dir.y, m_linVibration.y, time); - dir.z = Smooth(dir.z, m_linVibration.z, time); - m_object->SetLinVibration(dir); - - dir = m_object->RetCirVibration(); - dir.x = Smooth(dir.x, m_cirVibration.x, time); - dir.y = Smooth(dir.y, m_cirVibration.y, time); - dir.z = Smooth(dir.z, m_cirVibration.z, time); - m_object->SetCirVibration(dir); - - dir = m_object->RetInclinaison(); - dir.x = Smooth(dir.x, m_inclinaison.x, time); - dir.y = Smooth(dir.y, m_inclinaison.y, time); - dir.z = Smooth(dir.z, m_inclinaison.z, time); - m_object->SetInclinaison(dir); - - return TRUE; -} - -// (*) Avoids the bug of ants returned by the thumper and -// whose abdomen grown to infinity! - - -// Start an action. - -Error CMotion::SetAction(int action, float time) -{ - m_actionType = action; - m_actionTime = 1.0f/time; - m_progress = 0.0f; - return ERR_OK; -} - -// Returns the current action. - -int CMotion::RetAction() -{ - return m_actionType; -} - - -// Specifies a special parameter. - -BOOL CMotion::SetParam(int rank, float value) -{ - return FALSE; -} - -float CMotion::RetParam(int rank) -{ - return 0.0f; -} - - -// Saves all parameters of the object. - -BOOL CMotion::Write(char *line) -{ - char name[100]; - - if ( m_actionType == -1 ) return FALSE; - - sprintf(name, " mType=%d", m_actionType); - strcat(line, name); - - sprintf(name, " mTime=%.2f", m_actionTime); - strcat(line, name); - - sprintf(name, " mProgress=%.2f", m_progress); - strcat(line, name); - - return FALSE; -} - -// Restores all parameters of the object. - -BOOL CMotion::Read(char *line) -{ - m_actionType = OpInt(line, "mType", -1); - m_actionTime = OpFloat(line, "mTime", 0.0f); - m_progress = OpFloat(line, "mProgress", 0.0f); - - return FALSE; -} - - -// Gives the linear vibration. - -void CMotion::SetLinVibration(D3DVECTOR dir) -{ - m_linVibration = dir; -} - -D3DVECTOR CMotion::RetLinVibration() -{ - return m_linVibration; -} - -// Gives the circular vibration. - -void CMotion::SetCirVibration(D3DVECTOR dir) -{ - m_cirVibration = dir; -} - -D3DVECTOR CMotion::RetCirVibration() -{ - return m_cirVibration; -} - -// Gives the tilt. - -void CMotion::SetInclinaison(D3DVECTOR dir) -{ - m_inclinaison = dir; -} - -D3DVECTOR CMotion::RetInclinaison() -{ - return m_inclinaison; -} - diff --git a/src/motion.h b/src/motion.h deleted file mode 100644 index 5aa0afb..0000000 --- a/src/motion.h +++ /dev/null @@ -1,94 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motion.h - -#ifndef _MOTION_H_ -#define _MOTION_H_ - - -#include "d3dengine.h" - - -class CInstanceManager; -class CEngine; -class CLight; -class CParticule; -class CTerrain; -class CWater; -class CCamera; -class CBrain; -class CPhysics; -class CObject; -class CRobotMain; -class CSound; - - -class CMotion -{ -public: - CMotion(CInstanceManager* iMan, CObject* object); - virtual ~CMotion(); - - void SetPhysics(CPhysics* physics); - void SetBrain(CBrain* brain); - - virtual void DeleteObject(BOOL bAll=FALSE); - virtual BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); - virtual BOOL EventProcess(const Event &event); - virtual Error SetAction(int action, float time=0.2f); - virtual int RetAction(); - - virtual BOOL SetParam(int rank, float value); - virtual float RetParam(int rank); - - virtual BOOL Write(char *line); - virtual BOOL Read(char *line); - - virtual void SetLinVibration(D3DVECTOR dir); - virtual D3DVECTOR RetLinVibration(); - virtual void SetCirVibration(D3DVECTOR dir); - virtual D3DVECTOR RetCirVibration(); - virtual void SetInclinaison(D3DVECTOR dir); - virtual D3DVECTOR RetInclinaison(); - -protected: - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CLight* m_light; - CParticule* m_particule; - CTerrain* m_terrain; - CWater* m_water; - CCamera* m_camera; - CObject* m_object; - CBrain* m_brain; - CPhysics* m_physics; - CRobotMain* m_main; - CSound* m_sound; - - int m_actionType; - float m_actionTime; - float m_progress; - - D3DVECTOR m_linVibration; // linear vibration - D3DVECTOR m_cirVibration; // circular vibration - D3DVECTOR m_inclinaison; // tilt -}; - - -#endif //_MOTION_H_ diff --git a/src/motionant.cpp b/src/motionant.cpp deleted file mode 100644 index 3790f7e..0000000 --- a/src/motionant.cpp +++ /dev/null @@ -1,901 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motionant.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "light.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "modfile.h" -#include "sound.h" -#include "motion.h" -#include "motionant.h" - - - -#define ADJUST_ANGLE FALSE // TRUE -> adjusts the angles of the members -#define START_TIME 1000.0f // beginning of the relative time - - - -// Object's constructor. - -CMotionAnt::CMotionAnt(CInstanceManager* iMan, CObject* object) - : CMotion(iMan, object) -{ - CMotion::CMotion(iMan, object); - - m_armMember = START_TIME; - m_armTimeAbs = START_TIME; - m_armTimeMarch = START_TIME; - m_armTimeAction = START_TIME; - m_armTimeIndex = 0; - m_armPartIndex = 0; - m_armMemberIndex = 0; - m_armLastAction = -1; - m_bArmStop = FALSE; - m_lastParticule = 0.0f; -} - -// Object's destructor. - -CMotionAnt::~CMotionAnt() -{ -} - - -// Removes an object. - -void CMotionAnt::DeleteObject(BOOL bAll) -{ -} - - -// Creates a vehicle poses some rolling on the floor. - -BOOL CMotionAnt::Create(D3DVECTOR pos, float angle, ObjectType type, - float power) -{ - CModFile* pModFile; - int rank; - - if ( m_engine->RetRestCreate() < 3+18 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - m_object->SetType(type); - - // Creates the main base. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object - m_object->SetObjectRank(0, rank); - - pModFile->ReadModel("objects\\ant1.mod"); - pModFile->CreateEngineObject(rank); - - m_object->SetPosition(0, pos); - m_object->SetAngleY(0, angle); - - // A vehicle must have necessarily a collision - //with a sphere of center (0, y, 0) (see GetCrashSphere). - m_object->CreateCrashSphere(D3DVECTOR(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f); - m_object->SetGlobalSphere(D3DVECTOR(-0.5f, 1.0f, 0.0f), 4.0f); - - // Creates the head. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\ant2.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(2.0f, 0.0f, 0.0f)); - - // Creates the tail. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 0); - pModFile->ReadModel("objects\\ant3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2, D3DVECTOR(-1.0f, 0.0f, 0.0f)); - - // Creates a right-back thigh. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(3, rank); - m_object->SetObjectParent(3, 0); - pModFile->ReadModel("objects\\ant4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(3, D3DVECTOR(-0.4f, -0.1f, -0.3f)); - - // Creates a right-back leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(4, rank); - m_object->SetObjectParent(4, 3); - pModFile->ReadModel("objects\\ant5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(4, D3DVECTOR(0.0f, 0.0f, -1.0f)); - - // Creates a right-back foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(5, rank); - m_object->SetObjectParent(5, 4); - pModFile->ReadModel("objects\\ant6.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(5, D3DVECTOR(0.0f, 0.0f, -2.0f)); - - // Creates two middle-right thighs. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(6, rank); - m_object->SetObjectParent(6, 0); - pModFile->ReadModel("objects\\ant4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(6, D3DVECTOR(0.1f, -0.1f, -0.4f)); - - // Creates two middle-right legs. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(7, rank); - m_object->SetObjectParent(7, 6); - pModFile->ReadModel("objects\\ant5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(7, D3DVECTOR(0.0f, 0.0f, -1.0f)); - - // Creates two middle-right foots. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(8, rank); - m_object->SetObjectParent(8, 7); - pModFile->ReadModel("objects\\ant6.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(8, D3DVECTOR(0.0f, 0.0f, -2.0f)); - - // Creates the right front thigh. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(9, rank); - m_object->SetObjectParent(9, 0); - pModFile->ReadModel("objects\\ant4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(9, D3DVECTOR(1.4f, -0.1f, -0.6f)); - - // Creates the right front leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(10, rank); - m_object->SetObjectParent(10, 9); - pModFile->ReadModel("objects\\ant5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(10, D3DVECTOR(0.0f, 0.0f, -1.0f)); - - // Creates the right front foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(11, rank); - m_object->SetObjectParent(11, 10); - pModFile->ReadModel("objects\\ant6.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(11, D3DVECTOR(0.0f, 0.0f, -2.0f)); - - // Creates a left-back thigh. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(12, rank); - m_object->SetObjectParent(12, 0); - pModFile->ReadModel("objects\\ant4.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(12, D3DVECTOR(-0.4f, -0.1f, 0.3f)); - - // Creates a left-back leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(13, rank); - m_object->SetObjectParent(13, 12); - pModFile->ReadModel("objects\\ant5.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(13, D3DVECTOR(0.0f, 0.0f, 1.0f)); - - // Creates a left-back foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(14, rank); - m_object->SetObjectParent(14, 13); - pModFile->ReadModel("objects\\ant6.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(14, D3DVECTOR(0.0f, 0.0f, 2.0f)); - - // Creates two middle-left thighs. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(15, rank); - m_object->SetObjectParent(15, 0); - pModFile->ReadModel("objects\\ant4.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(15, D3DVECTOR(0.1f, -0.1f, 0.4f)); - - // Creates two middle-left legs. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(16, rank); - m_object->SetObjectParent(16, 15); - pModFile->ReadModel("objects\\ant5.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(16, D3DVECTOR(0.0f, 0.0f, 1.0f)); - - // Creates two middle-left foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(17, rank); - m_object->SetObjectParent(17, 16); - pModFile->ReadModel("objects\\ant6.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(17, D3DVECTOR(0.0f, 0.0f, 2.0f)); - - // Creates the left front thigh. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(18, rank); - m_object->SetObjectParent(18, 0); - pModFile->ReadModel("objects\\ant4.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(18, D3DVECTOR(1.4f, -0.1f, 0.6f)); - - // Creates the left front leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(19, rank); - m_object->SetObjectParent(19, 18); - pModFile->ReadModel("objects\\ant5.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(19, D3DVECTOR(0.0f, 0.0f, 1.0f)); - - // Creates the left front foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(20, rank); - m_object->SetObjectParent(20, 19); - pModFile->ReadModel("objects\\ant6.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(20, D3DVECTOR(0.0f, 0.0f, 2.0f)); - - m_object->CreateShadowCircle(4.0f, 0.5f); - - CreatePhysics(); - m_object->SetFloorHeight(0.0f); - - pos = m_object->RetPosition(0); - m_object->SetPosition(0, pos); // to display the shadows immediately - - m_engine->LoadAllTexture(); - - delete pModFile; - return TRUE; -} - -// Creates the physics of the object. - -void CMotionAnt::CreatePhysics() -{ - Character* character; - int i; - - int member_march[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: - 0,45,0, 0,45,0, 0,50,0, // t0: thighs 1..3 - 30,-70,0, 20,-105,20, 25,-100,0, // t0: legs 1..3 - -70,75,0, -30,80,0, -80,80,0, // t0: feet 1..3 - // on the ground: - 0,30,0, 0,20,0, 0,15,0, // t1: thighs 1..3 - -15,-50,0, -20,-60,0, -10,-75,0, // t1: legs 1..3 - -40,50,0, -25,15,0, -50,35,0, // t1: feet 1..3 - // on the ground back: - 0,35,0, 0,30,0, 0,20,0, // t2: thighs 1..3 - -20,-15,0, -30,-55,0, -25,-70,15, // t2: legs 1..3 - -25,25,0, -20,60,0, -30,95,0, // t2: feet 1..3 - }; - - int member_stop[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: - 0,30,0, 0,20,0, 0,15,0, // t0: thighs 1..3 - -15,-35,0, -20,-60,0, -15,-75,0, // t0: legs 1..3 - -35,35,0, -25,40,0, -40,65,0, // t0: feet 1..3 - // on the ground: - 0,30,0, 0,20,0, 0,15,0, // t1: thighs 1..3 - -15,-35,0, -20,-60,0, -15,-75,0, // t1: legs 1..3 - -35,35,0, -25,40,0, -40,65,0, // t1: feet 1..3 - // on the ground back: - 0,30,0, 0,20,0, 0,15,0, // t2: thighs 1..3 - -15,-35,0, -20,-60,0, -15,-75,0, // t2: legs 1..3 - -35,35,0, -25,40,0, -40,65,0, // t2: feet 1..3 - }; - - int member_spec[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, // prepares the fire: - 0,20,0, 0,10,0, 0,50,0, // s0: thighs 1..3 - -50,-30,0, -20,-15,0, 35,-65,0, // s0: legs 1..3 - -5,-40,0, 20,-70,0, -10,-40,0, // s0: feet 1..3 - // shot: - 0,20,0, 0,10,0, 0,50,0, // s1: thighs 1..3 - -50,-30,0, -20,-15,0, 35,-65,0, // s1: legs 1..3 - -5,-40,0, 20,-70,0, -10,-40,0, // s1: feet 1..3 - // ends the fire: - 0,30,0, 0,20,0, 0,15,0, // s2: thighs 1..3 - -15,-50,0, -20,-60,0, -10,-75,0, // s2: legs 1..3 - -40,50,0, -25,15,0, -50,35,0, // s2: feet 1..3 - // burning: - 0,30,0, 0,20,0, 0,15,0, // s3: thighs 1..3 - -15,-35,0, -20,-60,0, -15,-75,0, // s3: legs 1..3 - -35,35,0, -25,40,0, -40,65,0, // s3: feet 1..3 - // destroyed: - 0,30,0, 0,20,0, 0,15,0, // s4: thighs 1..3 - -15,-35,0, -20,-60,0, -15,-75,0, // s4: legs 1..3 - -35,35,0, -25,40,0, -40,65,0, // s4: feet 1..3 - // back1 : - 0,30,0, 0,20,0, 0,15,0, // s5: thighs 1..3 - -15,-35,0, -20,-60,0, -15,-75,0, // s5: legs 1..3 - -35,35,0, -25,40,0, -40,65,0, // s5: feet 1..3 - // back2 : - 0,45,0, 0,45,0, 0,50,0, // s6: thighs 1..3 - -35,-70,0, -20,-85,-25, -25,-100,0, // s6: legs 1..3 - -110,75,-15, -130,80,-25, -125,40,0, // s6: feet 1..3 - // back3 : - 0,30,0, 0,20,0, 0,15,0, // s7: thighs 1..3 - -15,-35,0, -20,-60,0, -15,-75,0, // s7: legs 1..3 - -35,35,0, -25,40,0, -40,65,0, // s7: feet 1..3 - }; - - m_physics->SetType(TYPE_ROLLING); - - character = m_object->RetCharacter(); - character->wheelFront = 3.0f; - character->wheelBack = 3.0f; - character->wheelLeft = 5.0f; - character->wheelRight = 5.0f; - character->height = 1.2f; - - m_physics->SetLinMotionX(MO_ADVSPEED, 12.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 12.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 15.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 15.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 5.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 5.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 10.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 1.0f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 1.0f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 20.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 20.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 40.0f); - - for ( i=0 ; i<3*3*3*3 ; i++ ) - { - m_armAngles[3*3*3*3*MA_MARCH+i] = member_march[i]; - } - for ( i=0 ; i<3*3*3*3 ; i++ ) - { - m_armAngles[3*3*3*3*MA_STOP+i] = member_stop[i]; - } - for ( i=0 ; i<3*3*3*8 ; i++ ) - { - m_armAngles[3*3*3*3*MA_SPEC+i] = member_spec[i]; - } -} - - -// Management of an event. - -BOOL CMotionAnt::EventProcess(const Event &event) -{ - CMotion::EventProcess(event); - - if ( event.event == EVENT_FRAME ) - { - return EventFrame(event); - } - - if ( event.event == EVENT_KEYDOWN ) - { -#if ADJUST_ANGLE - int i; - - if ( event.param == 'A' ) m_armTimeIndex++; - if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0; - - if ( event.param == 'Q' ) m_armPartIndex++; - if ( m_armPartIndex >= 3 ) m_armPartIndex = 0; - - if ( event.param == 'W' ) m_armMemberIndex++; - if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0; - - i = m_armMemberIndex*3; - i += m_armPartIndex*3*3; - i += m_armTimeIndex*3*3*3; -//? i += 3*3*3*3; - - if ( event.param == 'E' ) m_armAngles[i+0] += 5; - if ( event.param == 'D' ) m_armAngles[i+0] -= 5; - if ( event.param == 'R' ) m_armAngles[i+1] += 5; - if ( event.param == 'F' ) m_armAngles[i+1] -= 5; - if ( event.param == 'T' ) m_armAngles[i+2] += 5; - if ( event.param == 'G' ) m_armAngles[i+2] -= 5; - - if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop; -#endif - } - - return TRUE; -} - -// Calculates a value (radians) proportional between a and b (degrees). - -inline float Propf(float a, float b, float p) -{ - float aa, bb; - - aa = a*PI/180.0f; - bb = b*PI/180.0f; - - return aa+p*(bb-aa); -} - -// Management of an event. - -BOOL CMotionAnt::EventFrame(const Event &event) -{ - D3DVECTOR dir, pos, speed; - FPOINT dim; - float s, a, prog, time; - float tSt[9], tNd[9]; - int i, ii, st, nd, action; - BOOL bStop; - - if ( m_engine->RetPause() ) return TRUE; - if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return TRUE; - - s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f; - a = Abs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.0f); - - if ( s == 0.0f && a != 0.0f ) a *= 1.5f; - - m_armTimeAbs += event.rTime; - m_armTimeMarch += (s)*event.rTime*0.15f; - m_armMember += (s+a)*event.rTime*0.15f; - - bStop = ( a == 0.0f && s == 0.0f ); // stopped? - - action = MA_MARCH; // walking - if ( s == 0.0f && a == 0.0f ) - { - action = MA_STOP; // stop - } - - if ( bStop ) - { - prog = Mod(m_armTimeAbs, 2.0f)/10.0f; - a = Mod(m_armMember, 1.0f); - a = (prog-a)*event.rTime*2.0f; // stop position is pleasantly - m_armMember += a; - } - - if ( m_object->RetRuin() ) // destroyed? - { - m_actionType = MAS_RUIN; - } - if ( m_object->RetBurn() ) // burning? - { - if ( m_object->RetFixed() ) - { - m_actionType = MAS_BURN; - } - else - { - m_actionType = -1; - } - } - - for ( i=0 ; i<6 ; i++ ) // the six legs - { - if ( m_actionType != -1 ) // special action in progress? - { - st = 3*3*3*3*MA_SPEC + 3*3*3*m_actionType + (i%3)*3; - nd = st; - time = event.rTime*m_actionTime; - m_armTimeAction = 0.0f; - } - else - { - if ( i < 3 ) prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f); - else prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f); - if ( m_bArmStop ) - { - prog = (float)m_armTimeIndex/3.0f; - } - if ( prog < 0.33f ) // t0..t1 ? - { - prog = prog/0.33f; // 0..1 - st = 0; // index start - nd = 1; // index end - } - else if ( prog < 0.67f ) // t1..t2 ? - { - prog = (prog-0.33f)/0.33f; // 0..1 - st = 1; // index start - nd = 2; // index end - } - else // t2..t0 ? - { - prog = (prog-0.67f)/0.33f; // 0..1 - st = 2; // index start - nd = 0; // index end - } - st = 3*3*3*3*action + st*3*3*3 + (i%3)*3; - nd = 3*3*3*3*action + nd*3*3*3 + (i%3)*3; - - // More and more soft ... - time = event.rTime*(10.0f+Min(m_armTimeAction*100.0f, 200.0f)); - } - - tSt[0] = m_armAngles[st+ 0]; // x - tSt[1] = m_armAngles[st+ 1]; // y - tSt[2] = m_armAngles[st+ 2]; // z - tSt[3] = m_armAngles[st+ 9]; // x - tSt[4] = m_armAngles[st+10]; // y - tSt[5] = m_armAngles[st+11]; // z - tSt[6] = m_armAngles[st+18]; // x - tSt[7] = m_armAngles[st+19]; // y - tSt[8] = m_armAngles[st+20]; // z - - tNd[0] = m_armAngles[nd+ 0]; // x - tNd[1] = m_armAngles[nd+ 1]; // y - tNd[2] = m_armAngles[nd+ 2]; // z - tNd[3] = m_armAngles[nd+ 9]; // x - tNd[4] = m_armAngles[nd+10]; // y - tNd[5] = m_armAngles[nd+11]; // z - tNd[6] = m_armAngles[nd+18]; // x - tNd[7] = m_armAngles[nd+19]; // y - tNd[8] = m_armAngles[nd+20]; // z - - if ( m_actionType == MAS_BACK2 ) // on the back? - { - for ( ii=0 ; ii<9 ; ii++ ) - { - tSt[ii] += Rand()*50.0f; - tNd[ii] = tSt[ii]; - } -//? time = 100.0f; - time = event.rTime*10.0f; - } - - if ( i < 3 ) // right leg (1..3) ? - { - m_object->SetAngleX(3+3*i+0, Smooth(m_object->RetAngleX(3+3*i+0), Propf(tSt[0], tNd[0], prog), time)); - m_object->SetAngleY(3+3*i+0, Smooth(m_object->RetAngleY(3+3*i+0), Propf(tSt[1], tNd[1], prog), time)); - m_object->SetAngleZ(3+3*i+0, Smooth(m_object->RetAngleZ(3+3*i+0), Propf(tSt[2], tNd[2], prog), time)); - m_object->SetAngleX(3+3*i+1, Smooth(m_object->RetAngleX(3+3*i+1), Propf(tSt[3], tNd[3], prog), time)); - m_object->SetAngleY(3+3*i+1, Smooth(m_object->RetAngleY(3+3*i+1), Propf(tSt[4], tNd[4], prog), time)); - m_object->SetAngleZ(3+3*i+1, Smooth(m_object->RetAngleZ(3+3*i+1), Propf(tSt[5], tNd[5], prog), time)); - m_object->SetAngleX(3+3*i+2, Smooth(m_object->RetAngleX(3+3*i+2), Propf(tSt[6], tNd[6], prog), time)); - m_object->SetAngleY(3+3*i+2, Smooth(m_object->RetAngleY(3+3*i+2), Propf(tSt[7], tNd[7], prog), time)); - m_object->SetAngleZ(3+3*i+2, Smooth(m_object->RetAngleZ(3+3*i+2), Propf(tSt[8], tNd[8], prog), time)); - } - else // left leg (4..6) ? - { - m_object->SetAngleX(3+3*i+0, Smooth(m_object->RetAngleX(3+3*i+0), Propf(-tSt[0], -tNd[0], prog), time)); - m_object->SetAngleY(3+3*i+0, Smooth(m_object->RetAngleY(3+3*i+0), Propf(-tSt[1], -tNd[1], prog), time)); - m_object->SetAngleZ(3+3*i+0, Smooth(m_object->RetAngleZ(3+3*i+0), Propf( tSt[2], tNd[2], prog), time)); - m_object->SetAngleX(3+3*i+1, Smooth(m_object->RetAngleX(3+3*i+1), Propf(-tSt[3], -tNd[3], prog), time)); - m_object->SetAngleY(3+3*i+1, Smooth(m_object->RetAngleY(3+3*i+1), Propf(-tSt[4], -tNd[4], prog), time)); - m_object->SetAngleZ(3+3*i+1, Smooth(m_object->RetAngleZ(3+3*i+1), Propf( tSt[5], tNd[5], prog), time)); - m_object->SetAngleX(3+3*i+2, Smooth(m_object->RetAngleX(3+3*i+2), Propf(-tSt[6], -tNd[6], prog), time)); - m_object->SetAngleY(3+3*i+2, Smooth(m_object->RetAngleY(3+3*i+2), Propf(-tSt[7], -tNd[7], prog), time)); - m_object->SetAngleZ(3+3*i+2, Smooth(m_object->RetAngleZ(3+3*i+2), Propf( tSt[8], tNd[8], prog), time)); - } - } - -#if ADJUST_ANGLE - if ( m_object->RetSelect() ) - { - char s[100]; - sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex); - m_engine->SetInfoText(4, s); - } -#endif - - if ( m_actionType == MAS_PREPARE ) // prepares the shooting? - { - prog = m_progress; - - dir.x = 0.0f; - dir.y = 0.0f; - dir.z = Prop(0, -50, prog); - SetInclinaison(dir); - m_object->SetAngleZ(1, Prop(0, 65, prog)); // head - m_object->SetAngleZ(2, Prop(0, -95, prog)); // tail - } - else if ( m_actionType == MAS_FIRE ) // shooting? - { - if ( m_progress < 0.75f ) a = m_progress/0.75f; - else a = (1.0f-m_progress)/0.25f; - m_object->SetZoom(2, (a*0.5f)+1.0f); // tail - m_object->SetAngleX(2, (Rand()-0.5f)*0.3f*a); - m_object->SetAngleY(2, (Rand()-0.5f)*0.3f*a); - - dir.x = (Rand()-0.5f)*0.02f*a; - dir.y = (Rand()-0.5f)*0.05f*a; - dir.z = (Rand()-0.5f)*0.03f*a; - SetCirVibration(dir); - } - else if ( m_actionType == MAS_TERMINATE ) // ends the shooting? - { - prog = 1.0f-m_progress; - - dir.x = 0.0f; - dir.y = 0.0f; - dir.z = Prop(0, -50, prog); - SetInclinaison(dir); - m_object->SetAngleZ(1, Prop(0, 65, prog)); // head - m_object->SetAngleZ(2, Prop(0, -95, prog)); // tail - } - else if ( m_actionType == MAS_BURN ) // burning? - { - dir = D3DVECTOR(PI, 0.0f, 0.0f); - SetCirVibration(dir); - dir = D3DVECTOR(0.0f, -1.5f, 0.0f); - SetLinVibration(dir); - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - SetInclinaison(dir); - - time = event.rTime*1.0f; - m_object->SetAngleZ(1, Smooth(m_object->RetAngleZ(1), 0.0f, time)); // head - m_object->SetAngleZ(2, Smooth(m_object->RetAngleZ(2), 0.0f, time)); // tail - } - else if ( m_actionType == MAS_RUIN ) // destroyed? - { - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - SetLinVibration(dir); - SetCirVibration(dir); - SetInclinaison(dir); - } - else if ( m_actionType == MAS_BACK1 ) // starts on the back? - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) - { - m_lastParticule = m_armTimeAbs; - - pos = m_object->RetPosition(0); - speed.x = (Rand()-0.5f)*10.0f; - speed.z = (Rand()-0.5f)*10.0f; - speed.y = Rand()*5.0f; - dim.x = Rand()*3.0f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); - } - - if ( m_progress < 0.5f ) - { - dir.x = 0.0f; - dir.y = powf(m_progress/0.5f, 2.0f)*12.0f; - dir.z = 0.0f; - SetLinVibration(dir); - } - else - { - dir.x = 0.0f; - dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*12.0f; - dir.z = 0.0f; - SetLinVibration(dir); - } - dir.x = m_progress*PI; - dir.y = 0.0f; - dir.z = 0.0f; - SetCirVibration(dir); - - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - SetInclinaison(dir); - - if ( m_progress >= 1.0f ) - { - SetAction(MAS_BACK2, 55.0f+Rand()*10.0f); - } - } - else if ( m_actionType == MAS_BACK2 ) // moves on the back? - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) - { - m_lastParticule = m_armTimeAbs; - - if ( rand()%10 == 0 ) - { - pos = m_object->RetPosition(0); - pos.x += (Rand()-0.5f)*5.0f; - pos.z += (Rand()-0.5f)*5.0f; - pos.y -= 1.0f; - speed.x = (Rand()-0.5f)*2.0f; - speed.z = (Rand()-0.5f)*2.0f; - speed.y = Rand()*2.0f; - dim.x = Rand()*1.0f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); - } - } - - dir = D3DVECTOR(0.0f, -1.0f, 0.0f); - SetLinVibration(dir); - dir.x = sinf(m_armTimeAbs* 4.0f)*0.10f+ - sinf(m_armTimeAbs* 7.0f)*0.20f+ - sinf(m_armTimeAbs*10.0f)*0.40f+ - sinf(m_armTimeAbs*21.0f)*0.50f+PI; - dir.y = sinf(m_armTimeAbs* 3.0f)*0.01f+ - sinf(m_armTimeAbs* 6.0f)*0.02f+ - sinf(m_armTimeAbs*11.0f)*0.04f+ - sinf(m_armTimeAbs*20.0f)*0.02f; - dir.z = sinf(m_armTimeAbs* 5.0f)*0.01f+ - sinf(m_armTimeAbs* 8.0f)*0.02f+ - sinf(m_armTimeAbs* 9.0f)*0.04f+ - sinf(m_armTimeAbs*23.0f)*0.03f; - SetCirVibration(dir); - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - SetInclinaison(dir); - - m_object->SetAngleY(1, sinf(m_armTimeAbs*8.0f)*0.7f); // head - m_object->SetAngleY(2, cosf(m_armTimeAbs*8.0f)*0.7f); // tail - m_object->SetAngleZ(1, 0.0f); // head - m_object->SetAngleZ(2, 0.0f); // tail - - if ( m_progress >= 1.0f ) - { - SetAction(MAS_BACK3, 0.4f); - } - } - else if ( m_actionType == MAS_BACK3 ) // goes back on the legs? - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) - { - m_lastParticule = m_armTimeAbs; - - pos = m_object->RetPosition(0); - speed.x = (Rand()-0.5f)*10.0f; - speed.z = (Rand()-0.5f)*10.0f; - speed.y = Rand()*5.0f; - dim.x = Rand()*3.0f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); - } - - if ( m_progress < 0.5f ) - { - dir.x = 0.0f; - dir.y = powf(m_progress/0.5f, 2.0f)*5.0f; - dir.z = 0.0f; - SetLinVibration(dir); - } - else - { - dir.x = 0.0f; - dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*5.0f; - dir.z = 0.0f; - SetLinVibration(dir); - } - dir.x = (1.0f-m_progress)*PI; - dir.y = 0.0f; - dir.z = 0.0f; - SetCirVibration(dir); - - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - SetInclinaison(dir); - - if ( m_progress >= 1.0f ) - { - SetAction(-1); - m_object->SetFixed(FALSE); // moving again - } - } - else - { - m_object->SetZoom(2, 1.0f); // tail - m_object->SetAngleX(2, 0.0f); - m_object->SetAngleY(2, 0.0f); - - if ( bStop ) - { - m_object->SetAngleZ(2, sinf(m_armTimeAbs*1.7f)*0.15f); // tail - - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - SetLinVibration(dir); - SetInclinaison(dir); - } - else - { - a = Mod(m_armTimeMarch, 1.0f); - if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1 - else a = 3.0f-4.0f*a; // 1..-1 - dir.x = sinf(a)*0.05f; - - s = Mod(m_armTimeMarch/2.0f, 1.0f); - if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1 - else s = 3.0f-4.0f*s; // 1..-1 - dir.z = sinf(s)*0.1f; - - dir.y = 0.0f; - SetInclinaison(dir); - - m_object->SetAngleZ(2, -sinf(a)*0.3f); // tail - - a = Mod(m_armMember-0.1f, 1.0f); - if ( a < 0.33f ) - { - dir.y = -(1.0f-(a/0.33f))*0.3f; - } - else if ( a < 0.67f ) - { - dir.y = 0.0f; - } - else - { - dir.y = -(a-0.67f)/0.33f*0.3f; - } - dir.x = 0.0f; - dir.z = 0.0f; - SetLinVibration(dir); - } - - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - SetCirVibration(dir); - - m_object->SetAngleZ(1, sinf(m_armTimeAbs*1.4f)*0.20f); // head - m_object->SetAngleX(1, sinf(m_armTimeAbs*1.9f)*0.10f); // head - m_object->SetAngleY(1, sinf(m_armTimeAbs*2.1f)*0.50f); // head - } - - return TRUE; -} - - diff --git a/src/motionant.h b/src/motionant.h deleted file mode 100644 index e8d79c6..0000000 --- a/src/motionant.h +++ /dev/null @@ -1,80 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motionant.h - -#ifndef _MOTIONANT_H_ -#define _MOTIONANT_H_ - - -#include "motion.h" - - -class CInstanceManager; -class CEngine; -class CLight; -class CParticule; -class CTerrain; -class CCamera; -class CBrain; -class CPhysics; -class CObject; - - -#define MA_MARCH 0 -#define MA_STOP 1 -#define MA_SPEC 2 - -#define MAS_PREPARE 0 -#define MAS_FIRE 1 -#define MAS_TERMINATE 2 -#define MAS_BURN 3 -#define MAS_RUIN 4 -#define MAS_BACK1 5 -#define MAS_BACK2 6 -#define MAS_BACK3 7 - - -class CMotionAnt : public CMotion -{ -public: - CMotionAnt(CInstanceManager* iMan, CObject* object); - ~CMotionAnt(); - - void DeleteObject(BOOL bAll=FALSE); - BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); - BOOL EventProcess(const Event &event); - -protected: - void CreatePhysics(); - BOOL EventFrame(const Event &event); - -protected: - float m_armMember; - float m_armTimeAbs; - float m_armTimeMarch; - float m_armTimeAction; - short m_armAngles[3*3*3*3*3 + 3*3*3*8]; - int m_armTimeIndex; - int m_armPartIndex; - int m_armMemberIndex; - int m_armLastAction; - BOOL m_bArmStop; - float m_lastParticule; -}; - - -#endif //_MOTIONANT_H_ diff --git a/src/motionbee.cpp b/src/motionbee.cpp deleted file mode 100644 index 65ebeb7..0000000 --- a/src/motionbee.cpp +++ /dev/null @@ -1,663 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motionbee.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "light.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "modfile.h" -#include "sound.h" -#include "motion.h" -#include "motionbee.h" - - - -#define ADJUST_ANGLE FALSE // TRUE -> adjusts the angles of the members -#define START_TIME 1000.0f // beginning of the relative time - - - -// Object's constructor. - -CMotionBee::CMotionBee(CInstanceManager* iMan, CObject* object) - : CMotion(iMan, object) -{ - CMotion::CMotion(iMan, object); - - m_armMember = START_TIME; - m_armTimeAbs = START_TIME; - m_armTimeMarch = START_TIME; - m_armTimeAction = START_TIME; - m_armTimeIndex = 0; - m_armPartIndex = 0; - m_armMemberIndex = 0; - m_armLastAction = -1; - m_bArmStop = FALSE; -} - -// Object's destructor. - -CMotionBee::~CMotionBee() -{ -} - - -// Removes an object. - -void CMotionBee::DeleteObject(BOOL bAll) -{ -} - - -// Creates a vehicle traveling any lands on the ground. - -BOOL CMotionBee::Create(D3DVECTOR pos, float angle, ObjectType type, - float power) -{ - CModFile* pModFile; - int rank; - - if ( m_engine->RetRestCreate() < 3+18+2 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - m_object->SetType(type); - - // Creates main base. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object - m_object->SetObjectRank(0, rank); - - pModFile->ReadModel("objects\\bee1.mod"); - pModFile->CreateEngineObject(rank); - - m_object->SetPosition(0, pos); - m_object->SetAngleY(0, angle); - - // A vehicle must have an obligatory collision - // with a sphere of center (0, y, 0) (see GetCrashSphere). - m_object->CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f); - m_object->SetGlobalSphere(D3DVECTOR(-1.0f, 1.0f, 0.0f), 5.0f); - - // Creates the head. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\bee2.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(1.6f, 0.3f, 0.0f)); - - // Creates the tail. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 0); - pModFile->ReadModel("objects\\bee3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2, D3DVECTOR(-0.8f, 0.0f, 0.0f)); - - // Creates a right-back thigh. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(3, rank); - m_object->SetObjectParent(3, 0); - pModFile->ReadModel("objects\\ant4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(3, D3DVECTOR(-0.3f, -0.1f, -0.2f)); - - // Creates a right-back leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(4, rank); - m_object->SetObjectParent(4, 3); - pModFile->ReadModel("objects\\ant5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(4, D3DVECTOR(0.0f, 0.0f, -1.0f)); - - // Creates a right-back foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(5, rank); - m_object->SetObjectParent(5, 4); - pModFile->ReadModel("objects\\ant6.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(5, D3DVECTOR(0.0f, 0.0f, -2.0f)); - - // Creates two middle-right thighs. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(6, rank); - m_object->SetObjectParent(6, 0); - pModFile->ReadModel("objects\\ant4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(6, D3DVECTOR(0.3f, -0.1f, -0.4f)); - - // Creates two middle-right legs. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(7, rank); - m_object->SetObjectParent(7, 6); - pModFile->ReadModel("objects\\ant5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(7, D3DVECTOR(0.0f, 0.0f, -1.0f)); - - // Creates two middle-right feet. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(8, rank); - m_object->SetObjectParent(8, 7); - pModFile->ReadModel("objects\\ant6.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(8, D3DVECTOR(0.0f, 0.0f, -2.0f)); - - // Creates the right front thigh. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(9, rank); - m_object->SetObjectParent(9, 0); - pModFile->ReadModel("objects\\ant4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(9, D3DVECTOR(1.0f, -0.1f, -0.7f)); - - // Creates the right front leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(10, rank); - m_object->SetObjectParent(10, 9); - pModFile->ReadModel("objects\\ant5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(10, D3DVECTOR(0.0f, 0.0f, -1.0f)); - - // Creates the right front foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(11, rank); - m_object->SetObjectParent(11, 10); - pModFile->ReadModel("objects\\ant6.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(11, D3DVECTOR(0.0f, 0.0f, -2.0f)); - - // Creates a left-back thigh. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(12, rank); - m_object->SetObjectParent(12, 0); - pModFile->ReadModel("objects\\ant4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(12, D3DVECTOR(-0.3f, -0.1f, 0.2f)); - m_object->SetAngleY(12, PI); - - // Creates a left-back leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(13, rank); - m_object->SetObjectParent(13, 12); - pModFile->ReadModel("objects\\ant5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(13, D3DVECTOR(0.0f, 0.0f, -1.0f)); - - // Creates a left-back foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(14, rank); - m_object->SetObjectParent(14, 13); - pModFile->ReadModel("objects\\ant6.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(14, D3DVECTOR(0.0f, 0.0f, -2.0f)); - - // Creates two middle-left thigh. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(15, rank); - m_object->SetObjectParent(15, 0); - pModFile->ReadModel("objects\\ant4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(15, D3DVECTOR(0.3f, -0.1f, 0.4f)); - m_object->SetAngleY(15, PI); - - // Creates two middle-left legs. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(16, rank); - m_object->SetObjectParent(16, 15); - pModFile->ReadModel("objects\\ant5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(16, D3DVECTOR(0.0f, 0.0f, -1.0f)); - - // Creates two middle-left feet. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(17, rank); - m_object->SetObjectParent(17, 16); - pModFile->ReadModel("objects\\ant6.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(17, D3DVECTOR(0.0f, 0.0f, -2.0f)); - - // Creates front-left thigh. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(18, rank); - m_object->SetObjectParent(18, 0); - pModFile->ReadModel("objects\\ant4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(18, D3DVECTOR(1.0f, -0.1f, 0.7f)); - m_object->SetAngleY(18, PI); - - // Creates front-left leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(19, rank); - m_object->SetObjectParent(19, 18); - pModFile->ReadModel("objects\\ant5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(19, D3DVECTOR(0.0f, 0.0f, -1.0f)); - - // Creates front-left foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(20, rank); - m_object->SetObjectParent(20, 19); - pModFile->ReadModel("objects\\ant6.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(20, D3DVECTOR(0.0f, 0.0f, -2.0f)); - - // Creates the right wing. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(21, rank); - m_object->SetObjectParent(21, 0); - pModFile->ReadModel("objects\\bee7.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(21, D3DVECTOR(0.8f, 0.4f, -0.5f)); - - // Creates the left wing. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(22, rank); - m_object->SetObjectParent(22, 0); - pModFile->ReadModel("objects\\bee7.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(22, D3DVECTOR(0.8f, 0.4f, 0.5f)); - - m_object->CreateShadowCircle(6.0f, 0.5f); - - CreatePhysics(); - m_object->SetFloorHeight(0.0f); - - pos = m_object->RetPosition(0); - m_object->SetPosition(0, pos); // to display the shadows immediately - - m_engine->LoadAllTexture(); - - delete pModFile; - return TRUE; -} - -// Creates the physical object. - -void CMotionBee::CreatePhysics() -{ - Character* character; - int i; - - int member_march[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: - 0,45,0, 0,45,0, 0,50,0, // t0: thighs 1..3 - 30,-70,0, 20,-105,20, 25,-100,0, // t0: legs 1..3 - -70,75,0, -30,80,0, -80,80,0, // t0: feet 1..3 - // on the ground: - 0,30,0, 0,20,0, 0,15,0, // t1: thighs 1..3 - -15,-50,0, -20,-60,0, -10,-75,0, // t1: legs 1..3 - -40,50,0, -25,15,0, -50,35,0, // t1: feet 1..3 - // on the ground back: - 0,35,0, 0,30,0, 0,20,0, // t2: thighs 1..3 - -20,-15,0, -30,-55,0, -25,-70,15, // t2: legs 1..3 - -25,25,0, -20,60,0, -30,95,0, // t2: feet 1..3 - }; - - int member_spec[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, // ball carrier: - 0,45,0, 0,45,0, 0,50,0, // s0: thighs 1..3 - -35,-70,0, -20,-85,-25, -25,-100,0, // s0: legs 1..3 - -110,75,-15, -130,80,-25, -125,40,0, // s0: feet 1..3 - // burning: - 0,45,0, 0,45,0, 0,50,0, // s1: thighs 1..3 - -35,-70,0, -20,-85,-25, -25,-100,0, // s1: legs 1..3 - -110,75,-15, -130,80,-25, -125,40,0, // s1: feet 1..3 - // destroyed: - 0,45,0, 0,45,0, 0,50,0, // s2: thighs 1..3 - -35,-70,0, -20,-85,-25, -25,-100,0, // s2: legs 1..3 - -110,75,-15, -130,80,-25, -125,40,0, // s2: feet 1..3 - }; - - m_physics->SetType(TYPE_FLYING); - - character = m_object->RetCharacter(); - character->wheelFront = 3.0f; - character->wheelBack = 3.0f; - character->wheelLeft = 5.0f; - character->wheelRight = 5.0f; - character->height = 2.5f; - - m_physics->SetLinMotionX(MO_ADVSPEED, 50.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 50.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 20.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 10.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); - m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f); - m_physics->SetLinMotionY(MO_RECSPEED, 60.0f); - m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f); - m_physics->SetLinMotionY(MO_RECACCEL, 50.0f); - m_physics->SetLinMotionY(MO_STOACCEL, 50.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 1.0f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 1.0f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 20.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 20.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 40.0f); - - for ( i=0 ; i<3*3*3*3 ; i++ ) - { - m_armAngles[3*3*3*3*MB_MARCH+i] = member_march[i]; - } - for ( i=0 ; i<3*3*3*3 ; i++ ) - { - m_armAngles[3*3*3*3*MB_SPEC+i] = member_spec[i]; - } -} - - -// Management of an event. - -BOOL CMotionBee::EventProcess(const Event &event) -{ - CMotion::EventProcess(event); - - if ( event.event == EVENT_FRAME ) - { - return EventFrame(event); - } - - if ( event.event == EVENT_KEYDOWN ) - { -#if ADJUST_ANGLE - int i; - - if ( event.param == 'A' ) m_armTimeIndex++; - if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0; - - if ( event.param == 'Q' ) m_armPartIndex++; - if ( m_armPartIndex >= 3 ) m_armPartIndex = 0; - - if ( event.param == 'W' ) m_armMemberIndex++; - if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0; - - i = m_armMemberIndex*3; - i += m_armPartIndex*3*3; - i += m_armTimeIndex*3*3*3; -//? i += 3*3*3*3; - - if ( event.param == 'E' ) m_armAngles[i+0] += 5; - if ( event.param == 'D' ) m_armAngles[i+0] -= 5; - if ( event.param == 'R' ) m_armAngles[i+1] += 5; - if ( event.param == 'F' ) m_armAngles[i+1] -= 5; - if ( event.param == 'T' ) m_armAngles[i+2] += 5; - if ( event.param == 'G' ) m_armAngles[i+2] -= 5; - - if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop; -#endif - } - - return TRUE; -} - -// Management of an event. - -BOOL CMotionBee::EventFrame(const Event &event) -{ - D3DVECTOR dir; - float s, a, prog; - int action, i, st, nd; - BOOL bStop; - - if ( m_engine->RetPause() ) return TRUE; - if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return TRUE; - - s = m_physics->RetLinMotionX(MO_MOTSPEED)*0.30f; - a = Abs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.00f); - - if ( s == 0.0f && a != 0.0f ) a *= 1.5f; - - m_armTimeAbs += event.rTime; - m_armTimeMarch += (s)*event.rTime*0.15f; - m_armMember += (s+a)*event.rTime*0.15f; - - bStop = ( a == 0.0f && s == 0.0f ); // stopped? - if ( !m_physics->RetLand() ) bStop = TRUE; - - if ( bStop ) - { - prog = Mod(m_armTimeAbs, 2.0f)/10.0f; - a = Mod(m_armMember, 1.0f); - a = (prog-a)*event.rTime*2.0f; // stop position is pleasantly - m_armMember += a; - } - - action = MB_MARCH; // flying - - m_actionType = -1; - if ( m_object->RetFret() != 0 ) m_actionType = MBS_HOLD; // carries the ball - - if ( m_object->RetRuin() ) // destroyed? - { - m_actionType = MBS_RUIN; - } - if ( m_object->RetBurn() ) // burning? - { - m_actionType = MBS_BURN; - } - - for ( i=0 ; i<6 ; i++ ) // the six legs - { - if ( m_actionType != -1 ) // special action in progress? - { - st = 3*3*3*3*MB_SPEC + 3*3*3*m_actionType + (i%3)*3; - nd = st; - } - else - { - if ( i < 3 ) prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f); - else prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f); - if ( m_bArmStop ) - { - prog = (float)m_armTimeIndex/3.0f; - } - if ( prog < 0.33f ) // t0..t1 ? - { - prog = prog/0.33f; // 0..1 - st = 0; // index start - nd = 1; // index end - } - else if ( prog < 0.67f ) // t1..t2 ? - { - prog = (prog-0.33f)/0.33f; // 0..1 - st = 1; // index start - nd = 2; // index end - } - else // t2..t0 ? - { - prog = (prog-0.67f)/0.33f; // 0..1 - st = 2; // index start - nd = 0; // index end - } - st = 3*3*3*3*action + st*3*3*3 + (i%3)*3; - nd = 3*3*3*3*action + nd*3*3*3 + (i%3)*3; - } - - if ( i < 3 ) // right leg (1..3) ? - { - m_object->SetAngleX(3+3*i+0, Prop(m_armAngles[st+ 0], m_armAngles[nd+ 0], prog)); - m_object->SetAngleY(3+3*i+0, Prop(m_armAngles[st+ 1], m_armAngles[nd+ 1], prog)); - m_object->SetAngleZ(3+3*i+0, Prop(m_armAngles[st+ 2], m_armAngles[nd+ 2], prog)); - m_object->SetAngleX(3+3*i+1, Prop(m_armAngles[st+ 9], m_armAngles[nd+ 9], prog)); - m_object->SetAngleY(3+3*i+1, Prop(m_armAngles[st+10], m_armAngles[nd+10], prog)); - m_object->SetAngleZ(3+3*i+1, Prop(m_armAngles[st+11], m_armAngles[nd+11], prog)); - m_object->SetAngleX(3+3*i+2, Prop(m_armAngles[st+18], m_armAngles[nd+18], prog)); - m_object->SetAngleY(3+3*i+2, Prop(m_armAngles[st+19], m_armAngles[nd+19], prog)); - m_object->SetAngleZ(3+3*i+2, Prop(m_armAngles[st+20], m_armAngles[nd+20], prog)); - } - else // left leg(4..6) ? - { - m_object->SetAngleX(3+3*i+0, Prop( -m_armAngles[st+ 0], -m_armAngles[nd+ 0], prog)); - m_object->SetAngleY(3+3*i+0, Prop(180-m_armAngles[st+ 1], 180-m_armAngles[nd+ 1], prog)); - m_object->SetAngleZ(3+3*i+0, Prop( -m_armAngles[st+ 2], -m_armAngles[nd+ 2], prog)); - m_object->SetAngleX(3+3*i+1, Prop( m_armAngles[st+ 9], m_armAngles[nd+ 9], prog)); - m_object->SetAngleY(3+3*i+1, Prop( -m_armAngles[st+10], -m_armAngles[nd+10], prog)); - m_object->SetAngleZ(3+3*i+1, Prop( -m_armAngles[st+11], -m_armAngles[nd+11], prog)); - m_object->SetAngleX(3+3*i+2, Prop( m_armAngles[st+18], m_armAngles[nd+18], prog)); - m_object->SetAngleY(3+3*i+2, Prop( -m_armAngles[st+19], -m_armAngles[nd+19], prog)); - m_object->SetAngleZ(3+3*i+2, Prop( -m_armAngles[st+20], -m_armAngles[nd+20], prog)); - } - } - -#if ADJUST_ANGLE - if ( m_object->RetSelect() ) - { - char s[100]; - sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex); - m_engine->SetInfoText(4, s); - } -#endif - - if ( m_physics->RetLand() ) // on the ground? - { - if ( m_object->RetRuin() ) - { - } - else if ( bStop || m_object->RetBurn() ) - { - m_object->SetAngleZ(2, sinf(m_armTimeAbs*1.7f)*0.15f+0.35f); // tail - } - else - { - a = Mod(m_armTimeMarch, 1.0f); - if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1 - else a = 3.0f-4.0f*a; // 1..-1 - dir.x = sinf(a)*0.05f; - - s = Mod(m_armTimeMarch/2.0f, 1.0f); - if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1 - else s = 3.0f-4.0f*s; // 1..-1 - dir.z = sinf(s)*0.1f; - - dir.y = 0.0f; - m_object->SetInclinaison(dir); - - m_object->SetAngleZ(2, -sinf(a)*0.3f); // tail - - a = Mod(m_armMember-0.1f, 1.0f); - if ( a < 0.33f ) - { - dir.y = -(1.0f-(a/0.33f))*0.3f; - } - else if ( a < 0.67f ) - { - dir.y = 0.0f; - } - else - { - dir.y = -(a-0.67f)/0.33f*0.3f; - } - dir.x = 0.0f; - dir.z = 0.0f; - m_object->SetLinVibration(dir); - } - } - - if ( m_physics->RetLand() ) - { - if ( bStop ) prog = 0.05f; - else prog = 0.15f; - } - else - { - prog = 1.00f; - } - -#if 0 - a = Rand()*PI/2.0f*prog; - m_object->SetAngleX(21, a); // right wing - a = -Rand()*PI/4.0f*prog; - m_object->SetAngleY(21, a); - - a = -Rand()*PI/2.0f*prog; - m_object->SetAngleX(22, a); // left wing - a = Rand()*PI/4.0f*prog; - m_object->SetAngleY(22, a); -#else - m_object->SetAngleX(21, (sinf(m_armTimeAbs*30.0f)+1.0f)*(PI/4.0f)*prog); - m_object->SetAngleY(21, -Rand()*PI/6.0f*prog); - - m_object->SetAngleX(22, -(sinf(m_armTimeAbs*30.0f)+1.0f)*(PI/4.0f)*prog); - m_object->SetAngleY(22, Rand()*PI/6.0f*prog); -#endif - - m_object->SetAngleZ(1, sinf(m_armTimeAbs*1.4f)*0.20f); // head - m_object->SetAngleX(1, sinf(m_armTimeAbs*1.9f)*0.10f); // head - m_object->SetAngleY(1, sinf(m_armTimeAbs*2.1f)*0.50f); // head - -#if 0 - h = m_terrain->RetFloorHeight(RetPosition(0)); - radius = 4.0f+h/4.0f; - color.r = 0.3f+h/80.0f; - color.g = color.r; - color.b = color.r; - color.a = color.r; - m_engine->SetObjectShadowRadius(m_objectPart[0].object, radius); - m_engine->SetObjectShadowColor(m_objectPart[0].object, color); -#endif - - return TRUE; -} - - diff --git a/src/motionbee.h b/src/motionbee.h deleted file mode 100644 index facf650..0000000 --- a/src/motionbee.h +++ /dev/null @@ -1,73 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motionbee.h - -#ifndef _MOTIONBEE_H_ -#define _MOTIONBEE_H_ - - -#include "motion.h" - - -class CInstanceManager; -class CEngine; -class CLight; -class CParticule; -class CTerrain; -class CCamera; -class CBrain; -class CPhysics; -class CObject; - - -#define MB_MARCH 0 -#define MB_SPEC 1 - -#define MBS_HOLD 0 -#define MBS_BURN 1 -#define MBS_RUIN 2 - - -class CMotionBee : public CMotion -{ -public: - CMotionBee(CInstanceManager* iMan, CObject* object); - ~CMotionBee(); - - void DeleteObject(BOOL bAll=FALSE); - BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); - BOOL EventProcess(const Event &event); - -protected: - void CreatePhysics(); - BOOL EventFrame(const Event &event); - -protected: - float m_armMember; - float m_armTimeAbs; - float m_armTimeMarch; - float m_armTimeAction; - short m_armAngles[3*3*3*3*2]; - int m_armTimeIndex; - int m_armPartIndex; - int m_armMemberIndex; - int m_armLastAction; - BOOL m_bArmStop; -}; - - -#endif //_MOTIONBEE_H_ diff --git a/src/motionhuman.cpp b/src/motionhuman.cpp deleted file mode 100644 index 78750fa..0000000 --- a/src/motionhuman.cpp +++ /dev/null @@ -1,1799 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motionhuman.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "light.h" -#include "particule.h" -#include "terrain.h" -#include "water.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "modfile.h" -#include "robotmain.h" -#include "sound.h" -#include "motion.h" -#include "motionhuman.h" - - - -#define ADJUST_ANGLE FALSE // TRUE -> adjusts the angles of the members -#define ADJUST_ACTION (3*3*3*3*MH_SPEC+3*3*3*MHS_SATCOM) - -#define START_TIME 1000.0f // beginning of the relative time - - - -// Object's constructor. - -CMotionHuman::CMotionHuman(CInstanceManager* iMan, CObject* object) - : CMotion(iMan, object) -{ - CMotion::CMotion(iMan, object); - - m_partiReactor = -1; - m_armMember = START_TIME; - m_armTimeAbs = START_TIME; - m_armTimeAction = START_TIME; - m_armTimeSwim = START_TIME; - m_armTimeIndex = 0; - m_armPartIndex = 0; - m_armMemberIndex = 0; - m_armLastAction = -1; - m_bArmStop = FALSE; - m_lastSoundMarch = 0.0f; - m_lastSoundHhh = 0.0f; - m_time = 0.0f; - m_tired = 0.0f; - m_bDisplayPerso = FALSE; -} - -// Object's constructor. - -CMotionHuman::~CMotionHuman() -{ -} - - -// Removes an object. - -void CMotionHuman::DeleteObject(BOOL bAll) -{ - if ( m_partiReactor != -1 ) - { - m_particule->DeleteParticule(m_partiReactor); - m_partiReactor = -1; - } -} - - -// Starts an action. - -Error CMotionHuman::SetAction(int action, float time) -{ - CMotion::SetAction(action, time); - m_time = 0.0f; - return ERR_OK; -} - - -// Creates cosmonaut on the ground. - -BOOL CMotionHuman::Create(D3DVECTOR pos, float angle, ObjectType type, - float power) -{ - CModFile* pModFile; - char filename[100]; - int rank, option, face, glasses; - - if ( m_engine->RetRestCreate() < 16 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - m_object->SetType(type); - option = m_object->RetOption(); - - if ( m_main->RetGamerOnlyHead() ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object - m_object->SetObjectRank(0, rank); - face = m_main->RetGamerFace(); - sprintf(filename, "objects\\human2h%d.mod", face+1); - pModFile->ReadModel(filename); - pModFile->CreateEngineObject(rank); - - glasses = m_main->RetGamerGlasses(); - if ( glasses != 0 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - sprintf(filename, "objects\\human2g%d.mod", glasses); - pModFile->ReadModel(filename); - pModFile->CreateEngineObject(rank); - } - - CreatePhysics(type); - m_object->SetFloorHeight(0.0f); - - m_engine->LoadAllTexture(); - - delete pModFile; - return TRUE; - } - - // Creates the main base. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object - m_object->SetObjectRank(0, rank); - - if ( option == 0 ) // head in helmet? - { - pModFile->ReadModel("objects\\human1c.mod"); - } - if ( option == 1 ) // head without helmet? - { - pModFile->ReadModel("objects\\human1h.mod"); - } - if ( option == 2 ) // without a backpack? - { - pModFile->ReadModel("objects\\human1v.mod"); - } - pModFile->CreateEngineObject(rank); - - m_object->SetPosition(0, pos); - m_object->SetAngleY(0, angle); - - // A vehicle must have an obligatory collision with a sphere of center (0, y, 0) (see GetCrashSphere). - m_object->CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 2.0f, SOUND_AIE, 0.20f); - m_object->SetGlobalSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 4.0f); - - // Creates the head. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - - if ( type == OBJECT_HUMAN ) - { - if ( option == 0 ) // head in helmet? - { - face = m_main->RetGamerFace(); - sprintf(filename, "objects\\human2c%d.mod", face+1); - pModFile->ReadModel(filename); - } - if ( option == 1 || // head without helmet? - option == 2 ) // without a backpack? - { - face = m_main->RetGamerFace(); - sprintf(filename, "objects\\human2h%d.mod", face+1); - pModFile->ReadModel(filename); - } - } - if ( type == OBJECT_TECH ) - { - pModFile->ReadModel("objects\\human2t.mod"); - } - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(0.0f, 2.7f, 0.0f)); - if ( option == 1 || // head without helmet? - option == 2 ) // without a backpack? - { - m_object->SetZoom(1, D3DVECTOR(1.0f, 1.05f, 1.0f)); - } - - // Creates the glasses. - glasses = m_main->RetGamerGlasses(); - if ( glasses != 0 && type == OBJECT_HUMAN ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(15, rank); - m_object->SetObjectParent(15, 1); - sprintf(filename, "objects\\human2g%d.mod", glasses); - pModFile->ReadModel(filename); - pModFile->CreateEngineObject(rank); - } - - // Creates the right arm. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 0); - pModFile->ReadModel("objects\\human3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2, D3DVECTOR(0.0f, 2.3f, -1.2f)); - m_object->SetAngle(2, D3DVECTOR(90.0f*PI/180.0f, 90.0f*PI/180.0f, -50.0f*PI/180.0f)); - - // Creates the right forearm. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(3, rank); - m_object->SetObjectParent(3, 2); - pModFile->ReadModel("objects\\human4r.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(3, D3DVECTOR(1.3f, 0.0f, 0.0f)); - m_object->SetAngle(3, D3DVECTOR(0.0f*PI/180.0f, -20.0f*PI/180.0f, 0.0f*PI/180.0f)); - - // Creates right hand. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(4, rank); - m_object->SetObjectParent(4, 3); - pModFile->ReadModel("objects\\human5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(4, D3DVECTOR(1.2f, 0.0f, 0.0f)); - - // Creates the right thigh. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(5, rank); - m_object->SetObjectParent(5, 0); - pModFile->ReadModel("objects\\human6.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(5, D3DVECTOR(0.0f, 0.0f, -0.7f)); - m_object->SetAngle(5, D3DVECTOR(10.0f*PI/180.0f, 0.0f*PI/180.0f, 5.0f*PI/180.0f)); - - // Creates the right leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(6, rank); - m_object->SetObjectParent(6, 5); - pModFile->ReadModel("objects\\human7.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(6, D3DVECTOR(0.0f, -1.5f, 0.0f)); - m_object->SetAngle(6, D3DVECTOR(0.0f*PI/180.0f, 0.0f*PI/180.0f, -10.0f*PI/180.0f)); - - // Creates the right foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(7, rank); - m_object->SetObjectParent(7, 6); - pModFile->ReadModel("objects\\human8.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(7, D3DVECTOR(0.0f, -1.5f, 0.0f)); - m_object->SetAngle(7, D3DVECTOR(-10.0f*PI/180.0f, 5.0f*PI/180.0f, 5.0f*PI/180.0f)); - - // Creates the left arm. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(8, rank); - m_object->SetObjectParent(8, 0); - pModFile->ReadModel("objects\\human3.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(8, D3DVECTOR(0.0f, 2.3f, 1.2f)); - m_object->SetAngle(8, D3DVECTOR(-90.0f*PI/180.0f, -90.0f*PI/180.0f, -50.0f*PI/180.0f)); - - // Creates the left forearm. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(9, rank); - m_object->SetObjectParent(9, 8); - pModFile->ReadModel("objects\\human4l.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(9, D3DVECTOR(1.3f, 0.0f, 0.0f)); - m_object->SetAngle(9, D3DVECTOR(0.0f*PI/180.0f, 20.0f*PI/180.0f, 0.0f*PI/180.0f)); - - // Creates left hand. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(10, rank); - m_object->SetObjectParent(10, 9); - pModFile->ReadModel("objects\\human5.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(10, D3DVECTOR(1.2f, 0.0f, 0.0f)); - - // Creates the left thigh. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(11, rank); - m_object->SetObjectParent(11, 0); - pModFile->ReadModel("objects\\human6.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(11, D3DVECTOR(0.0f, 0.0f, 0.7f)); - m_object->SetAngle(11, D3DVECTOR(-10.0f*PI/180.0f, 0.0f*PI/180.0f, 5.0f*PI/180.0f)); - - // Creates the left leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(12, rank); - m_object->SetObjectParent(12, 11); - pModFile->ReadModel("objects\\human7.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(12, D3DVECTOR(0.0f, -1.5f, 0.0f)); - m_object->SetAngle(12, D3DVECTOR(0.0f*PI/180.0f, 0.0f*PI/180.0f, -10.0f*PI/180.0f)); - - // Creates the left foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(13, rank); - m_object->SetObjectParent(13, 12); - pModFile->ReadModel("objects\\human8.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(13, D3DVECTOR(0.0f, -1.5f, 0.0f)); - m_object->SetAngle(13, D3DVECTOR(10.0f*PI/180.0f, -5.0f*PI/180.0f, 5.0f*PI/180.0f)); - - // Creates the neutron gun. - if ( option != 2 ) // with backpack? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(14, rank); - m_object->SetObjectParent(14, 0); - pModFile->ReadModel("objects\\human9.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(14, D3DVECTOR(-1.5f, 0.3f, -1.35f)); - m_object->SetAngleZ(14, PI); - } - - m_object->CreateShadowCircle(2.0f, 0.8f); - - CreatePhysics(type); - m_object->SetFloorHeight(0.0f); - - pos = m_object->RetPosition(0); - m_object->SetPosition(0, pos); // to display the shadows immediately - - m_engine->LoadAllTexture(); - - delete pModFile; - return TRUE; -} - -// Creates the physical object. - -void CMotionHuman::CreatePhysics(ObjectType type) -{ - Character* character; - int i; - - int member_march[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: - 90,90,-50, 10,0,55, 0,0,0, // t0: arms/thighs/- - 0,-20,0, -5,0,-110, 0,0,0, // t0: forearm/legs/- - 0,0,0, -5,0,40, 0,0,0, // t0: hands/feet/- - // on the ground: - 125,115,-45, 10,0,50, 0,0,0, // t1: arms/thighs/- - 0,-20,0, -5,0,-15, 0,0,0, // t1: forearm/legs/- - 0,0,0, -5,0,0, 0,0,0, // t1: hands/feet/- - // on the ground back: - 25,55,-40, 10,0,-15, 0,0,0, // t2: arms/thighs/- - 30,-50,40, -5,0,-55, 0,0,0, // t2: forearm/legs/- - 0,0,0, -5,0,25, 0,0,0, // t2: hands/feet/- - }; - - int member_march_take[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: - 15,50,-50, 10,0,55, 0,0,0, // t0: arms/thighs/- - 45,-70,10, -5,0,-110, 0,0,0, // t0: forearm/legs/- - -10,25,0, -5,0,40, 0,0,0, // t0: hands/feet/- - // on the ground: - 15,50,-55, 10,0,50, 0,0,0, // t1: arms/thighs/- - 45,-70,10, -5,0,-15, 0,0,0, // t1: forearm/legs/- - -10,25,0, -5,0,0, 0,0,0, // t1: hands/feet/- - // on the ground back: - 15,50,-45, 10,0,-15, 0,0,0, // t2: arms/thighs/- - 45,-70,10, -5,0,-55, 0,0,0, // t2: forearm/legs/- - -10,25,0, -5,0,45, 0,0,0, // t2: hands/feet/- - }; - - int member_turn[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: - 90,90,-50, 10,0,30, 0,0,0, // t0: arms/thighs/- - 0,-20,0, -5,0,-60, 0,0,0, // t0: forearm/legs/- - 0,0,0, -5,0,30, 0,0,0, // t0: hands/feet/- - // on the ground: - 90,110,-45, 10,0,0, 0,0,0, // t1: arms/thighs/- - 0,-20,0, -5,5,0, 0,0,0, // t1: forearm/legs/- - 0,0,0, -5,10,0, 0,0,0, // t1: hands/feet/- - // on the ground back: - 90,70,-45, 10,0,0, 0,0,0, // t2: arms/thighs/- - 0,-20,10, -5,-5,0, 0,0,0, // t2: forearm/legs/- - 0,0,0, -5,-10,0, 0,0,0, // t2: hands/feet/- - }; - - int member_stop[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, - 90,90,-50, 10,0,5, 0,0,0, // arms/thighs/- - 0,-20,0, 0,0,-10, 0,0,0, // forearm/legs/- - 0,0,0, -10,5,5, 0,0,0, // hands/feet/- - // - 90,90,-55, 10,0,5, 0,0,0, // arms/thighs/- - 0,-15,0, 0,0,-10, 0,0,0, // forearm/legs/- - 0,0,0, -10,5,5, 0,0,0, // hands/feet/- - // - 90,90,-60, 10,0,5, 0,0,0, // arms/thighs/- - 0,-10,0, 0,0,-10, 0,0,0, // forearm/legs/- - 0,0,0, -10,5,5, 0,0,0, // hands/feet/- - }; - - int member_fly[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, - -5,90,-60, 20,5,-25, 0,0,0, // arms/thighs/- - 85,-40,-25, 10,0,-30, 0,0,0, // forearm/legs/- - 40,10,25, 0,15,0, 0,0,0, // hands/feet/- - // - -15,90,-40, 20,5,-35, 0,0,0, // arms/thighs/- - 85,-40,-25, 10,0,-40, 0,0,0, // forearm/legs/- - 45,5,20, 0,15,0, 0,0,0, // hands/feet/- - // - -25,90,-50, 20,5,-20, 0,0,0, // arms/thighs/- - 85,-40,-25, 10,0,-10, 0,0,0, // forearm/legs/- - 30,15,25, 0,15,0, 0,0,0, // hands/feet/- - }; - - int member_swim[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, -#if 1 - 130,-70,200, 10,20,55, 0,0,0, // arms/thighs/- - 115,-125,0, -5,0,-110, 0,0,0, // forearm/legs/- - 0,0,0, -5,10,-5, 0,0,0, // hands/feet/- - // - 130,-95,115,55,5,5, 0,0,0, // arms/thighs/- - 75,-50,25, -5,0,-15, 0,0,0, // forearm/legs/- - 0,0,0, -5,5,-30, 0,0,0, // hands/feet/- - // - 130,-100,220,5,0,0, 0,0,0, // arms/thighs/- - 150,5,0, -5,0,-15, 0,0,0, // forearm/legs/- - 0,0,0, -5,30,-20, 0,0,0, // hands/feet/- -#endif -#if 0 - 130,-70,200,5,0,0, 0,0,0, // arms/thighs/- - 115,-125,0, -5,0,-15, 0,0,0, // forearm/legs/- - 0,0,0, -5,30,-20, 0,0,0, // hands/feet/- - // - 130,-95,115, 10,20,55, 0,0,0, // arms/thighs/- - 75,-50,25, -5,0,-110, 0,0,0, // forearm/legs/- - 0,0,0, -5,10,-5, 0,0,0, // hands/feet/- - // - 130,-100,220, 55,5,5, 0,0,0, // arms/thighs/- - 150,5,0, -5,0,-15, 0,0,0, // forearm/legs/- - 0,0,0, -5,5,-30, 0,0,0, // hands/feet/- -#endif -#if 0 - 130,-70,200, 55,5,5, 0,0,0, // arms/thighs/- - 115,-125,0, -5,0,-15, 0,0,0, // forearm/legs/- - 0,0,0, -5,5,-30, 0,0,0, // hands/feet/- - // - 130,-95,115, 5,0,0, 0,0,0, // arms/thighs/- - 75,-50,25, -5,0,-15, 0,0,0, // forearm/legs/- - 0,0,0, -5,30,-20, 0,0,0, // hands/feet/- - // - 130,-100,220, 10,20,55, 0,0,0, // arms/thighs/- - 150,5,0, -5,0,-110, 0,0,0, // forearm/legs/- - 0,0,0, -5,10,-5, 0,0,0, // hands/feet/- -#endif - }; - - int member_spec[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, // shooting: - 65,5,-20, 10,0,40, 0,0,0, // s0: arms/thighs/- - -50,-30,50, 0,0,-70, 0,0,0, // s0: forearm/legs/- - 0,50,0, -10,0,35, 0,0,0, // s0: hands/feet/- - // takes weapon: - 160,135,-20,10,0,5, 0,0,0, // s1: arms/thighs/- - 10,-60,40, 0,0,-10, 0,0,0, // s1: forearm/legs/- - 0,-5,-25, -10,5,5, 0,0,0, // s1: hands/feet/- - // carries earth: - 25,40,-40, 10,0,60, 0,0,0, // s2: arms/thighs/- - 0,-45,0, 0,0,-120, 0,0,0, // s2: forearm/legs/- - 0,15,5, -10,0,70, 0,0,0, // s2: hands/feet/- - // carries in front: - 25,20,5, 10,0,55, 0,0,0, // s3: arms/thighs/- - -15,-30,10, 0,0,-110, 0,0,0, // s3: forearm/legs/- - 0,0,0, -10,0,65, 0,0,0, // s3: hands/feet/- - // carries vertically: - -30,15,-5, 10,0,15, 0,0,0, // s4: arms/thighs/- - 0,-15,15, 0,0,-30, 0,0,0, // s4: forearm/legs/- - 35,0,-15, -10,0,25, 0,0,0, // s4: hands/feet/- - // rises: - 15,50,-50, 10,0,5, 0,0,0, // s5: arms/thighs/- - 45,-70,10, 0,0,-10, 0,0,0, // s5: forearm/legs/- - -10,25,0, -10,5,5, 0,0,0, // s5: hands/feet/- - // wins: - 90,90,-30, 20,0,5, 0,0,0, // s6: arms/thighs/- - 0,-90,0, -10,0,-10, 0,0,0, // s6: forearm/legs/- - 0,25,0, -10,5,5, 0,0,0, // s6: hands/feet/- - // lose: - -70,45,35, 10,0,40, 0,0,0, // s7: arms/thighs/- - 15,-95,-5, 0,0,-70, 0,0,0, // s7: forearm/legs/- - 0,0,0, -10,0,35, 0,0,0, // s7: hands/feet/- - // shooting death (falls): - 90,90,-50, 10,0,5, 0,0,0, // s8: arms/thighs/- - 0,-20,0, 0,0,-10, 0,0,0, // s8: forearm/legs/- - 0,0,0, -10,5,5, 0,0,0, // s8: hands/feet/- - // shooting death (knees): - 110,105,-5, 10,0,25, 0,0,0, // s9: arms/thighs/- - 0,-40,20, 0,0,-120, 0,0,0, // s9: forearm/legs/- - 0,0,0, -10,5,5, 0,0,0, // s9: hands/feet/- - // shooting death (knees): - 110,120,-25, 10,0,25, 0,0,0, // s10: arms/thighs/- - 0,-40,20, 0,0,-120, 0,0,0, // s10: forearm/legs/- - 0,0,0, -10,5,5, 0,0,0, // s10: hands/feet/- - // shooting death (face down): - 110,100,-25, 25,0,10, 0,0,0, // s11: arms/thighs/- - 0,-40,20, 0,0,-25, 0,0,0, // s11: forearm/legs/- - 0,0,0, -10,5,5, 0,0,0, // s11: hands/feet/- - // shooting death (face down): - 110,100,-25, 25,0,10, 0,0,0, // s12: arms/thighs/- - 0,-40,20, 0,0,-25, 0,0,0, // s12: forearm/legs/- - 0,0,0, -10,5,5, 0,0,0, // s12: hands/feet/- - // drowned: - 110,100,-25, 25,0,10, 0,0,0, // s13: arms/thighs/- - 0,-40,20, 0,0,-25, 0,0,0, // s13: forearm/legs/- - 0,0,0, -10,5,5, 0,0,0, // s13: hands/feet/- - // puts / removes flag: - 85,45,-50, 10,0,60, 0,0,0, // s14: arms/thighs/- - -60,15,65, 0,0,-105, 0,0,0, // s14: forearm/legs/- - 0,10,0, -10,0,60, 0,0,0, // s14: hands/feet/- - // reads SatCom: - 70,30,-20, 10,0,5, 0,0,0, // s15: arms/thighs/- - 115,-65,60, 0,0,-10, 0,0,0, // s15: forearm/legs/- - 0,20,0, -10,5,5, 0,0,0, // s15: hands/feet/- - }; - - m_physics->SetType(TYPE_FLYING); - - character = m_object->RetCharacter(); - character->wheelFront = 4.0f; - character->wheelBack = 4.0f; - character->wheelLeft = 4.0f; - character->wheelRight = 4.0f; - character->height = 3.5f; - - if ( type == OBJECT_HUMAN ) - { - m_physics->SetLinMotionX(MO_ADVSPEED, 50.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 35.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 20.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 70.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 40.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); - m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f); - m_physics->SetLinMotionY(MO_RECSPEED, 60.0f); - m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f); - m_physics->SetLinMotionY(MO_RECACCEL, 50.0f); - m_physics->SetLinMotionY(MO_STOACCEL, 50.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 0.8f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 0.8f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 6.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 6.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 4.0f); - } - else - { - m_physics->SetLinMotionX(MO_ADVSPEED, 40.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 15.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 8.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 8.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 8.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 50.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 50.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); - m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f); - m_physics->SetLinMotionY(MO_RECSPEED, 60.0f); - m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f); - m_physics->SetLinMotionY(MO_RECACCEL, 50.0f); - m_physics->SetLinMotionY(MO_STOACCEL, 50.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 0.6f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 0.6f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 4.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 4.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 3.0f); - } - - for ( i=0 ; i<3*3*3*3 ; i++ ) - { - m_armAngles[3*3*3*3*MH_MARCH+i] = member_march[i]; - } - for ( i=0 ; i<3*3*3*3 ; i++ ) - { - m_armAngles[3*3*3*3*MH_MARCHTAKE+i] = member_march_take[i]; - } - for ( i=0 ; i<3*3*3*3 ; i++ ) - { - m_armAngles[3*3*3*3*MH_TURN+i] = member_turn[i]; - } - for ( i=0 ; i<3*3*3*3 ; i++ ) - { - m_armAngles[3*3*3*3*MH_STOP+i] = member_stop[i]; - } - for ( i=0 ; i<3*3*3*3 ; i++ ) - { - m_armAngles[3*3*3*3*MH_FLY+i] = member_fly[i]; - } - for ( i=0 ; i<3*3*3*3 ; i++ ) - { - m_armAngles[3*3*3*3*MH_SWIM+i] = member_swim[i]; - } - for ( i=0 ; i<3*3*3*16 ; i++ ) - { - m_armAngles[3*3*3*3*MH_SPEC+i] = member_spec[i]; - } -} - - -// Management of an event. - -BOOL CMotionHuman::EventProcess(const Event &event) -{ - CMotion::EventProcess(event); - - if ( event.event == EVENT_FRAME ) - { - return EventFrame(event); - } - - if ( event.event == EVENT_KEYDOWN ) - { -#if ADJUST_ANGLE - int i; - - if ( event.param == 'A' ) m_armTimeIndex++; - if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0; - - if ( event.param == 'Q' ) m_armPartIndex++; - if ( m_armPartIndex >= 3 ) m_armPartIndex = 0; - - if ( event.param == 'W' ) m_armMemberIndex++; - if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0; - - i = m_armMemberIndex*3; - i += m_armPartIndex*3*3; - i += m_armTimeIndex*3*3*3; - i += ADJUST_ACTION; - - if ( event.param == 'E' ) m_armAngles[i+0] += 5; - if ( event.param == 'D' ) m_armAngles[i+0] -= 5; - if ( event.param == 'R' ) m_armAngles[i+1] += 5; - if ( event.param == 'F' ) m_armAngles[i+1] -= 5; - if ( event.param == 'T' ) m_armAngles[i+2] += 5; - if ( event.param == 'G' ) m_armAngles[i+2] -= 5; - - if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop; - - if ( event.param == 'Y' ) - { - char s[100]; - sprintf(s, "index dans table = %d %d %d\n", i, i+9, i+18); - OutputDebugString(s); - } -#endif - } - - return TRUE; -} - -// Calculates a value (radians) proportional between a and b (degrees). - -inline float Propf(float a, float b, float p) -{ - float aa, bb; - - aa = a*PI/180.0f; - bb = b*PI/180.0f; - - return aa+p*(bb-aa); -} - -// Management of an event. - -BOOL CMotionHuman::EventFrame(const Event &event) -{ - D3DMATRIX* mat; - D3DVECTOR dir, actual, pos, speed, pf; - FPOINT center, dim, p2; - float s, a, prog, rTime[2], lTime[2], time, rot, hr, hl; - float al, ar, af; - float tSt[9], tNd[9]; - float aa, bb, shield, deadFactor, level; - int i, ii, st, nd, action, legAction, armAction; - BOOL bOnBoard, bSwim, bStop; - - if ( m_engine->RetPause() ) - { - if ( m_actionType == MHS_SATCOM ) - { - m_progress += event.rTime*m_actionTime; - } - else - { - return TRUE; - } - } - - bOnBoard = FALSE; - if ( m_object->RetSelect() && - m_camera->RetType() == CAMERA_ONBOARD ) - { - bOnBoard = TRUE; - } - - if ( m_bDisplayPerso && m_main->RetGamerOnlyHead() ) - { - m_time += event.rTime; - m_object->SetLinVibration(D3DVECTOR(0.0f, -0.55f, 0.0f)); - m_object->SetCirVibration(D3DVECTOR(0.0f, m_main->RetPersoAngle(), 0.0f)); - return TRUE; - } - if ( m_bDisplayPerso ) - { - m_object->SetCirVibration(D3DVECTOR(0.0f, m_main->RetPersoAngle()+0.2f, 0.0f)); - } - - shield = m_object->RetShield(); - shield += event.rTime*(1.0f/120.0f); // regeneration in 120 seconds - if ( shield > 1.0f ) shield = 1.0f; - m_object->SetShield(shield); - - bSwim = m_physics->RetSwim(); - -#if 0 - rot = m_physics->RetCirMotionY(MO_MOTSPEED); - s = m_physics->RetLinMotionX(MO_REASPEED)*2.0f; - a = m_physics->RetLinMotionX(MO_TERSPEED); - if ( a < 0.0f ) // rises? - { - if ( s > 0.0f && s < 20.0f ) s = 20.0f; // moving slowly? -//? if ( s < 0.0f && s > -10.0f ) s = 0.0f; // falling slowly? - } - if ( a > 0.0f && !bSwim ) // falls? - { - if ( s > 0.0f && s < 10.0f ) s = 0.0f; // moving slowly? -//? if ( s < 0.0f && s > -5.0f ) s = -5.0f; // falling slowly? - } - a = Abs(rot*12.0f); - - if ( !m_physics->RetLand() && !bSwim ) // in flight? - { - s = 0.0f; - } - - if ( m_object->RetFret() != 0 ) // carries something? - { - s *= 1.3f; - } -#else - rot = m_physics->RetCirMotionY(MO_MOTSPEED); -#if 0 - s = m_physics->RetLinMotionX(MO_REASPEED); -#else - a = m_physics->RetLinMotionX(MO_REASPEED); - s = m_physics->RetLinMotionX(MO_MOTSPEED)*0.2f; - if ( Abs(a) > Abs(s) ) s = a; // the highest value -#endif - a = m_physics->RetLinMotionX(MO_TERSPEED); - if ( a < 0.0f ) // rises? - { - a += m_physics->RetLinMotionX(MO_TERSLIDE); - if ( a < 0.0f ) s -= a; - } - if ( a > 0.0f ) // falls? - { - a -= m_physics->RetLinMotionX(MO_TERSLIDE); - if ( a > 0.0f ) s -= a; - } - s *= 2.0f; - a = Abs(rot*12.0f); - - if ( !m_physics->RetLand() && !bSwim ) // in flight? - { - s = 0.0f; - } - - if ( m_object->RetFret() != 0 ) // carries something? - { - s *= 1.3f; - } -#endif - - m_time += event.rTime; - m_armTimeAbs += event.rTime; - m_armTimeAction += event.rTime; - m_armMember += s*event.rTime*0.05f; - - // Fatigue management when short. - if ( m_physics->RetLand() && s != 0.0f ) // on the ground? - { - m_tired += event.rTime*0.1f; - if ( m_tired > 1.0f ) - { - m_tired = 1.0f; - if ( m_lastSoundHhh > 3.0f ) m_lastSoundHhh = 0.5f; - } - } - else - { - m_tired -= event.rTime*0.2f; - if ( m_tired < 0.0f ) m_tired = 0.0f; - } - - if ( bSwim ) // swims? - { - s += Abs(m_physics->RetLinMotionY(MO_REASPEED)*2.0f); - a *= 2.0f; - m_armTimeSwim += Min(Max(s,a,3.0f),15.0f)*event.rTime*0.05f; - } - - bStop = ( s == 0.0f ); // stop? - prog = 0.0f; - - if ( m_physics->RetLand() ) // on the ground? - { - if ( s == 0.0f && a == 0.0f ) - { - action = MH_STOP; // stop - rTime[0] = rTime[1] = m_armTimeAbs*0.21f; - lTime[0] = lTime[1] = m_armTimeAbs*0.25f; - m_armMember = START_TIME; - } - else - { - if ( s == 0.0f ) - { - action = MH_TURN; // turn - rTime[0] = rTime[1] = m_armTimeAbs; - lTime[0] = lTime[1] = m_armTimeAbs+0.5f; - if ( rot < 0.0f ) - { - rTime[1] = 1000000.0f-rTime[1]; - } - else - { - lTime[1] = 1000000.0f-lTime[1]; - } - m_armMember = START_TIME; - } - else - { - action = MH_MARCH; // walking - if ( m_object->RetFret() != 0 ) action = MH_MARCHTAKE; // take walking - rTime[0] = rTime[1] = m_armMember; - lTime[0] = lTime[1] = m_armMember+0.5f; - } - } - if ( bSwim ) - { - rTime[0] *= 0.6f; - rTime[1] *= 0.6f; - lTime[0] = rTime[0]+0.5f; - lTime[1] = rTime[1]+0.5f; - } - } - else - { - if ( bSwim ) - { - action = MH_SWIM; // swim - rTime[0] = rTime[1] = m_armTimeSwim; - lTime[0] = lTime[1] = m_armTimeSwim; - } - else - { - action = MH_FLY; // fly - rTime[0] = rTime[1] = m_armTimeAbs*0.30f; - lTime[0] = lTime[1] = m_armTimeAbs*0.31f; - m_armMember = START_TIME; - } - } - - if ( action != m_armLastAction ) - { - m_armLastAction = action; - m_armTimeAction = 0.0f; - } - - armAction = action; - legAction = action; - - if ( m_object->RetFret() != 0 ) // carries something? - { - armAction = MH_MARCHTAKE; // take walking - } - - if ( m_physics->RetLand() ) // on the ground? - { - a = m_object->RetAngleY(0); - pos = m_object->RetPosition(0); - m_terrain->MoveOnFloor(pos); - - pf.x = pos.x+cosf(a+PI*1.5f)*0.7f; - pf.y = pos.y; - pf.z = pos.z-sinf(a+PI*1.5f)*0.7f; - m_terrain->MoveOnFloor(pf); - al = atanf((pf.y-pos.y)/0.7f); // angle for left leg - - pf = pos; - pf.x = pos.x+cosf(a+PI*0.5f)*0.7f; - pf.y = pos.y; - pf.z = pos.z-sinf(a+PI*0.5f)*0.7f; - m_terrain->MoveOnFloor(pf); - ar = atanf((pf.y-pos.y)/0.7f); // angle to right leg - - pf.x = pos.x+cosf(a+PI)*0.3f; - pf.y = pos.y; - pf.z = pos.z-sinf(a+PI)*0.3f; - m_terrain->MoveOnFloor(pf); - af = atanf((pf.y-pos.y)/0.3f); // angle for feet - } - else - { - al = 0.0f; - ar = 0.0f; - af = 0.0f; - } - - for ( i=0 ; i<4 ; i++ ) // 4 members - { - if ( m_bArmStop ) // focus? - { - st = ADJUST_ACTION + (i%2)*3; - nd = st; - time = 100.0f; - m_armTimeAction = 0.0f; - } - else if ( m_actionType != -1 ) // special action in progress? - { - st = 3*3*3*3*MH_SPEC + 3*3*3*m_actionType + (i%2)*3; - nd = st; - time = event.rTime*m_actionTime; - m_armTimeAction = 0.0f; - } - else - { - if ( i < 2 ) prog = Mod(rTime[i%2], 1.0f); - else prog = Mod(lTime[i%2], 1.0f); - if ( prog < 0.25f ) // t0..t1 ? - { - prog = prog/0.25f; // 0..1 - st = 0; // index start - nd = 1; // index end - } - else if ( prog < 0.75f ) // t1..t2 ? - { - prog = (prog-0.25f)/0.50f; // 0..1 - st = 1; // index start - nd = 2; // index end - } - else // t2..t0 ? - { - prog = (prog-0.75f)/0.25f; // 0..1 - st = 2; // index start - nd = 0; // index end - } - if ( i%2 == 0 ) // arm? - { - st = 3*3*3*3*armAction + st*3*3*3 + (i%2)*3; - nd = 3*3*3*3*armAction + nd*3*3*3 + (i%2)*3; - } - else // leg? - { - st = 3*3*3*3*legAction + st*3*3*3 + (i%2)*3; - nd = 3*3*3*3*legAction + nd*3*3*3 + (i%2)*3; - } - - // Less soft ... - time = event.rTime*(5.0f+Min(m_armTimeAction*50.0f, 100.0f)); - if ( bSwim ) time *= 0.25f; - } - - tSt[0] = m_armAngles[st+ 0]; // x - tSt[1] = m_armAngles[st+ 1]; // y - tSt[2] = m_armAngles[st+ 2]; // z - tSt[3] = m_armAngles[st+ 9]; // x - tSt[4] = m_armAngles[st+10]; // y - tSt[5] = m_armAngles[st+11]; // z - tSt[6] = m_armAngles[st+18]; // x - tSt[7] = m_armAngles[st+19]; // y - tSt[8] = m_armAngles[st+20]; // z - - tNd[0] = m_armAngles[nd+ 0]; // x - tNd[1] = m_armAngles[nd+ 1]; // y - tNd[2] = m_armAngles[nd+ 2]; // z - tNd[3] = m_armAngles[nd+ 9]; // x - tNd[4] = m_armAngles[nd+10]; // y - tNd[5] = m_armAngles[nd+11]; // z - tNd[6] = m_armAngles[nd+18]; // x - tNd[7] = m_armAngles[nd+19]; // y - tNd[8] = m_armAngles[nd+20]; // z - - aa = 0.5f; - if ( i%2 == 0 ) // arm? - { - if ( m_object->RetFret() == 0 ) // does nothing? - { - aa = 2.0f; // moves a lot - } - else - { - aa = 0.0f; // immobile - } - } - - if ( i < 2 ) // left? - { - bb = sinf(m_time*1.1f)*aa; tSt[0] += bb; tNd[0] += bb; - bb = sinf(m_time*1.0f)*aa; tSt[1] += bb; tNd[1] += bb; - bb = sinf(m_time*1.2f)*aa; tSt[2] += bb; tNd[2] += bb; - bb = sinf(m_time*2.5f)*aa; tSt[3] += bb; tNd[3] += bb; - bb = sinf(m_time*2.0f)*aa; tSt[4] += bb; tNd[4] += bb; - bb = sinf(m_time*3.8f)*aa; tSt[5] += bb; tNd[5] += bb; - bb = sinf(m_time*3.0f)*aa; tSt[6] += bb; tNd[6] += bb; - bb = sinf(m_time*2.3f)*aa; tSt[7] += bb; tNd[7] += bb; - bb = sinf(m_time*4.0f)*aa; tSt[8] += bb; tNd[8] += bb; - } - else // right? - { - bb = sinf(m_time*0.9f)*aa; tSt[0] += bb; tNd[0] += bb; - bb = sinf(m_time*1.2f)*aa; tSt[1] += bb; tNd[1] += bb; - bb = sinf(m_time*1.4f)*aa; tSt[2] += bb; tNd[2] += bb; - bb = sinf(m_time*2.9f)*aa; tSt[3] += bb; tNd[3] += bb; - bb = sinf(m_time*1.4f)*aa; tSt[4] += bb; tNd[4] += bb; - bb = sinf(m_time*3.1f)*aa; tSt[5] += bb; tNd[5] += bb; - bb = sinf(m_time*3.7f)*aa; tSt[6] += bb; tNd[6] += bb; - bb = sinf(m_time*2.0f)*aa; tSt[7] += bb; tNd[7] += bb; - bb = sinf(m_time*3.1f)*aa; tSt[8] += bb; tNd[8] += bb; - } - -#if 1 - if ( i%2 == 1 && // leg? - m_actionType == -1 ) // no special action? - { - if ( i == 1 ) // right leg? - { - ii = 5; - a = ar*0.25f; - } - else - { - ii = 11; - a = al*0.25f; - } - if ( a < -0.2f ) a = -0.2f; - if ( a > 0.2f ) a = 0.2f; - - pos = m_object->RetPosition(ii+0); - pos.y = 0.0f+a; - m_object->SetPosition(ii+0, pos); // lengthens / shortcuts thigh - - pos = m_object->RetPosition(ii+1); - pos.y = -1.5f+a; - m_object->SetPosition(ii+1, pos); // lengthens / shortcuts leg - - pos = m_object->RetPosition(ii+2); - pos.y = -1.5f+a; - m_object->SetPosition(ii+2, pos); // lengthens / shortcuts foot - - if ( i == 1 ) // right leg? - { - aa = (ar*180.0f/PI*0.5f); - } - else // left leg? - { - aa = (al*180.0f/PI*0.5f); - } - tSt[6] += aa; - tNd[6] += aa; // increases the angle X of the foot - - if ( i == 1 ) // right leg? - { - aa = (ar*180.0f/PI); - } - else // left leg? - { - aa = (al*180.0f/PI); - } - if ( aa < 0.0f ) aa = 0.0f; - if ( aa > 30.0f ) aa = 30.0f; - - tSt[2] += aa; - tNd[2] += aa; // increases the angle Z of the thigh - tSt[5] -= aa*2; - tNd[5] -= aa*2; // increases the angle Z of the leg - tSt[8] += aa; - tNd[8] += aa; // increases the angle Z of the foot - - aa = (af*180.0f/PI)*0.7f; - if ( aa < -30.0f ) aa = -30.0f; - if ( aa > 30.0f ) aa = 30.0f; - - tSt[8] -= aa; - tNd[8] -= aa; // increases the angle Z of the foot - } -#endif - - if ( m_actionType == MHS_DEADw ) // drowned? - { - if ( m_progress < 0.5f ) - { - deadFactor = m_progress/0.5f; - } - else - { - deadFactor = 1.0f-(m_progress-0.5f)/0.5f; - } - if ( deadFactor < 0.0f ) deadFactor = 0.0f; - if ( deadFactor > 1.0f ) deadFactor = 1.0f; - - for ( ii=0 ; ii<9 ; ii++ ) - { - tSt[ii] += Rand()*20.0f*deadFactor; - tNd[ii] = tSt[ii]; - } - time = 100.0f; - } - - if ( i < 2 ) // right member (0..1) ? - { - m_object->SetAngleX(2+3*i+0, Smooth(m_object->RetAngleX(2+3*i+0), Propf(tSt[0], tNd[0], prog), time)); - m_object->SetAngleY(2+3*i+0, Smooth(m_object->RetAngleY(2+3*i+0), Propf(tSt[1], tNd[1], prog), time)); - m_object->SetAngleZ(2+3*i+0, Smooth(m_object->RetAngleZ(2+3*i+0), Propf(tSt[2], tNd[2], prog), time)); - m_object->SetAngleX(2+3*i+1, Smooth(m_object->RetAngleX(2+3*i+1), Propf(tSt[3], tNd[3], prog), time)); - m_object->SetAngleY(2+3*i+1, Smooth(m_object->RetAngleY(2+3*i+1), Propf(tSt[4], tNd[4], prog), time)); - m_object->SetAngleZ(2+3*i+1, Smooth(m_object->RetAngleZ(2+3*i+1), Propf(tSt[5], tNd[5], prog), time)); - m_object->SetAngleX(2+3*i+2, Smooth(m_object->RetAngleX(2+3*i+2), Propf(tSt[6], tNd[6], prog), time)); - m_object->SetAngleY(2+3*i+2, Smooth(m_object->RetAngleY(2+3*i+2), Propf(tSt[7], tNd[7], prog), time)); - m_object->SetAngleZ(2+3*i+2, Smooth(m_object->RetAngleZ(2+3*i+2), Propf(tSt[8], tNd[8], prog), time)); - } - else // left member (2..3) ? - { - m_object->SetAngleX(2+3*i+0, Smooth(m_object->RetAngleX(2+3*i+0), Propf(-tSt[0], -tNd[0], prog), time)); - m_object->SetAngleY(2+3*i+0, Smooth(m_object->RetAngleY(2+3*i+0), Propf(-tSt[1], -tNd[1], prog), time)); - m_object->SetAngleZ(2+3*i+0, Smooth(m_object->RetAngleZ(2+3*i+0), Propf( tSt[2], tNd[2], prog), time)); - m_object->SetAngleX(2+3*i+1, Smooth(m_object->RetAngleX(2+3*i+1), Propf(-tSt[3], -tNd[3], prog), time)); - m_object->SetAngleY(2+3*i+1, Smooth(m_object->RetAngleY(2+3*i+1), Propf(-tSt[4], -tNd[4], prog), time)); - m_object->SetAngleZ(2+3*i+1, Smooth(m_object->RetAngleZ(2+3*i+1), Propf( tSt[5], tNd[5], prog), time)); - m_object->SetAngleX(2+3*i+2, Smooth(m_object->RetAngleX(2+3*i+2), Propf(-tSt[6], -tNd[6], prog), time)); - m_object->SetAngleY(2+3*i+2, Smooth(m_object->RetAngleY(2+3*i+2), Propf(-tSt[7], -tNd[7], prog), time)); - m_object->SetAngleZ(2+3*i+2, Smooth(m_object->RetAngleZ(2+3*i+2), Propf( tSt[8], tNd[8], prog), time)); - } - } - -#if ADJUST_ANGLE - if ( m_object->RetSelect() ) - { - char s[100]; - sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex); - m_engine->SetInfoText(4, s); - } -#endif - - // calculates the height lowering as a function - // of the position of the legs. - hr = 1.5f*(1.0f-cosf(m_object->RetAngleZ(5))) + - 1.5f*(1.0f-cosf(m_object->RetAngleZ(5)+m_object->RetAngleZ(6))); - a = 1.0f*sinf(m_object->RetAngleZ(5)+m_object->RetAngleZ(6)+m_object->RetAngleZ(7)); - if ( a < 0.0f ) hr += a; - - hl = 1.5f*(1.0f-cosf(m_object->RetAngleZ(11))) + - 1.5f*(1.0f-cosf(m_object->RetAngleZ(11)+m_object->RetAngleZ(12))); - a = 1.0f*sinf(m_object->RetAngleZ(11)+m_object->RetAngleZ(12)+m_object->RetAngleZ(13)); - if ( a < 0.0f ) hl += a; - - hr = Min(hr, hl); - - if ( m_actionType == MHS_FIRE ) // shooting? - { - time = event.rTime*m_actionTime; - - dir.x = (Rand()-0.5f)/8.0f; - dir.z = (Rand()-0.5f)/8.0f; - dir.y = -0.5f; // slightly lower - actual = m_object->RetLinVibration(); - dir.x = Smooth(actual.x, dir.x, time); -//? dir.y = Smooth(actual.y, dir.y, time); - dir.y = -hr; - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetLinVibration(dir); - - dir.x = 0.0f; - dir.y = (Rand()-0.5f)/3.0f; - dir.z = -0.1f; // slightly leaning forward - actual = m_object->RetInclinaison(); - dir.x = Smooth(actual.x, dir.x, time); - dir.y = Smooth(actual.y, dir.y, time); - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetInclinaison(dir); - } - else if ( m_actionType == MHS_TAKE || // carrying? - m_actionType == MHS_TAKEOTHER ) // flag? - { - time = event.rTime*m_actionTime*2.0f; - - dir.x = 0.0f; - dir.z = 0.0f; - dir.y = -1.5f; // slightly lower - actual = m_object->RetLinVibration(); - dir.x = Smooth(actual.x, dir.x, time); -//? dir.y = Smooth(actual.y, dir.y, time); - dir.y = -hr; - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetLinVibration(dir); - - dir.x = 0.0f; - dir.y = 0.0f; - dir.z = -0.2f; - actual = m_object->RetInclinaison(); - dir.x = Smooth(actual.x, dir.x, time); - dir.y = Smooth(actual.y, dir.y, time); - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetInclinaison(dir); - } - else if ( m_actionType == MHS_TAKEHIGH ) // carrying? - { - time = event.rTime*m_actionTime*2.0f; - - dir.x = 0.4f; // slightly forward - dir.z = 0.0f; - dir.y = 0.0f; - actual = m_object->RetLinVibration(); - dir.x = Smooth(actual.x, dir.x, time); -//? dir.y = Smooth(actual.y, dir.y, time); - dir.y = -hr; - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetLinVibration(dir); - - dir.x = 0.0f; - dir.y = 0.0f; - dir.z = -0.2f; - actual = m_object->RetInclinaison(); - dir.x = Smooth(actual.x, dir.x, time); - dir.y = Smooth(actual.y, dir.y, time); - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetInclinaison(dir); - } - else if ( m_actionType == MHS_FLAG ) // flag? - { - time = event.rTime*m_actionTime*2.0f; - - dir.x = 0.0f; - dir.z = 0.0f; - dir.y = -2.0f; // slightly lower - actual = m_object->RetLinVibration(); - dir.x = Smooth(actual.x, dir.x, time); -//? dir.y = Smooth(actual.y, dir.y, time); - dir.y = -hr; - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetLinVibration(dir); - - dir.x = 0.0f; - dir.y = 0.0f; - dir.z = -0.4f; - actual = m_object->RetInclinaison(); - dir.x = Smooth(actual.x, dir.x, time); - dir.y = Smooth(actual.y, dir.y, time); - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetInclinaison(dir); - } - else if ( m_actionType == MHS_DEADg ) // shooting death (falls)? - { - if ( m_physics->RetLand() ) // on the ground? - { - SetAction(MHS_DEADg1, 0.5f); // knees - } - } - else if ( m_actionType == MHS_DEADg1 ) // shooting death (knees)? - { - prog = m_progress; - if ( prog >= 1.0f ) - { - prog = 1.0f; - - for ( i=0 ; i<10 ; i++ ) - { - pos = m_object->RetPosition(0); - pos.x += (Rand()-0.5f)*4.0f; - pos.z += (Rand()-0.5f)*4.0f; - m_terrain->MoveOnFloor(pos); - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 1.2f+Rand()*1.2f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.0f); - } - m_sound->Play(SOUND_BOUMv, m_object->RetPosition(0)); - - SetAction(MHS_DEADg2, 1.0f); // expects knees - } - - time = 100.0f; - - dir.x = 0.0f; - dir.z = 0.0f; - dir.y = -1.5f*prog; - actual = m_object->RetLinVibration(); - dir.x = Smooth(actual.x, dir.x, time); - dir.y = Smooth(actual.y, dir.y, time); - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetLinVibration(dir); - - dir.x = 0.0f; - dir.y = 0.0f; - dir.z = -(20.0f*PI/180.0f)*prog; - actual = m_object->RetInclinaison(); - dir.x = Smooth(actual.x, dir.x, time); - dir.y = Smooth(actual.y, dir.y, time); - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetInclinaison(dir); - } - else if ( m_actionType == MHS_DEADg2 ) // shooting death (knees)? - { - if ( m_progress >= 1.0f ) - { - SetAction(MHS_DEADg3, 1.0f); // face down - } - - time = 100.0f; - - dir.x = 0.0f; - dir.z = 0.0f; - dir.y = -1.5f; - actual = m_object->RetLinVibration(); - dir.x = Smooth(actual.x, dir.x, time); - dir.y = Smooth(actual.y, dir.y, time); - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetLinVibration(dir); - - dir.x = 0.0f; - dir.y = 0.0f; - dir.z = -(20.0f*PI/180.0f); - actual = m_object->RetInclinaison(); - dir.x = Smooth(actual.x, dir.x, time); - dir.y = Smooth(actual.y, dir.y, time); - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetInclinaison(dir); - } - else if ( m_actionType == MHS_DEADg3 ) // shooting death (face down)? - { - prog = m_progress; - if ( prog >= 1.0f ) - { - prog = 1.0f; - - for ( i=0 ; i<20 ; i++ ) - { - pos = m_object->RetPosition(0); - pos.x += (Rand()-0.5f)*8.0f; - pos.z += (Rand()-0.5f)*8.0f; - m_terrain->MoveOnFloor(pos); - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 2.0f+Rand()*1.5f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.0f); - } - m_sound->Play(SOUND_BOUMv, m_object->RetPosition(0)); - - SetAction(MHS_DEADg4, 3.0f); // expects face down - } - - time = 100.0f; - prog = powf(prog, 3.0f); - - dir.y = -(1.5f+1.5f*prog); - dir.x = 0.0f; - dir.z = 0.0f; - actual = m_object->RetLinVibration(); - dir.x = Smooth(actual.x, dir.x, time); - dir.y = Smooth(actual.y, dir.y, time); - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetLinVibration(dir); - - dir.z = -((20.0f*PI/180.0f)+(70.0f*PI/180.0f)*prog); - dir.x = 0.0f; - dir.y = 0.0f; - actual = m_object->RetInclinaison(); - dir.x = Smooth(actual.x, dir.x, time); - dir.y = Smooth(actual.y, dir.y, time); - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetInclinaison(dir); - } - else if ( m_actionType == MHS_DEADg4 ) // shooting death (face down)? - { - if ( m_progress >= 1.0f ) - { - m_object->SetEnable(FALSE); - } - - time = 100.0f; - - dir.y = -(1.5f+1.5f); - dir.x = 0.0f; - dir.z = 0.0f; - actual = m_object->RetLinVibration(); - dir.x = Smooth(actual.x, dir.x, time); - dir.y = Smooth(actual.y, dir.y, time); - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetLinVibration(dir); - - dir.z = -((20.0f*PI/180.0f)+(70.0f*PI/180.0f)); - dir.x = 0.0f; - dir.y = 0.0f; - actual = m_object->RetInclinaison(); - dir.x = Smooth(actual.x, dir.x, time); - dir.y = Smooth(actual.y, dir.y, time); - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetInclinaison(dir); - } - else if ( m_actionType == MHS_DEADw ) // drowned? - { - pos = m_object->RetPosition(0); - level = m_water->RetLevel()-0.5f; - if ( pos.y < level ) - { - pos.y += 4.0f*event.rTime; // back to the surface - if ( pos.y > level ) pos.y = level; - m_object->SetPosition(0, pos); - } - if ( pos.y > level ) - { - pos.y -= 10.0f*event.rTime; // down quickly - if ( pos.y < level ) pos.y = level; - m_object->SetPosition(0, pos); - } - - prog = m_progress; - if ( prog >= 1.0f ) - { - prog = 1.0f; - if ( pos.y >= level ) m_object->SetEnable(FALSE); - } - - prog *= 2.0f; - if ( prog > 1.0f ) prog = 1.0f; - - time = 100.0f; - - dir.z = -(90.0f*PI/180.0f)*prog; - dir.x = Rand()*0.3f*deadFactor; - dir.y = Rand()*0.3f*deadFactor; - actual = m_object->RetInclinaison(); - dir.x = Smooth(actual.x, dir.x, time); - dir.y = Smooth(actual.y, dir.y, time); - dir.z = Smooth(actual.z, dir.z, time); - m_object->SetInclinaison(dir); - - m_object->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); - } - else if ( m_actionType == MHS_LOST ) // lost? - { - time = m_time; - if ( time < 10.0f ) time *= time/10.0f; // starts slowly - - dir.x = time*2.0f; - dir.y = sinf(m_time*0.8f)*0.8f; - dir.z = sinf(m_time*0.6f)*0.5f; - m_object->SetInclinaison(dir); - SetInclinaison(dir); - -//? dir.x = -(sinf(time*0.05f+PI*1.5f)+1.0f)*100.0f; - // original code: Min(time/30.0f) (?) changed to time/30.0f - dir.x = -(powf(time/30.0f, 4.0f))*1000.0f; // from the distance - dir.y = 0.0f; - dir.z = 0.0f; - m_object->SetLinVibration(dir); - SetLinVibration(dir); - - mat = m_object->RetWorldMatrix(0); - pos = D3DVECTOR(0.5f, 3.7f, 0.0f); - pos.x += (Rand()-0.5f)*1.0f; - pos.y += (Rand()-0.5f)*1.0f; - pos.z += (Rand()-0.5f)*1.0f; - pos = Transform(*mat, pos); - speed.x = (Rand()-0.5f)*0.5f; - speed.y = (Rand()-0.5f)*0.5f; - speed.z = (Rand()-0.5f)*0.5f; - dim.x = 0.5f+Rand()*0.5f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTILENS1, 5.0f, 0.0f, 0.0f); - } - else if ( m_actionType == MHS_SATCOM ) // look at the SatCom? - { - SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); - SetLinVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); - SetInclinaison(D3DVECTOR(0.0f, 0.0f, 0.0f)); - } - else - { - if ( m_physics->RetLand() ) // on the ground? - { - time = event.rTime*8.0f; - if ( bSwim ) time *= 0.25f; - - if ( action == MH_MARCH ) // walking? - { - dir.x = sinf(Mod(rTime[0]+0.5f, 1.0f)*PI*2.0f)*0.10f; - dir.y = sinf(Mod(rTime[0]+0.6f, 1.0f)*PI*2.0f)*0.20f; - s = m_physics->RetLinMotionX(MO_REASPEED)*0.03f; - } - else if ( action == MH_MARCHTAKE ) // takes walking? - { - dir.x = sinf(Mod(rTime[0]+0.5f, 1.0f)*PI*2.0f)*0.10f; - dir.y = sinf(Mod(rTime[0]+0.6f, 1.0f)*PI*2.0f)*0.15f; - s = m_physics->RetLinMotionX(MO_REASPEED)*0.02f; - } - else - { - dir.x = 0.0f; - dir.y = 0.0f; - s = m_physics->RetLinMotionX(MO_REASPEED)*0.03f; - } - - if ( s < 0.0f ) s *= 0.5f; - dir.z = -s*0.7f; - - actual = m_object->RetInclinaison(); - dir.x = Smooth(actual.x, dir.x, time); - dir.y = Smooth(actual.y, dir.y, time); - dir.z = Smooth(actual.z, dir.z, time); - if ( bOnBoard ) dir *= 0.3f; - m_object->SetInclinaison(dir); - SetInclinaison(dir); - - if ( action == MH_MARCH ) // walking? - { - p2.x = 0.0f; - p2.y = sinf(Mod(rTime[0]+0.5f, 1.0f)*PI*2.0f)*0.5f; - p2 = RotatePoint(-m_object->RetAngleY(0), p2); - dir.x = p2.x; - dir.z = p2.y; - dir.y = sinf(Mod(rTime[0]*2.0f, 1.0f)*PI*2.0f)*0.3f; - } - else if ( action == MH_MARCHTAKE ) // takes walking? - { - p2.x = 0.0f; - p2.y = sinf(Mod(rTime[0]+0.5f, 1.0f)*PI*2.0f)*0.25f; - p2 = RotatePoint(-m_object->RetAngleY(0), p2); - dir.x = p2.x; - dir.z = p2.y; - dir.y = sinf(Mod(rTime[0]*2.0f, 1.0f)*PI*2.0f)*0.05f-0.3f; - } - else - { - dir.x = 0.0f; - dir.z = 0.0f; - dir.y = 0.0f; - } - - actual = m_object->RetLinVibration(); - dir.x = Smooth(actual.x, dir.x, time); - if ( action == MH_MARCHTAKE ) // takes walking? - { - dir.y = -hr; - } - else - { - s = Min(m_armTimeAction, 1.0f); - dir.y = Smooth(actual.y, dir.y, time)*s; - dir.y += -hr*(1.0f-s); - } - dir.z = Smooth(actual.z, dir.z, time); - if ( bOnBoard ) dir *= 0.3f; - m_object->SetLinVibration(dir); - - dir.x = 0.0f; - dir.z = 0.0f; - dir.y = 0.0f; - SetCirVibration(dir); - } - } - - // Management of the head. - if ( m_actionType == MHS_TAKE || // takes? - m_actionType == MHS_FLAG ) // takes? - { - m_object->SetAngleZ(1, Smooth(m_object->RetAngleZ(1), sinf(m_armTimeAbs*1.0f)*0.2f-0.6f, event.rTime*5.0f)); - m_object->SetAngleX(1, sinf(m_armTimeAbs*1.1f)*0.1f); - m_object->SetAngleY(1, Smooth(m_object->RetAngleY(1), sinf(m_armTimeAbs*1.3f)*0.2f+rot*0.3f, event.rTime*5.0f)); - } - else if ( m_actionType == MHS_TAKEOTHER || // takes? - m_actionType == MHS_TAKEHIGH ) // takes? - { - m_object->SetAngleZ(1, Smooth(m_object->RetAngleZ(1), sinf(m_armTimeAbs*1.0f)*0.2f-0.3f, event.rTime*5.0f)); - m_object->SetAngleX(1, sinf(m_armTimeAbs*1.1f)*0.1f); - m_object->SetAngleY(1, Smooth(m_object->RetAngleY(1), sinf(m_armTimeAbs*1.3f)*0.2f+rot*0.3f, event.rTime*5.0f)); - } - else if ( m_actionType == MHS_WIN ) // win - { - float factor = 0.6f+(sinf(m_armTimeAbs*0.5f)*0.40f); - m_object->SetAngleZ(1, sinf(m_armTimeAbs*5.0f)*0.20f*factor); - m_object->SetAngleX(1, sinf(m_armTimeAbs*0.6f)*0.10f); - m_object->SetAngleY(1, sinf(m_armTimeAbs*1.5f)*0.15f); - } - else if ( m_actionType == MHS_LOST ) // lost? - { - float factor = 0.6f+(sinf(m_armTimeAbs*0.5f)*0.40f); - m_object->SetAngleZ(1, sinf(m_armTimeAbs*0.6f)*0.10f); - m_object->SetAngleX(1, sinf(m_armTimeAbs*0.7f)*0.10f); - m_object->SetAngleY(1, sinf(m_armTimeAbs*3.0f)*0.30f*factor); - } - else if ( m_object->RetDead() ) // dead? - { - } - else - { - m_object->SetAngleZ(1, Smooth(m_object->RetAngleZ(1), sinf(m_armTimeAbs*1.0f)*0.2f, event.rTime*5.0f)); - m_object->SetAngleX(1, sinf(m_armTimeAbs*1.1f)*0.1f); - m_object->SetAngleY(1, Smooth(m_object->RetAngleY(1), sinf(m_armTimeAbs*1.3f)*0.2f+rot*0.3f, event.rTime*5.0f)); - } - - if ( bOnBoard ) - { - m_object->SetAngleZ(1, 0.0f); - m_object->SetAngleX(1, 0.0f); - m_object->SetAngleY(1, 0.0f); - } - - // Steps sound effects. - if ( legAction == MH_MARCH || - legAction == MH_MARCHTAKE ) - { - Sound sound[2]; - float speed, synchro, volume[2], freq[2], hard, level; - - speed = m_physics->RetLinMotionX(MO_REASPEED); - - if ( m_object->RetFret() == 0 ) - { - if ( speed > 0.0f ) synchro = 0.21f; // synchro forward - else synchro = 0.29f; // synchro backward - } - else - { - if ( speed > 0.0f ) synchro = 0.15f; // synchro forward - else synchro = 0.35f; // synchro backward - } - time = rTime[1]+synchro; - - if ( Abs(m_lastSoundMarch-time) > 0.4f && - Mod(time, 0.5f) < 0.1f ) - { - volume[0] = 0.5f; - freq[0] = 1.0f; - if ( m_object->RetFret() != 0 ) - { -//? volume[0] *= 2.0f; - freq[0] = 0.7f; - } - volume[1] = volume[0]; - freq[1] = freq[0]; - sound[0] = SOUND_CLICK; - sound[1] = SOUND_CLICK; - - pos = m_object->RetPosition(0); - - level = m_water->RetLevel(); - if ( pos.y <= level+3.0f ) // underwater? - { - sound[0] = SOUND_STEPw; - } - else - { - hard = m_terrain->RetHardness(pos); - - if ( hard >= 0.875 ) - { - sound[0] = SOUND_STEPm; // metal - } - else - { - hard /= 0.875; - sound[0] = SOUND_STEPs; // smooth - sound[1] = SOUND_STEPh; // hard - - volume[0] *= 1.0f-hard; - volume[1] *= hard; - if ( hard < 0.5f ) - { - volume[0] *= 1.0f+hard*2.0f; - volume[1] *= 1.0f+hard*2.0f; - } - else - { - volume[0] *= 3.0f-hard*2.0f; - volume[1] *= 3.0f-hard*2.0f; - } - freq[0] *= 1.0f+hard; - freq[1] *= 0.5f+hard; - } - } - - if ( sound[0] != SOUND_CLICK ) - { - m_sound->Play(sound[0], pos, volume[0], freq[0]); - } - if ( sound[1] != SOUND_CLICK ) - { - m_sound->Play(sound[1], pos, volume[1], freq[1]); - } - m_lastSoundMarch = time; - } - } - - if ( legAction == MH_SWIM ) - { - time = rTime[0]+0.5f; - - if ( Abs(m_lastSoundMarch-time) > 0.9f && - Mod(time, 1.0f) < 0.1f ) - { - m_sound->Play(SOUND_SWIM, m_object->RetPosition(0), 0.5f); - m_lastSoundMarch = time; - } - } - - m_lastSoundHhh -= event.rTime; - if ( m_lastSoundHhh <= 0.0f && - m_object->RetSelect() && - m_object->RetOption() == 0 ) // helmet? - { - m_sound->Play(SOUND_HUMAN1, m_object->RetPosition(0), (0.5f+m_tired*0.2f)); - m_lastSoundHhh = (4.0f-m_tired*2.5f)+(4.0f-m_tired*2.5f)*Rand(); - } - - return TRUE; -} - - -// Management of the display mode when customizing the personal. - -void CMotionHuman::StartDisplayPerso() -{ - m_bDisplayPerso = TRUE; -} - -void CMotionHuman::StopDisplayPerso() -{ - m_bDisplayPerso = FALSE; -} - - diff --git a/src/motionhuman.h b/src/motionhuman.h deleted file mode 100644 index 44a0c4c..0000000 --- a/src/motionhuman.h +++ /dev/null @@ -1,102 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motionhuman.h - -#ifndef _MOTIONHUMAN_H_ -#define _MOTIONHUMAN_H_ - - -#include "motion.h" -#include "misc.h" - - -class CInstanceManager; -class CEngine; -class CLight; -class CParticule; -class CTerrain; -class CCamera; -class CBrain; -class CPhysics; -class CObject; - - -#define MH_MARCH 0 -#define MH_MARCHTAKE 1 -#define MH_TURN 2 -#define MH_STOP 3 -#define MH_FLY 4 -#define MH_SWIM 5 -#define MH_SPEC 6 - -#define MHS_FIRE 0 -#define MHS_GUN 1 -#define MHS_TAKE 2 -#define MHS_TAKEOTHER 3 -#define MHS_TAKEHIGH 4 -#define MHS_UPRIGHT 5 -#define MHS_WIN 6 -#define MHS_LOST 7 -#define MHS_DEADg 8 -#define MHS_DEADg1 9 -#define MHS_DEADg2 10 -#define MHS_DEADg3 11 -#define MHS_DEADg4 12 -#define MHS_DEADw 13 -#define MHS_FLAG 14 -#define MHS_SATCOM 15 - - -class CMotionHuman : public CMotion -{ -public: - CMotionHuman(CInstanceManager* iMan, CObject* object); - ~CMotionHuman(); - - void DeleteObject(BOOL bAll=FALSE); - BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); - BOOL EventProcess(const Event &event); - Error SetAction(int action, float time=0.2f); - - void StartDisplayPerso(); - void StopDisplayPerso(); - -protected: - void CreatePhysics(ObjectType type); - BOOL EventFrame(const Event &event); - -protected: - int m_partiReactor; - float m_armMember; - float m_armTimeAbs; - float m_armTimeAction; - float m_armTimeSwim; - short m_armAngles[3*3*3*3*7 + 3*3*3*16]; - int m_armTimeIndex; - int m_armPartIndex; - int m_armMemberIndex; - int m_armLastAction; - BOOL m_bArmStop; - float m_lastSoundMarch; - float m_lastSoundHhh; - float m_time; - float m_tired; - BOOL m_bDisplayPerso; -}; - - -#endif //_MOTIONHUMAN_H_ diff --git a/src/motionmother.cpp b/src/motionmother.cpp deleted file mode 100644 index 872ef76..0000000 --- a/src/motionmother.cpp +++ /dev/null @@ -1,543 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motionmother.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "light.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "modfile.h" -#include "sound.h" -#include "motion.h" -#include "motionmother.h" - - - -#define ADJUST_ANGLE FALSE // TRUE -> adjusts the angles of the members -#define START_TIME 1000.0f // beginning of the relative time - - - -// Object's constructor. - -CMotionMother::CMotionMother(CInstanceManager* iMan, CObject* object) - : CMotion(iMan, object) -{ - CMotion::CMotion(iMan, object); - - m_armMember = START_TIME; - m_armTimeAbs = START_TIME; - m_armTimeMarch = START_TIME; - m_armTimeAction = START_TIME; - m_armTimeIndex = 0; - m_armPartIndex = 0; - m_armMemberIndex = 0; - m_armLastAction = -1; - m_specAction = -1; - m_bArmStop = FALSE; -} - -// Object's destructor. - -CMotionMother::~CMotionMother() -{ -} - - -// Removes an object. - -void CMotionMother::DeleteObject(BOOL bAll) -{ -} - - -// Creates a vehicle traveling any lands on the ground. - -BOOL CMotionMother::Create(D3DVECTOR pos, float angle, ObjectType type, - float power) -{ - CModFile* pModFile; - int rank; - - if ( m_engine->RetRestCreate() < 2+12+6 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - m_object->SetType(type); - - // Creates main base. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object - m_object->SetObjectRank(0, rank); - - pModFile->ReadModel("objects\\mother1.mod"); - pModFile->CreateEngineObject(rank); - - m_object->SetPosition(0, pos); - m_object->SetAngleY(0, angle); - - // A vehicle must have a obligatory collision - //with a sphere of center (0, y, 0) (see GetCrashSphere). - m_object->CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 20.0f, SOUND_BOUM, 0.20f); - m_object->SetGlobalSphere(D3DVECTOR(-2.0f, 10.0f, 0.0f), 25.0f); - - // Creates the head. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\mother2.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(16.0f, 3.0f, 0.0f)); - - // Creates a right-back leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 0); - pModFile->ReadModel("objects\\mother3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2, D3DVECTOR(-5.0f, -1.0f, -12.0f)); - - // Creates a right-back foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(3, rank); - m_object->SetObjectParent(3, 2); - pModFile->ReadModel("objects\\mother4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(3, D3DVECTOR(0.0f, 0.0f, -8.5f)); - - // Creates a middle-right leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(4, rank); - m_object->SetObjectParent(4, 0); - pModFile->ReadModel("objects\\mother3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(4, D3DVECTOR(3.5f, -1.0f, -12.0f)); - - // Creates a middle-right foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(5, rank); - m_object->SetObjectParent(5, 4); - pModFile->ReadModel("objects\\mother4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(5, D3DVECTOR(0.0f, 0.0f, -8.5f)); - - // Creates a right-front leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(6, rank); - m_object->SetObjectParent(6, 0); - pModFile->ReadModel("objects\\mother3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(6, D3DVECTOR(10.0f, -1.0f, -10.0f)); - - // Creates a right-front foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(7, rank); - m_object->SetObjectParent(7, 6); - pModFile->ReadModel("objects\\mother4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(7, D3DVECTOR(0.0f, 0.0f, -8.5f)); - - // Creates a left-back leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(8, rank); - m_object->SetObjectParent(8, 0); - pModFile->ReadModel("objects\\mother3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(8, D3DVECTOR(-5.0f, -1.0f, 12.0f)); - m_object->SetAngleY(8, PI); - - // Creates a left-back foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(9, rank); - m_object->SetObjectParent(9, 8); - pModFile->ReadModel("objects\\mother4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(9, D3DVECTOR(0.0f, 0.0f, -8.5f)); - - // Creates a middle-left leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(10, rank); - m_object->SetObjectParent(10, 0); - pModFile->ReadModel("objects\\mother3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(10, D3DVECTOR(3.5f, -1.0f, 12.0f)); - m_object->SetAngleY(10, PI); - - // Creates a middle-left foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(11, rank); - m_object->SetObjectParent(11, 10); - pModFile->ReadModel("objects\\mother4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(11, D3DVECTOR(0.0f, 0.0f, -8.5f)); - - // Creates a left-front leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(12, rank); - m_object->SetObjectParent(12, 0); - pModFile->ReadModel("objects\\mother3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(12, D3DVECTOR(10.0f, -1.0f, 10.0f)); - m_object->SetAngleY(12, PI); - - // Creates a left-front foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(13, rank); - m_object->SetObjectParent(13, 12); - pModFile->ReadModel("objects\\mother4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(13, D3DVECTOR(0.0f, 0.0f, -8.5f)); - - // Creates the right antenna. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(14, rank); - m_object->SetObjectParent(14, 1); - pModFile->ReadModel("objects\\mother5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(14, D3DVECTOR(6.0f, 1.0f, -2.5f)); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(15, rank); - m_object->SetObjectParent(15, 14); - pModFile->ReadModel("objects\\mother6.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(15, D3DVECTOR(8.0f, 0.0f, 0.0f)); - - // Creates the left antenna. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(16, rank); - m_object->SetObjectParent(16, 1); - pModFile->ReadModel("objects\\mother5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(16, D3DVECTOR(6.0f, 1.0f, 2.5f)); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(17, rank); - m_object->SetObjectParent(17, 16); - pModFile->ReadModel("objects\\mother6.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(17, D3DVECTOR(8.0f, 0.0f, 0.0f)); - - // Creates the right claw. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(18, rank); - m_object->SetObjectParent(18, 1); - pModFile->ReadModel("objects\\mother7.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(18, D3DVECTOR(-4.0f, -3.5f, -8.0f)); - m_object->SetZoomX(18, 1.2f); - - // Creates the left claw. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(19, rank); - m_object->SetObjectParent(19, 1); - pModFile->ReadModel("objects\\mother7.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(19, D3DVECTOR(-4.0f, -3.5f, 8.0f)); - m_object->SetZoomX(19, 1.2f); - - m_object->CreateShadowCircle(18.0f, 0.8f); - - CreatePhysics(); - m_object->SetFloorHeight(0.0f); - - pos = m_object->RetPosition(0); - m_object->SetPosition(0, pos); // to display the shadows immediately - - m_engine->LoadAllTexture(); - - delete pModFile; - return TRUE; -} - -// Creates the physics of the object. - -void CMotionMother::CreatePhysics() -{ - Character* character; - int i; - - int member[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: - 30,30,10, 35,-15,10, 35,-35,10, // t0: legs 1..3 - -80,-45,-35, -115,-40,-35, -90,10,-55, // t0: feet 1..3 - 0,0,0, 0,0,0, 0,0,0, // t0: unused - // on the ground: - 15,-5,10, 10,-30,10, 5,-50,10, // t1: legs 1..3 - -90,-15,-15, -110,-55,-35, -75,-75,-30, // t1: feet 1..3 - 0,0,0, 0,0,0, 0,0,0, // t1: unused - // on the ground back: - 0,40,10, 5,5,10, 0,-15,10, // t2: legs 1..3 - -45,0,-55, -65,10,-50, -125,-85,-45, // t2: feet 1..3 - 0,0,0, 0,0,0, 0,0,0, // t2: unused - }; - - m_physics->SetType(TYPE_ROLLING); - - character = m_object->RetCharacter(); - character->wheelFront = 10.0f; - character->wheelBack = 10.0f; - character->wheelLeft = 20.0f; - character->wheelRight = 20.0f; - character->height = 3.0f; - - m_physics->SetLinMotionX(MO_ADVSPEED, 8.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 8.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 10.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 10.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 30.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 20.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 0.1f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 0.1f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 10.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 20.0f); - - for ( i=0 ; i<3*3*3*3 ; i++ ) - { - m_armAngles[i] = member[i]; - } -} - - -// Management of an event. - -BOOL CMotionMother::EventProcess(const Event &event) -{ - CMotion::EventProcess(event); - - if ( event.event == EVENT_FRAME ) - { - return EventFrame(event); - } - - if ( event.event == EVENT_KEYDOWN ) - { -#if ADJUST_ANGLE - int i; - - if ( event.param == 'A' ) m_armTimeIndex++; - if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0; - - if ( event.param == 'Q' ) m_armPartIndex++; - if ( m_armPartIndex >= 3 ) m_armPartIndex = 0; - - if ( event.param == 'W' ) m_armMemberIndex++; - if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0; - - i = m_armMemberIndex*3; - i += m_armPartIndex*3*3; - i += m_armTimeIndex*3*3*3; -//? i += 3*3*3*3; - - if ( event.param == 'E' ) m_armAngles[i+0] += 5; - if ( event.param == 'D' ) m_armAngles[i+0] -= 5; - if ( event.param == 'R' ) m_armAngles[i+1] += 5; - if ( event.param == 'F' ) m_armAngles[i+1] -= 5; - if ( event.param == 'T' ) m_armAngles[i+2] += 5; - if ( event.param == 'G' ) m_armAngles[i+2] -= 5; - - if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop; -#endif - } - - return TRUE; -} - -// Management of an event. - -BOOL CMotionMother::EventFrame(const Event &event) -{ - D3DVECTOR dir; - float s, a, prog; - int i, st, nd; - BOOL bStop; - - if ( m_engine->RetPause() ) return TRUE; - if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return TRUE; - - s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f; - a = Abs(m_physics->RetCirMotionY(MO_MOTSPEED)*26.0f); - - if ( s == 0.0f && a != 0.0f ) a *= 1.5f; - - m_armTimeAbs += event.rTime; - m_armTimeMarch += (s)*event.rTime*0.05f; - m_armMember += (s+a)*event.rTime*0.05f; - - bStop = ( a == 0.0f && s == 0.0f ); // stop? - - if ( bStop ) - { - prog = Mod(m_armTimeAbs, 2.0f)/10.0f; - a = Mod(m_armMember, 1.0f); - a = (prog-a)*event.rTime*1.0f; // stop position just pleasantly - m_armMember += a; - } - - for ( i=0 ; i<6 ; i++ ) // the six legs - { - if ( i < 3 ) prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f); - else prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f); - if ( m_bArmStop ) - { - prog = (float)m_armTimeIndex/3.0f; - } - if ( prog < 0.33f ) // t0..t1 ? - { - prog = prog/0.33f; // 0..1 - st = 0; // index start - nd = 1; // index end - } - else if ( prog < 0.67f ) // t1..t2 ? - { - prog = (prog-0.33f)/0.33f; // 0..1 - st = 1; // index start - nd = 2; // index end - } - else // t2..t0 ? - { - prog = (prog-0.67f)/0.33f; // 0..1 - st = 2; // index start - nd = 0; // index end - } - st = st*27+(i%3)*3; - nd = nd*27+(i%3)*3; - if ( i < 3 ) // right leg (1..3) ? - { - m_object->SetAngleX(2+2*i+0, Prop(m_armAngles[st+ 0], m_armAngles[nd+ 0], prog)); - m_object->SetAngleY(2+2*i+0, Prop(m_armAngles[st+ 1], m_armAngles[nd+ 1], prog)); - m_object->SetAngleZ(2+2*i+0, Prop(m_armAngles[st+ 2], m_armAngles[nd+ 2], prog)); - m_object->SetAngleX(2+2*i+1, Prop(m_armAngles[st+ 9], m_armAngles[nd+ 9], prog)); - m_object->SetAngleY(2+2*i+1, Prop(m_armAngles[st+10], m_armAngles[nd+10], prog)); - m_object->SetAngleZ(2+2*i+1, Prop(m_armAngles[st+11], m_armAngles[nd+11], prog)); - } - else // left leg (4..6) ? - { - m_object->SetAngleX(2+2*i+0, Prop( m_armAngles[st+ 0], m_armAngles[nd+ 0], prog)); - m_object->SetAngleY(2+2*i+0, Prop(180-m_armAngles[st+ 1], 180-m_armAngles[nd+ 1], prog)); - m_object->SetAngleZ(2+2*i+0, Prop( -m_armAngles[st+ 2], -m_armAngles[nd+ 2], prog)); - m_object->SetAngleX(2+2*i+1, Prop( m_armAngles[st+ 9], m_armAngles[nd+ 9], prog)); - m_object->SetAngleY(2+2*i+1, Prop( -m_armAngles[st+10], -m_armAngles[nd+10], prog)); - m_object->SetAngleZ(2+2*i+1, Prop( -m_armAngles[st+11], -m_armAngles[nd+11], prog)); - } - } - -#if ADJUST_ANGLE - if ( m_object->RetSelect() ) - { - char s[100]; - sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex); - m_engine->SetInfoText(4, s); - } -#endif - - if ( !bStop && !m_object->RetRuin() ) - { - a = Mod(m_armTimeMarch, 1.0f); - if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1 - else a = 3.0f-4.0f*a; // 1..-1 - dir.x = sinf(a)*0.03f; - - s = Mod(m_armTimeMarch/2.0f, 1.0f); - if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1 - else s = 3.0f-4.0f*s; // 1..-1 - dir.z = sinf(s)*0.05f; - - dir.y = 0.0f; - m_object->SetInclinaison(dir); - - a = Mod(m_armMember-0.1f, 1.0f); - if ( a < 0.33f ) - { - dir.y = -(1.0f-(a/0.33f))*0.3f; - } - else if ( a < 0.67f ) - { - dir.y = 0.0f; - } - else - { - dir.y = -(a-0.67f)/0.33f*0.3f; - } - dir.x = 0.0f; - dir.z = 0.0f; - m_object->SetLinVibration(dir); - } - - m_object->SetAngleZ(1, sinf(m_armTimeAbs*0.5f)*0.20f); // head - m_object->SetAngleX(1, sinf(m_armTimeAbs*0.6f)*0.10f); // head - m_object->SetAngleY(1, sinf(m_armTimeAbs*0.7f)*0.20f); // head - - m_object->SetAngleZ(14, 0.50f); - m_object->SetAngleZ(16, 0.50f); - m_object->SetAngleY(14, 0.80f+sinf(m_armTimeAbs*1.1f)*0.53f); // right antenna - m_object->SetAngleY(15, 0.70f-sinf(m_armTimeAbs*1.7f)*0.43f); - m_object->SetAngleY(16, -0.80f+sinf(m_armTimeAbs*0.9f)*0.53f); // left antenna - m_object->SetAngleY(17, -0.70f-sinf(m_armTimeAbs*1.3f)*0.43f); - - m_object->SetAngleY(18, sinf(m_armTimeAbs*1.1f)*0.20f); // right claw - m_object->SetAngleZ(18, -0.20f); - m_object->SetAngleY(19, sinf(m_armTimeAbs*0.9f)*0.20f); // left claw - m_object->SetAngleZ(19, -0.20f); - - return TRUE; -} - - diff --git a/src/motionmother.h b/src/motionmother.h deleted file mode 100644 index 6e8eb32..0000000 --- a/src/motionmother.h +++ /dev/null @@ -1,67 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motionmother.h - -#ifndef _MOTIONMOTHER_H_ -#define _MOTIONMOTHER_H_ - - -#include "motion.h" - - -class CInstanceManager; -class CEngine; -class CLight; -class CParticule; -class CTerrain; -class CCamera; -class CBrain; -class CPhysics; -class CObject; - - -class CMotionMother : public CMotion -{ -public: - CMotionMother(CInstanceManager* iMan, CObject* object); - ~CMotionMother(); - - void DeleteObject(BOOL bAll=FALSE); - BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); - BOOL EventProcess(const Event &event); - -protected: - void CreatePhysics(); - BOOL EventFrame(const Event &event); - -protected: - float m_armMember; - float m_armTimeAbs; - float m_armTimeMarch; - float m_armTimeAction; - short m_armAngles[3*3*3*3*10]; - int m_armTimeIndex; - int m_armPartIndex; - int m_armMemberIndex; - int m_armLastAction; - int m_specAction; - float m_specTime; - BOOL m_bArmStop; -}; - - -#endif //_MOTIONMOTHER_H_ diff --git a/src/motionspider.cpp b/src/motionspider.cpp deleted file mode 100644 index 99c3d06..0000000 --- a/src/motionspider.cpp +++ /dev/null @@ -1,789 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motionspider.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "light.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "modfile.h" -#include "sound.h" -#include "motion.h" -#include "motionspider.h" - - - -#define ADJUST_ANGLE FALSE // TRUE -> adjusts the angles of the members -#define START_TIME 1000.0f // beginning of the relative time - - - -// Object's constructor. - -CMotionSpider::CMotionSpider(CInstanceManager* iMan, CObject* object) - : CMotion(iMan, object) -{ - CMotion::CMotion(iMan, object); - - m_armMember = START_TIME; - m_armTimeAbs = START_TIME; - m_armTimeMarch = START_TIME; - m_armTimeAction = START_TIME; - m_armTimeIndex = 0; - m_armPartIndex = 0; - m_armMemberIndex = 0; - m_armLastAction = -1; - m_bArmStop = FALSE; - m_lastParticule = 0.0f; -} - -// Object's destructor. - -CMotionSpider::~CMotionSpider() -{ -} - - -// Removes an object. - -void CMotionSpider::DeleteObject(BOOL bAll) -{ -} - - -// Creates a vehicle traveling any lands on the ground. - -BOOL CMotionSpider::Create(D3DVECTOR pos, float angle, ObjectType type, - float power) -{ - CModFile* pModFile; - int rank, i, j, parent; - char name[50]; - - float table[] = - { - // x y z - 0.6f, 0.0f, 0.0f, // back leg - 0.0f, 0.0f, -2.0f, - 0.0f, 0.0f, -2.0f, - 0.0f, 0.0f, -2.0f, - - 0.8f, 0.0f, -0.2f, // middle-back leg - 0.0f, 0.0f, -2.0f, - 0.0f, 0.0f, -2.0f, - 0.0f, 0.0f, -2.0f, - - 1.0f, 0.0f, -0.2f, // middle-front leg - 0.0f, 0.0f, -2.0f, - 0.0f, 0.0f, -2.0f, - 0.0f, 0.0f, -2.0f, - - 1.2f, 0.0f, 0.0f, // front leg - 0.0f, 0.0f, -2.0f, - 0.0f, 0.0f, -2.0f, - 0.0f, 0.0f, -2.0f, - }; - - if ( m_engine->RetRestCreate() < 3+32+2 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - m_object->SetType(type); - - // Creates the main base. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object - m_object->SetObjectRank(0, rank); - pModFile->ReadModel("objects\\spider0.mod"); // doesn't exist - pModFile->CreateEngineObject(rank); - m_object->SetPosition(0, pos); - m_object->SetAngleY(0, angle); - - // A vehicle must have a obligatory collision - // with a sphere of center (0, y, 0) (see GetCrashSphere). - m_object->CreateCrashSphere(D3DVECTOR(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f); - m_object->SetGlobalSphere(D3DVECTOR(-0.5f, 1.0f, 0.0f), 4.0f); - - // Creates the abdomen. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\spider1.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(1.0f, 0.0f, 0.0f)); - - // Creates the head. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 0); - pModFile->ReadModel("objects\\spider2.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2, D3DVECTOR(1.0f, 0.0f, 0.0f)); - - // Creates legs. - for ( i=0 ; i<4 ; i++ ) - { - for ( j=0 ; j<4 ; j++ ) - { - sprintf(name, "objects\\spider%d.mod", j+3); // 3..6 - - // Creates the right leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(3+i*4+j, rank); - if ( j == 0 ) parent = 0; - else parent = 3+i*4+j-1; - m_object->SetObjectParent(3+i*4+j, parent); - pModFile->ReadModel(name); - pModFile->CreateEngineObject(rank); - pos.x = table[i*12+j*3+0]; - pos.y = table[i*12+j*3+1]; - pos.z = table[i*12+j*3+2]; - m_object->SetPosition(3+i*4+j, pos); - - // Creates the left leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(19+i*4+j, rank); - if ( j == 0 ) parent = 0; - else parent = 19+i*4+j-1; - m_object->SetObjectParent(19+i*4+j, parent); - pModFile->ReadModel(name); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - pos.x = table[i*12+j*3+0]; - pos.y = table[i*12+j*3+1]; - pos.z = -table[i*12+j*3+2]; - m_object->SetPosition(19+i*4+j, pos); - } - } - - // Creates the right mandible. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(35, rank); - m_object->SetObjectParent(35, 1); - pModFile->ReadModel("objects\\spider7.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(35, D3DVECTOR(0.0f, 0.0f, -0.3f)); - - // Creates the left mandible. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(36, rank); - m_object->SetObjectParent(36, 1); - pModFile->ReadModel("objects\\spider7.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(36, D3DVECTOR(0.0f, 0.0f, 0.3f)); - - m_object->CreateShadowCircle(4.0f, 0.5f); - - CreatePhysics(); - m_object->SetFloorHeight(0.0f); - - pos = m_object->RetPosition(0); - m_object->SetPosition(0, pos); // to display the shadows immediately - - m_engine->LoadAllTexture(); - - delete pModFile; - return TRUE; -} - -// Creates the physics of the object. - -void CMotionSpider::CreatePhysics() -{ - Character* character; - int i; - - int member_march[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4, // in the air: - 60,25,0, 60,0,0, 60,-25,0, 60,-50,0, // t0: thighs 1..4 - -35,40,0, -35,0,0, -35,0,0, -35,-40,0, // t0: legs 1..4 - -65,0,-30, -65,0,0, -65,0,0, -65,0,30, // t0: feet 1..4 - 25,0,0, 25,0,0, 25,0,0, 25,0,0, // t0: fingers 1..4 - // on the ground: - 30,15,0, 30,-10,0, 30,-35,0, 30,-60,0, // t1: thighs 1..4 - -10,40,0, -45,0,0, -45,0,0, -45,-40,0, // t1: legs 1..4 - -90,0,0, -20,0,0, -20,0,0, -20,0,0, // t1: feet 1..4 - -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t1: fingers 1..4 - // on the ground back: - 35,35,0, 40,10,0, 40,-15,0, 40,-40,0, // t2: thighs 1..4 - -35,40,0, -35,0,0, -35,0,0, -25,-40,0, // t2: legs 1..4 - -50,-25,-30, -65,0,0, -65,0,0, -90,0,30, // t2: feet 1..4 - -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t2: fingers 1..4 - }; - - int member_stop[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4, // in the air: - 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // t0: thighs 1..4 - -35,40,0, -45,0,0, -45,0,0, -45,-40,0, // t0: legs 1..4 - -50,-25,-30, -20,0,0, -20,0,0, -20,0,30, // t0: feet 1..4 - -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t0: fingers 1..4 - // on the ground: - 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // t1: thighs 1..4 - -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // t1: legs 1..4 - -55,-25,-30, -25,0,0, -25,0,0, -25,0,0, // t1: feet 1..4 - -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t1: fingers 1..4 - // on the ground back: - 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // t2: thighs 1..4 - -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // t2: legs 1..4 - -50,-25,-30, -20,0,0, -20,0,0, -20,0,30, // t2: feet 1..4 - -10,0,0, -10,0,0, -10,0,0, -10,0,0, // t2: fingers 1..4 - }; - - int member_spec[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4, // burning: - 30,25,0, 30,0,0, 30,-25,0, 30,-50,0, // s0: thighs 1..4 - -45,0,0, -45,0,0, -45,0,0, -45,0,0, // s0: legs 1..4 - -20,0,0, -20,0,0, -20,0,0, -20,0,0, // s0: feet 1..4 - -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s0: fingers 1..4 - // destroyed: - 30,25,0, 30,0,0, 30,-25,0, 30,-50,0, // s1: thighs 1..4 - -45,0,0, -45,0,0, -45,0,0, -45,0,0, // s1: legs 1..4 - -20,0,0, -20,0,0, -20,0,0, -20,0,0, // s1: feet 1..4 - -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s1: fingers 1..4 - // explodes: - 40,25,0, 40,0,0, 40,-25,0, 40,-50,0, // s2: thighs 1..4 - -55,0,0, -55,0,0, -55,0,0, -55,0,0, // s2: legs 1..4 - -30,0,0, -30,0,0, -30,0,0, -30,0,0, // s2: feet 1..4 - -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s2: fingers 1..4 - // back1 : - 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // s3: thighs 1..4 - -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // s3: legs 1..4 - -55,-25,-30, -25,0,0, -25,0,0, -25,0,0, // s3: feet 1..4 - -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s3: fingers 1..4 - // back2 : - 15,35,0, 15,0,0, 15,-25,0, 15,-50,0, // s4: thighs 1..4 - -60,40,0, -60,0,0, -60,0,0, -60,-40,0, // s4: legs 1..4 - -65,-25,-30, -65,0,0, -65,0,0, -65,0,0, // s4: feet 1..4 - -15,0,0, -15,0,0, -15,0,0, -15,0,0, // s4: fingers 1..4 - // back3 : - 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // s5: thighs 1..4 - -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // s5: legs 1..4 - -55,-25,-30, -25,0,0, -25,0,0, -25,0,0, // s5: feet 1..4 - -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s5: fingers 1..4 - }; - - m_physics->SetType(TYPE_ROLLING); - - character = m_object->RetCharacter(); - character->wheelFront = 4.0f; - character->wheelBack = 4.0f; - character->wheelLeft = 6.0f; - character->wheelRight = 6.0f; - character->height = 0.6f; - - m_physics->SetLinMotionX(MO_ADVSPEED, 12.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 12.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 15.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 15.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 5.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 5.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 10.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 1.0f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 1.0f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 20.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 20.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 40.0f); - - for ( i=0 ; i<3*4*4*3 ; i++ ) - { - m_armAngles[3*4*4*3*MS_MARCH+i] = member_march[i]; - } - for ( i=0 ; i<3*4*4*3 ; i++ ) - { - m_armAngles[3*4*4*3*MS_STOP+i] = member_stop[i]; - } - for ( i=0 ; i<3*4*4*6 ; i++ ) - { - m_armAngles[3*4*4*3*MS_SPEC+i] = member_spec[i]; - } -} - - -// Management of an event. - -BOOL CMotionSpider::EventProcess(const Event &event) -{ - CMotion::EventProcess(event); - - if ( event.event == EVENT_FRAME ) - { - return EventFrame(event); - } - - if ( event.event == EVENT_KEYDOWN ) - { -#if ADJUST_ANGLE - int i; - - if ( event.param == 'A' ) m_armTimeIndex++; - if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0; - - if ( event.param == 'Q' ) m_armPartIndex++; - if ( m_armPartIndex >= 4 ) m_armPartIndex = 0; - - if ( event.param == 'W' ) m_armMemberIndex++; - if ( m_armMemberIndex >= 4 ) m_armMemberIndex = 0; - - i = m_armMemberIndex*3; - i += m_armPartIndex*3*4; - i += m_armTimeIndex*3*4*4; - - if ( event.param == 'E' ) m_armAngles[i+0] += 5; - if ( event.param == 'D' ) m_armAngles[i+0] -= 5; - if ( event.param == 'R' ) m_armAngles[i+1] += 5; - if ( event.param == 'F' ) m_armAngles[i+1] -= 5; - if ( event.param == 'T' ) m_armAngles[i+2] += 5; - if ( event.param == 'G' ) m_armAngles[i+2] -= 5; - if ( event.param == 'Z' ) m_armAngles[i+3] += 5; - if ( event.param == 'H' ) m_armAngles[i+3] -= 5; - - if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop; -#endif - } - - return TRUE; -} - -// Calculates a value (radians) proportional between a and b (degrees). - -inline float Propf(float a, float b, float p) -{ - float aa, bb; - - aa = a*PI/180.0f; - bb = b*PI/180.0f; - - return aa+p*(bb-aa); -} - -// Management of an event. - -BOOL CMotionSpider::EventFrame(const Event &event) -{ - D3DVECTOR dir, pos, speed; - FPOINT dim; - float s, a, prog, time; - float tSt[12], tNd[12]; - int i, ii, st, nd, action; - BOOL bStop; - - if ( m_engine->RetPause() ) return TRUE; - if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return TRUE; - - s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f; - a = Abs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.0f); - - if ( s == 0.0f && a != 0.0f ) a *= 1.5f; - - m_armTimeAbs += event.rTime; - m_armTimeAction += event.rTime; - m_armTimeMarch += (s)*event.rTime*0.15f; - m_armMember += (s+a)*event.rTime*0.15f; - - bStop = ( a == 0.0f && s == 0.0f ); // stop? - - action = MS_MARCH; // waslking - if ( s == 0.0f && a == 0.0f ) - { - action = MS_STOP; // stop - } - - if ( bStop ) - { - prog = Mod(m_armTimeAbs, 2.0f)/10.0f; - a = Mod(m_armMember, 1.0f); - a = (prog-a)*event.rTime*2.0f; // stop position just pleasantly - m_armMember += a; - } - - if ( m_object->RetRuin() ) // destroyed? - { - m_actionType = MSS_RUIN; - } - if ( m_object->RetBurn() ) // burning? - { - if ( m_object->RetFixed() ) - { - m_actionType = MSS_BURN; - } - else - { - m_actionType = -1; - } - } - - for ( i=0 ; i<8 ; i++ ) // the 8 legs - { - if ( m_actionType != -1 ) // special action in progress? - { - st = 3*4*4*3*MS_SPEC + 3*4*4*m_actionType + (i%4)*3; - nd = st; - time = event.rTime*m_actionTime; - m_armTimeAction = 0.0f; - } - else - { -//? if ( i < 4 ) prog = Mod(m_armMember+(2.0f-(i%4))*0.25f+0.0f, 1.0f); -//? else prog = Mod(m_armMember+(2.0f-(i%4))*0.25f+0.3f, 1.0f); - if ( i < 4 ) prog = Mod(m_armMember+(2.0f-(i%4))*0.25f+0.0f, 1.0f); - else prog = Mod(m_armMember+(2.0f-(i%4))*0.25f+0.5f, 1.0f); - if ( m_bArmStop ) - { - prog = (float)m_armTimeIndex/3.0f; - action = MS_MARCH; - } - if ( prog < 0.33f ) // t0..t1 ? - { - prog = prog/0.33f; // 0..1 - st = 0; // index start - nd = 1; // index end - } - else if ( prog < 0.67f ) // t1..t2 ? - { - prog = (prog-0.33f)/0.33f; // 0..1 - st = 1; // index start - nd = 2; // index end - } - else // t2..t0 ? - { - prog = (prog-0.67f)/0.33f; // 0..1 - st = 2; // index start - nd = 0; // index end - } - st = 3*4*4*3*action + st*3*4*4 + (i%4)*3; - nd = 3*4*4*3*action + nd*3*4*4 + (i%4)*3; - - // Less and less soft ... -//? time = event.rTime*(2.0f+Min(m_armTimeAction*20.0f, 40.0f)); - time = event.rTime*10.0f; - } - - tSt[ 0] = m_armAngles[st+ 0]; // x - tSt[ 1] = m_armAngles[st+ 1]; // y - tSt[ 2] = m_armAngles[st+ 2]; // z - tSt[ 3] = m_armAngles[st+12]; // x - tSt[ 4] = m_armAngles[st+13]; // y - tSt[ 5] = m_armAngles[st+14]; // z - tSt[ 6] = m_armAngles[st+24]; // x - tSt[ 7] = m_armAngles[st+25]; // y - tSt[ 8] = m_armAngles[st+26]; // z - tSt[ 9] = m_armAngles[st+36]; // x - tSt[10] = m_armAngles[st+37]; // y - tSt[11] = m_armAngles[st+38]; // z - - tNd[ 0] = m_armAngles[nd+ 0]; // x - tNd[ 1] = m_armAngles[nd+ 1]; // y - tNd[ 2] = m_armAngles[nd+ 2]; // z - tNd[ 3] = m_armAngles[nd+12]; // x - tNd[ 4] = m_armAngles[nd+13]; // y - tNd[ 5] = m_armAngles[nd+14]; // z - tNd[ 6] = m_armAngles[nd+24]; // x - tNd[ 7] = m_armAngles[nd+25]; // y - tNd[ 8] = m_armAngles[nd+26]; // z - tNd[ 9] = m_armAngles[nd+36]; // z - tNd[10] = m_armAngles[nd+37]; // z - tNd[11] = m_armAngles[nd+38]; // z - - if ( m_actionType == MSS_BACK2 ) // on the back? - { - for ( ii=0 ; ii<12 ; ii++ ) - { - tSt[ii] += Rand()*20.0f; - tNd[ii] = tSt[ii]; - } -//? time = 100.0f; - time = event.rTime*10.0f; - } - - if ( i < 4 ) // right leg (1..4) ? - { - m_object->SetAngleX(3+4*i+0, Smooth(m_object->RetAngleX(3+4*i+0), Propf(tSt[ 0], tNd[ 0], prog), time)); - m_object->SetAngleY(3+4*i+0, Smooth(m_object->RetAngleY(3+4*i+0), Propf(tSt[ 1], tNd[ 1], prog), time)); - m_object->SetAngleZ(3+4*i+0, Smooth(m_object->RetAngleZ(3+4*i+0), Propf(tSt[ 2], tNd[ 2], prog), time)); - m_object->SetAngleX(3+4*i+1, Smooth(m_object->RetAngleX(3+4*i+1), Propf(tSt[ 3], tNd[ 3], prog), time)); - m_object->SetAngleY(3+4*i+1, Smooth(m_object->RetAngleY(3+4*i+1), Propf(tSt[ 4], tNd[ 4], prog), time)); - m_object->SetAngleZ(3+4*i+1, Smooth(m_object->RetAngleZ(3+4*i+1), Propf(tSt[ 5], tNd[ 5], prog), time)); - m_object->SetAngleX(3+4*i+2, Smooth(m_object->RetAngleX(3+4*i+2), Propf(tSt[ 6], tNd[ 6], prog), time)); - m_object->SetAngleY(3+4*i+2, Smooth(m_object->RetAngleY(3+4*i+2), Propf(tSt[ 7], tNd[ 7], prog), time)); - m_object->SetAngleZ(3+4*i+2, Smooth(m_object->RetAngleZ(3+4*i+2), Propf(tSt[ 8], tNd[ 8], prog), time)); - m_object->SetAngleX(3+4*i+3, Smooth(m_object->RetAngleX(3+4*i+3), Propf(tSt[ 9], tNd[ 9], prog), time)); - m_object->SetAngleY(3+4*i+3, Smooth(m_object->RetAngleY(3+4*i+3), Propf(tSt[10], tNd[10], prog), time)); - m_object->SetAngleZ(3+4*i+3, Smooth(m_object->RetAngleZ(3+4*i+3), Propf(tSt[11], tNd[11], prog), time)); - } - else // left leg (5..8) ? - { - m_object->SetAngleX(3+4*i+0, Smooth(m_object->RetAngleX(3+4*i+0), Propf(-tSt[ 0], -tNd[ 0], prog), time)); - m_object->SetAngleY(3+4*i+0, Smooth(m_object->RetAngleY(3+4*i+0), Propf(-tSt[ 1], -tNd[ 1], prog), time)); - m_object->SetAngleZ(3+4*i+0, Smooth(m_object->RetAngleZ(3+4*i+0), Propf( tSt[ 2], tNd[ 2], prog), time)); - m_object->SetAngleX(3+4*i+1, Smooth(m_object->RetAngleX(3+4*i+1), Propf(-tSt[ 3], -tNd[ 3], prog), time)); - m_object->SetAngleY(3+4*i+1, Smooth(m_object->RetAngleY(3+4*i+1), Propf(-tSt[ 4], -tNd[ 4], prog), time)); - m_object->SetAngleZ(3+4*i+1, Smooth(m_object->RetAngleZ(3+4*i+1), Propf( tSt[ 5], tNd[ 5], prog), time)); - m_object->SetAngleX(3+4*i+2, Smooth(m_object->RetAngleX(3+4*i+2), Propf(-tSt[ 6], -tNd[ 6], prog), time)); - m_object->SetAngleY(3+4*i+2, Smooth(m_object->RetAngleY(3+4*i+2), Propf(-tSt[ 7], -tNd[ 7], prog), time)); - m_object->SetAngleZ(3+4*i+2, Smooth(m_object->RetAngleZ(3+4*i+2), Propf( tSt[ 8], tNd[ 8], prog), time)); - m_object->SetAngleX(3+4*i+3, Smooth(m_object->RetAngleX(3+4*i+3), Propf(-tSt[ 9], -tNd[ 9], prog), time)); - m_object->SetAngleY(3+4*i+3, Smooth(m_object->RetAngleY(3+4*i+3), Propf(-tSt[10], -tNd[10], prog), time)); - m_object->SetAngleZ(3+4*i+3, Smooth(m_object->RetAngleZ(3+4*i+3), Propf( tSt[11], tNd[11], prog), time)); - } - } - -#if ADJUST_ANGLE - if ( m_object->RetSelect() ) - { - char s[100]; - sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex); - m_engine->SetInfoText(4, s); - } -#endif - - if ( m_actionType == MSS_BURN ) // burning? - { - dir = D3DVECTOR(PI, 0.0f, 0.0f); - SetCirVibration(dir); - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - SetLinVibration(dir); - SetInclinaison(dir); - - time = event.rTime*1.0f; - m_object->SetAngleZ(1, Smooth(m_object->RetAngleZ(1), 0.0f, time)); // head - } - else if ( m_actionType == MSS_RUIN ) // destroyed? - { - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - SetLinVibration(dir); - SetCirVibration(dir); - SetInclinaison(dir); - } - else if ( m_actionType == MSS_EXPLO ) // exploded? - { - m_object->SetZoomY(1, 1.0f+m_progress); - m_object->SetZoomZ(1, 1.0f+m_progress); - m_object->SetZoomX(1, 1.0f+m_progress/2.0f); - - dir.x = (Rand()-0.5f)*0.1f*m_progress; - dir.y = (Rand()-0.5f)*0.1f*m_progress; - dir.z = (Rand()-0.5f)*0.1f*m_progress; - m_object->SetCirVibration(dir); - } - else if ( m_actionType == MSS_BACK1 ) // turns on the back? - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) - { - m_lastParticule = m_armTimeAbs; - - pos = m_object->RetPosition(0); - speed.x = (Rand()-0.5f)*10.0f; - speed.z = (Rand()-0.5f)*10.0f; - speed.y = Rand()*5.0f; - dim.x = Rand()*3.0f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); - } - - if ( m_progress < 0.5f ) - { - dir.x = 0.0f; - dir.y = powf(m_progress/0.5f, 2.0f)*12.0f; - dir.z = 0.0f; - SetLinVibration(dir); - } - else - { - dir.x = 0.0f; - dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*12.0f; - dir.z = 0.0f; - SetLinVibration(dir); - } - dir.x = m_progress*PI; - dir.y = 0.0f; - dir.z = 0.0f; - SetCirVibration(dir); - - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - SetInclinaison(dir); - - if ( m_progress >= 1.0f ) - { - SetAction(MSS_BACK2, 55.0f+Rand()*10.0f); - } - } - else if ( m_actionType == MSS_BACK2 ) // moves on the back? - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) - { - m_lastParticule = m_armTimeAbs; - - if ( rand()%10 == 0 ) - { - pos = m_object->RetPosition(0); - pos.x += (Rand()-0.5f)*8.0f; - pos.z += (Rand()-0.5f)*8.0f; - pos.y -= 1.0f; - speed.x = (Rand()-0.5f)*2.0f; - speed.z = (Rand()-0.5f)*2.0f; - speed.y = Rand()*2.0f; - dim.x = Rand()*1.0f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); - } - } - - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - SetLinVibration(dir); - dir.x = sinf(m_armTimeAbs* 3.0f)*0.20f+ - sinf(m_armTimeAbs* 6.0f)*0.20f+ - sinf(m_armTimeAbs*10.0f)*0.20f+ - sinf(m_armTimeAbs*17.0f)*0.30f+PI; - dir.y = sinf(m_armTimeAbs* 4.0f)*0.02f+ - sinf(m_armTimeAbs* 5.0f)*0.02f+ - sinf(m_armTimeAbs*11.0f)*0.02f+ - sinf(m_armTimeAbs*18.0f)*0.03f; - dir.z = sinf(m_armTimeAbs* 2.0f)*0.02f+ - sinf(m_armTimeAbs* 7.0f)*0.02f+ - sinf(m_armTimeAbs*13.0f)*0.02f+ - sinf(m_armTimeAbs*15.0f)*0.03f; - SetCirVibration(dir); - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - SetInclinaison(dir); - - m_object->SetAngleY(1, sinf(m_armTimeAbs*5.0f)*0.05f); // tail - m_object->SetAngleY(2, cosf(m_armTimeAbs*5.0f)*0.20f); // head - m_object->SetAngleZ(1, 0.4f); // tail - m_object->SetAngleZ(2, 0.0f); // head - - if ( m_progress >= 1.0f ) - { - SetAction(MSS_BACK3, 0.4f); - } - } - else if ( m_actionType == MSS_BACK3 ) // recovers on the legs? - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) - { - m_lastParticule = m_armTimeAbs; - - pos = m_object->RetPosition(0); - speed.x = (Rand()-0.5f)*10.0f; - speed.z = (Rand()-0.5f)*10.0f; - speed.y = Rand()*5.0f; - dim.x = Rand()*3.0f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); - } - - if ( m_progress < 0.5f ) - { - dir.x = 0.0f; - dir.y = powf(m_progress/0.5f, 2.0f)*5.0f; - dir.z = 0.0f; - SetLinVibration(dir); - } - else - { - dir.x = 0.0f; - dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*5.0f; - dir.z = 0.0f; - SetLinVibration(dir); - } - dir.x = (1.0f-m_progress)*PI; - dir.y = 0.0f; - dir.z = 0.0f; - SetCirVibration(dir); - - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - SetInclinaison(dir); - - if ( m_progress >= 1.0f ) - { - SetAction(-1); - m_object->SetFixed(FALSE); // moving again - } - } - else - { - if ( bStop ) - { - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - SetInclinaison(dir); - } - else - { - a = Mod(m_armMember, 1.0f); - if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1 - else a = 3.0f-4.0f*a; // 1..-1 - dir.x = sinf(a)*0.05f; - - s = Mod(m_armMember/2.0f, 1.0f); - if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1 - else s = 3.0f-4.0f*s; // 1..-1 - dir.z = sinf(s)*0.1f; - - dir.y = 0.0f; - SetInclinaison(dir); - } - - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - SetLinVibration(dir); - SetCirVibration(dir); - - m_object->SetAngleZ(1, sinf(m_armTimeAbs*1.7f)*0.02f); // tail - m_object->SetAngleX(1, sinf(m_armTimeAbs*1.3f)*0.05f); - m_object->SetAngleY(1, sinf(m_armTimeAbs*2.4f)*0.10f); - m_object->SetZoom(1, 1.0f+sinf(m_armTimeAbs*3.3f)*0.05f); - - m_object->SetAngleZ(2, sinf(m_armTimeAbs*1.4f)*0.20f); // head - m_object->SetAngleX(2, sinf(m_armTimeAbs*1.9f)*0.10f); - m_object->SetAngleY(2, sinf(m_armTimeAbs*2.1f)*0.10f); - - m_object->SetAngleY(35, sinf(m_armTimeAbs*3.1f)*0.20f); // mandible - m_object->SetAngleY(36, -sinf(m_armTimeAbs*3.1f)*0.20f); // mandible - } - - return TRUE; -} - - diff --git a/src/motionspider.h b/src/motionspider.h deleted file mode 100644 index 294daf3..0000000 --- a/src/motionspider.h +++ /dev/null @@ -1,78 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motionspider.h - -#ifndef _MOTIONSPIDER_H_ -#define _MOTIONSPIDER_H_ - - -#include "motion.h" - - -class CInstanceManager; -class CEngine; -class CLight; -class CParticule; -class CTerrain; -class CCamera; -class CBrain; -class CPhysics; -class CObject; - - -#define MS_MARCH 0 -#define MS_STOP 1 -#define MS_SPEC 2 - -#define MSS_BURN 0 -#define MSS_RUIN 1 -#define MSS_EXPLO 2 -#define MSS_BACK1 3 -#define MSS_BACK2 4 -#define MSS_BACK3 5 - - -class CMotionSpider : public CMotion -{ -public: - CMotionSpider(CInstanceManager* iMan, CObject* object); - ~CMotionSpider(); - - void DeleteObject(BOOL bAll=FALSE); - BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); - BOOL EventProcess(const Event &event); - -protected: - void CreatePhysics(); - BOOL EventFrame(const Event &event); - -protected: - float m_armMember; - float m_armTimeAbs; - float m_armTimeMarch; - float m_armTimeAction; - short m_armAngles[3*4*4*3*3 + 3*4*4*6]; - int m_armTimeIndex; - int m_armPartIndex; - int m_armMemberIndex; - int m_armLastAction; - BOOL m_bArmStop; - float m_lastParticule; -}; - - -#endif //_MOTIONSPIDER_H_ diff --git a/src/motiontoto.cpp b/src/motiontoto.cpp deleted file mode 100644 index afd5779..0000000 --- a/src/motiontoto.cpp +++ /dev/null @@ -1,886 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motiontoto.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "light.h" -#include "particule.h" -#include "terrain.h" -#include "water.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "modfile.h" -#include "robotmain.h" -#include "sound.h" -#include "motion.h" -#include "motiontoto.h" - - - -#define START_TIME 1000.0f // beginning of the relative time - - - -// Object's constructor. - -CMotionToto::CMotionToto(CInstanceManager* iMan, CObject* object) - : CMotion(iMan, object) -{ - CMotion::CMotion(iMan, object); - - m_time = 0.0f; - m_bDisplayInfo = FALSE; - m_bQuickPos = FALSE; - m_bStartAction = FALSE; - m_speedAction = 20.0f; - m_soundChannel = -1; - m_clownRadius = 0.0f; - m_clownDelay = 0.0f; - m_clownTime = 0.0f; - m_blinkTime = 0.0f; - m_blinkProgress = -1.0f; - m_lastMotorParticule = 0.0f; - m_type = OBJECT_NULL; - m_mousePos = FPOINT(0.0f, 0.0f); -} - -// Object's destructor. - -CMotionToto::~CMotionToto() -{ -} - - -// Removes an object. - -void CMotionToto::DeleteObject(BOOL bAll) -{ - if ( m_soundChannel != -1 ) - { - m_sound->Stop(m_soundChannel); - m_soundChannel = -1; - } -} - - -// Creates a vehicle traveling any lands on the ground. - -BOOL CMotionToto::Create(D3DVECTOR pos, float angle, ObjectType type, - float power) -{ - CModFile* pModFile; - int rank; - - if ( m_engine->RetRestCreate() < 10 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - m_object->SetType(type); - - // Creates the head. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object - m_object->SetObjectRank(0, rank); - pModFile->ReadModel("objects\\toto1.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(0, pos); - m_object->SetAngleY(0, angle); - - // Creates mouth. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\toto2.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(1.00f, 0.17f, 0.00f)); - - // Creates the left eye. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 0); - pModFile->ReadModel("objects\\toto3.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2, D3DVECTOR(0.85f, 1.04f, 0.25f)); - m_object->SetAngleY(2, -20.0f*PI/180.0f); - - // Creates the right eye. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(3, rank); - m_object->SetObjectParent(3, 0); - pModFile->ReadModel("objects\\toto3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(3, D3DVECTOR(0.85f, 1.04f, -0.25f)); - m_object->SetAngleY(3, 20.0f*PI/180.0f); - - // Creates left antenna. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(4, rank); - m_object->SetObjectParent(4, 0); - pModFile->ReadModel("objects\\toto4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(4, D3DVECTOR(0.0f, 1.9f, 0.3f)); - m_object->SetAngleX(4, 30.0f*PI/180.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(5, rank); - m_object->SetObjectParent(5, 4); - pModFile->ReadModel("objects\\toto4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(5, D3DVECTOR(0.0f, 0.67f, 0.0f)); - m_object->SetAngleX(5, 30.0f*PI/180.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(6, rank); - m_object->SetObjectParent(6, 5); - pModFile->ReadModel("objects\\toto5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(6, D3DVECTOR(0.0f, 0.70f, 0.0f)); - m_object->SetAngleX(6, 30.0f*PI/180.0f); - - // Creates right antenna. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(7, rank); - m_object->SetObjectParent(7, 0); - pModFile->ReadModel("objects\\toto4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(7, D3DVECTOR(0.0f, 1.9f, -0.3f)); - m_object->SetAngleX(7, -30.0f*PI/180.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(8, rank); - m_object->SetObjectParent(8, 7); - pModFile->ReadModel("objects\\toto4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(8, D3DVECTOR(0.0f, 0.67f, 0.0f)); - m_object->SetAngleX(8, -30.0f*PI/180.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(9, rank); - m_object->SetObjectParent(9, 8); - pModFile->ReadModel("objects\\toto5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(9, D3DVECTOR(0.0f, 0.70f, 0.0f)); - m_object->SetAngleX(9, -30.0f*PI/180.0f); - - m_object->SetZoom(0, 0.5f); // is little - m_object->SetFloorHeight(0.0f); - - pos = m_object->RetPosition(0); - m_object->SetPosition(0, pos); // to display the shadows immediately - - m_engine->LoadAllTexture(); - - delete pModFile; - return TRUE; -} - - -// Beginning of the display of informations, with foo in the left margin. - -void CMotionToto::StartDisplayInfo() -{ -return; -//? - m_bDisplayInfo = TRUE; - - m_actionType = -1; - m_actionTime = 0.0f; - m_progress = 0.0f; - - m_object->SetAngleY(0, 0.0f); - m_mousePos = FPOINT(0.5f, 0.5f); -} - -// End of the display of informations. - -void CMotionToto::StopDisplayInfo() -{ - m_bDisplayInfo = FALSE; - m_bQuickPos = TRUE; -} - -// Gives the position of the mouse. - -void CMotionToto::SetMousePos(FPOINT pos) -{ - m_mousePos = pos; -} - - -// Management of an event. - -BOOL CMotionToto::EventProcess(const Event &event) -{ - CMotion::EventProcess(event); - - if ( event.event == EVENT_FRAME ) - { - return EventFrame(event); - } - - return TRUE; -} - -// Management of an event. - -BOOL CMotionToto::EventFrame(const Event &event) -{ - D3DMATRIX* mat; - D3DVECTOR eye, lookat, dir, perp, nPos, aPos, pos, speed; - D3DVECTOR vibLin, vibCir, dirSpeed, aAntenna; - FPOINT dim; - POINT wDim; - ParticuleType type; - float progress, focus, distance, shift, verti, level, zoom; - float aAngle, nAngle, mAngle, angle, linSpeed, cirSpeed; - int sheet, i, r; - BOOL bHidden; - - if ( m_engine->RetPause() && - !m_main->RetInfoLock() ) return TRUE; - - if ( m_bDisplayInfo ) // "looks" mouse? - { - bHidden = FALSE; - } - else - { - bHidden = FALSE; - - if ( m_main->RetMovieLock() ) // current movie? - { - bHidden = TRUE; - } - if ( !m_engine->RetTotoMode() ) - { - if ( !m_main->RetEditLock() ) // current edition? - { - bHidden = TRUE; - } - } - } - - if ( bHidden ) - { - nPos = m_object->RetPosition(0); - m_terrain->MoveOnFloor(nPos, TRUE); - nPos.y -= 100.0f; // hidden under the ground! - m_object->SetPosition(0, nPos); - return TRUE; - } - - m_time += event.rTime; - m_blinkTime -= event.rTime; - - progress = 0.0f; - if ( m_actionType != -1 ) // current action? - { - if ( m_progress < 0.15f ) - { - progress = m_progress/0.15f; - } - else if ( m_progress < 0.85f ) - { - progress = 1.0f; - } - else - { - progress = (1.0f-m_progress)/0.15f; - } - } - - if ( m_progress >= 1.0f ) - { - m_actionType = -1; // action ended - m_actionTime = 0.0f; - m_progress = 0.0f; - - m_clownTime = 0.0f; - m_clownDelay = 0.0f; - } - - focus = m_engine->RetFocus(); - eye = m_engine->RetEyePt(); - lookat = m_engine->RetLookatPt(); - - vibLin = D3DVECTOR(0.0f, 0.0f, 0.0f); - vibCir = D3DVECTOR(0.0f, 0.0f, 0.0f); - aAntenna = D3DVECTOR(0.0f, 0.0f, 0.0f); - aAntenna.x += 30.0f*PI/180.0f; - - // Calculates the new position. - if ( m_bDisplayInfo ) - { - wDim = m_engine->RetDim(); - nPos.x = -4.0f*((float)wDim.x/(float)wDim.y)/(640.0f/480.0f); - nPos.y = -0.5f; - nPos.z = 7.0f; // in the left margin - - linSpeed = 0.0f; - } - else - { -#if 0 - distance = 30.0f-progress*24.5f; // remoteness - shift = 18.0f-progress*15.4f; // shift is left - verti = 10.0f-progress* 9.6f; // shift at the top -#else - distance = 30.0f-progress*18.0f; // remoteness - shift = 18.0f-progress*11.0f; // shift is left - verti = 10.0f-progress* 8.0f; // shift at the top -#endif - - if ( m_actionType == -1 && - (m_type == OBJECT_HUMAN || - m_type == OBJECT_TECH || - m_type == OBJECT_MOBILEwa || - m_type == OBJECT_MOBILEta || - m_type == OBJECT_MOBILEfa || - m_type == OBJECT_MOBILEia || - m_type == OBJECT_MOBILEwc || - m_type == OBJECT_MOBILEtc || - m_type == OBJECT_MOBILEfc || - m_type == OBJECT_MOBILEic || - m_type == OBJECT_MOBILEwi || - m_type == OBJECT_MOBILEti || - m_type == OBJECT_MOBILEfi || - m_type == OBJECT_MOBILEii || - m_type == OBJECT_MOBILEws || - m_type == OBJECT_MOBILEts || - m_type == OBJECT_MOBILEfs || - m_type == OBJECT_MOBILEis || - m_type == OBJECT_MOBILErt || - m_type == OBJECT_MOBILErc || - m_type == OBJECT_MOBILErr || - m_type == OBJECT_MOBILErs || - m_type == OBJECT_MOBILEsa || - m_type == OBJECT_MOBILEwt || - m_type == OBJECT_MOBILEtt || - m_type == OBJECT_MOBILEft || - m_type == OBJECT_MOBILEit || - m_type == OBJECT_MOBILEdr ) ) // vehicle? - { - m_clownTime += event.rTime; - if ( m_clownTime >= m_clownDelay ) - { - if ( rand()%10 < 2 ) - { - m_clownRadius = 2.0f+Rand()*10.0f; -//? m_clownDelay = m_clownRadius/(2.0f+Rand()*2.0f); - m_clownDelay = 1.5f+Rand()*1.0f; - } - else - { - m_clownRadius = 0.0f; - m_clownDelay = 2.0f+Rand()*2.0f; - } - pos = m_object->RetPosition(0); - if ( pos.y < m_water->RetLevel() ) // underwater? - { - m_clownRadius /= 1.5f; - m_clownDelay *= 2.0f; - } - m_clownTime = 0.0f; - } - else - { - distance -= m_clownRadius*sinf(m_clownTime*PI*2.0f/m_clownDelay); - shift -= m_clownRadius-m_clownRadius*cosf(m_clownTime*PI*2.0f/m_clownDelay); - } - - verti += (18.0f-shift)*0.2f; - } - - distance /= focus; -//? shift *= focus; - verti /= focus; - - dir = Normalize(lookat-eye); - nPos = eye + dir*distance; - - perp.x = -dir.z; - perp.y = dir.y; - perp.z = dir.x; - nPos = nPos + perp*shift; - - nPos.y += verti; - - if ( m_bQuickPos ) // immediately in place? - { - m_bQuickPos = FALSE; - linSpeed = 0.0f; - } - else - { - aPos = m_object->RetPosition(0); - if ( m_actionType == -1 ) - { - level = 4.0f; - } - else - { - if ( m_bStartAction ) - { - m_bStartAction = FALSE; - m_speedAction = Length(nPos, aPos)/15.0f; - if ( m_speedAction < 20.0f ) m_speedAction = 20.0f; - } - level = m_speedAction; - } - if ( level > 1.0f/event.rTime ) level = 1.0f/event.rTime; - nPos = aPos + (nPos-aPos)*event.rTime*level; // progression aPos -> nPos - - linSpeed = Length2d(nPos, aPos)/event.rTime; - dirSpeed = (nPos-aPos)/event.rTime; - nPos.y -= linSpeed*0.015f*(1.0f-progress); // at ground level if moving fast - } - } - - // Calculate the new angle. - nAngle = NormAngle(RotateAngle(eye.x-lookat.x, lookat.z-eye.z)-0.9f); - if ( linSpeed == 0.0f || m_actionType != -1 ) - { - mAngle = nAngle; - } - else - { - mAngle = NormAngle(RotateAngle(dirSpeed.x, -dirSpeed.z)); - } - level = Min(linSpeed*0.1f, 1.0f); - nAngle = nAngle*(1.0f-level) + mAngle*level; - aAngle = NormAngle(m_object->RetAngleY(0)); - - if ( nAngle < aAngle ) - { - if ( nAngle+PI*2.0f-aAngle < aAngle-nAngle ) nAngle += PI*2.0f; - } - else - { - if ( aAngle+PI*2.0f-nAngle < nAngle-aAngle ) aAngle += PI*2.0f; - } - nAngle = aAngle + (nAngle-aAngle)*event.rTime*4.0f; - - // Leans quotes if running. - cirSpeed = (aAngle-nAngle)/event.rTime; - angle = cirSpeed*0.3f*(1.0f-progress); - if ( angle > 0.7f ) angle = 0.7f; - if ( angle < -0.7f ) angle = -0.7f; - vibCir.x += angle*1.5f; - aAntenna.x += Abs(angle)*0.8f; // deviates - - // Leans forward so quickly advance. - angle = linSpeed*0.10f*(1.0f-progress); - if ( angle > 1.0f ) angle = 1.0f; - vibCir.z -= angle/2.0f; // leans forward - aAntenna.z -= angle; // leans forward - - // Calculates the residual motion. -#if 1 - vibLin.y += (sinf(m_time*2.00f)*0.5f+ - sinf(m_time*2.11f)*0.2f)*(1.0f-progress); - - vibCir.z += sinf(m_time*PI* 2.01f)*(PI/ 75.0f)+ - sinf(m_time*PI* 2.51f)*(PI/100.0f)+ - sinf(m_time*PI*19.01f)*(PI/200.0f); - - vibCir.x += sinf(m_time*PI* 2.03f)*(PI/ 75.0f)+ - sinf(m_time*PI* 2.52f)*(PI/100.0f)+ - sinf(m_time*PI*19.53f)*(PI/200.0f); - - vibCir.y += (sinf(m_time*PI* 1.07f)*(PI/ 10.0f)+ - sinf(m_time*PI* 1.19f)*(PI/ 17.0f)+ - sinf(m_time*PI* 1.57f)*(PI/ 31.0f))*(1.0f-progress); -#endif - - // Calculates the animations in action. - if ( m_actionType == MT_ERROR ) // no-no? - { - vibCir.y += progress*sinf(m_progress*PI*11.0f)*1.0f; - vibCir.z -= progress*0.5f; // leans forward - - aAntenna.x -= progress*0.4f; // narrows - aAntenna.z += progress*1.0f; // leaning back - } - - if ( m_actionType == MT_WARNING ) // warning? - { - vibCir.x += progress*sinf(m_progress*PI*17.0f)*0.5f; - - aAntenna.x += progress*sinf(m_progress*PI*17.0f)*0.5f; // deviates - aAntenna.z += progress*cosf(m_progress*PI*17.0f)*0.5f; // turns - } - - if ( m_actionType == MT_INFO ) // yes-yes? - { - vibCir.z += progress*sinf(m_progress*PI*19.0f)*0.7f; - - aAntenna.x -= progress*0.2f; // narrows - aAntenna.z -= progress*cosf(m_progress*PI*19.0f)*0.9f; // turns - } - - if ( m_actionType == MT_MESSAGE ) // message? - { - vibCir.x += progress*sinf(m_progress*PI*15.0f)*0.3f; - vibCir.z += progress*cosf(m_progress*PI*15.0f)*0.3f; - - aAntenna.x -= progress*0.4f; // narrows - aAntenna.z -= progress*cosf(m_progress*PI*19.0f)*0.8f; - } - - // Initialize the object. - if ( m_bDisplayInfo ) // "looks" mouse? - { - if ( m_mousePos.x < 0.15f ) - { - progress = 1.0f-m_mousePos.x/0.15f; - vibCir.y += progress*PI/2.0f; - } - else - { - progress = (m_mousePos.x-0.15f)/0.85f; - vibCir.y -= progress*PI/3.0f; - } - - angle = RotateAngle(m_mousePos.x-0.1f, m_mousePos.y-0.5f-vibLin.y*0.2f); - if ( angle < PI ) - { - if ( angle > PI*0.5f ) angle = PI-angle; - if ( angle > PI*0.3f ) angle = PI*0.3f; - vibCir.z += angle; - } - else - { - angle = PI*2.0f-angle; - if ( angle > PI*0.5f ) angle = PI-angle; - if ( angle > PI*0.3f ) angle = PI*0.3f; - vibCir.z -= angle; - } - } - else - { - nPos.y += vibLin.y; - level = m_terrain->RetFloorLevel(nPos); - if ( nPos.y < level+2.0f ) - { - nPos.y = level+2.0f; // just above the ground - } - nPos.y -= vibLin.y; - } - m_object->SetPosition(0, nPos); - m_object->SetAngleY(0, nAngle); - - SetLinVibration(vibLin); - SetCirVibration(vibCir); - - // Calculates the residual movement of the antennas. - pos = aAntenna*0.40f; - pos.x += sinf(m_time*PI*2.07f)*(PI/50.0f)+ - sinf(m_time*PI*2.59f)*(PI/70.0f)+ - sinf(m_time*PI*2.67f)*(PI/90.0f); - - pos.y += sinf(m_time*PI*2.22f)*(PI/50.0f)+ - sinf(m_time*PI*2.36f)*(PI/70.0f)+ - sinf(m_time*PI*3.01f)*(PI/90.0f); - - pos.z += sinf(m_time*PI*2.11f)*(PI/50.0f)+ - sinf(m_time*PI*2.83f)*(PI/70.0f)+ - sinf(m_time*PI*3.09f)*(PI/90.0f); - - m_object->SetAngle(4, pos); // left antenna - m_object->SetAngle(5, pos); // left antenna - m_object->SetAngle(6, pos); // left antenna - - pos = aAntenna*0.40f; - pos.x = -pos.x; - pos.x += sinf(m_time*PI*2.33f)*(PI/50.0f)+ - sinf(m_time*PI*2.19f)*(PI/70.0f)+ - sinf(m_time*PI*2.07f)*(PI/90.0f); - - pos.y += sinf(m_time*PI*2.44f)*(PI/50.0f)+ - sinf(m_time*PI*2.77f)*(PI/70.0f)+ - sinf(m_time*PI*3.22f)*(PI/90.0f); - - pos.z += sinf(m_time*PI*2.05f)*(PI/50.0f)+ - sinf(m_time*PI*2.38f)*(PI/70.0f)+ - sinf(m_time*PI*2.79f)*(PI/90.0f); - - m_object->SetAngle(7, pos); // right antenna - m_object->SetAngle(8, pos); // right antenna - m_object->SetAngle(9, pos); // right antenna - - // Movement of the mouth. - if ( m_actionType == MT_ERROR ) // no-no? - { - m_object->SetAngleX(1, 0.0f); - m_object->SetAngleZ(1, 0.2f+sinf(m_time*10.0f)*0.2f); - m_object->SetZoomY(1, 2.0f+sinf(m_time*10.0f)); - m_object->SetZoomZ(1, 1.0f); - } - else if ( m_actionType == MT_WARNING ) // warning? - { - m_object->SetAngleX(1, 15.0f*PI/180.0f); - m_object->SetAngleZ(1, 0.0f); - m_object->SetZoomY(1, 1.0f); - m_object->SetZoomZ(1, 1.0f); - } - else if ( m_actionType == MT_INFO ) // yes-yes? - { - m_object->SetAngleX(1, 0.0f); - m_object->SetAngleZ(1, 0.0f); - m_object->SetZoomY(1, 1.0f); - m_object->SetZoomZ(1, 0.7f+sinf(m_time*10.0f)*0.3f); - } - else if ( m_actionType == MT_MESSAGE ) // message? - { - m_object->SetAngleX(1, 0.0f); - m_object->SetAngleZ(1, 0.0f); - m_object->SetZoomY(1, 1.0f); - m_object->SetZoomZ(1, 0.8f+sinf(m_time*7.0f)*0.2f); - } - else - { - m_object->SetAngleX(1, 0.0f); - m_object->SetAngleZ(1, 0.0f); - m_object->SetZoomY(1, 1.0f); - m_object->SetZoomZ(1, 1.0f); - } - - // Eye blinking management. - if ( m_blinkTime <= 0.0f && m_blinkProgress == -1.0f ) - { - m_blinkProgress = 0.0f; - } - - if ( m_blinkProgress >= 0.0f ) - { - m_blinkProgress += event.rTime*3.2f; - - if ( m_blinkProgress < 1.0f ) - { - if ( m_blinkProgress < 0.5f ) zoom = m_blinkProgress/0.5f; - else zoom = 2.0f-m_blinkProgress/0.5f; - m_object->SetZoomY(2, 1.0f-zoom*0.9f); - m_object->SetZoomY(3, 1.0f-zoom*0.9f); - } - else - { - m_blinkProgress = -1.0f; - m_blinkTime = 0.1f+Rand()*4.0f; - m_object->SetZoomY(2, 1.0f); - m_object->SetZoomY(3, 1.0f); - } - } - - if ( m_actionType == MT_ERROR ) // no-no? - { - m_object->SetAngleX(2, -30.0f*PI/180.0f); - m_object->SetAngleX(3, 30.0f*PI/180.0f); - } - else if ( m_actionType == MT_WARNING ) // warning? - { - m_object->SetAngleX(2, -15.0f*PI/180.0f); - m_object->SetAngleX(3, 15.0f*PI/180.0f); - } - else if ( m_actionType == MT_INFO ) // yes-yes? - { - m_object->SetAngleX(2, 40.0f*PI/180.0f); - m_object->SetAngleX(3, -40.0f*PI/180.0f); - } - else if ( m_actionType == MT_MESSAGE ) // message? - { - m_object->SetAngleX(2, 20.0f*PI/180.0f); - m_object->SetAngleX(3, -20.0f*PI/180.0f); - } - else - { - m_object->SetAngleX(2, 0.0f); - m_object->SetAngleX(3, 0.0f); - } - - mat = m_object->RetWorldMatrix(0); // must be done every time! - - // Generates particles. - if ( m_time-m_lastMotorParticule >= m_engine->ParticuleAdapt(0.05f) ) - { - m_lastMotorParticule = m_time; - - if ( m_bDisplayInfo ) sheet = SH_FRONT; - else sheet = SH_WORLD; - - pos = m_object->RetPosition(0); - if ( !m_bDisplayInfo && - pos.y < m_water->RetLevel() ) // underwater? - { - float t = Mod(m_time, 3.5f); - if ( t >= 2.2f || ( t >= 1.2f && t <= 1.4f ) ) // breathe? - { - pos = D3DVECTOR(1.0f, 0.2f, 0.0f); - pos.z += (Rand()-0.5f)*0.5f; - - speed = pos; - speed.y += 5.0f+Rand()*5.0f; - speed.x += Rand()*2.0f; - speed.z += (Rand()-0.5f)*2.0f; - - pos = Transform(*mat, pos); - speed = Transform(*mat, speed)-pos; - - dim.x = 0.12f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBUBBLE, 3.0f, 0.0f, 0.0f); - } - } - else // out of water? - { - pos = D3DVECTOR(0.0f, -0.5f, 0.0f); - pos.z += (Rand()-0.5f)*0.5f; - - speed = pos; - speed.y -= (1.5f+Rand()*1.5f) + vibLin.y; - speed.x += (Rand()-0.5f)*2.0f; - speed.z += (Rand()-0.5f)*2.0f; - -// mat = m_object->RetWorldMatrix(0); - pos = Transform(*mat, pos); - speed = Transform(*mat, speed)-pos; - - dim.x = (Rand()*0.4f+0.4f)*(1.0f+Min(linSpeed*0.1f, 5.0f)); - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTITOTO, 1.0f+Rand()*1.0f, 0.0f, 1.0f, sheet); - } - - if ( m_actionType != -1 && // current action? - m_progress <= 0.85f ) - { - pos.x = (Rand()-0.5f)*1.0f; - pos.y = (Rand()-0.5f)*1.0f+3.5f; - pos.z = (Rand()-0.5f)*1.0f; - pos = Transform(*mat, pos); - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = (Rand()*0.3f+0.3f); - dim.y = dim.x; - if ( m_actionType == MT_ERROR ) type = PARTIERROR; - if ( m_actionType == MT_WARNING ) type = PARTIWARNING; - if ( m_actionType == MT_INFO ) type = PARTIINFO; - if ( m_actionType == MT_MESSAGE ) type = PARTIWARNING; - m_particule->CreateParticule(pos, speed, dim, type, 0.5f+Rand()*0.5f, 0.0f, 1.0f, sheet); - - pos.x = 0.50f+(Rand()-0.5f)*0.80f; - pos.y = 0.86f+(Rand()-0.5f)*0.08f; - pos.z = 0.00f; - dim.x = (Rand()*0.04f+0.04f); - dim.y = dim.x/0.75f; - m_particule->CreateParticule(pos, speed, dim, type, 0.5f+Rand()*0.5f, 0.0f, 1.0f, SH_INTERFACE); - } - -//? if ( m_bDisplayInfo && m_main->RetGlint() ) - if ( FALSE ) - { - pos.x = (Rand()-0.5f)*1.4f; - pos.y = (Rand()-0.5f)*1.4f+3.5f; - pos.z = (Rand()-0.5f)*1.4f; - pos = Transform(*mat, pos); - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = (Rand()*0.5f+0.5f); - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIERROR, 0.5f+Rand()*0.5f, 0.0f, 1.0f, sheet); - - for ( i=0 ; i<10 ; i++ ) - { - pos.x = 0.60f+(Rand()-0.5f)*0.76f; - pos.y = 0.47f+(Rand()-0.5f)*0.90f; - pos.z = 0.00f; - r = rand()%4; - if ( r == 0 ) pos.x = 0.21f; // the left edge - else if ( r == 1 ) pos.x = 0.98f; // the right edge - else if ( r == 2 ) pos.y = 0.02f; // on the lower edge - else pos.y = 0.92f; // on the upper edge - dim.x = (Rand()*0.02f+0.02f); - dim.y = dim.x/0.75f; - m_particule->CreateParticule(pos, speed, dim, PARTIERROR, 0.5f+Rand()*0.5f, 0.0f, 1.0f, SH_INTERFACE); - } - } - } - - // Move the sound. - if ( m_soundChannel != -1 ) - { - if ( !m_sound->Position(m_soundChannel, m_object->RetPosition(0)) ) - { - m_soundChannel = -1; - } - } - - return TRUE; -} - - -// Starts an action. - -Error CMotionToto::SetAction(int action, float time) -{ - Sound sound; - - CMotion::SetAction(action, time); - - m_bStartAction = TRUE; - - sound = SOUND_CLICK; - if ( action == MT_ERROR ) sound = SOUND_ERROR; - if ( action == MT_WARNING ) sound = SOUND_WARNING; - if ( action == MT_INFO ) sound = SOUND_INFO; - if ( action == MT_MESSAGE ) sound = SOUND_MESSAGE; - - if ( sound != SOUND_CLICK ) - { - m_soundChannel = m_sound->Play(sound, m_object->RetPosition(0)); - } - - return ERR_OK; -} - -// Specifies the type of the object is attached to toto. - -void CMotionToto::SetLinkType(ObjectType type) -{ - m_type = type; -} - - diff --git a/src/motiontoto.h b/src/motiontoto.h deleted file mode 100644 index 22955bb..0000000 --- a/src/motiontoto.h +++ /dev/null @@ -1,81 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motiontoto.h - -#ifndef _MOTIONTOTO_H_ -#define _MOTIONTOTO_H_ - - -#include "struct.h" -#include "object.h" -#include "motion.h" - - -class CInstanceManager; -class CEngine; -class CLight; -class CParticule; -class CTerrain; -class CCamera; -class CBrain; -class CPhysics; - - -#define MT_ERROR 0 -#define MT_WARNING 1 -#define MT_INFO 2 -#define MT_MESSAGE 3 - - -class CMotionToto : public CMotion -{ -public: - CMotionToto(CInstanceManager* iMan, CObject* object); - ~CMotionToto(); - - void DeleteObject(BOOL bAll=FALSE); - BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); - BOOL EventProcess(const Event &event); - Error SetAction(int action, float time=0.2f); - void SetLinkType(ObjectType type); - - void StartDisplayInfo(); - void StopDisplayInfo(); - void SetMousePos(FPOINT pos); - -protected: - BOOL EventFrame(const Event &event); - -protected: - float m_time; - float m_lastMotorParticule; - BOOL m_bDisplayInfo; - BOOL m_bQuickPos; - BOOL m_bStartAction; - float m_speedAction; - float m_clownRadius; - float m_clownDelay; - float m_clownTime; - float m_blinkTime; - float m_blinkProgress; - int m_soundChannel; - ObjectType m_type; - FPOINT m_mousePos; -}; - - -#endif //_MOTIONTOTO_H_ diff --git a/src/motionvehicle.cpp b/src/motionvehicle.cpp deleted file mode 100644 index 73dae74..0000000 --- a/src/motionvehicle.cpp +++ /dev/null @@ -1,2091 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motionvehicle.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "light.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "modfile.h" -#include "sound.h" -#include "motion.h" -#include "motionvehicle.h" - - - -#define ARM_NEUTRAL_ANGLE1 110.0f*PI/180.0f -#define ARM_NEUTRAL_ANGLE2 -130.0f*PI/180.0f -#define ARM_NEUTRAL_ANGLE3 -50.0f*PI/180.0f - - - -// Object's constructor. - -CMotionVehicle::CMotionVehicle(CInstanceManager* iMan, CObject* object) - : CMotion(iMan, object) -{ - int i; - - CMotion::CMotion(iMan, object); - - for ( i=0 ; i<4 ; i++ ) - { - m_wheelTurn[i] = 0.0f; - } - for ( i=0 ; i<3 ; i++ ) - { - m_flyPaw[i] = 0.0f; - } - m_posTrackLeft = 0.0f; - m_posTrackRight = 0.0f; - m_partiReactor = -1; - m_armTimeAbs = 1000.0f; - m_armMember = 1000.0f; - m_canonTime = 0.0f; - m_lastTimeCanon = 0.0f; - m_wheelLastPos = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_wheelLastAngle = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_posKey = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_bFlyFix = FALSE; - - m_bTraceDown = FALSE; - m_traceColor = 1; // black - m_traceWidth = 0.5f; -} - -// Object's destructor. - -CMotionVehicle::~CMotionVehicle() -{ -} - - -// Removes an object. - -void CMotionVehicle::DeleteObject(BOOL bAll) -{ - if ( m_partiReactor != -1 ) - { - m_particule->DeleteParticule(m_partiReactor); - m_partiReactor = -1; - } -} - - -// Creates a vehicle traveling any lands on the ground. - -BOOL CMotionVehicle::Create(D3DVECTOR pos, float angle, ObjectType type, - float power) -{ - CModFile* pModFile; - CObject* pPower; - int rank, i, j, parent; - D3DCOLORVALUE color; - char name[50]; - - if ( m_engine->RetRestCreate() < 1+5+18+1 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - m_object->SetType(type); - - // Creates the main base. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object - m_object->SetObjectRank(0, rank); - - if ( type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEfs ) - { - pModFile->ReadModel("objects\\lem1f.mod"); - } - if ( type == OBJECT_MOBILEta || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEts ) - { - pModFile->ReadModel("objects\\lem1t.mod"); - } - if ( type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEws ) - { - if ( m_object->RetTrainer() ) - { - pModFile->ReadModel("objects\\lem1wt.mod"); - } - else - { - pModFile->ReadModel("objects\\lem1w.mod"); - } - } - if ( type == OBJECT_MOBILEia || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEis ) - { - pModFile->ReadModel("objects\\lem1i.mod"); - } - if ( type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs ) - { - pModFile->ReadModel("objects\\roller1.mod"); - } - if ( type == OBJECT_MOBILEsa ) - { - pModFile->ReadModel("objects\\subm1.mod"); - } - if ( type == OBJECT_MOBILEtg ) - { - pModFile->ReadModel("objects\\target.mod"); - } - if ( type == OBJECT_MOBILEwt ) - { - pModFile->ReadModel("objects\\trainerw.mod"); - } - if ( type == OBJECT_MOBILEft ) - { - pModFile->ReadModel("objects\\trainerf.mod"); - } - if ( type == OBJECT_MOBILEtt ) - { - pModFile->ReadModel("objects\\trainert.mod"); - } - if ( type == OBJECT_MOBILEit ) - { - pModFile->ReadModel("objects\\traineri.mod"); - } - if ( type == OBJECT_MOBILEdr ) - { - pModFile->ReadModel("objects\\drawer1.mod"); - } - if ( type == OBJECT_APOLLO2 ) - { - pModFile->ReadModel("objects\\apolloj1.mod"); - } - pModFile->CreateEngineObject(rank); - - m_object->SetPosition(0, pos); - m_object->SetAngleY(0, angle); - - // A vehicle must have a obligatory collision - // with a sphere of center (0, y, 0) (see GetCrashSphere). - if ( type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs ) - { - m_object->CreateCrashSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 6.5f, SOUND_BOUMm, 0.45f); - m_object->SetGlobalSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 7.0f); - } - else if ( type == OBJECT_MOBILEsa ) - { - m_object->CreateCrashSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f); - m_object->SetGlobalSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 6.0f); - } - else if ( type == OBJECT_MOBILEdr ) - { - m_object->CreateCrashSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - m_object->SetGlobalSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 7.0f); - } - else if ( type == OBJECT_APOLLO2 ) - { - m_object->CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 8.0f, SOUND_BOUMm, 0.45f); - } - else - { - m_object->CreateCrashSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f); - m_object->SetGlobalSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 6.0f); - } - - if ( type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia ) - { - // Creates the arm. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\lem2.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(0.0f, 5.3f, 0.0f)); - m_object->SetAngleZ(1, ARM_NEUTRAL_ANGLE1); - - // Creates the forearm. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 1); - pModFile->ReadModel("objects\\lem3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2, D3DVECTOR(5.0f, 0.0f, 0.0f)); - m_object->SetAngleZ(2, ARM_NEUTRAL_ANGLE2); - - // Creates the hand. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(3, rank); - m_object->SetObjectParent(3, 2); - pModFile->ReadModel("objects\\lem4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(3, D3DVECTOR(3.5f, 0.0f, 0.0f)); - m_object->SetAngleZ(3, ARM_NEUTRAL_ANGLE3); - m_object->SetAngleX(3, PI/2.0f); - - // Creates the close clamp. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(4, rank); - m_object->SetObjectParent(4, 3); - pModFile->ReadModel("objects\\lem5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(4, D3DVECTOR(1.5f, 0.0f, 0.0f)); - m_object->SetAngleZ(4, -PI*0.10f); - - // Creates the remote clamp. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(5, rank); - m_object->SetObjectParent(5, 3); - pModFile->ReadModel("objects\\lem6.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(5, D3DVECTOR(1.5f, 0.0f, 0.0f)); - m_object->SetAngleZ(5, PI*0.10f); - } - - if ( type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEis ) - { - // Creates the arm. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\lem2.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(0.0f, 5.3f, 0.0f)); - m_object->SetAngleZ(1, 110.0f*PI/180.0f); - - // Creates the forearm. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 1); - pModFile->ReadModel("objects\\lem3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2, D3DVECTOR(5.0f, 0.0f, 0.0f)); - m_object->SetAngleZ(2, -110.0f*PI/180.0f); - - // Creates the sensor. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(3, rank); - m_object->SetObjectParent(3, 2); - pModFile->ReadModel("objects\\lem4s.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(3, D3DVECTOR(3.5f, 0.0f, 0.0f)); - m_object->SetAngleZ(3, -65.0f*PI/180.0f); - } - - if ( type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic ) - { - // Creates the cannon. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\canon.mod"); - pModFile->CreateEngineObject(rank); -//? m_object->SetPosition(1, D3DVECTOR(0.0f, 5.3f, 0.0f)); - m_object->SetPosition(1, D3DVECTOR(0.0f, 5.3f, 0.0f)); - m_object->SetAngleZ(1, 0.0f); - } - - if ( type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii ) - { - // Creates the insect cannon. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\canoni1.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(0.0f, 5.3f, 0.0f)); - m_object->SetAngleZ(1, 0.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 1); - pModFile->ReadModel("objects\\canoni2.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2, D3DVECTOR(0.0f, 2.5f, 0.0f)); - m_object->SetAngleZ(2, 0.0f); - } - - if ( type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEwt ) - { - // Creates the right-back wheel. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(6, rank); - m_object->SetObjectParent(6, 0); - pModFile->ReadModel("objects\\lem2w.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(6, D3DVECTOR(-3.0f, 1.0f, -3.0f)); - - // Creates the left-back wheel. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(7, rank); - m_object->SetObjectParent(7, 0); - pModFile->ReadModel("objects\\lem2w.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(7, D3DVECTOR(-3.0f, 1.0f, 3.0f)); - m_object->SetAngleY(7, PI); - - // Creates the right-front wheel. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(8, rank); - m_object->SetObjectParent(8, 0); - pModFile->ReadModel("objects\\lem2w.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(8, D3DVECTOR(2.0f, 1.0f, -3.0f)); - - // Creates the left-front wheel. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(9, rank); - m_object->SetObjectParent(9, 0); - pModFile->ReadModel("objects\\lem2w.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(9, D3DVECTOR(2.0f, 1.0f, 3.0f)); - m_object->SetAngleY(9, PI); - } - - if ( type == OBJECT_MOBILEtg ) - { - // Creates the right-back wheel. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(6, rank); - m_object->SetObjectParent(6, 0); - pModFile->ReadModel("objects\\lem2w.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(6, D3DVECTOR(-2.0f, 1.0f, -3.0f)); - - // Creates the left-back wheel. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(7, rank); - m_object->SetObjectParent(7, 0); - pModFile->ReadModel("objects\\lem2w.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(7, D3DVECTOR(-2.0f, 1.0f, 3.0f)); - m_object->SetAngleY(7, PI); - - // Creates the right-front wheel. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(8, rank); - m_object->SetObjectParent(8, 0); - pModFile->ReadModel("objects\\lem2w.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(8, D3DVECTOR(3.0f, 1.0f, -3.0f)); - - // Creates the left-front wheel. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(9, rank); - m_object->SetObjectParent(9, 0); - pModFile->ReadModel("objects\\lem2w.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(9, D3DVECTOR(3.0f, 1.0f, 3.0f)); - m_object->SetAngleY(9, PI); - } - - if ( type == OBJECT_MOBILEta || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEts ) // caterpillars? - { - // Creates the right caterpillar. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(6, rank); - m_object->SetObjectParent(6, 0); - pModFile->ReadModel("objects\\lem2t.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(6, D3DVECTOR(0.0f, 2.0f, -3.0f)); - - // Creates the left caterpillar. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(7, rank); - m_object->SetObjectParent(7, 0); - pModFile->ReadModel("objects\\lem3t.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(7, D3DVECTOR(0.0f, 2.0f, 3.0f)); - } - - if ( type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs ) // large caterpillars? - { - // Creates the right caterpillar. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(6, rank); - m_object->SetObjectParent(6, 0); - pModFile->ReadModel("objects\\roller2.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(6, D3DVECTOR(0.0f, 2.0f, -3.0f)); - - // Creates the left caterpillar. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(7, rank); - m_object->SetObjectParent(7, 0); - pModFile->ReadModel("objects\\roller3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(7, D3DVECTOR(0.0f, 2.0f, 3.0f)); - } - - if ( type == OBJECT_MOBILEsa ) // underwater caterpillars? - { - // Creates the right caterpillar. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(6, rank); - m_object->SetObjectParent(6, 0); - pModFile->ReadModel("objects\\subm4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(6, D3DVECTOR(0.0f, 1.0f, -3.0f)); - - // Creates the left caterpillar. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(7, rank); - m_object->SetObjectParent(7, 0); - pModFile->ReadModel("objects\\subm5.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(7, D3DVECTOR(0.0f, 1.0f, 3.0f)); - } - - if ( type == OBJECT_MOBILEdr ) // caterpillars? - { - // Creates the right caterpillar. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(6, rank); - m_object->SetObjectParent(6, 0); - pModFile->ReadModel("objects\\drawer2.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(6, D3DVECTOR(0.0f, 1.0f, -3.0f)); - - // Creates the left caterpillar. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(7, rank); - m_object->SetObjectParent(7, 0); - pModFile->ReadModel("objects\\drawer3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(7, D3DVECTOR(0.0f, 1.0f, 3.0f)); - } - - if ( type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEft ) // flying? - { - // Creates the front foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(6, rank); - m_object->SetObjectParent(6, 0); - pModFile->ReadModel("objects\\lem2f.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(6, D3DVECTOR(1.7f, 3.0f, 0.0f)); - - // Creates the right-back foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(7, rank); - m_object->SetObjectParent(7, 0); - pModFile->ReadModel("objects\\lem2f.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(7, D3DVECTOR(-1.8f, 3.0f, -1.5f)); - m_object->SetAngleY(7, 120.0f*PI/180.0f); - - // Creates the left-back foot. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(8, rank); - m_object->SetObjectParent(8, 0); - pModFile->ReadModel("objects\\lem2f.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(8, D3DVECTOR(-1.8f, 3.0f, 1.5f)); - m_object->SetAngleY(8, -120.0f*PI/180.0f); - } - - if ( type == OBJECT_MOBILEia || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILEii ) // insect legs? - { - float table[] = - { - // x y z - -1.5f, 1.2f, -0.7f, // back leg - 0.0f, 0.0f, -1.0f, - 0.0f, 0.0f, -2.0f, - - 0.0f, 1.2f, -0.9f, // middle leg - 0.0f, 0.0f, -1.0f, - 0.0f, 0.0f, -2.0f, - - 1.5f, 1.2f, -0.7f, // front leg - 0.0f, 0.0f, -1.0f, - 0.0f, 0.0f, -2.0f, - }; - - for ( i=0 ; i<3 ; i++ ) - { - for ( j=0 ; j<3 ; j++ ) - { - sprintf(name, "objects\\ant%d.mod", j+4); // 4..6 - - // Creates the right leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(6+i*3+j, rank); - if ( j == 0 ) parent = 0; - else parent = 6+i*3+j-1; - m_object->SetObjectParent(6+i*3+j, parent); - pModFile->ReadModel(name); - pModFile->CreateEngineObject(rank); - pos.x = table[i*9+j*3+0]; - pos.y = table[i*9+j*3+1]; - pos.z = table[i*9+j*3+2]; - m_object->SetPosition(6+i*3+j, pos); - - // Creates the left leg. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(15+i*3+j, rank); - if ( j == 0 ) parent = 0; - else parent = 15+i*3+j-1; - m_object->SetObjectParent(15+i*3+j, parent); - pModFile->ReadModel(name); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - pos.x = table[i*9+j*3+0]; - pos.y = table[i*9+j*3+1]; - pos.z = -table[i*9+j*3+2]; - m_object->SetPosition(15+i*3+j, pos); - } - } - } - - if ( type == OBJECT_MOBILErt ) - { - // Creates the holder. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\roller2t.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(0.0f, 0.0f, 0.0f)); - m_object->SetAngleZ(1, 0.0f); - - // Creates the pestle. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 0); - pModFile->ReadModel("objects\\roller3t.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2, D3DVECTOR(9.0f, 4.0f, 0.0f)); - m_object->SetAngleZ(2, 0.0f); - } - - if ( type == OBJECT_MOBILErc ) - { - // Creates the holder. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\roller2c.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(3.0f, 4.6f, 0.0f)); - m_object->SetAngleZ(1, PI/8.0f); - - // Creates the cannon. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 0); - pModFile->ReadModel("objects\\roller3p.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2, D3DVECTOR(7.0f, 6.5f, 0.0f)); - m_object->SetAngleZ(2, 0.0f); - } - - if ( type == OBJECT_MOBILErr ) - { - // Creates the holder. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\recover1.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(2.0f, 5.0f, 0.0f)); - - // Creates the right arm. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 1); - pModFile->ReadModel("objects\\recover2.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2, D3DVECTOR(0.1f, 0.0f, -5.0f)); - m_object->SetAngleZ(2, 126.0f*PI/180.0f); - - // Creates the right forearm. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(3, rank); - m_object->SetObjectParent(3, 2); - pModFile->ReadModel("objects\\recover3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(3, D3DVECTOR(5.0f, 0.0f, -0.5f)); - m_object->SetAngleZ(3, -144.0f*PI/180.0f); - - // Creates the left arm. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(4, rank); - m_object->SetObjectParent(4, 1); - pModFile->ReadModel("objects\\recover2.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(4, D3DVECTOR(0.1f, 0.0f, 5.0f)); - m_object->SetAngleZ(4, 126.0f*PI/180.0f); - - // Creates the left forearm. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(5, rank); - m_object->SetObjectParent(5, 4); - pModFile->ReadModel("objects\\recover3.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(5, D3DVECTOR(5.0f, 0.0f, 0.5f)); - m_object->SetAngleZ(5, -144.0f*PI/180.0f); - } - - if ( type == OBJECT_MOBILErs ) - { - // Creates the holder. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\roller2s.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(0.0f, 0.0f, 0.0f)); - m_object->SetAngleZ(1, 0.0f); - - // Creates the intermediate piston. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 1); - pModFile->ReadModel("objects\\roller3s.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2, D3DVECTOR(7.0f, 4.5f, 0.0f)); - m_object->SetAngleZ(2, 0.0f); - - // Creates the piston with the sphere. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(3, rank); - m_object->SetObjectParent(3, 2); - pModFile->ReadModel("objects\\roller4s.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(3, D3DVECTOR(0.0f, 1.0f, 0.0f)); - m_object->SetAngleZ(3, 0.0f); - } - - if ( type == OBJECT_MOBILEsa ) - { - // Creates the holder. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\subm2.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(4.2f, 3.0f, 0.0f)); - - // Creates the right tong. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 1); - pModFile->ReadModel("objects\\subm3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2, D3DVECTOR(0.5f, 0.0f, -1.5f)); - - // Creates the left tong. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(3, rank); - m_object->SetObjectParent(3, 1); - pModFile->ReadModel("objects\\subm3.mod"); - pModFile->Mirror(); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(3, D3DVECTOR(0.5f, 0.0f, 1.5f)); - } - - if ( type == OBJECT_MOBILEdr ) - { - // Creates the carousel. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\drawer4.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(-3.0f, 3.0f, 0.0f)); - - // Creates the key. - if ( m_object->RetToy() ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 0); - pModFile->ReadModel("objects\\drawer5.mod"); - pModFile->CreateEngineObject(rank); - m_posKey = D3DVECTOR(3.0f, 5.7f, 0.0f); - m_object->SetPosition(2, m_posKey); - m_object->SetAngleY(2, 90.0f*PI/180.0f); - } - - // Creates pencils. - for ( i=0 ; i<8 ; i++ ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(10+i, rank); - m_object->SetObjectParent(10+i, 1); - sprintf(name, "objects\\drawer%d.mod", 10+i); - pModFile->ReadModel(name); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(10+i, D3DVECTOR(0.0f, 0.0f, 0.0f)); - m_object->SetAngleY(10+i, 45.0f*PI/180.0f*i); - } - } - - if ( type == OBJECT_MOBILEwt ) - { - // Creates the key. - if ( m_object->RetToy() ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 0); - pModFile->ReadModel("objects\\drawer5.mod"); - pModFile->CreateEngineObject(rank); - m_posKey = D3DVECTOR(0.2f, 4.1f, 0.0f); - m_object->SetPosition(2, m_posKey); - m_object->SetAngleY(2, 90.0f*PI/180.0f); - } - } - - if ( type == OBJECT_APOLLO2 ) - { - // Creates the accessories. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\apolloj2.mod"); // antenna - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(5.5f, 8.8f, 2.0f)); - m_object->SetAngleY(1, -120.0f*PI/180.0f); - m_object->SetAngleZ(1, 45.0f*PI/180.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2, rank); - m_object->SetObjectParent(2, 0); - pModFile->ReadModel("objects\\apolloj3.mod"); // camera - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2, D3DVECTOR(5.5f, 2.8f, -2.0f)); - m_object->SetAngleY(2, 30.0f*PI/180.0f); - - // Creates the wheels. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(6, rank); - m_object->SetObjectParent(6, 0); - pModFile->ReadModel("objects\\apolloj4.mod"); // wheel - pModFile->CreateEngineObject(rank); - m_object->SetPosition(6, D3DVECTOR(-5.75f, 1.65f, -5.0f)); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(7, rank); - m_object->SetObjectParent(7, 0); - pModFile->ReadModel("objects\\apolloj4.mod"); // wheel - pModFile->CreateEngineObject(rank); - m_object->SetPosition(7, D3DVECTOR(-5.75f, 1.65f, 5.0f)); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(8, rank); - m_object->SetObjectParent(8, 0); - pModFile->ReadModel("objects\\apolloj4.mod"); // wheel - pModFile->CreateEngineObject(rank); - m_object->SetPosition(8, D3DVECTOR(5.75f, 1.65f, -5.0f)); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(9, rank); - m_object->SetObjectParent(9, 0); - pModFile->ReadModel("objects\\apolloj4.mod"); // wheel - pModFile->CreateEngineObject(rank); - m_object->SetPosition(9, D3DVECTOR(5.75f, 1.65f, 5.00f)); - - // Creates mud guards. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(10, rank); - m_object->SetObjectParent(10, 0); - pModFile->ReadModel("objects\\apolloj6.mod"); // wheel - pModFile->CreateEngineObject(rank); - m_object->SetPosition(10, D3DVECTOR(-5.75f, 1.65f, -5.0f)); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(11, rank); - m_object->SetObjectParent(11, 0); - pModFile->ReadModel("objects\\apolloj6.mod"); // wheel - pModFile->CreateEngineObject(rank); - m_object->SetPosition(11, D3DVECTOR(-5.75f, 1.65f, 5.0f)); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(12, rank); - m_object->SetObjectParent(12, 0); - pModFile->ReadModel("objects\\apolloj5.mod"); // wheel - pModFile->CreateEngineObject(rank); - m_object->SetPosition(12, D3DVECTOR(5.75f, 1.65f, -5.0f)); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(13, rank); - m_object->SetObjectParent(13, 0); - pModFile->ReadModel("objects\\apolloj5.mod"); // wheel - pModFile->CreateEngineObject(rank); - m_object->SetPosition(13, D3DVECTOR(5.75f, 1.65f, 5.00f)); - } - -#if 1 - if ( type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs ) - { - m_object->CreateShadowCircle(6.0f, 1.0f); - } - else if ( type == OBJECT_MOBILEta || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEsa ) - { - m_object->CreateShadowCircle(5.0f, 1.0f); - } - else if ( type == OBJECT_MOBILEdr ) - { - m_object->CreateShadowCircle(4.5f, 1.0f); - } - else if ( type == OBJECT_APOLLO2 ) - { - m_object->CreateShadowCircle(7.0f, 0.8f); - } - else - { - m_object->CreateShadowCircle(4.0f, 1.0f); - } -#else - if ( type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs ) - { - m_object->CreateShadowCircle(6.0f, 1.0f, D3DSHADOWTANK); - } - else if ( type == OBJECT_MOBILEta || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEts ) - { - m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWTANK); - } - else if ( type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEfs ) - { - m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWFLY); - } - else if ( type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEws ) - { - m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWWHEEL); - } - else if ( type == OBJECT_APOLLO2 ) - { - m_object->CreateShadowCircle(6.0f, 0.8f); - } - else - { - m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWNORM); - } -#endif - - if ( type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEft ) // flying? - { -//? color.r = 0.5f-1.0f; -//? color.g = 0.2f-1.0f; -//? color.b = 0.0f-1.0f; // orange -//? color.r = 0.8f; -//? color.g = 0.6f; -//? color.b = 0.0f; // yellow-orange - color.r = 0.0f; - color.g = 0.4f; - color.b = 0.8f; // blue - color.a = 0.0f; - m_object->CreateShadowLight(50.0f, color); - } - - CreatePhysics(type); - m_object->SetFloorHeight(0.0f); - - if ( power > 0.0f && - type != OBJECT_MOBILEdr && - type != OBJECT_APOLLO2 ) - { - color.r = 1.0f; - color.g = 1.0f; - color.b = 0.0f; // yellow - color.a = 0.0f; - m_object->CreateEffectLight(20.0f, color); - - // Creates the battery. - pPower = new CObject(m_iMan); - pPower->SetType(power<=1.0f?OBJECT_POWER:OBJECT_ATOMIC); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - pPower->SetObjectRank(0, rank); - - if ( power <= 1.0f ) pModFile->ReadModel("objects\\power.mod"); - else pModFile->ReadModel("objects\\atomic.mod"); - pModFile->CreateEngineObject(rank); - - pPower->SetPosition(0, m_object->RetCharacter()->posPower); - pPower->CreateCrashSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - pPower->SetGlobalSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 1.5f); - - pPower->SetTruck(m_object); - m_object->SetPower(pPower); - - if ( power <= 1.0f ) pPower->SetEnergy(power); - else pPower->SetEnergy(power/100.0f); - } - - pos = m_object->RetPosition(0); - m_object->SetPosition(0, pos); //to display the shadows immediately - - m_engine->LoadAllTexture(); - - delete pModFile; - return TRUE; -} - -// Creates the physics of the object. - -void CMotionVehicle::CreatePhysics(ObjectType type) -{ - Character* character; - - character = m_object->RetCharacter(); - - if ( type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEwt ) // wheels? - { - m_physics->SetType(TYPE_ROLLING); - - character->wheelFront = 3.0f; - character->wheelBack = 4.0f; - character->wheelLeft = 4.0f; - character->wheelRight = 4.0f; - character->posPower = D3DVECTOR(-3.2f, 3.0f, 0.0f); - - m_physics->SetLinMotionX(MO_ADVSPEED, 20.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 10.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 40.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 50.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 30.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 20.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 0.8f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 0.8f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 8.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 8.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 12.0f); - } - - if ( type == OBJECT_MOBILEtg ) - { - m_physics->SetType(TYPE_ROLLING); - - character->wheelFront = 4.0f; - character->wheelBack = 3.0f; - character->wheelLeft = 4.0f; - character->wheelRight = 4.0f; - character->posPower = D3DVECTOR(-3.2f, 3.0f, 0.0f); - - m_physics->SetLinMotionX(MO_ADVSPEED, 20.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 10.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 40.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 50.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 20.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 20.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 0.8f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 0.8f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 10.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 15.0f); - } - - if ( type == OBJECT_MOBILEta || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEts ) // caterpillars? - { - m_physics->SetType(TYPE_ROLLING); - - character->wheelFront = 4.0f; - character->wheelBack = 4.0f; - character->wheelLeft = 4.8f; - character->wheelRight = 4.8f; - character->posPower = D3DVECTOR(-3.2f, 3.0f, 0.0f); - - m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 8.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 15.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 8.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 20.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 10.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 6.0f); - } - - if ( type == OBJECT_MOBILEia || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEis ) // legs? - { - m_physics->SetType(TYPE_ROLLING); - - character->wheelFront = 4.0f; - character->wheelBack = 4.0f; - character->wheelLeft = 5.0f; - character->wheelRight = 5.0f; - character->posPower = D3DVECTOR(-3.2f, 3.0f, 0.0f); - - m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 8.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 40.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 10.0f); -//? m_physics->SetLinMotionX(MO_TERFORCE, 15.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 10.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 15.0f); - } - - if ( type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEft ) // flying? - { - m_physics->SetType(TYPE_FLYING); - - character->wheelFront = 5.0f; - character->wheelBack = 4.0f; - character->wheelLeft = 4.5f; - character->wheelRight = 4.5f; - character->posPower = D3DVECTOR(-3.2f, 3.0f, 0.0f); - - m_physics->SetLinMotionX(MO_ADVSPEED, 50.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 50.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 20.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 50.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 50.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); - m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f); - m_physics->SetLinMotionY(MO_RECSPEED, 60.0f); - m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f); - m_physics->SetLinMotionY(MO_RECACCEL, 50.0f); - m_physics->SetLinMotionY(MO_STOACCEL, 50.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 0.4f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 0.4f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 2.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 2.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 2.0f); - } - - if ( type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs ) // large caterpillars? - { - m_physics->SetType(TYPE_ROLLING); - - character->wheelFront = 5.0f; - character->wheelBack = 5.0f; - character->wheelLeft = 6.0f; - character->wheelRight = 6.0f; - character->posPower = D3DVECTOR(-5.8f, 4.0f, 0.0f); - - m_physics->SetLinMotionX(MO_ADVSPEED, 10.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 5.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 10.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 5.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 20.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 0.3f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 0.3f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 2.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 2.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 4.0f); - } - - if ( type == OBJECT_MOBILEsa ) - { - m_physics->SetType(TYPE_ROLLING); - - character->wheelFront = 4.0f; - character->wheelBack = 4.0f; - character->wheelLeft = 4.0f; - character->wheelRight = 4.0f; - character->posPower = D3DVECTOR(-5.0f, 3.0f, 0.0f); - - m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 10.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 10.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 20.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 5.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 5.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 10.0f); - } - - if ( type == OBJECT_MOBILEdr ) - { - m_physics->SetType(TYPE_ROLLING); - - character->wheelFront = 4.0f; - character->wheelBack = 4.0f; - character->wheelLeft = 4.0f; - character->wheelRight = 4.0f; - character->posPower = D3DVECTOR(-5.0f, 3.0f, 0.0f); - - m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 10.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 10.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 20.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 5.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 5.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 10.0f); - } - - if ( type == OBJECT_APOLLO2 ) // jeep? - { - m_physics->SetType(TYPE_ROLLING); - - character->wheelFront = 6.0f; - character->wheelBack = 6.0f; - character->wheelLeft = 5.0f; - character->wheelRight = 5.0f; - - m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 10.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 2.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 2.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 30.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 20.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 0.4f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 0.4f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 2.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 2.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 4.0f); - } -} - - -// Management of an event. - -BOOL CMotionVehicle::EventProcess(const Event &event) -{ - CMotion::EventProcess(event); - - if ( event.event == EVENT_FRAME ) - { - return EventFrame(event); - } - - if ( event.event == EVENT_KEYDOWN ) - { - } - - return TRUE; -} - -// Management of an event. - -BOOL CMotionVehicle::EventFrame(const Event &event) -{ - D3DMATRIX* mat; - Character* character; - D3DVECTOR pos, angle, floor; - ObjectType type; - float s, a, speedBL, speedBR, speedFL, speedFR, h, a1, a2; - float back, front, dist, radius, limit[2]; - - if ( m_engine->RetPause() ) return TRUE; - if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return TRUE; - - type = m_object->RetType(); - - if ( type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEtg || - type == OBJECT_APOLLO2 ) // wheels? - { - s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.0f; - a = m_physics->RetCirMotionY(MO_MOTSPEED)*3.0f; - - if ( type == OBJECT_APOLLO2 ) s *= 0.5f; - - speedBR = -s+a; - speedBL = s+a; - speedFR = -s+a; - speedFL = s+a; - - m_object->SetAngleZ(6, m_object->RetAngleZ(6)+event.rTime*speedBR); // turning the wheels - m_object->SetAngleZ(7, m_object->RetAngleZ(7)+event.rTime*speedBL); - m_object->SetAngleZ(8, m_object->RetAngleZ(8)+event.rTime*speedFR); - m_object->SetAngleZ(9, m_object->RetAngleZ(9)+event.rTime*speedFL); - - if ( s > 0.0f ) - { - m_wheelTurn[0] = -a*0.05f; - m_wheelTurn[1] = -a*0.05f+PI; - m_wheelTurn[2] = a*0.05f; - m_wheelTurn[3] = a*0.05f+PI; - } - else if ( s < 0.0f ) - { - m_wheelTurn[0] = a*0.05f; - m_wheelTurn[1] = a*0.05f+PI; - m_wheelTurn[2] = -a*0.05f; - m_wheelTurn[3] = -a*0.05f+PI; - } - else - { - m_wheelTurn[0] = Abs(a)*0.05f; - m_wheelTurn[1] = -Abs(a)*0.05f+PI; - m_wheelTurn[2] = -Abs(a)*0.05f; - m_wheelTurn[3] = Abs(a)*0.05f+PI; - } - m_object->SetAngleY(6, m_object->RetAngleY(6)+(m_wheelTurn[0]-m_object->RetAngleY(6))*event.rTime*8.0f); - m_object->SetAngleY(7, m_object->RetAngleY(7)+(m_wheelTurn[1]-m_object->RetAngleY(7))*event.rTime*8.0f); - m_object->SetAngleY(8, m_object->RetAngleY(8)+(m_wheelTurn[2]-m_object->RetAngleY(8))*event.rTime*8.0f); - m_object->SetAngleY(9, m_object->RetAngleY(9)+(m_wheelTurn[3]-m_object->RetAngleY(9))*event.rTime*8.0f); - - if ( type == OBJECT_APOLLO2 ) - { - m_object->SetAngleY(10, m_object->RetAngleY(6)+(m_wheelTurn[0]-m_object->RetAngleY(6))*event.rTime*8.0f); - m_object->SetAngleY(11, m_object->RetAngleY(7)+(m_wheelTurn[1]-m_object->RetAngleY(7))*event.rTime*8.0f+PI); - m_object->SetAngleY(12, m_object->RetAngleY(8)+(m_wheelTurn[2]-m_object->RetAngleY(8))*event.rTime*8.0f); - m_object->SetAngleY(13, m_object->RetAngleY(9)+(m_wheelTurn[3]-m_object->RetAngleY(9))*event.rTime*8.0f+PI); - } - - pos = m_object->RetPosition(0); - angle = m_object->RetAngle(0); - if ( pos.x != m_wheelLastPos.x || - pos.y != m_wheelLastPos.y || - pos.z != m_wheelLastPos.z || - angle.x != m_wheelLastAngle.x || - angle.y != m_wheelLastAngle.y || - angle.z != m_wheelLastAngle.z ) - { - m_wheelLastPos = pos; - m_wheelLastAngle = angle; - - if ( type == OBJECT_MOBILEtg ) - { - back = -2.0f; // back wheels position - front = 3.0f; // front wheels position - dist = 3.0f; // distancing wheels Z - radius = 1.0f; - } - else if ( type == OBJECT_APOLLO2 ) - { - back = -5.75f; // back wheels position - front = 5.75f; // front wheels position - dist = 5.00f; // distancing wheels Z - radius = 1.65f; - } - else - { - back = -3.0f; // back wheels position - front = 2.0f; // front wheels position - dist = 3.0f; // distancing wheels Z - radius = 1.0f; - } - - if ( Length(pos, m_engine->RetEyePt()) < 50.0f ) // suspension? - { - character = m_object->RetCharacter(); - mat = m_object->RetWorldMatrix(0); - - pos.x = -character->wheelBack; // right back wheel - pos.z = -character->wheelRight; - pos.y = 0.0f; - pos = Transform(*mat, pos); - h = m_terrain->RetFloorHeight(pos); - if ( h > 0.5f ) h = 0.5f; - if ( h < -0.5f ) h = -0.5f; - pos.x = back; - pos.y = radius-h; - pos.z = -dist; - m_object->SetPosition(6, pos); - if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(10, pos); - - pos.x = -character->wheelBack; // left back wheel - pos.z = character->wheelLeft; - pos.y = 0.0f; - pos = Transform(*mat, pos); - h = m_terrain->RetFloorHeight(pos); - if ( h > 0.5f ) h = 0.5f; - if ( h < -0.5f ) h = -0.5f; - pos.x = back; - pos.y = radius-h; - pos.z = dist; - m_object->SetPosition(7, pos); - if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(11, pos); - - pos.x = character->wheelFront; // right front wheel - pos.z = -character->wheelRight; - pos.y = 0.0f; - pos = Transform(*mat, pos); - h = m_terrain->RetFloorHeight(pos); - if ( h > 0.5f ) h = 0.5f; - if ( h < -0.5f ) h = -0.5f; - pos.x = front; - pos.y = radius-h; - pos.z = -dist; - m_object->SetPosition(8, pos); - if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(12, pos); - - pos.x = character->wheelFront; // left front wheel - pos.z = character->wheelLeft; - pos.y = 0.0f; - pos = Transform(*mat, pos); - h = m_terrain->RetFloorHeight(pos); - if ( h > 0.5f ) h = 0.5f; - if ( h < -0.5f ) h = -0.5f; - pos.x = front; - pos.y = radius-h; - pos.z = dist; - m_object->SetPosition(9, pos); - if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(13, pos); - } - else - { - m_object->SetPosition(6, D3DVECTOR(back, radius, -dist)); - m_object->SetPosition(7, D3DVECTOR(back, radius, dist)); - m_object->SetPosition(8, D3DVECTOR(front, radius, -dist)); - m_object->SetPosition(9, D3DVECTOR(front, radius, dist)); - - if ( type == OBJECT_APOLLO2 ) - { - m_object->SetPosition(10, D3DVECTOR(back, radius, -dist)); - m_object->SetPosition(11, D3DVECTOR(back, radius, dist)); - m_object->SetPosition(12, D3DVECTOR(front, radius, -dist)); - m_object->SetPosition(13, D3DVECTOR(front, radius, dist)); - } - } - } - } - - if ( type == OBJECT_MOBILEta || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs || - type == OBJECT_MOBILEsa || - type == OBJECT_MOBILEdr ) // caterpillars? - { - s = m_physics->RetLinMotionX(MO_MOTSPEED)*0.7f; - a = m_physics->RetCirMotionY(MO_MOTSPEED)*2.5f; - - m_posTrackLeft += event.rTime*(s+a); - m_posTrackRight += event.rTime*(s-a); - - UpdateTrackMapping(m_posTrackLeft, m_posTrackRight, type); - - pos = m_object->RetPosition(0); - angle = m_object->RetAngle(0); - if ( pos.x != m_wheelLastPos.x || - pos.y != m_wheelLastPos.y || - pos.z != m_wheelLastPos.z || - angle.x != m_wheelLastAngle.x || - angle.y != m_wheelLastAngle.y || - angle.z != m_wheelLastAngle.z ) - { - m_wheelLastPos = pos; - m_wheelLastAngle = angle; - - if ( type == OBJECT_MOBILEta || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEts ) - { - limit[0] = 8.0f*PI/180.0f; - limit[1] = -12.0f*PI/180.0f; - } - else if ( type == OBJECT_MOBILEsa ) - { - limit[0] = 15.0f*PI/180.0f; - limit[1] = -15.0f*PI/180.0f; - } - else if ( type == OBJECT_MOBILEdr ) - { - limit[0] = 10.0f*PI/180.0f; - limit[1] = -10.0f*PI/180.0f; - } - else - { - limit[0] = 15.0f*PI/180.0f; - limit[1] = -10.0f*PI/180.0f; - } - - if ( Length(pos, m_engine->RetEyePt()) < 50.0f ) // suspension? - { - character = m_object->RetCharacter(); - mat = m_object->RetWorldMatrix(0); - - pos.x = character->wheelFront; // right front wheel - pos.z = -character->wheelRight; - pos.y = 0.0f; - pos = Transform(*mat, pos); - a1 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelFront); - - pos.x = -character->wheelBack; // right back wheel - pos.z = -character->wheelRight; - pos.y = 0.0f; - pos = Transform(*mat, pos); - a2 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelBack); - - a = (a2-a1)/2.0f; - if ( a > limit[0] ) a = limit[0]; - if ( a < limit[1] ) a = limit[1]; - m_object->SetAngleZ(6, a); - - pos.x = character->wheelFront; // left front wheel - pos.z = character->wheelLeft; - pos.y = 0.0f; - pos = Transform(*mat, pos); - a1 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelFront); - - pos.x = -character->wheelBack; // left back wheel - pos.z = character->wheelLeft; - pos.y = 0.0f; - pos = Transform(*mat, pos); - a2 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelBack); - - a = (a2-a1)/2.0f; - if ( a > limit[0] ) a = limit[0]; - if ( a < limit[1] ) a = limit[1]; - m_object->SetAngleZ(7, a); - } - else - { - m_object->SetAngleZ(6, 0.0f); - m_object->SetAngleZ(7, 0.0f); - } - } - } - - if ( type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEdr ) // toy is key? - { - pos = m_posKey; - if ( m_object->RetSelect() && - m_camera->RetType() == CAMERA_ONBOARD ) - { - pos.y += 10.0f; // out of sight! - } - m_object->SetPosition(2, pos); - - s = -Abs(m_physics->RetLinMotionX(MO_MOTSPEED)*0.1f); - s += -Abs(m_physics->RetCirMotionY(MO_MOTSPEED)*1.5f); - m_object->SetAngleY(2, m_object->RetAngleY(2)+event.rTime*s); // turns the key - } - - if ( type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEft ) // flying? - { - EventFrameFly(event); - } - - if ( type == OBJECT_MOBILEia || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEis ) // legs? - { - EventFrameInsect(event); - } - - if ( type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEii ) // insect cannon? - { - EventFrameCanoni(event); - } - - return TRUE; -} - -// Managing an event for a flying robot. - -BOOL CMotionVehicle::EventFrameFly(const Event &event) -{ - D3DMATRIX* mat; - D3DVECTOR pos, angle, paw[3]; - float hope[3], actual, final, h, a; - int i; - - pos = m_object->RetPosition(0); - angle = m_object->RetAngle(0); - if ( m_bFlyFix && - pos.x == m_wheelLastPos.x && - pos.y == m_wheelLastPos.y && - pos.z == m_wheelLastPos.z && - angle.x == m_wheelLastAngle.x && - angle.y == m_wheelLastAngle.y && - angle.z == m_wheelLastAngle.z ) return TRUE; - - m_wheelLastPos = pos; - m_wheelLastAngle = angle; - - if ( m_physics->RetLand() ) // on the ground? - { - mat = m_object->RetWorldMatrix(0); - paw[0] = Transform(*mat, D3DVECTOR( 4.2f, 0.0f, 0.0f)); // front - paw[1] = Transform(*mat, D3DVECTOR(-3.0f, 0.0f, -3.7f)); // right back - paw[2] = Transform(*mat, D3DVECTOR(-3.0f, 0.0f, 3.7f)); // left back - - for ( i=0 ; i<3 ; i++ ) - { - h = m_terrain->RetFloorHeight(paw[i]); - a = -atanf(h*0.5f); - if ( a > PI*0.2f ) a = PI*0.2f; - if ( a < -PI*0.2f ) a = -PI*0.2f; - hope[i] = a; - } - } - else // in flight? - { - hope[0] = 0.0f; // front - hope[1] = 0.0f; // right back - hope[2] = 0.0f; // left back - } - - m_bFlyFix = TRUE; - for ( i=0 ; i<3 ; i++ ) - { - actual = m_object->RetAngleZ(6+i); - final = Smooth(actual, hope[i], event.rTime*5.0f); - if ( final != actual ) - { - m_bFlyFix = FALSE; // it is moving - m_object->SetAngleZ(6+i, final); - } - } - - return TRUE; -} - -// Event management for insect legs. - -BOOL CMotionVehicle::EventFrameInsect(const Event &event) -{ - D3DVECTOR dir; - float s, a, prog, time; - int i, st, nd, action; - BOOL bStop, bOnBoard; - - static int table[] = - { - // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: - 60,25,0, 60,0,0, 60,-25,0, // t0: thighs 1..4 - -35,0,0, -35,0,0, -35,0,0, // t0: legs 1..4 - -65,0,0, -65,0,0, -65,0,0, // t0: feet 1..4 - // on the ground: - 30,10,0, 30,-15,0, 30,-40,0, // t1: thighs 1..4 - -45,0,0, -45,0,0, -45,0,0, // t1: legs 1..4 - -20,0,0, -20,0,0, -20,0,0, // t1: feet 1..4 - // on the ground back: - 35,40,0, 40,15,0, 40,-10,0, // t2: thighs 1..4 - -35,0,0, -35,0,0, -35,0,0, // t2: legs 1..4 - -50,0,0, -65,0,0, -65,0,0, // t2: feet 1..4 - // stop: - 35,35,0, 40,10,0, 40,-15,0, // s0: thighs 1..4 - -35,0,0, -35,0,0, -35,0,0, // s0: legs 1..4 - -50,0,0, -65,0,0, -65,0,0, // s0: feet 1..4 - }; - - bOnBoard = FALSE; - if ( m_object->RetSelect() && - m_camera->RetType() == CAMERA_ONBOARD ) - { - bOnBoard = TRUE; - } - - s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f; - a = Abs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.0f); - - if ( s == 0.0f && a != 0.0f ) a *= 1.5f; - - m_armTimeAbs += event.rTime; - m_armMember += (s+a)*event.rTime*0.15f; - - bStop = ( a == 0.0f && s == 0.0f ); // stop? - - action = 0; // walking - if ( s == 0.0f && a == 0.0f ) - { - action = 3; // stop - } - - if ( bStop ) - { - prog = Mod(m_armTimeAbs, 2.0f)/10.0f; - a = Mod(m_armMember, 1.0f); - a = (prog-a)*event.rTime*2.0f; // stop position is pleasantly - m_armMember += a; - } - - if ( m_object->RetRuin() ) // burn or explode? - { - action = 3; - } - - for ( i=0 ; i<6 ; i++ ) // the six legs - { - if ( action != 0 ) // special action in progress? - { - st = 3*3*3*action + (i%3)*3; - nd = st; - time = event.rTime*5.0f; - } - else - { - if ( i < 3 ) prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f); - else prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f); - if ( prog < 0.33f ) // t0..t1 ? - { - prog = prog/0.33f; // 0..1 - st = 0; // index start - nd = 1; // index end - } - else if ( prog < 0.67f ) // t1..t2 ? - { - prog = (prog-0.33f)/0.33f; // 0..1 - st = 1; // index start - nd = 2; // index end - } - else // t2..t0 ? - { - prog = (prog-0.67f)/0.33f; // 0..1 - st = 2; // index start - nd = 0; // index end - } - st = 3*3*3*action + st*3*3*3 + (i%3)*3; - nd = 3*3*3*action + nd*3*3*3 + (i%3)*3; - - // Less and less soft ... - time = event.rTime*20.0f; - } - - if ( i < 3 ) // right leg (1..3) ? - { - m_object->SetAngleX(6+3*i+0, Smooth(m_object->RetAngleX(6+3*i+0), Prop(table[st+ 0], table[nd+ 0], prog), time)); - m_object->SetAngleY(6+3*i+0, Smooth(m_object->RetAngleY(6+3*i+0), Prop(table[st+ 1], table[nd+ 1], prog), time)); - m_object->SetAngleZ(6+3*i+0, Smooth(m_object->RetAngleZ(6+3*i+0), Prop(table[st+ 2], table[nd+ 2], prog), time)); - m_object->SetAngleX(6+3*i+1, Smooth(m_object->RetAngleX(6+3*i+1), Prop(table[st+ 9], table[nd+ 9], prog), time)); - m_object->SetAngleY(6+3*i+1, Smooth(m_object->RetAngleY(6+3*i+1), Prop(table[st+10], table[nd+10], prog), time)); - m_object->SetAngleZ(6+3*i+1, Smooth(m_object->RetAngleZ(6+3*i+1), Prop(table[st+11], table[nd+11], prog), time)); - m_object->SetAngleX(6+3*i+2, Smooth(m_object->RetAngleX(6+3*i+2), Prop(table[st+18], table[nd+18], prog), time)); - m_object->SetAngleY(6+3*i+2, Smooth(m_object->RetAngleY(6+3*i+2), Prop(table[st+19], table[nd+19], prog), time)); - m_object->SetAngleZ(6+3*i+2, Smooth(m_object->RetAngleZ(6+3*i+2), Prop(table[st+20], table[nd+20], prog), time)); - } - else // left leg (4..6) ? - { - m_object->SetAngleX(6+3*i+0, Smooth(m_object->RetAngleX(6+3*i+0), Prop(-table[st+ 0], -table[nd+ 0], prog), time)); - m_object->SetAngleY(6+3*i+0, Smooth(m_object->RetAngleY(6+3*i+0), Prop(-table[st+ 1], -table[nd+ 1], prog), time)); - m_object->SetAngleZ(6+3*i+0, Smooth(m_object->RetAngleZ(6+3*i+0), Prop( table[st+ 2], table[nd+ 2], prog), time)); - m_object->SetAngleX(6+3*i+1, Smooth(m_object->RetAngleX(6+3*i+1), Prop(-table[st+ 9], -table[nd+ 9], prog), time)); - m_object->SetAngleY(6+3*i+1, Smooth(m_object->RetAngleY(6+3*i+1), Prop(-table[st+10], -table[nd+10], prog), time)); - m_object->SetAngleZ(6+3*i+1, Smooth(m_object->RetAngleZ(6+3*i+1), Prop( table[st+11], table[nd+11], prog), time)); - m_object->SetAngleX(6+3*i+2, Smooth(m_object->RetAngleX(6+3*i+2), Prop(-table[st+18], -table[nd+18], prog), time)); - m_object->SetAngleY(6+3*i+2, Smooth(m_object->RetAngleY(6+3*i+2), Prop(-table[st+19], -table[nd+19], prog), time)); - m_object->SetAngleZ(6+3*i+2, Smooth(m_object->RetAngleZ(6+3*i+2), Prop( table[st+20], table[nd+20], prog), time)); - } - } - - if ( bStop ) - { - } - else - { - a = Mod(m_armMember, 1.0f); - if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1 - else a = 3.0f-4.0f*a; // 1..-1 - dir.x = sinf(a)*0.05f; - - s = Mod(m_armMember/2.0f, 1.0f); - if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1 - else s = 3.0f-4.0f*s; // 1..-1 - dir.z = sinf(s)*0.1f; - - dir.y = 0.0f; - - if ( bOnBoard ) dir *= 0.6f; - SetInclinaison(dir); - } - - return TRUE; -} - -// Event management for a insect cannon. - -BOOL CMotionVehicle::EventFrameCanoni(const Event &event) -{ - CObject* power; - D3DVECTOR pos, speed; - FPOINT dim; - float zoom, angle, energy, factor; - BOOL bOnBoard = FALSE; - - m_canonTime += event.rTime; - - if ( m_object->RetSelect() && - m_camera->RetType() == CAMERA_ONBOARD ) - { - bOnBoard = TRUE; - } - - power = m_object->RetPower(); - if ( power == 0 ) - { - energy = 0.0f; - } - else - { - energy = power->RetEnergy(); - } - if ( energy == 0.0f ) return TRUE; - - factor = 0.5f+energy*0.5f; - if ( bOnBoard ) factor *= 0.8f; - - zoom = 1.3f+ - sinf(m_canonTime*PI*0.31f)*0.10f+ - sinf(m_canonTime*PI*0.52f)*0.08f+ - sinf(m_canonTime*PI*1.53f)*0.05f; - zoom *= factor; - m_object->SetZoomY(2, zoom); - - zoom = 1.0f+ - sinf(m_canonTime*PI*0.27f)*0.07f+ - sinf(m_canonTime*PI*0.62f)*0.06f+ - sinf(m_canonTime*PI*1.73f)*0.03f; - zoom *= factor; - m_object->SetZoomZ(2, zoom); - - angle = sinf(m_canonTime*1.0f)*0.10f+ - sinf(m_canonTime*1.3f)*0.15f+ - sinf(m_canonTime*2.7f)*0.05f; - m_object->SetAngleX(2, angle); - -#if 0 - m_lastTimeCanon -= event.rTime; - if ( m_lastTimeCanon <= 0.0f ) - { - m_lastTimeCanon = m_engine->ParticuleAdapt(0.5f+Rand()*0.5f); - - pos = m_object->RetPosition(0); - pos.y += 8.0f; - speed.y = 7.0f+Rand()*3.0f; - speed.x = (Rand()-0.5f)*2.0f; - speed.z = 2.0f+Rand()*2.0f; - if ( Rand() < 0.5f ) speed.z = -speed.z; - mat = m_object->RetRotateMatrix(0); - speed = Transform(*mat, speed); - dim.x = Rand()*0.1f+0.1f; - if ( bOnBoard ) dim.x *= 0.4f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIORGANIC2, 2.0f, 10.0f); - } -#endif - - return TRUE; -} - - -// Updates the mapping of the texture of the caterpillars. - -void CMotionVehicle::UpdateTrackMapping(float left, float right, ObjectType type) -{ - D3DMATERIAL7 mat; - float limit[4]; - int rRank, lRank, i; - - ZeroMemory( &mat, sizeof(D3DMATERIAL7) ); - mat.diffuse.r = 1.0f; - mat.diffuse.g = 1.0f; - mat.diffuse.b = 1.0f; // white - mat.ambient.r = 0.5f; - mat.ambient.g = 0.5f; - mat.ambient.b = 0.5f; - - rRank = m_object->RetObjectRank(6); - lRank = m_object->RetObjectRank(7); - - - if ( type == OBJECT_MOBILEdr ) - { - limit[0] = 0.0f; - limit[1] = 1000000.0f; - limit[2] = limit[1]; - limit[3] = m_engine->RetLimitLOD(1); - - m_engine->TrackTextureMapping(rRank, mat, D3DSTATEPART1, "drawer.tga", "", - limit[0], limit[1], D3DMAPPINGX, - right, 1.0f, 8.0f, 192.0f, 256.0f); - - m_engine->TrackTextureMapping(lRank, mat, D3DSTATEPART2, "drawer.tga", "", - limit[0], limit[1], D3DMAPPINGX, - left, 1.0f, 8.0f, 192.0f, 256.0f); - } - else - { - limit[0] = 0.0f; - limit[1] = m_engine->RetLimitLOD(0); - limit[2] = limit[1]; - limit[3] = m_engine->RetLimitLOD(1); - - for ( i=0 ; i<2 ; i++ ) - { - m_engine->TrackTextureMapping(rRank, mat, D3DSTATEPART1, "lemt.tga", "", - limit[i*2+0], limit[i*2+1], D3DMAPPINGX, - right, 1.0f, 8.0f, 192.0f, 256.0f); - - m_engine->TrackTextureMapping(lRank, mat, D3DSTATEPART2, "lemt.tga", "", - limit[i*2+0], limit[i*2+1], D3DMAPPINGX, - left, 1.0f, 8.0f, 192.0f, 256.0f); - } - } - -} - - - -// State management of the pencil drawing robot. - -BOOL CMotionVehicle::RetTraceDown() -{ - return m_bTraceDown; -} - -void CMotionVehicle::SetTraceDown(BOOL bDown) -{ - m_bTraceDown = bDown; -} - -int CMotionVehicle::RetTraceColor() -{ - return m_traceColor; -} - -void CMotionVehicle::SetTraceColor(int color) -{ - m_traceColor = color; -} - -float CMotionVehicle::RetTraceWidth() -{ - return m_traceWidth; -} - -void CMotionVehicle::SetTraceWidth(float width) -{ - m_traceWidth = width; -} - - diff --git a/src/motionvehicle.h b/src/motionvehicle.h deleted file mode 100644 index 1b351c4..0000000 --- a/src/motionvehicle.h +++ /dev/null @@ -1,82 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motionvehicle.h - -#ifndef _MOTIONVEHICLE_H_ -#define _MOTIONVEHICLE_H_ - - -#include "motion.h" - - -class CInstanceManager; -class CEngine; -class CLight; -class CParticule; -class CTerrain; -class CCamera; -class CBrain; -class CPhysics; -class CObject; - - -class CMotionVehicle : public CMotion -{ -public: - CMotionVehicle(CInstanceManager* iMan, CObject* object); - ~CMotionVehicle(); - - void DeleteObject(BOOL bAll=FALSE); - BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); - BOOL EventProcess(const Event &event); - - BOOL RetTraceDown(); - void SetTraceDown(BOOL bDown); - int RetTraceColor(); - void SetTraceColor(int color); - float RetTraceWidth(); - void SetTraceWidth(float width); - -protected: - void CreatePhysics(ObjectType type); - BOOL EventFrame(const Event &event); - BOOL EventFrameFly(const Event &event); - BOOL EventFrameInsect(const Event &event); - BOOL EventFrameCanoni(const Event &event); - void UpdateTrackMapping(float left, float right, ObjectType type); - -protected: - float m_wheelTurn[4]; - float m_flyPaw[3]; - float m_posTrackLeft; - float m_posTrackRight; - int m_partiReactor; - float m_armTimeAbs; - float m_armMember; - float m_canonTime; - float m_lastTimeCanon; - D3DVECTOR m_wheelLastPos; - D3DVECTOR m_wheelLastAngle; - D3DVECTOR m_posKey; - BOOL m_bFlyFix; - BOOL m_bTraceDown; - int m_traceColor; - float m_traceWidth; -}; - - -#endif //_MOTIONVEHICLE_H_ diff --git a/src/motionworm.cpp b/src/motionworm.cpp deleted file mode 100644 index eb32b44..0000000 --- a/src/motionworm.cpp +++ /dev/null @@ -1,380 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motionworm.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "light.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "modfile.h" -#include "sound.h" -#include "motion.h" -#include "motionworm.h" - - - -#define START_TIME 1000.0f // beginning of the relative time -#define TIME_UPDOWN 2.0f // time for up / down -#define DOWN_ALTITUDE 3.0f // underground distance -#define WORM_PART 7 // number of parts of a worm - - - -// Object's constructor. - -CMotionWorm::CMotionWorm(CInstanceManager* iMan, CObject* object) - : CMotion(iMan, object) -{ - CMotion::CMotion(iMan, object); - - m_timeUp = 18.0f; - m_timeDown = 18.0f; - m_armMember = START_TIME; - m_armTimeAbs = START_TIME; - m_armTimeMarch = START_TIME; - m_armTimeAction = START_TIME; - m_armTimeIndex = 0; - m_armPartIndex = 0; - m_armMemberIndex = 0; - m_armLinSpeed = 0.0f; - m_armCirSpeed = 0.0f; - m_armLastAction = -1; - m_specAction = -1; - m_lastParticule = 0.0f; - m_bArmStop = FALSE; -} - -// Object's destructor. - -CMotionWorm::~CMotionWorm() -{ -} - - -// Removes an object. - -void CMotionWorm::DeleteObject(BOOL bAll) -{ -} - - -// Creates a vehicle traveling any lands on the ground. - -BOOL CMotionWorm::Create(D3DVECTOR pos, float angle, ObjectType type, - float power) -{ - CModFile* pModFile; - int rank, i; - float px; - - if ( m_engine->RetRestCreate() < 2+WORM_PART+1 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - m_object->SetType(type); - - // Creates the main base. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object - m_object->SetObjectRank(0, rank); - pModFile->ReadModel("objects\\worm0.mod"); // there is no purpose! - pModFile->CreateEngineObject(rank); - m_object->SetPosition(0, pos); - m_object->SetAngleY(0, angle); - - // A vehicle must have a obligatory collision with a sphere of center (0, y, 0) (see GetCrashSphere). - m_object->CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f); - m_object->SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 5.0f); - - px = 1.0f+WORM_PART/2; - - // Creates the head. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(1, rank); - m_object->SetObjectParent(1, 0); - pModFile->ReadModel("objects\\worm1.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(1, D3DVECTOR(px, 0.0f, 0.0f)); - px -= 1.0f; - - // Creates the body. - for ( i=0 ; iCreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2+i, rank); - m_object->SetObjectParent(2+i, 0); - pModFile->ReadModel("objects\\worm2.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2+i, D3DVECTOR(px, 0.0f, 0.0f)); - px -= 1.0f; - } - - // Creates the tail. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - m_object->SetObjectRank(2+WORM_PART, rank); - m_object->SetObjectParent(2+WORM_PART, 0); - pModFile->ReadModel("objects\\worm3.mod"); - pModFile->CreateEngineObject(rank); - m_object->SetPosition(2+WORM_PART, D3DVECTOR(px, 0.0f, 0.0f)); - - m_object->CreateShadowCircle(0.0f, 1.0f, D3DSHADOWWORM); - - CreatePhysics(); - m_object->SetFloorHeight(0.0f); - - pos = m_object->RetPosition(0); - m_object->SetPosition(0, pos); // to display the shadows immediately - - m_engine->LoadAllTexture(); - - delete pModFile; - return TRUE; -} - -// Creates the physics of the object. - -void CMotionWorm::CreatePhysics() -{ - Character* character; - - m_physics->SetType(TYPE_ROLLING); - - character = m_object->RetCharacter(); - character->wheelFront = 10.0f; - character->wheelBack = 10.0f; - character->wheelLeft = 2.0f; - character->wheelRight = 2.0f; - character->height = -0.2f; - - m_physics->SetLinMotionX(MO_ADVSPEED, 3.0f); - m_physics->SetLinMotionX(MO_RECSPEED, 3.0f); - m_physics->SetLinMotionX(MO_ADVACCEL, 10.0f); - m_physics->SetLinMotionX(MO_RECACCEL, 10.0f); - m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); - m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); - m_physics->SetLinMotionX(MO_TERFORCE, 5.0f); - m_physics->SetLinMotionZ(MO_TERFORCE, 5.0f); - m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); - - m_physics->SetCirMotionY(MO_ADVSPEED, 0.2f*PI); - m_physics->SetCirMotionY(MO_RECSPEED, 0.2f*PI); - m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f); - m_physics->SetCirMotionY(MO_RECACCEL, 10.0f); - m_physics->SetCirMotionY(MO_STOACCEL, 20.0f); -} - - - -// Specifies a special parameter. - -BOOL CMotionWorm::SetParam(int rank, float value) -{ - if ( rank == 0 ) - { - m_timeDown = value; - return TRUE; - } - - if ( rank == 1 ) - { - m_timeUp = value; - return TRUE; - } - - return FALSE; -} - -float CMotionWorm::RetParam(int rank) -{ - if ( rank == 0 ) return m_timeDown; - if ( rank == 1 ) return m_timeUp; - return 0.0f; -} - - - -// Management of an event. - -BOOL CMotionWorm::EventProcess(const Event &event) -{ - CMotion::EventProcess(event); - - if ( event.event == EVENT_FRAME ) - { - return EventFrame(event); - } - - if ( event.event == EVENT_KEYDOWN ) - { - } - - return TRUE; -} - -// Management of an event. - -BOOL CMotionWorm::EventFrame(const Event &event) -{ - D3DMATRIX* mat; - D3DVECTOR pos, p, angle, speed; - FPOINT center, pp, dim; - float height[WORM_PART+2]; - float floor, a, s, px, curve, phase, h, zoom, radius; - int i, under; - - if ( m_engine->RetPause() ) return TRUE; - - s = m_physics->RetLinMotionX(MO_MOTSPEED)/m_physics->RetLinMotionX(MO_ADVSPEED); - a = m_physics->RetCirMotionY(MO_MOTSPEED)/m_physics->RetCirMotionY(MO_ADVSPEED); - - if ( s == 0.0f && a != 0.0f ) s = a; - - m_armLinSpeed += (s-m_armLinSpeed)*event.rTime*3.0f; - m_armCirSpeed += (a-m_armCirSpeed)*event.rTime*1.5f; - - m_armTimeAbs += event.rTime; - m_armTimeMarch += event.rTime*m_armLinSpeed; - - under = 0; // no piece under the ground - for ( i=0 ; iRetBurn() ) // is burning? - { - h = 0.0f; // remains on earth - } - h += 0.3f; - height[i] = h; - } - m_object->SetVisible(under!=WORM_PART+2); - - if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return TRUE; - - pos = m_object->RetPosition(0); - floor = m_terrain->RetFloorLevel(pos, TRUE); - - mat = m_object->RetWorldMatrix(0); - - px = 1.0f+WORM_PART/2; - for ( i=0 ; iSetObjectShadowRadius(m_object->RetObjectRank(0), radius); - - pos.x = px+ sinf(m_armTimeMarch*4.0f+0.5f*i)*0.6f; - pos.y = height[i]+sinf(m_armTimeMarch*4.0f+0.5f*i)*0.2f*m_armLinSpeed; - pos.y += sinf(m_armTimeAbs *1.3f+0.2f*i)*0.1f; - pos.z = sinf(m_armTimeAbs *2.0f+0.7f*i)*0.2f; - - curve = ((float)i-(WORM_PART+2)/2)*m_armCirSpeed*0.1f; - center.x = 0.0f; - center.y = 0.0f; - pp.x = pos.x; - pp.y = pos.z; - pp = RotatePoint(center, curve, pp); - pos.x = pp.x; - pos.z = pp.y; - - p = Transform(*mat, pos); - pos.y += m_terrain->RetFloorLevel(p, TRUE)-floor; - m_object->SetPosition(i+1, pos); - - zoom = Mod(m_armTimeAbs*0.5f+100.0f-i*0.1f, 2.0f); - if ( zoom > 1.0f ) zoom = 2.0f-zoom; - zoom *= 1.6f; - if ( zoom < 1.0f ) zoom = 1.0f; - m_object->SetZoomY(i+1, 0.2f+zoom*0.8f); - m_object->SetZoomZ(i+1, zoom); - - if ( height[i] >= -1.0f && height[i] < -0.2f && - m_lastParticule+m_engine->ParticuleAdapt(0.2f) <= m_armTimeMarch ) - { - m_lastParticule = m_armTimeMarch; - - pos = p; - pos.y += -height[i]; - pos.x += (Rand()-0.5f)*4.0f; - pos.z += (Rand()-0.5f)*4.0f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = Rand()*2.0f+1.5f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); - } - - px -= 1.0f; - } - - for ( i=0 ; iRetPosition(i+2); - pos -= m_object->RetPosition(i+1); - - angle.z = -RotateAngle(Length(pos.x, pos.z), pos.y); - angle.y = PI-RotateAngle(pos.x, pos.z); - angle.x = 0.0f; - m_object->SetAngle(i+1, angle); - - if ( i == WORM_PART ) - { - m_object->SetAngle(i+2, angle); - } - } - - return TRUE; -} - - diff --git a/src/motionworm.h b/src/motionworm.h deleted file mode 100644 index cabb2ba..0000000 --- a/src/motionworm.h +++ /dev/null @@ -1,75 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// motionworm.h - -#ifndef _MOTIONWORM_H_ -#define _MOTIONWORM_H_ - - -#include "motion.h" - - -class CInstanceManager; -class CEngine; -class CLight; -class CParticule; -class CTerrain; -class CCamera; -class CBrain; -class CPhysics; -class CObject; - - -class CMotionWorm : public CMotion -{ -public: - CMotionWorm(CInstanceManager* iMan, CObject* object); - ~CMotionWorm(); - - void DeleteObject(BOOL bAll=FALSE); - BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); - BOOL EventProcess(const Event &event); - - BOOL SetParam(int rank, float value); - float RetParam(int rank); - -protected: - void CreatePhysics(); - BOOL EventFrame(const Event &event); - -protected: - float m_timeUp; - float m_timeDown; - float m_armMember; - float m_armTimeAbs; - float m_armTimeMarch; - float m_armTimeAction; - short m_armAngles[3*3*3*3*10]; - int m_armTimeIndex; - int m_armPartIndex; - int m_armMemberIndex; - int m_armLastAction; - float m_armLinSpeed; - float m_armCirSpeed; - int m_specAction; - float m_specTime; - BOOL m_bArmStop; - float m_lastParticule; -}; - - -#endif //_MOTIONWORM_H_ diff --git a/src/object.cpp b/src/object.cpp deleted file mode 100644 index 0757e46..0000000 --- a/src/object.cpp +++ /dev/null @@ -1,7607 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// object.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "CBot/CBotDll.h" -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "d3dutil.h" -#include "global.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "restext.h" -#include "math3d.h" -#include "mainmovie.h" -#include "robotmain.h" -#include "light.h" -#include "terrain.h" -#include "water.h" -#include "blitz.h" -#include "camera.h" -#include "particule.h" -#include "physics.h" -#include "brain.h" -#include "motion.h" -#include "motionhuman.h" -#include "motiontoto.h" -#include "motionvehicle.h" -#include "motionmother.h" -#include "motionant.h" -#include "motionspider.h" -#include "motionbee.h" -#include "motionworm.h" -#include "modfile.h" -#include "auto.h" -#include "autobase.h" -#include "autoportico.h" -#include "autoderrick.h" -#include "autofactory.h" -#include "autorepair.h" -#include "autodestroyer.h" -#include "autostation.h" -#include "autoenergy.h" -#include "autoconvert.h" -#include "autotower.h" -#include "autoresearch.h" -#include "autolabo.h" -#include "autonuclear.h" -#include "autoradar.h" -#include "autoegg.h" -#include "autonest.h" -#include "autoroot.h" -#include "autoflag.h" -#include "autoinfo.h" -#include "autojostle.h" -#include "autopara.h" -#include "autosafe.h" -#include "autohuston.h" -#include "automush.h" -#include "autokid.h" -#include "task.h" -#include "pyro.h" -#include "displaytext.h" -#include "cmdtoken.h" -#include "cbottoken.h" -#include "sound.h" -#include "object.h" - - - -#define ADJUST_ONBOARD FALSE // TRUE -> adjusts the camera ONBOARD -#define ADJUST_ARM FALSE // TRUE -> adjusts the manipulator arm -#define VIRUS_DELAY 60.0f // duration of virus infection -#define LOSS_SHIELD 0.24f // loss of the shield by shot -#define LOSS_SHIELD_H 0.10f // loss of the shield for humans -#define LOSS_SHIELD_M 0.02f // loss of the shield for the laying - -#if ADJUST_ONBOARD -static float debug_x = 0.0f; -static float debug_y = 0.0f; -static float debug_z = 0.0f; -#endif - -#if ADJUST_ARM -static float debug_arm1 = 0.0f; -static float debug_arm2 = 0.0f; -static float debug_arm3 = 0.0f; -#endif - - - - -// Updates the class Object. - -void uObject(CBotVar* botThis, void* user) -{ - CObject* object = (CObject*)user; - CObject* power; - CObject* fret; - CPhysics* physics; - CBotVar *pVar, *pSub; - ObjectType type; - D3DVECTOR pos; - float value; - int iValue; - - if ( object == 0 ) return; - - physics = object->RetPhysics(); - - // Updates the object's type. - pVar = botThis->GivItemList(); // "category" - type = object->RetType(); - pVar->SetValInt(type, object->RetName()); - - // Updates the position of the object. - pVar = pVar->GivNext(); // "position" - if ( object->RetTruck() == 0 ) - { - pos = object->RetPosition(0); - pos.y -= object->RetWaterLevel(); // relative to sea level! - pSub = pVar->GivItemList(); // "x" - pSub->SetValFloat(pos.x/g_unit); - pSub = pSub->GivNext(); // "y" - pSub->SetValFloat(pos.z/g_unit); - pSub = pSub->GivNext(); // "z" - pSub->SetValFloat(pos.y/g_unit); - } - else // object transported? - { - pSub = pVar->GivItemList(); // "x" - pSub->SetInit(IS_NAN); - pSub = pSub->GivNext(); // "y" - pSub->SetInit(IS_NAN); - pSub = pSub->GivNext(); // "z" - pSub->SetInit(IS_NAN); - } - - // Updates the angle. - pos = object->RetAngle(0); - pos += object->RetInclinaison(); - pVar = pVar->GivNext(); // "orientation" - pVar->SetValFloat(360.0f-Mod(pos.y*180.0f/PI, 360.0f)); - pVar = pVar->GivNext(); // "pitch" - pVar->SetValFloat(pos.z*180.0f/PI); - pVar = pVar->GivNext(); // "roll" - pVar->SetValFloat(pos.x*180.0f/PI); - - // Updates the energy level of the object. - pVar = pVar->GivNext(); // "energyLevel" - value = object->RetEnergy(); - pVar->SetValFloat(value); - - // Updates the shield level of the object. - pVar = pVar->GivNext(); // "shieldLevel" - value = object->RetShield(); - pVar->SetValFloat(value); - - // Updates the temperature of the reactor. - pVar = pVar->GivNext(); // "temperature" - if ( physics == 0 ) value = 0.0f; - else value = 1.0f-physics->RetReactorRange(); - pVar->SetValFloat(value); - - // Updates the height above the ground. - pVar = pVar->GivNext(); // "altitude" - if ( physics == 0 ) value = 0.0f; - else value = physics->RetFloorHeight(); - pVar->SetValFloat(value/g_unit); - - // Updates the lifetime of the object. - pVar = pVar->GivNext(); // "lifeTime" - value = object->RetAbsTime(); - pVar->SetValFloat(value); - - // Updates the material of the object. - pVar = pVar->GivNext(); // "material" - iValue = object->RetMaterial(); - pVar->SetValInt(iValue); - - // Updates the type of battery. - pVar = pVar->GivNext(); // "energyCell" - power = object->RetPower(); - if ( power == 0 ) pVar->SetPointer(0); - else pVar->SetPointer(power->RetBotVar()); - - // Updates the transported object's type. - pVar = pVar->GivNext(); // "load" - fret = object->RetFret(); - if ( fret == 0 ) pVar->SetPointer(0); - else pVar->SetPointer(fret->RetBotVar()); -} - - - - -// Object's constructor. - -CObject::CObject(CInstanceManager* iMan) -{ - int i; - - m_iMan = iMan; - m_iMan->AddInstance(CLASS_OBJECT, this, 500); - - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - m_physics = 0; - m_brain = 0; - m_motion = 0; - m_auto = 0; - m_runScript = 0; - - m_type = OBJECT_FIX; - m_id = ++g_id; - m_option = 0; - m_name[0] = 0; - m_partiReactor = -1; - m_shadowLight = -1; - m_effectLight = -1; - m_linVibration = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_cirVibration = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_inclinaison = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_lastParticule = 0.0f; - - m_power = 0; - m_fret = 0; - m_truck = 0; - m_truckLink = 0; - m_energy = 1.0f; - m_capacity = 1.0f; - m_shield = 1.0f; - m_range = 0.0f; - m_transparency = 0.0f; - m_lastEnergy = 999.9f; - m_bHilite = FALSE; - m_bSelect = FALSE; - m_bSelectable = TRUE; - m_bCheckToken = TRUE; - m_bVisible = TRUE; - m_bEnable = TRUE; - m_bGadget = FALSE; - m_bProxyActivate = FALSE; - m_bTrainer = FALSE; - m_bToy = FALSE; - m_bManual = FALSE; - m_bFixed = FALSE; - m_bClip = TRUE; - m_bShowLimit = FALSE; - m_showLimitRadius = 0.0f; - m_aTime = 0.0f; - m_shotTime = 0.0f; - m_bVirusMode = FALSE; - m_virusTime = 0.0f; - m_lastVirusParticule = 0.0f; - m_totalDesectList = 0; - m_bLock = FALSE; - m_bExplo = FALSE; - m_bCargo = FALSE; - m_bBurn = FALSE; - m_bDead = FALSE; - m_bFlat = FALSE; - m_gunGoalV = 0.0f; - m_gunGoalH = 0.0f; - m_shieldRadius = 0.0f; - m_defRank = -1; - m_magnifyDamage = 1.0f; - m_proxyDistance = 60.0f; - m_param = 0.0f; - - ZeroMemory(&m_character, sizeof(Character)); - m_character.wheelFront = 1.0f; - m_character.wheelBack = 1.0f; - m_character.wheelLeft = 1.0f; - m_character.wheelRight = 1.0f; - - m_resetCap = RESET_NONE; - m_bResetBusy = FALSE; - m_resetPosition = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_resetAngle = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_resetRun = -1; - - m_cameraType = CAMERA_BACK; - m_cameraDist = 50.0f; - m_bCameraLock = FALSE; - - m_infoTotal = 0; - m_infoReturn = NAN; - m_bInfoUpdate = FALSE; - - for ( i=0 ; iAddUpdateFunc(uObject); - } - - m_botVar = CBotVar::Create("", CBotTypResult(CBotTypClass, "object")); - m_botVar->SetUserPtr(this); - m_botVar->SetIdent(m_id); -} - -// Object's destructor. - -CObject::~CObject() -{ - if ( m_botVar != 0 ) - { - m_botVar->SetUserPtr(OBJECTDELETED); - delete m_botVar; - } - - delete m_physics; - delete m_brain; - delete m_motion; - delete m_auto; - - m_iMan->DeleteInstance(CLASS_OBJECT, this); -} - - -// Removes an object. -// If bAll = TRUE, it does not help, -// because all objects in the scene are quickly destroyed! - -void CObject::DeleteObject(BOOL bAll) -{ - CObject* pObj; - CPyro* pPyro; - int i; - - if ( m_botVar != 0 ) - { - m_botVar->SetUserPtr(OBJECTDELETED); - } - - if ( m_camera->RetObject() == this ) - { - m_camera->SetObject(0); - } - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - pObj->DeleteDeselList(this); - } - - if ( !bAll ) - { -#if 0 - type = m_camera->RetType(); - if ( (type == CAMERA_BACK || - type == CAMERA_FIX || - type == CAMERA_EXPLO || - type == CAMERA_ONBOARD) && - m_camera->RetObject() == this ) - { - pObj = m_main->SearchNearest(RetPosition(0), this); - if ( pObj == 0 ) - { - m_camera->SetObject(0); - m_camera->SetType(CAMERA_FREE); - } - else - { - m_camera->SetObject(pObj); - m_camera->SetType(CAMERA_BACK); - } - } -#endif - for ( i=0 ; i<1000000 ; i++ ) - { - pPyro = (CPyro*)m_iMan->SearchInstance(CLASS_PYRO, i); - if ( pPyro == 0 ) break; - - pPyro->CutObjectLink(this); // the object no longer exists - } - - if ( m_bSelect ) - { - SetSelect(FALSE); - } - - if ( m_type == OBJECT_BASE || - m_type == OBJECT_FACTORY || - m_type == OBJECT_REPAIR || - m_type == OBJECT_DESTROYER|| - m_type == OBJECT_DERRICK || - m_type == OBJECT_STATION || - m_type == OBJECT_CONVERT || - m_type == OBJECT_TOWER || - m_type == OBJECT_RESEARCH || - m_type == OBJECT_RADAR || - m_type == OBJECT_INFO || - m_type == OBJECT_ENERGY || - m_type == OBJECT_LABO || - m_type == OBJECT_NUCLEAR || - m_type == OBJECT_PARA || - m_type == OBJECT_SAFE || - m_type == OBJECT_HUSTON || - m_type == OBJECT_START || - m_type == OBJECT_END ) // building? - { - m_terrain->DeleteBuildingLevel(RetPosition(0)); // flattens the field - } - } - - m_type = OBJECT_NULL; // invalid object until complete destruction - - if ( m_partiReactor != -1 ) - { - m_particule->DeleteParticule(m_partiReactor); - m_partiReactor = -1; - } - - if ( m_shadowLight != -1 ) - { - m_light->DeleteLight(m_shadowLight); - m_shadowLight = -1; - } - - if ( m_effectLight != -1 ) - { - m_light->DeleteLight(m_effectLight); - m_effectLight = -1; - } - - if ( m_physics != 0 ) - { - m_physics->DeleteObject(bAll); - } - - if ( m_brain != 0 ) - { - m_brain->DeleteObject(bAll); - } - - if ( m_motion != 0 ) - { - m_motion->DeleteObject(bAll); - } - - if ( m_auto != 0 ) - { - m_auto->DeleteObject(bAll); - } - - for ( i=0 ; iDeleteObject(m_objectPart[i].object); - - if ( m_objectPart[i].masterParti != -1 ) - { - m_particule->DeleteParticule(m_objectPart[i].masterParti); - m_objectPart[i].masterParti = -1; - } - } - } - - if ( m_bShowLimit ) - { - m_main->FlushShowLimit(0); - m_bShowLimit = FALSE; - } - - if ( !bAll ) m_main->CreateShortcuts(); -} - -// Simplifies a object (he was the brain, among others). - -void CObject::Simplify() -{ - if ( m_brain != 0 ) - { - m_brain->StopProgram(); - } - m_main->SaveOneScript(this); - - if ( m_physics != 0 ) - { - m_physics->DeleteObject(); - delete m_physics; - m_physics = 0; - } - - if ( m_brain != 0 ) - { - m_brain->DeleteObject(); - delete m_brain; - m_brain = 0; - } - - if ( m_motion != 0 ) - { - m_motion->DeleteObject(); - delete m_motion; - m_motion = 0; - } - - if ( m_auto != 0 ) - { - m_auto->DeleteObject(); - delete m_auto; - m_auto = 0; - } - - m_main->CreateShortcuts(); -} - - -// Detonates an object, when struck by a shot. -// If FALSE is returned, the object is still screwed. -// If TRUE is returned, the object is destroyed. - -BOOL CObject::ExploObject(ExploType type, float force, float decay) -{ - PyroType pyroType; - CPyro* pyro; - float loss, shield; - - if ( type == EXPLO_BURN ) - { - if ( m_type == OBJECT_MOBILEtg || - m_type == OBJECT_TEEN28 || // cylinder? - m_type == OBJECT_METAL || - m_type == OBJECT_POWER || - m_type == OBJECT_ATOMIC || - m_type == OBJECT_TNT || - m_type == OBJECT_SCRAP1 || - m_type == OBJECT_SCRAP2 || - m_type == OBJECT_SCRAP3 || - m_type == OBJECT_SCRAP4 || - m_type == OBJECT_SCRAP5 || - m_type == OBJECT_BULLET || - m_type == OBJECT_EGG ) // object that isn't burning? - { - type = EXPLO_BOUM; - force = 1.0f; - decay = 1.0f; - } - } - - if ( EXPLO_BOUM ) - { - if ( m_shotTime < 0.5f ) return FALSE; - m_shotTime = 0.0f; - } - - if ( m_type == OBJECT_HUMAN && m_bDead ) return FALSE; - - // Calculate the power lost by the explosion. - if ( force == 0.0f ) - { - if ( m_type == OBJECT_HUMAN ) - { - loss = LOSS_SHIELD_H; - } - else if ( m_type == OBJECT_MOTHER ) - { - loss = LOSS_SHIELD_M; - } - else - { - loss = LOSS_SHIELD; - } - } - else - { - loss = force; - } - loss *= m_magnifyDamage; - loss *= decay; - - // Decreases the power of the shield. - shield = RetShield(); - shield -= loss; - if ( shield < 0.0f ) shield = 0.0f; - SetShield(shield); - - if ( shield > 0.0f ) // not dead yet? - { - if ( type == EXPLO_WATER ) - { - if ( m_type == OBJECT_HUMAN ) - { - pyroType = PT_SHOTH; - } - else - { - pyroType = PT_SHOTW; - } - } - else - { - if ( m_type == OBJECT_HUMAN ) - { - pyroType = PT_SHOTH; - } - else if ( m_type == OBJECT_MOTHER ) - { - pyroType = PT_SHOTM; - } - else - { - pyroType = PT_SHOTT; - } - } - } - else // completely dead? - { - if ( type == EXPLO_BURN ) // burning? - { - if ( m_type == OBJECT_MOTHER || - m_type == OBJECT_ANT || - m_type == OBJECT_SPIDER || - m_type == OBJECT_BEE || - m_type == OBJECT_WORM || - m_type == OBJECT_BULLET ) - { - pyroType = PT_BURNO; - SetBurn(TRUE); - } - else if ( m_type == OBJECT_HUMAN ) - { - pyroType = PT_DEADG; - } - else - { - pyroType = PT_BURNT; - SetBurn(TRUE); - } - SetVirusMode(FALSE); - } - else if ( type == EXPLO_WATER ) - { - if ( m_type == OBJECT_HUMAN ) - { - pyroType = PT_DEADW; - } - else - { - pyroType = PT_FRAGW; - } - } - else // explosion? - { - if ( m_type == OBJECT_ANT || - m_type == OBJECT_SPIDER || - m_type == OBJECT_BEE || - m_type == OBJECT_WORM ) - { - pyroType = PT_EXPLOO; - } - else if ( m_type == OBJECT_MOTHER || - m_type == OBJECT_NEST || - m_type == OBJECT_BULLET ) - { - pyroType = PT_FRAGO; - } - else if ( m_type == OBJECT_HUMAN ) - { - pyroType = PT_DEADG; - } - else if ( m_type == OBJECT_BASE || - m_type == OBJECT_DERRICK || - m_type == OBJECT_FACTORY || - m_type == OBJECT_STATION || - m_type == OBJECT_CONVERT || - m_type == OBJECT_REPAIR || - m_type == OBJECT_DESTROYER|| - m_type == OBJECT_TOWER || - m_type == OBJECT_NEST || - m_type == OBJECT_RESEARCH || - m_type == OBJECT_RADAR || - m_type == OBJECT_INFO || - m_type == OBJECT_ENERGY || - m_type == OBJECT_LABO || - m_type == OBJECT_NUCLEAR || - m_type == OBJECT_PARA || - m_type == OBJECT_SAFE || - m_type == OBJECT_HUSTON || - m_type == OBJECT_START || - m_type == OBJECT_END ) // building? - { - pyroType = PT_FRAGT; - } - else if ( m_type == OBJECT_MOBILEtg || - m_type == OBJECT_TEEN28 || // cylinder? - m_type == OBJECT_TEEN31 ) // basket? - { - pyroType = PT_FRAGT; - } - else - { - pyroType = PT_EXPLOT; - } - } - - loss = 1.0f; - } - - pyro = new CPyro(m_iMan); - pyro->Create(pyroType, this, loss); - - if ( shield == 0.0f ) // dead? - { - if ( m_brain != 0 ) - { - m_brain->StopProgram(); - } - m_main->SaveOneScript(this); - } - - if ( shield > 0.0f ) return FALSE; // not dead yet - - if ( RetSelect() ) - { - SetSelect(FALSE); // deselects the object - m_camera->SetType(CAMERA_EXPLO); - m_main->DeselectAll(); - } - DeleteDeselList(this); - - if ( m_botVar != 0 ) - { - if ( m_type == OBJECT_STONE || - m_type == OBJECT_URANIUM || - m_type == OBJECT_METAL || - m_type == OBJECT_POWER || - m_type == OBJECT_ATOMIC || - m_type == OBJECT_BULLET || - m_type == OBJECT_BBOX || - m_type == OBJECT_TNT || - m_type == OBJECT_SCRAP1 || - m_type == OBJECT_SCRAP2 || - m_type == OBJECT_SCRAP3 || - m_type == OBJECT_SCRAP4 || - m_type == OBJECT_SCRAP5 ) // (*) - { - m_botVar->SetUserPtr(OBJECTDELETED); - } - } - - return TRUE; -} - -// (*) If a robot or cosmonaut dies, the subject must continue to exist, -// so that programs of the ants continue to operate as usual. - - -// Initializes a new part. - -void CObject::InitPart(int part) -{ - m_objectPart[part].bUsed = TRUE; - m_objectPart[part].object = -1; - m_objectPart[part].parentPart = -1; - - m_objectPart[part].position = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_objectPart[part].angle.y = 0.0f; - m_objectPart[part].angle.x = 0.0f; - m_objectPart[part].angle.z = 0.0f; - m_objectPart[part].zoom = D3DVECTOR(1.0f, 1.0f, 1.0f); - - m_objectPart[part].bTranslate = TRUE; - m_objectPart[part].bRotate = TRUE; - m_objectPart[part].bZoom = FALSE; - - D3DUtil_SetIdentityMatrix(m_objectPart[part].matTranslate); - D3DUtil_SetIdentityMatrix(m_objectPart[part].matRotate); - D3DUtil_SetIdentityMatrix(m_objectPart[part].matTransform); - D3DUtil_SetIdentityMatrix(m_objectPart[part].matWorld); - - m_objectPart[part].masterParti = -1; -} - -// Creates a new part, and returns its number. -// Returns -1 on error. - -int CObject::CreatePart() -{ - int i; - - for ( i=0 ; iDeleteParticule(m_objectPart[part].masterParti); - m_objectPart[part].masterParti = -1; - } - - m_objectPart[part].bUsed = FALSE; - m_engine->DeleteObject(m_objectPart[part].object); - UpdateTotalPart(); -} - -void CObject::UpdateTotalPart() -{ - int i; - - m_totalPart = 0; - for ( i=0 ; iSetIdent(m_id); - } -} - -int CObject::RetID() -{ - return m_id; -} - - -// Saves all the parameters of the object. - -BOOL CObject::Write(char *line) -{ - D3DVECTOR pos; - Info info; - char name[100]; - float value; - int i; - - sprintf(name, " camera=%s", GetCamera(RetCameraType())); - strcat(line, name); - - if ( RetCameraLock() != 0 ) - { - sprintf(name, " cameraLock=%d", RetCameraLock()); - strcat(line, name); - } - - if ( RetEnergy() != 0.0f ) - { - sprintf(name, " energy=%.2f", RetEnergy()); - strcat(line, name); - } - - if ( RetCapacity() != 1.0f ) - { - sprintf(name, " capacity=%.2f", RetCapacity()); - strcat(line, name); - } - - if ( RetShield() != 1.0f ) - { - sprintf(name, " shield=%.2f", RetShield()); - strcat(line, name); - } - - if ( RetRange() != 1.0f ) - { - sprintf(name, " range=%.2f", RetRange()); - strcat(line, name); - } - - if ( RetSelectable() != 1 ) - { - sprintf(name, " selectable=%d", RetSelectable()); - strcat(line, name); - } - - if ( RetEnable() != 1 ) - { - sprintf(name, " enable=%d", RetEnable()); - strcat(line, name); - } - - if ( RetFixed() != 0 ) - { - sprintf(name, " fixed=%d", RetFixed()); - strcat(line, name); - } - - if ( RetClip() != 1 ) - { - sprintf(name, " clip=%d", RetClip()); - strcat(line, name); - } - - if ( RetLock() != 0 ) - { - sprintf(name, " lock=%d", RetLock()); - strcat(line, name); - } - - if ( RetProxyActivate() != 0 ) - { - sprintf(name, " proxyActivate=%d", RetProxyActivate()); - strcat(line, name); - - sprintf(name, " proxyDistance=%.2f", RetProxyDistance()/g_unit); - strcat(line, name); - } - - if ( RetMagnifyDamage() != 1.0f ) - { - sprintf(name, " magnifyDamage=%.2f", RetMagnifyDamage()); - strcat(line, name); - } - - if ( RetGunGoalV() != 0.0f ) - { - sprintf(name, " aimV=%.2f", RetGunGoalV()); - strcat(line, name); - } - if ( RetGunGoalH() != 0.0f ) - { - sprintf(name, " aimH=%.2f", RetGunGoalH()); - strcat(line, name); - } - - if ( RetParam() != 0.0f ) - { - sprintf(name, " param=%.2f", RetParam()); - strcat(line, name); - } - - if ( RetResetCap() != 0 ) - { - sprintf(name, " resetCap=%d", RetResetCap()); - strcat(line, name); - - pos = RetResetPosition()/g_unit; - sprintf(name, " resetPos=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); - strcat(line, name); - - pos = RetResetAngle()/(PI/180.0f); - sprintf(name, " resetAngle=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); - strcat(line, name); - - sprintf(name, " resetRun=%d", RetResetRun()); - strcat(line, name); - } - - if ( m_bVirusMode != 0 ) - { - sprintf(name, " virusMode=%d", m_bVirusMode); - strcat(line, name); - } - - if ( m_virusTime != 0.0f ) - { - sprintf(name, " virusTime=%.2f", m_virusTime); - strcat(line, name); - } - - // Puts information in terminal (OBJECT_INFO). - for ( i=0 ; iWrite(line); - } - - if ( m_brain != 0 ) - { - m_brain->Write(line); - } - - if ( m_physics != 0 ) - { - m_physics->Write(line); - } - - if ( m_auto != 0 ) - { - m_auto->Write(line); - } - - return TRUE; -} - -// Returns all parameters of the object. - -BOOL CObject::Read(char *line) -{ - D3DVECTOR pos, dir; - Info info; - CameraType cType; - char op[20]; - char text[100]; - char* p; - float value; - int i; - - cType = OpCamera(line, "camera"); - if ( cType != CAMERA_NULL ) - { - SetCameraType(cType); - } - - SetCameraLock(OpInt(line, "cameraLock", 0)); - SetEnergy(OpFloat(line, "energy", 0.0f)); - SetCapacity(OpFloat(line, "capacity", 1.0f)); - SetShield(OpFloat(line, "shield", 1.0f)); - SetRange(OpFloat(line, "range", 1.0f)); - SetSelectable(OpInt(line, "selectable", 1)); - SetEnable(OpInt(line, "enable", 1)); - SetFixed(OpInt(line, "fixed", 0)); - SetClip(OpInt(line, "clip", 1)); - SetLock(OpInt(line, "lock", 0)); - SetProxyActivate(OpInt(line, "proxyActivate", 0)); - SetProxyDistance(OpFloat(line, "proxyDistance", 15.0f)*g_unit); - SetRange(OpFloat(line, "range", 30.0f)); - SetMagnifyDamage(OpFloat(line, "magnifyDamage", 1.0f)); - SetGunGoalV(OpFloat(line, "aimV", 0.0f)); - SetGunGoalH(OpFloat(line, "aimH", 0.0f)); - SetParam(OpFloat(line, "param", 0.0f)); - SetResetCap((ResetCap)OpInt(line, "resetCap", 0)); - SetResetPosition(OpDir(line, "resetPos")*g_unit); - SetResetAngle(OpDir(line, "resetAngle")*(PI/180.0f)); - SetResetRun(OpInt(line, "resetRun", 0)); - m_bBurn = OpInt(line, "burnMode", 0); - m_bVirusMode = OpInt(line, "virusMode", 0); - m_virusTime = OpFloat(line, "virusTime", 0.0f); - - // Puts information in terminal (OBJECT_INFO). - for ( i=0 ; iReadModel("objects\\convert1.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetFloorHeight(0.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(1, rank); - SetObjectParent(1, 0); - pModFile->ReadModel("objects\\convert2.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(1, D3DVECTOR(0.0f, 14.0f, 0.0f)); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(2, rank); - SetObjectParent(2, 0); - pModFile->ReadModel("objects\\convert3.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(2, D3DVECTOR(0.0f, 11.5f, 0.0f)); - SetAngleX(2, -PI*0.35f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(3, rank); - SetObjectParent(3, 0); - pModFile->ReadModel("objects\\convert3.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(3, D3DVECTOR(0.0f, 11.5f, 0.0f)); - SetAngleY(3, PI); - SetAngleX(3, -PI*0.35f); - - m_terrain->AddBuildingLevel(pos, 7.0f, 9.0f, 1.0f, 0.5f); - - CreateCrashSphere(D3DVECTOR(-10.0f, 2.0f, 4.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-10.0f, 2.0f, -4.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-10.0f, 9.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 14.0f, 0.0f), 1.5f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(-3.0f, 8.0f, 0.0f), 14.0f); - } - - if ( m_type == OBJECT_TOWER ) - { - pModFile->ReadModel("objects\\tower.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetFloorHeight(0.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(1, rank); - SetObjectParent(1, 0); - pModFile->ReadModel("objects\\roller2c.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(1, D3DVECTOR(0.0f, 20.0f, 0.0f)); - SetAngleZ(1, PI/2.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(2, rank); - SetObjectParent(2, 1); - pModFile->ReadModel("objects\\roller3c.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(2, D3DVECTOR(4.5f, 0.0f, 0.0f)); - SetAngleZ(2, 0.0f); - - CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 6.5f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(0.0f, 8.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(0.0f, 15.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(0.0f, 24.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 7.0f); - - m_character.posPower = D3DVECTOR(5.0f, 3.0f, 0.0f); - - CreateShadowCircle(6.0f, 1.0f); - m_showLimitRadius = BLITZPARA; - } - - if ( m_type == OBJECT_NUCLEAR ) - { - pModFile->ReadModel("objects\\nuclear1.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetFloorHeight(0.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(1, rank); - SetObjectParent(1, 0); - pModFile->ReadModel("objects\\nuclear2.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(1, D3DVECTOR(20.0f, 10.0f, 0.0f)); - SetAngleZ(1, 135.0f*PI/180.0f); - - CreateCrashSphere(D3DVECTOR( 0.0f, 0.0f, 0.0f), 19.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 24.0f, 0.0f), 15.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(22.0f, 1.0f, 0.0f), 1.5f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 17.0f, 0.0f), 26.0f); - - m_character.posPower = D3DVECTOR(22.0f, 3.0f, 0.0f); - - CreateShadowCircle(21.0f, 1.0f); - } - - if ( m_type == OBJECT_PARA ) - { - pModFile->ReadModel("objects\\para.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetFloorHeight(0.0f); - - m_terrain->AddBuildingLevel(pos, 16.0f, 18.0f, 1.0f, 0.5f); - - CreateCrashSphere(D3DVECTOR( 13.0f, 3.0f, 13.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 11.0f, 15.0f, 11.0f), 2.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-13.0f, 3.0f, 13.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-11.0f, 15.0f, -11.0f), 2.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 13.0f, 3.0f, -13.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 11.0f, 15.0f, -11.0f), 2.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-13.0f, 3.0f, -13.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-11.0f, 15.0f, -11.0f), 2.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 26.0f, 0.0f), 9.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 54.0f, 0.0f), 14.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 20.0f); - - CreateShadowCircle(21.0f, 1.0f); - m_showLimitRadius = BLITZPARA; - } - - if ( m_type == OBJECT_SAFE ) - { - pModFile->ReadModel("objects\\safe1.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetFloorHeight(0.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(1, rank); - SetObjectParent(1, 0); - pModFile->ReadModel("objects\\safe2.mod"); - pModFile->CreateEngineObject(rank); - SetZoom(1, 1.05f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(2, rank); - SetObjectParent(2, 0); - pModFile->ReadModel("objects\\safe3.mod"); - pModFile->CreateEngineObject(rank); - SetZoom(2, 1.05f); - - m_terrain->AddBuildingLevel(pos, 18.0f, 20.0f, 1.0f, 0.5f); - - CreateCrashSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 13.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 13.0f); - - CreateShadowCircle(23.0f, 1.0f); - } - - if ( m_type == OBJECT_HUSTON ) - { - pModFile->ReadModel("objects\\huston1.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetFloorHeight(0.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(1, rank); - SetObjectParent(1, 0); - pModFile->ReadModel("objects\\huston2.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(1, D3DVECTOR(0.0f, 39.0f, 30.0f)); - SetAngleY(1, -PI/2.0f); - SetZoom(1, 3.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(2, rank); - SetObjectParent(2, 1); - pModFile->ReadModel("objects\\huston3.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(2, D3DVECTOR(0.0f, 4.5f, 1.9f)); - - CreateCrashSphere(D3DVECTOR( 15.0f, 6.0f, -53.0f), 16.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-15.0f, 6.0f, -53.0f), 16.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 15.0f, 6.0f, -26.0f), 16.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-15.0f, 6.0f, -26.0f), 16.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 15.0f, 6.0f, 0.0f), 16.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-15.0f, 6.0f, 0.0f), 16.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 15.0f, 6.0f, 26.0f), 16.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-15.0f, 6.0f, 26.0f), 16.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 15.0f, 6.0f, 53.0f), 16.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-15.0f, 6.0f, 53.0f), 16.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 27.0f, 30.0f), 12.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 45.0f, 30.0f), 14.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 26.0f, 4.0f, -61.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-26.0f, 4.0f, -61.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 26.0f, 4.0f, 61.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-26.0f, 4.0f, 61.0f), 5.0f, SOUND_BOUMm, 0.45f); - } - - if ( m_type == OBJECT_TARGET1 ) - { - pModFile->ReadModel("objects\\target1.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, 1.5f); - SetFloorHeight(0.0f); - - CreateCrashSphere(D3DVECTOR( 0.0f, 50.0f+14.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( -7.0f, 50.0f+12.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 7.0f, 50.0f+12.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-12.0f, 50.0f+ 7.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 12.0f, 50.0f+ 7.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-14.0f, 50.0f+ 0.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 14.0f, 50.0f+ 0.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-12.0f, 50.0f- 7.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 12.0f, 50.0f- 7.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( -7.0f, 50.0f-12.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 7.0f, 50.0f-12.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 50.0f-14.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - - CreateCrashSphere(D3DVECTOR(0.0f, 30.0f, 0.0f), 2.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(0.0f, 24.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(0.0f, 16.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 8.0f, SOUND_BOUMm, 0.45f); - - CreateShadowCircle(15.0f, 1.0f); - } - - if ( m_type == OBJECT_TARGET2 ) - { - pModFile->ReadModel("objects\\target2.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetFloorHeight(0.0f); - - height += 50.0f*1.5f; - } - - if ( m_type == OBJECT_NEST ) - { - pModFile->ReadModel("objects\\nest.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetFloorHeight(0.0f); - - m_terrain->AddBuildingLevel(pos, 3.0f, 5.0f, 1.0f, 0.5f); - - CreateShadowCircle(4.0f, 1.0f); - } - - if ( m_type == OBJECT_START ) - { - pModFile->ReadModel("objects\\start.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetFloorHeight(0.0f); - - m_terrain->AddBuildingLevel(pos, 7.0f, 9.0f, 1.0f, 0.5f); - } - - if ( m_type == OBJECT_END ) - { - pModFile->ReadModel("objects\\end.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetFloorHeight(0.0f); - - m_terrain->AddBuildingLevel(pos, 7.0f, 9.0f, 1.0f, 0.5f); - } - -#if 0 - if ( power > 0.0f ) // creates a battery? - { - CObject* pPower; - - pPower = new CObject(m_iMan); - pPower->SetType(power<=1.0f?OBJECT_POWER:OBJECT_ATOMIC); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - pPower->SetObjectRank(0, rank); - - if ( power <= 1.0f ) pModFile->ReadModel("objects\\power.mod"); - else pModFile->ReadModel("objects\\atomic.mod"); - pModFile->CreateEngineObject(rank); - - pPower->SetPosition(0, RetCharacter()->posPower); - pPower->CreateCrashSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - pPower->SetGlobalSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 1.5f); - - pPower->SetTruck(this); - SetPower(pPower); - - if ( power <= 1.0f ) pPower->SetEnergy(power); - else pPower->SetEnergy(power/100.0f); - } -#endif - - pos = RetPosition(0); - pos.y += height; - SetPosition(0, pos); // to display the shadows immediately - - CreateOtherObject(type); - m_engine->LoadAllTexture(); - - delete pModFile; - return TRUE; -} - -// Creates a small resource set on the ground. - -BOOL CObject::CreateResource(D3DVECTOR pos, float angle, ObjectType type, - float power) -{ - CModFile* pModFile; - char name[50]; - int rank; - float radius, height; - - if ( type != OBJECT_SHOW ) - { - if ( m_engine->RetRestCreate() < 1 ) return FALSE; - } - - pModFile = new CModFile(m_iMan); - - SetType(type); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object - SetObjectRank(0, rank); - SetEnergy(power); - - name[0] = 0; - if ( type == OBJECT_STONE ) strcpy(name, "objects\\stone.mod"); - if ( type == OBJECT_URANIUM ) strcpy(name, "objects\\uranium.mod"); - if ( type == OBJECT_METAL ) strcpy(name, "objects\\metal.mod"); - if ( type == OBJECT_POWER ) strcpy(name, "objects\\power.mod"); - if ( type == OBJECT_ATOMIC ) strcpy(name, "objects\\atomic.mod"); - if ( type == OBJECT_BULLET ) strcpy(name, "objects\\bullet.mod"); - if ( type == OBJECT_BBOX ) strcpy(name, "objects\\bbox.mod"); - if ( type == OBJECT_KEYa ) strcpy(name, "objects\\keya.mod"); - if ( type == OBJECT_KEYb ) strcpy(name, "objects\\keyb.mod"); - if ( type == OBJECT_KEYc ) strcpy(name, "objects\\keyc.mod"); - if ( type == OBJECT_KEYd ) strcpy(name, "objects\\keyd.mod"); - if ( type == OBJECT_TNT ) strcpy(name, "objects\\tnt.mod"); - if ( type == OBJECT_SCRAP1 ) strcpy(name, "objects\\scrap1.mod"); - if ( type == OBJECT_SCRAP2 ) strcpy(name, "objects\\scrap2.mod"); - if ( type == OBJECT_SCRAP3 ) strcpy(name, "objects\\scrap3.mod"); - if ( type == OBJECT_SCRAP4 ) strcpy(name, "objects\\scrap4.mod"); - if ( type == OBJECT_SCRAP5 ) strcpy(name, "objects\\scrap5.mod"); - if ( type == OBJECT_BOMB ) strcpy(name, "objects\\bomb.mod"); - if ( type == OBJECT_WAYPOINT ) strcpy(name, "objects\\waypoint.mod"); - if ( type == OBJECT_SHOW ) strcpy(name, "objects\\show.mod"); - if ( type == OBJECT_WINFIRE ) strcpy(name, "objects\\winfire.mod"); - if ( type == OBJECT_BAG ) strcpy(name, "objects\\bag.mod"); - if ( type == OBJECT_MARKSTONE ) strcpy(name, "objects\\cross1.mod"); - if ( type == OBJECT_MARKURANIUM ) strcpy(name, "objects\\cross3.mod"); - if ( type == OBJECT_MARKPOWER ) strcpy(name, "objects\\cross2.mod"); - if ( type == OBJECT_MARKKEYa ) strcpy(name, "objects\\crossa.mod"); - if ( type == OBJECT_MARKKEYb ) strcpy(name, "objects\\crossb.mod"); - if ( type == OBJECT_MARKKEYc ) strcpy(name, "objects\\crossc.mod"); - if ( type == OBJECT_MARKKEYd ) strcpy(name, "objects\\crossd.mod"); - if ( type == OBJECT_EGG ) strcpy(name, "objects\\egg.mod"); - - pModFile->ReadModel(name); - pModFile->CreateEngineObject(rank); - - SetPosition(0, pos); - SetAngleY(0, angle); - - if ( type == OBJECT_SHOW ) // remains in the air? - { - delete pModFile; - return TRUE; - } - - radius = 1.5f; - height = 0.0f; - - if ( type == OBJECT_MARKSTONE || - type == OBJECT_MARKURANIUM || - type == OBJECT_MARKKEYa || - type == OBJECT_MARKKEYb || - type == OBJECT_MARKKEYc || - type == OBJECT_MARKKEYd || - type == OBJECT_MARKPOWER || - type == OBJECT_WAYPOINT ) - { - } - else if ( type == OBJECT_EGG ) - { - CreateCrashSphere(D3DVECTOR(-1.0f, 2.8f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 10.0f); - radius = 3.0f; - } - else if ( type == OBJECT_BOMB ) - { - CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 3.0f); - radius = 3.0f; - } - else if ( type == OBJECT_BAG ) - { - CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f); - SetZoom(0, 1.5f); - radius = 5.0f; - height = -1.4f; - } - else - { - CreateCrashSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 1.5f); - } - CreateShadowCircle(radius, 1.0f); - - SetFloorHeight(0.0f); - CreateOtherObject(type); - m_engine->LoadAllTexture(); - FloorAdjust(); - - pos = RetPosition(0); - pos.y += height; - SetPosition(0, pos); // to display the shadows immediately - - delete pModFile; - return TRUE; -} - -// Creates a flag placed on the ground. - -BOOL CObject::CreateFlag(D3DVECTOR pos, float angle, ObjectType type) -{ - CModFile* pModFile; - char name[50]; - int rank, i; - - if ( m_engine->RetRestCreate() < 1+4 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - SetType(type); - - name[0] = 0; - if ( type == OBJECT_FLAGb ) strcpy(name, "objects\\flag1b.mod"); - if ( type == OBJECT_FLAGr ) strcpy(name, "objects\\flag1r.mod"); - if ( type == OBJECT_FLAGg ) strcpy(name, "objects\\flag1g.mod"); - if ( type == OBJECT_FLAGy ) strcpy(name, "objects\\flag1y.mod"); - if ( type == OBJECT_FLAGv ) strcpy(name, "objects\\flag1v.mod"); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object - SetObjectRank(0, rank); - pModFile->ReadModel(name); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - name[0] = 0; - if ( type == OBJECT_FLAGb ) strcpy(name, "objects\\flag2b.mod"); - if ( type == OBJECT_FLAGr ) strcpy(name, "objects\\flag2r.mod"); - if ( type == OBJECT_FLAGg ) strcpy(name, "objects\\flag2g.mod"); - if ( type == OBJECT_FLAGy ) strcpy(name, "objects\\flag2y.mod"); - if ( type == OBJECT_FLAGv ) strcpy(name, "objects\\flag2v.mod"); - - for ( i=0 ; i<4 ; i++ ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(1+i, rank); - SetObjectParent(1+i, i); - pModFile->ReadModel(name); - pModFile->CreateEngineObject(rank); - if ( i == 0 ) SetPosition(1+i, D3DVECTOR(0.15f, 5.0f, 0.0f)); - else SetPosition(1+i, D3DVECTOR(0.79f, 0.0f, 0.0f)); - } - - SetJotlerSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 1.0f); - CreateShadowCircle(2.0f, 0.3f); - - SetFloorHeight(0.0f); - CreateOtherObject(type); - m_engine->LoadAllTexture(); - FloorAdjust(); - - pos = RetPosition(0); - SetPosition(0, pos); // to display the shadows immediately - - delete pModFile; - return TRUE; -} - -// Creates a barrier placed on the ground. - -BOOL CObject::CreateBarrier(D3DVECTOR pos, float angle, float height, - ObjectType type) -{ - CModFile* pModFile; - int rank; - - if ( m_engine->RetRestCreate() < 1 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - SetType(type); - - if ( type == OBJECT_BARRIER0 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\barrier0.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR( 3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - - CreateShadowCircle(6.0f, 0.5f, D3DSHADOWWORM); - } - - if ( type == OBJECT_BARRIER1 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\barrier1.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR( 8.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-8.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - - CreateShadowCircle(12.0f, 0.5f, D3DSHADOWWORM); - } - - if ( type == OBJECT_BARRIER2 ) // cardboard? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\barrier2.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR( 8.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-8.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - - CreateShadowCircle(12.0f, 0.8f, D3DSHADOWWORM); - } - - if ( type == OBJECT_BARRIER3 ) // match + straw? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\barrier3.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR( 8.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-8.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - - CreateShadowCircle(10.0f, 0.5f, D3DSHADOWWORM); - } - - pos = RetPosition(0); - SetPosition(0, pos); // to display the shadows immediately - - SetFloorHeight(0.0f); - CreateOtherObject(type); - FloorAdjust(); - - pos = RetPosition(0); - pos.y += height; - SetPosition(0, pos); - - delete pModFile; - return TRUE; -} - -// Creates a plant placed on the ground. - -BOOL CObject::CreatePlant(D3DVECTOR pos, float angle, float height, - ObjectType type) -{ - CModFile* pModFile; - int rank; - - if ( m_engine->RetRestCreate() < 1 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - SetType(type); - - if ( type == OBJECT_PLANT0 || - type == OBJECT_PLANT1 || - type == OBJECT_PLANT2 || - type == OBJECT_PLANT3 || - type == OBJECT_PLANT4 ) // standard? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - if ( type == OBJECT_PLANT0 ) pModFile->ReadModel("objects\\plant0.mod"); - if ( type == OBJECT_PLANT1 ) pModFile->ReadModel("objects\\plant1.mod"); - if ( type == OBJECT_PLANT2 ) pModFile->ReadModel("objects\\plant2.mod"); - if ( type == OBJECT_PLANT3 ) pModFile->ReadModel("objects\\plant3.mod"); - if ( type == OBJECT_PLANT4 ) pModFile->ReadModel("objects\\plant4.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - height -= 2.0f; - - CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f); - SetGlobalSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 6.0f); - SetJotlerSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 8.0f); - - CreateShadowCircle(8.0f, 0.5f); - } - - if ( type == OBJECT_PLANT5 || - type == OBJECT_PLANT6 || - type == OBJECT_PLANT7 ) // clover? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - if ( type == OBJECT_PLANT5 ) pModFile->ReadModel("objects\\plant5.mod"); - if ( type == OBJECT_PLANT6 ) pModFile->ReadModel("objects\\plant6.mod"); - if ( type == OBJECT_PLANT7 ) pModFile->ReadModel("objects\\plant7.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - -//? CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 3.0f, SOUND_BOUM, 0.10f); - SetJotlerSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f); - - CreateShadowCircle(5.0f, 0.3f); - } - - if ( type == OBJECT_PLANT8 || - type == OBJECT_PLANT9 ) // squash? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - if ( type == OBJECT_PLANT8 ) pModFile->ReadModel("objects\\plant8.mod"); - if ( type == OBJECT_PLANT9 ) pModFile->ReadModel("objects\\plant9.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f); - CreateCrashSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f); - - CreateShadowCircle(10.0f, 0.5f); - } - - if ( type == OBJECT_PLANT10 || - type == OBJECT_PLANT11 || - type == OBJECT_PLANT12 || - type == OBJECT_PLANT13 || - type == OBJECT_PLANT14 ) // succulent? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - if ( type == OBJECT_PLANT10 ) pModFile->ReadModel("objects\\plant10.mod"); - if ( type == OBJECT_PLANT11 ) pModFile->ReadModel("objects\\plant11.mod"); - if ( type == OBJECT_PLANT12 ) pModFile->ReadModel("objects\\plant12.mod"); - if ( type == OBJECT_PLANT13 ) pModFile->ReadModel("objects\\plant13.mod"); - if ( type == OBJECT_PLANT14 ) pModFile->ReadModel("objects\\plant14.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR(0.0f, 12.0f, 0.0f), 5.0f, SOUND_BOUM, 0.10f); - SetGlobalSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 6.0f); - SetJotlerSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 8.0f); - - CreateShadowCircle(8.0f, 0.3f); - } - - if ( type == OBJECT_PLANT15 || - type == OBJECT_PLANT16 || - type == OBJECT_PLANT17 || - type == OBJECT_PLANT18 || - type == OBJECT_PLANT19 ) // fern? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - if ( type == OBJECT_PLANT15 ) pModFile->ReadModel("objects\\plant15.mod"); - if ( type == OBJECT_PLANT16 ) pModFile->ReadModel("objects\\plant16.mod"); - if ( type == OBJECT_PLANT17 ) pModFile->ReadModel("objects\\plant17.mod"); - if ( type == OBJECT_PLANT18 ) pModFile->ReadModel("objects\\plant18.mod"); - if ( type == OBJECT_PLANT19 ) pModFile->ReadModel("objects\\plant19.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - if ( type != OBJECT_PLANT19 ) - { - CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f); - SetGlobalSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 6.0f); - } - SetJotlerSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 8.0f); - - CreateShadowCircle(8.0f, 0.5f); - } - - if ( type == OBJECT_TREE0 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\tree0.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR( 0.0f, 3.0f, 2.0f), 3.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR(-1.0f, 10.0f, 1.0f), 2.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR( 0.0f, 17.0f, 0.0f), 2.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR( 1.0f, 27.0f, 0.0f), 2.0f, SOUND_BOUMs, 0.20f); - - CreateShadowCircle(8.0f, 0.5f); - } - - if ( type == OBJECT_TREE1 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\tree1.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR( 0.0f, 3.0f, 2.0f), 3.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR(-2.0f, 11.0f, 1.0f), 2.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR(-2.0f, 19.0f, 2.0f), 2.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR( 2.0f, 26.0f, 0.0f), 2.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR( 2.0f, 34.0f,-2.0f), 2.0f, SOUND_BOUMs, 0.20f); - - CreateShadowCircle(8.0f, 0.5f); - } - - if ( type == OBJECT_TREE2 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\tree2.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR( 0.0f, 3.0f, 1.0f), 3.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR(-2.0f, 10.0f, 1.0f), 2.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR(-2.0f, 19.0f, 2.0f), 2.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR( 2.0f, 25.0f, 0.0f), 2.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR( 3.0f, 32.0f,-2.0f), 2.0f, SOUND_BOUMs, 0.20f); - - CreateShadowCircle(8.0f, 0.5f); - } - - if ( type == OBJECT_TREE3 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\tree3.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR(-2.0f, 3.0f, 2.0f), 3.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR(-3.0f, 9.0f, 1.0f), 2.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR( 0.0f, 18.0f, 0.0f), 2.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR( 0.0f, 27.0f, 7.0f), 2.0f, SOUND_BOUMs, 0.20f); - - CreateShadowCircle(8.0f, 0.5f); - } - - if ( type == OBJECT_TREE4 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\tree4.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 10.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR(0.0f, 21.0f, 0.0f), 8.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR(0.0f, 32.0f, 0.0f), 7.0f, SOUND_BOUMs, 0.20f); - - CreateShadowCircle(8.0f, 0.5f); - } - - if ( type == OBJECT_TREE5 ) // giant tree (for the world "teen") - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\tree5.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR( 0.0f, 5.0f,-10.0f), 25.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR(-65.0f, 5.0f, 65.0f), 20.0f, SOUND_BOUMs, 0.20f); - CreateCrashSphere(D3DVECTOR( 38.0f, 5.0f, 21.0f), 18.0f, SOUND_BOUMs, 0.20f); - - CreateShadowCircle(50.0f, 0.5f); - } - - pos = RetPosition(0); - SetPosition(0, pos); // to display the shadows immediately - - SetFloorHeight(0.0f); - CreateOtherObject(type); - - pos = RetPosition(0); - pos.y += height; - SetPosition(0, pos); - - delete pModFile; - return TRUE; -} - -// Creates a mushroom placed on the ground. - -BOOL CObject::CreateMushroom(D3DVECTOR pos, float angle, float height, - ObjectType type) -{ - CModFile* pModFile; - int rank; - - if ( m_engine->RetRestCreate() < 1 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - SetType(type); - - if ( type == OBJECT_MUSHROOM1 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\mush1.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 3.0f, SOUND_BOUM, 0.10f); - SetGlobalSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 5.5f); - SetJotlerSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 5.5f); - - CreateShadowCircle(6.0f, 0.5f); - } - - if ( type == OBJECT_MUSHROOM2 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\mush2.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 3.0f, SOUND_BOUM, 0.10f); - SetGlobalSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 5.5f); - SetJotlerSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 5.5f); - - CreateShadowCircle(5.0f, 0.5f); - } - - pos = RetPosition(0); - SetPosition(0, pos); // to display the shadows immediately - - SetFloorHeight(0.0f); - CreateOtherObject(type); - - pos = RetPosition(0); - pos.y += height; - SetPosition(0, pos); - - delete pModFile; - return TRUE; -} - -// Creates a toy placed on the ground. - -BOOL CObject::CreateTeen(D3DVECTOR pos, float angle, float zoom, float height, - ObjectType type) -{ - CModFile* pModFile; - D3DMATRIX* mat; - D3DCOLORVALUE color; - int rank; - float fShadow; - BOOL bFloorAdjust = TRUE; - - if ( m_engine->RetRestCreate() < 1 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - SetType(type); - - fShadow = Norm(1.0f-height/10.0f); - - if ( type == OBJECT_TEEN0 ) // orange pencil lg=10 - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen0.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR( 5.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 2.5f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-2.5f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-5.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - - CreateShadowCircle(5.0f, 0.8f*fShadow, D3DSHADOWWORM); - } - - if ( type == OBJECT_TEEN1 ) // blue pencil lg=14 - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen1.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR( 6.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 4.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 2.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-2.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-4.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-6.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - - CreateShadowCircle(6.0f, 0.8f*fShadow, D3DSHADOWWORM); - } - - if ( type == OBJECT_TEEN2 ) // red pencil lg=16 - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen2.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR( 7.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 4.7f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 2.3f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-2.3f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-4.7f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-7.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - - CreateShadowCircle(6.0f, 0.8f*fShadow, D3DSHADOWWORM); - } - - if ( type == OBJECT_TEEN3 ) // jar with pencils - { - rank = m_engine->CreateObject(); -//? m_engine->SetObjectType(rank, TYPEFIX); - m_engine->SetObjectType(rank, TYPEMETAL); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen3.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 4.0f); - CreateShadowCircle(6.0f, 0.5f*fShadow); - } - - if ( type == OBJECT_TEEN4 ) // scissors - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen4.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-9.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-6.0f, 1.0f, 0.0f), 1.1f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-3.0f, 1.0f, 0.0f), 1.2f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 1.0f, 0.0f), 1.3f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 5.1f, 1.0f,-1.3f), 2.6f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 8.0f, 1.0f, 2.2f), 2.3f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 9.4f, 1.0f,-2.0f), 2.0f, SOUND_BOUMm, 0.45f); - - CreateShadowCircle(10.0f, 0.5f*fShadow, D3DSHADOWWORM); - } - - if ( type == OBJECT_TEEN5 ) // CD - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen5.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - SetFloorHeight(0.0f); - bFloorAdjust = FALSE; - - m_terrain->AddBuildingLevel(pos, 5.9f, 6.1f, 0.2f, 0.5f); - CreateShadowCircle(8.0f, 0.2f*fShadow); - } - - if ( type == OBJECT_TEEN6 ) // book 1 - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen6.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); - - CreateShadowCircle(20.0f, 0.2f*fShadow); - } - - if ( type == OBJECT_TEEN7 ) // book 2 - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen7.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); - - CreateShadowCircle(20.0f, 0.2f*fShadow); - } - - if ( type == OBJECT_TEEN8 ) // a stack of books 1 - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen8.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); - - SetGlobalSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 12.0f); - CreateShadowCircle(20.0f, 0.2f*fShadow); - } - - if ( type == OBJECT_TEEN9 ) // a stack of books 2 - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen9.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); - - SetGlobalSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 12.0f); - CreateShadowCircle(20.0f, 0.2f*fShadow); - } - - if ( type == OBJECT_TEEN10 ) // bookcase - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen10.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-26.0f, 3.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-15.0f, 3.0f,-4.0f), 6.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-15.0f, 3.0f, 5.0f), 6.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( -4.0f, 3.0f,-4.0f), 6.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( -4.0f, 3.0f, 5.0f), 6.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 6.0f, 3.0f,-4.0f), 6.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 6.0f, 3.0f, 4.0f), 6.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 14.0f, 3.0f,-3.0f), 6.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 14.0f, 3.0f, 2.0f), 6.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 24.0f, 3.0f, 5.0f), 6.0f, SOUND_BOUMm, 0.45f); - - SetGlobalSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 20.0f); - CreateShadowCircle(40.0f, 0.2f*fShadow); - } - - if ( type == OBJECT_TEEN11 ) // lamp - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen11.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetFloorHeight(0.0f); - SetZoom(0, zoom); - - mat = RetWorldMatrix(0); - pos = Transform(*mat, D3DVECTOR(-56.0f, 22.0f, 0.0f)); - m_particule->CreateParticule(pos, D3DVECTOR(0.0f, 0.0f, 0.0f), FPOINT(20.0f, 20.0f), PARTISELY, 1.0f, 0.0f, 0.0f); - - pos = Transform(*mat, D3DVECTOR(-65.0f, 40.0f, 0.0f)); - color.r = 4.0f; - color.g = 2.0f; - color.b = 0.0f; // yellow-orange - color.a = 0.0f; - m_main->CreateSpot(pos, color); - } - - if ( type == OBJECT_TEEN12 ) // coke - { - rank = m_engine->CreateObject(); -//? m_engine->SetObjectType(rank, TYPEFIX); - m_engine->SetObjectType(rank, TYPEMETAL); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen12.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 9.0f, 0.0f), 5.0f); - CreateShadowCircle(4.5f, 1.0f*fShadow); - } - - if ( type == OBJECT_TEEN13 ) // cardboard farm - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen13.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); - - SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 15.0f); - CreateShadowCircle(20.0f, 1.0f*fShadow); - } - - if ( type == OBJECT_TEEN14 ) // open box - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen14.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); - - SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 15.0f); - CreateShadowCircle(20.0f, 1.0f*fShadow); - } - - if ( type == OBJECT_TEEN15 ) // stack of cartons - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen15.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); - - SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 15.0f); - CreateShadowCircle(20.0f, 1.0f*fShadow); - } - - if ( type == OBJECT_TEEN16 ) // watering can - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen16.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-8.0f, 4.0f, 0.0f), 12.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 8.0f, 4.0f, 0.0f), 12.0f, SOUND_BOUMm, 0.45f); - - SetGlobalSphere(D3DVECTOR(0.0f, 13.0f, 0.0f), 20.0f); - CreateShadowCircle(18.0f, 1.0f*fShadow); - } - - if ( type == OBJECT_TEEN17 ) // wheel | - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen17.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR( 0.0f, 31.0f, 0.0f), 31.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 31.0f, 0.0f), 31.0f); - CreateShadowCircle(24.0f, 0.5f*fShadow); - } - - if ( type == OBJECT_TEEN18 ) // wheel / - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen18.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR( 0.0f, 31.0f, 0.0f), 31.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 31.0f, 0.0f), 31.0f); - CreateShadowCircle(24.0f, 0.5f*fShadow); - } - - if ( type == OBJECT_TEEN19 ) // wheel = - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen19.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR( 0.0f, 10.0f, 0.0f), 32.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 32.0f); - CreateShadowCircle(33.0f, 1.0f*fShadow); - } - - if ( type == OBJECT_TEEN20 ) // wall with shelf - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen20.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-175.0f, 0.0f, -5.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-175.0f, 0.0f, -35.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( -55.0f, 0.0f, -5.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( -55.0f, 0.0f, -35.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( -37.0f, 0.0f, -5.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( -37.0f, 0.0f, -35.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 83.0f, 0.0f, -5.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 83.0f, 0.0f, -35.0f), 4.0f, SOUND_BOUMm, 0.45f); - } - - if ( type == OBJECT_TEEN21 ) // wall with window - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen21.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - } - - if ( type == OBJECT_TEEN22 ) // wall with door and shelf - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen22.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-135.0f, 0.0f, -5.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-135.0f, 0.0f, -35.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( -15.0f, 0.0f, -5.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( -15.0f, 0.0f, -35.0f), 4.0f, SOUND_BOUMm, 0.45f); - } - - if ( type == OBJECT_TEEN23 ) // skateboard on wheels - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen23.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - if ( m_option == 1 ) // passage under the prohibited skateboard? - { - CreateCrashSphere(D3DVECTOR(-10.0f, 2.0f, 0.0f), 11.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 10.0f, 2.0f, 0.0f), 11.0f, SOUND_BOUMm, 0.45f); - } - - CreateCrashSphere(D3DVECTOR(-23.0f, 2.0f, 7.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-23.0f, 2.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-23.0f, 2.0f,-7.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 23.0f, 2.0f, 7.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 23.0f, 2.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 23.0f, 2.0f,-7.0f), 3.0f, SOUND_BOUMm, 0.45f); - - CreateShadowCircle(35.0f, 0.8f*fShadow, D3DSHADOWWORM); - } - - if ( type == OBJECT_TEEN24 ) // skate / - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen24.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-12.0f, 0.0f, -3.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-12.0f, 0.0f, 3.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateShadowCircle(20.0f, 0.2f*fShadow); - } - - if ( type == OBJECT_TEEN25 ) // skate / - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen25.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-12.0f, 0.0f, -3.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-12.0f, 0.0f, 3.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateShadowCircle(20.0f, 0.2f*fShadow); - } - - if ( type == OBJECT_TEEN26 ) // ceiling lamp - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen26.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - SetFloorHeight(0.0f); - - mat = RetWorldMatrix(0); - pos = Transform(*mat, D3DVECTOR(0.0f, 50.0f, 0.0f)); - m_particule->CreateParticule(pos, D3DVECTOR(0.0f, 0.0f, 0.0f), FPOINT(100.0f, 100.0f), PARTISELY, 1.0f, 0.0f, 0.0f); - - pos = Transform(*mat, D3DVECTOR(0.0f, 50.0f, 0.0f)); - color.r = 4.0f; - color.g = 2.0f; - color.b = 0.0f; // yellow-orange - color.a = 0.0f; - m_main->CreateSpot(pos, color); - } - - if ( type == OBJECT_TEEN27 ) // large plant? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen27.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f); - CreateShadowCircle(40.0f, 0.5f); - } - - if ( type == OBJECT_TEEN28 ) // bottle? - { - rank = m_engine->CreateObject(); -//? m_engine->SetObjectType(rank, TYPEFIX); - m_engine->SetObjectType(rank, TYPEMETAL); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen28.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 5.0f, SOUND_BOUM, 0.10f); - CreateShadowCircle(7.0f, 0.6f*fShadow); - } - - if ( type == OBJECT_TEEN29 ) // bridge? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen29.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - bFloorAdjust = FALSE; - } - - if ( type == OBJECT_TEEN30 ) // jump? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen30.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 15.0f, SOUND_BOUM, 0.10f); - SetGlobalSphere(D3DVECTOR(0.0f, 15.0f, 0.0f), 17.0f); - CreateShadowCircle(20.0f, 1.0f*fShadow); - } - - if ( type == OBJECT_TEEN31 ) // basket? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen31.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-10.0f, 2.0f, 0.0f), 5.0f, SOUND_BOUM, 0.10f); - CreateCrashSphere(D3DVECTOR( 0.0f, 2.0f, 0.0f), 6.0f, SOUND_BOUM, 0.10f); - CreateCrashSphere(D3DVECTOR( 9.0f, 4.0f, 1.0f), 6.0f, SOUND_BOUM, 0.10f); - - SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 10.0f); - CreateShadowCircle(16.0f, 0.6f*fShadow); - } - - if ( type == OBJECT_TEEN32 ) // chair? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen32.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR( 17.5f, 1.0f, 17.5f), 3.5f, SOUND_BOUM, 0.10f); - CreateCrashSphere(D3DVECTOR( 17.5f, 1.0f, -17.5f), 3.5f, SOUND_BOUM, 0.10f); - CreateCrashSphere(D3DVECTOR(-17.5f, 1.0f, 17.5f), 3.5f, SOUND_BOUM, 0.10f); - CreateCrashSphere(D3DVECTOR(-17.5f, 1.0f, -17.5f), 3.5f, SOUND_BOUM, 0.10f); - SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 26.0f); - CreateShadowCircle(35.0f, 0.3f*fShadow); - } - - if ( type == OBJECT_TEEN33 ) // panel? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen33.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f); - CreateShadowCircle(10.0f, 0.3f*fShadow); - } - - if ( type == OBJECT_TEEN34 ) // stone? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen34.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f); - CreateShadowCircle(3.0f, 1.0f*fShadow); - } - - if ( type == OBJECT_TEEN35 ) // pipe? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen35.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(-40.0f, 5.0f, 0.0f), 10.0f, SOUND_BOUM, 0.10f); - CreateCrashSphere(D3DVECTOR(-20.0f, 5.0f, 0.0f), 10.0f, SOUND_BOUM, 0.10f); - CreateCrashSphere(D3DVECTOR( 0.0f, 5.0f, 0.0f), 10.0f, SOUND_BOUM, 0.10f); - CreateCrashSphere(D3DVECTOR( 20.0f, 5.0f, 0.0f), 10.0f, SOUND_BOUM, 0.10f); - CreateCrashSphere(D3DVECTOR( 40.0f, 5.0f, 0.0f), 10.0f, SOUND_BOUM, 0.10f); - CreateShadowCircle(40.0f, 0.8f*fShadow, D3DSHADOWWORM); - } - - if ( type == OBJECT_TEEN36 ) // trunk? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen36.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - bFloorAdjust = FALSE; - } - - if ( type == OBJECT_TEEN37 ) // boat? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen37.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - bFloorAdjust = FALSE; - } - - if ( type == OBJECT_TEEN38 ) // fan? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen38a.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(1, rank); - SetObjectParent(1, 0); - pModFile->ReadModel("objects\\teen38b.mod"); // engine - pModFile->CreateEngineObject(rank); - SetPosition(1, D3DVECTOR(0.0f, 30.0f, 0.0f)); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(2, rank); - SetObjectParent(2, 1); - pModFile->ReadModel("objects\\teen38c.mod"); // propeller - pModFile->CreateEngineObject(rank); - SetPosition(2, D3DVECTOR(0.0f, 0.0f, 0.0f)); - - CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 10.0f, SOUND_BOUM, 0.10f); - SetGlobalSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 10.0f); - CreateShadowCircle(15.0f, 0.5f*fShadow); - } - - if ( type == OBJECT_TEEN39 ) // potted plant? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen39.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 8.5f, SOUND_BOUM, 0.10f); - SetGlobalSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 8.5f); - CreateShadowCircle(10.0f, 1.0f*fShadow); - } - - if ( type == OBJECT_TEEN40 ) // balloon? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen40.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 11.0f, SOUND_BOUM, 0.10f); - SetGlobalSphere(D3DVECTOR(0.0f, 14.0f, 0.0f), 15.0f); - CreateShadowCircle(15.0f, 0.7f*fShadow); - } - - if ( type == OBJECT_TEEN41 ) // fence? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen41.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - } - - if ( type == OBJECT_TEEN42 ) // clover? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen42.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 2.0f, SOUND_BOUM, 0.10f); - CreateShadowCircle(15.0f, 0.4f*fShadow); - } - - if ( type == OBJECT_TEEN43 ) // clover? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen43.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 2.0f, SOUND_BOUM, 0.10f); - CreateShadowCircle(15.0f, 0.4f*fShadow); - } - - if ( type == OBJECT_TEEN44 ) // car? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\teen44.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, zoom); - - CreateCrashSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 55.0f, SOUND_BOUM, 0.10f); - SetGlobalSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 55.0f); - CreateShadowCircle(55.0f, 1.0f*fShadow); - } - - pos = RetPosition(0); - SetPosition(0, pos); // to display the shadows immediately - - if ( bFloorAdjust ) - { - SetFloorHeight(0.0f); - FloorAdjust(); - } - - CreateOtherObject(type); - - pos = RetPosition(0); - pos.y += height; - SetPosition(0, pos); - - delete pModFile; - return TRUE; -} - -// Creates a crystal placed on the ground. - -BOOL CObject::CreateQuartz(D3DVECTOR pos, float angle, float height, - ObjectType type) -{ - CModFile* pModFile; - float radius; - int rank; - - if ( m_engine->RetRestCreate() < 1 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - SetType(type); - - if ( type == OBJECT_QUARTZ0 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEQUARTZ); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\quartz0.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 3.5f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 3.5f); - - CreateShadowCircle(4.0f, 0.5f); - } - if ( type == OBJECT_QUARTZ1 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEQUARTZ); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\quartz1.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 5.0f); - - CreateShadowCircle(5.0f, 0.5f); - } - if ( type == OBJECT_QUARTZ2 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEQUARTZ); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\quartz2.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 6.0f); - - CreateShadowCircle(6.0f, 0.5f); - } - if ( type == OBJECT_QUARTZ3 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEQUARTZ); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\quartz3.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - - CreateCrashSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 10.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 10.0f); - - CreateShadowCircle(10.0f, 0.5f); - } - - pos = RetPosition(0); - SetPosition(0, pos); // to display the shadows immediately - - SetFloorHeight(0.0f); - CreateOtherObject(type); - - pos = RetPosition(0); - pos.y += height; - SetPosition(0, pos); - - if ( type == OBJECT_QUARTZ0 ) - { - pos.y += 4.0f; - radius = 2.0f; - } - if ( type == OBJECT_QUARTZ1 ) - { - pos.y += 6.0f; - radius = 4.0f; - } - if ( type == OBJECT_QUARTZ2 ) - { - pos.y += 10.0f; - radius = 5.0f; - } - if ( type == OBJECT_QUARTZ3 ) - { - pos.y += 16.0f; - radius = 8.0f; - } - m_particule->CreateParticule(pos, pos, FPOINT(2.0f, 2.0f), PARTIQUARTZ, 0.7f+Rand()*0.7f, radius, 0.0f); - m_particule->CreateParticule(pos, pos, FPOINT(2.0f, 2.0f), PARTIQUARTZ, 0.7f+Rand()*0.7f, radius, 0.0f); - - delete pModFile; - return TRUE; -} - -// Creates a root placed on the ground. - -BOOL CObject::CreateRoot(D3DVECTOR pos, float angle, float height, - ObjectType type) -{ - CModFile* pModFile; - int rank; - - if ( m_engine->RetRestCreate() < 1 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - SetType(type); - - if ( type == OBJECT_ROOT0 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\root0.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, 2.0f); - - CreateCrashSphere(D3DVECTOR(-5.0f, 1.0f, 0.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 4.0f, 1.0f, 2.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 4.0f, 1.0f, -3.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 2.0f, 5.0f, -1.0f), 1.5f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR(-4.0f, 5.0f, -1.0f), 1.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR(-2.0f, 8.0f, -0.5f), 1.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 0.0f, 10.0f, -0.5f), 1.0f, SOUND_BOUMv, 0.15f); -//? SetGlobalSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 11.0f); - - CreateShadowCircle(16.0f, 0.5f); - } - if ( type == OBJECT_ROOT1 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\root1.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, 2.0f); - - CreateCrashSphere(D3DVECTOR(-4.0f, 1.0f, 1.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 0.0f, 1.0f, 2.0f), 1.5f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 3.0f, 1.0f, -2.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR(-2.0f, 5.0f, 1.0f), 1.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 2.0f, 5.0f, 0.0f), 1.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 0.0f, 8.0f, 1.0f), 1.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 0.0f, 12.0f, 1.0f), 1.0f, SOUND_BOUMv, 0.15f); -//? SetGlobalSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 12.0f); - - CreateShadowCircle(16.0f, 0.5f); - } - if ( type == OBJECT_ROOT2 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\root2.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, 2.0f); - - CreateCrashSphere(D3DVECTOR(-3.0f, 1.0f, 0.5f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 3.0f, 1.0f, -1.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR(-1.0f, 4.5f, 0.0f), 1.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 3.0f, 7.0f, 1.0f), 1.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 0.0f, 7.0f, -1.0f), 1.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 4.0f, 11.0f, 1.0f), 1.0f, SOUND_BOUMv, 0.15f); -//? SetGlobalSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 10.0f); - - CreateShadowCircle(16.0f, 0.5f); - } - if ( type == OBJECT_ROOT3 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\root3.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, 2.0f); - - CreateCrashSphere(D3DVECTOR(-4.0f, 1.0f, 1.0f), 3.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 4.0f, 1.0f, -3.0f), 3.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 6.0f, 1.0f, 4.0f), 3.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR(-2.5f, 7.0f, 2.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 4.0f, 7.0f, 2.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 3.0f, 6.0f, -1.0f), 1.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 0.0f, 12.0f, 0.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 1.0f, 16.0f, 0.0f), 1.0f, SOUND_BOUMv, 0.15f); -//? SetGlobalSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 14.0f); - - CreateShadowCircle(22.0f, 0.5f); - } - if ( type == OBJECT_ROOT4 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\root4.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, 2.0f); - - CreateCrashSphere(D3DVECTOR( -7.0f, 2.0f, 3.0f), 4.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 5.0f, 2.0f, -6.0f), 4.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 6.0f, 2.0f, 6.0f), 3.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR(-11.0f, 1.0f, -2.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 1.0f, 1.0f, -7.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( -4.0f, 10.0f, 3.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 1.0f, 11.0f, 7.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 3.0f, 11.0f, -3.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( -3.0f, 17.0f, 1.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( -3.0f, 23.0f, -1.0f), 2.0f, SOUND_BOUMv, 0.15f); -//? SetGlobalSphere(D3DVECTOR(0.0f, 12.0f, 0.0f), 20.0f); - - CreateShadowCircle(30.0f, 0.5f); - } - if ( type == OBJECT_ROOT5 ) // gravity root ? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\root4.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, 2.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(1, rank); - SetObjectParent(1, 0); - pModFile->ReadModel("objects\\root5.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(1, D3DVECTOR(-5.0f, 28.0f, -4.0f)); - SetAngleX(1, -30.0f*PI/180.0f); - SetAngleZ(1, 20.0f*PI/180.0f); - - CreateCrashSphere(D3DVECTOR( -7.0f, 2.0f, 3.0f), 4.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 5.0f, 2.0f, -6.0f), 4.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 6.0f, 2.0f, 6.0f), 3.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR(-11.0f, 1.0f, -2.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 1.0f, 1.0f, -7.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( -4.0f, 10.0f, 3.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 1.0f, 11.0f, 7.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( 3.0f, 11.0f, -3.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( -3.0f, 17.0f, 1.0f), 2.0f, SOUND_BOUMv, 0.15f); - CreateCrashSphere(D3DVECTOR( -3.0f, 23.0f, -1.0f), 2.0f, SOUND_BOUMv, 0.15f); -//? SetGlobalSphere(D3DVECTOR(0.0f, 12.0f, 0.0f), 20.0f); - - CreateShadowCircle(30.0f, 0.5f); - } - - pos = RetPosition(0); - SetPosition(0, pos); // to display the shadows immediately - - SetFloorHeight(0.0f); - CreateOtherObject(type); - - pos = RetPosition(0); - pos.y += height; - SetPosition(0, pos); - - delete pModFile; - return TRUE; -} - -// Creates a small home. - -BOOL CObject::CreateHome(D3DVECTOR pos, float angle, float height, - ObjectType type) -{ - CModFile* pModFile; - int rank; - - if ( m_engine->RetRestCreate() < 1 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - SetType(type); - - if ( type == OBJECT_HOME1 ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\home1.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, 1.3f); - - CreateCrashSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 10.0f, SOUND_BOUMs, 0.25f); -//? SetGlobalSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 11.0f); - CreateShadowCircle(16.0f, 0.5f); - } - - pos = RetPosition(0); - SetPosition(0, pos); // to display the shadows immediately - - SetFloorHeight(0.0f); - CreateOtherObject(type); - - pos = RetPosition(0); - pos.y += height; - SetPosition(0, pos); - - delete pModFile; - return TRUE; -} - -// Creates ruin placed on the ground. - -BOOL CObject::CreateRuin(D3DVECTOR pos, float angle, float height, - ObjectType type) -{ - CModFile* pModFile; - char name[50]; - int rank; - - if ( m_engine->RetRestCreate() < 1+4 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - SetType(type); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object - SetObjectRank(0, rank); - - name[0] = 0; - if ( type == OBJECT_RUINmobilew1 ) strcpy(name, "objects\\ruin1.mod"); - if ( type == OBJECT_RUINmobilew2 ) strcpy(name, "objects\\ruin1.mod"); - if ( type == OBJECT_RUINmobilet1 ) strcpy(name, "objects\\ruin2.mod"); - if ( type == OBJECT_RUINmobilet2 ) strcpy(name, "objects\\ruin2.mod"); - if ( type == OBJECT_RUINmobiler1 ) strcpy(name, "objects\\ruin3.mod"); - if ( type == OBJECT_RUINmobiler2 ) strcpy(name, "objects\\ruin3.mod"); - if ( type == OBJECT_RUINfactory ) strcpy(name, "objects\\ruin4.mod"); - if ( type == OBJECT_RUINdoor ) strcpy(name, "objects\\ruin5.mod"); - if ( type == OBJECT_RUINsupport ) strcpy(name, "objects\\ruin6.mod"); - if ( type == OBJECT_RUINradar ) strcpy(name, "objects\\ruin7.mod"); - if ( type == OBJECT_RUINconvert ) strcpy(name, "objects\\ruin8.mod"); - if ( type == OBJECT_RUINbase ) strcpy(name, "objects\\ruin9.mod"); - if ( type == OBJECT_RUINhead ) strcpy(name, "objects\\ruin10.mod"); - - pModFile->ReadModel(name); - pModFile->CreateEngineObject(rank); - - SetPosition(0, pos); - SetAngleY(0, angle); - - if ( type == OBJECT_RUINmobilew1 ) // vehicle had wheels? - { - // Creates the right-back wheel. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(6, rank); - SetObjectParent(6, 0); - - pModFile->ReadModel("objects\\ruin1w.mod"); - pModFile->CreateEngineObject(rank); - - SetPosition(6, D3DVECTOR(-3.0f, 1.8f, -4.0f)); - SetAngleX(6, -PI/2.0f); - - // Creates the left-back wheel. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(7, rank); - SetObjectParent(7, 0); - - pModFile->ReadModel("objects\\ruin1w.mod"); - pModFile->CreateEngineObject(rank); - - SetPosition(7, D3DVECTOR(-3.0f, 1.0f, 3.0f)); - SetAngleY(7, PI-0.3f); - SetAngleX(7, -0.3f); - - // Creates the right-front wheel. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(8, rank); - SetObjectParent(8, 0); - - pModFile->ReadModel("objects\\ruin1w.mod"); - pModFile->CreateEngineObject(rank); - - SetPosition(8, D3DVECTOR(2.0f, 1.6f, -3.0f)); - SetAngleY(8, 0.3f); - - // Creates the left-front wheel. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(9, rank); - SetObjectParent(9, 0); - - pModFile->ReadModel("objects\\ruin1w.mod"); - pModFile->CreateEngineObject(rank); - - SetPosition(9, D3DVECTOR(2.0f, 1.0f, 3.0f)); - SetAngleY(9, PI-0.2f); - SetAngleX(9, 0.2f); - - CreateCrashSphere(D3DVECTOR(0.0f, 2.8f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); -//? SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 10.0f); - - CreateShadowCircle(4.0f, 1.0f); - } - - if ( type == OBJECT_RUINmobilew2 ) // vehicle has wheels? - { - // Creates the left-back wheel. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(7, rank); - SetObjectParent(7, 0); - - pModFile->ReadModel("objects\\ruin1w.mod"); - pModFile->CreateEngineObject(rank); - - SetPosition(7, D3DVECTOR(-3.0f, 1.0f, 3.0f)); - SetAngleY(7, PI+0.3f); - SetAngleX(7, 0.4f); - - // Creates the left-front wheel. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(9, rank); - SetObjectParent(9, 0); - - pModFile->ReadModel("objects\\ruin1w.mod"); - pModFile->CreateEngineObject(rank); - - SetPosition(9, D3DVECTOR(2.0f, 1.0f, 3.0f)); - SetAngleY(9, PI+0.3f); - SetAngleX(9, -0.3f); - - CreateCrashSphere(D3DVECTOR(0.0f, 2.8f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); -//? SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 10.0f); - - CreateShadowCircle(4.0f, 1.0f); - } - - if ( type == OBJECT_RUINmobilet1 ) // vehicle have caterpillars? - { - // Creates the cannon. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(1, rank); - SetObjectParent(1, 0); - - pModFile->ReadModel("objects\\ruin2c.mod"); - pModFile->CreateEngineObject(rank); - - SetPosition(1, D3DVECTOR(3.0f, 5.0f, -2.5f)); - SetAngleX(1, -PI*0.85f); - SetAngleY(1, -0.4f); - SetAngleZ(1, -0.1f); - - CreateCrashSphere(D3DVECTOR(1.0f, 2.8f, -1.0f), 5.0f, SOUND_BOUMm, 0.45f); -//? SetGlobalSphere(D3DVECTOR(1.0f, 5.0f, -1.0f), 10.0f); - - CreateShadowCircle(5.0f, 1.0f); - } - - if ( type == OBJECT_RUINmobilet2 ) // vehicle have caterpillars? - { - CreateCrashSphere(D3DVECTOR(0.0f, 2.8f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); -//? SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 10.0f); - - CreateShadowCircle(5.0f, 1.0f); - } - - if ( type == OBJECT_RUINmobiler1 ) // vehicle skating? - { - CreateCrashSphere(D3DVECTOR(1.0f, 2.8f, -1.0f), 5.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(1.0f, 5.0f, -1.0f), 10.0f); - - CreateShadowCircle(5.0f, 1.0f); - } - - if ( type == OBJECT_RUINmobiler2 ) // vehicle skating? - { - CreateCrashSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 10.0f); - - CreateShadowCircle(6.0f, 1.0f); - } - - if ( type == OBJECT_RUINfactory ) // factory ? - { - CreateCrashSphere(D3DVECTOR( 9.0f, 1.0f, -11.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 2.0f, -11.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, -10.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-12.0f, 11.0f, -4.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, -2.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-11.0f, 8.0f, 3.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-11.0f, 2.0f, 4.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-11.0f, 2.0f, 10.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( -4.0f, 0.0f, 10.0f), 3.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 18.0f); - - CreateShadowCircle(20.0f, 0.7f); - } - - if ( type == OBJECT_RUINdoor ) // converter holder? - { - CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); -//? SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 6.0f); - - CreateShadowCircle(6.0f, 1.0f); - } - - if ( type == OBJECT_RUINsupport ) // radar holder? - { - CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); -//? SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f); - - CreateShadowCircle(3.0f, 1.0f); - } - - if ( type == OBJECT_RUINradar ) // radar base? - { - CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); -//? SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 6.0f); - - CreateShadowCircle(6.0f, 1.0f); - } - - if ( type == OBJECT_RUINconvert ) // converter? - { - m_terrain->AddBuildingLevel(pos, 7.0f, 9.0f, 1.0f, 0.5f); - - CreateCrashSphere(D3DVECTOR(-10.0f, 0.0f, 4.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-10.0f, 0.0f, -4.0f), 5.0f, SOUND_BOUMm, 0.45f); -//? SetGlobalSphere(D3DVECTOR(-3.0f, 0.0f, 0.0f), 14.0f); - } - - if ( type == OBJECT_RUINbase ) // base? - { - CreateCrashSphere(D3DVECTOR( 0.0f, 15.0f, 0.0f),28.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 17.0f, 6.0f, 42.0f), 6.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 17.0f, 17.0f, 42.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-17.0f, 6.0f, 42.0f), 6.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-17.0f, 17.0f, 42.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-42.0f, 6.0f, 17.0f), 6.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-42.0f, 17.0f, 17.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-42.0f, 6.0f, -17.0f), 6.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-42.0f, 17.0f, -17.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-17.0f, 6.0f, -42.0f), 6.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-17.0f, 10.0f, -42.0f), 4.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 15.0f, 13.0f, -34.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 31.0f, 15.0f, -13.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 21.0f, 8.0f, -39.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 26.0f, 8.0f, -33.0f), 5.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 48.0f); - - CreateShadowCircle(40.0f, 1.0f); - } - - if ( type == OBJECT_RUINhead ) // base cap? - { - CreateCrashSphere(D3DVECTOR( 0.0f, 13.0f, 0.0f),20.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, -8.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f,-16.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f,-22.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-21.0f, 7.0f, 9.0f), 8.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( -9.0f, 7.0f, 21.0f), 8.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 21.0f, 7.0f, 9.0f), 8.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 9.0f, 7.0f, 21.0f), 8.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-21.0f, 7.0f, -9.0f), 8.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( -9.0f, 7.0f, -21.0f), 8.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 21.0f, 7.0f, -9.0f), 8.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 9.0f, 7.0f, -21.0f), 8.0f, SOUND_BOUMm, 0.45f); - SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 35.0f); - - CreateShadowCircle(30.0f, 1.0f); - } - - pos = RetPosition(0); - SetPosition(0, pos); //to display the shadows immediately - - SetFloorHeight(0.0f); - CreateOtherObject(type); - - if ( type != OBJECT_RUINfactory && - type != OBJECT_RUINconvert && - type != OBJECT_RUINbase ) - { - FloorAdjust(); - } - - pos = RetPosition(0); - pos.y += height; - SetPosition(0, pos); //to display the shadows immediately - - if ( type == OBJECT_RUINmobilew1 ) - { - pos = RetPosition(0); - pos.y -= 0.5f; - SetPosition(0, pos); - - angle = RetAngleX(0)-0.1f; - SetAngleX(0, angle); - } - - if ( type == OBJECT_RUINmobilew2 ) - { - pos = RetPosition(0); - pos.y -= 1.5f; - SetPosition(0, pos); - - angle = RetAngleX(0)-0.9f; - SetAngleX(0, angle); - - angle = RetAngleZ(0)-0.1f; - SetAngleZ(0, angle); - } - - if ( type == OBJECT_RUINmobilet1 ) - { - pos = RetPosition(0); - pos.y -= 0.9f; - SetPosition(0, pos); - - angle = RetAngleX(0)-0.3f; - SetAngleX(0, angle); - } - - if ( type == OBJECT_RUINmobilet2 ) - { - pos = RetPosition(0); - pos.y -= 1.5f; - SetPosition(0, pos); - - angle = RetAngleX(0)-0.3f; - SetAngleX(0, angle); - - angle = RetAngleZ(0)+0.8f; - SetAngleZ(0, angle); - } - - if ( type == OBJECT_RUINmobiler1 ) - { - pos = RetPosition(0); - pos.y += 4.0f; - SetPosition(0, pos); - - angle = RetAngleX(0)-PI*0.6f; - SetAngleX(0, angle); - - angle = RetAngleZ(0)-0.2f; - SetAngleZ(0, angle); - } - - if ( type == OBJECT_RUINmobiler2 ) - { - pos = RetPosition(0); - pos.y += 2.0f; - SetPosition(0, pos); - - angle = RetAngleX(0)-0.1f; - SetAngleX(0, angle); - - angle = RetAngleZ(0)-0.3f; - SetAngleZ(0, angle); - } - - if ( type == OBJECT_RUINdoor ) - { - pos = RetPosition(0); - pos.y -= 0.5f; - SetPosition(0, pos); - - angle = RetAngleZ(0)-0.1f; - SetAngleZ(0, angle); - } - - if ( type == OBJECT_RUINsupport ) - { - pos = RetPosition(0); - pos.y += 0.5f; - SetPosition(0, pos); - -//? angle = RetAngleY(0)+0.1f; -//? SetAngleY(0, angle); - - angle = RetAngleX(0)+0.1f; - SetAngleX(0, angle); - - angle = RetAngleZ(0)+0.1f; - SetAngleZ(0, angle); - } - - if ( type == OBJECT_RUINradar ) - { - pos = RetPosition(0); - pos.y -= 0.5f; - SetPosition(0, pos); - - angle = RetAngleX(0)+0.15f; - SetAngleX(0, angle); - - angle = RetAngleZ(0)+0.1f; - SetAngleZ(0, angle); - } - - if ( type == OBJECT_RUINconvert ) - { - pos = RetPosition(0); - pos.y -= 1.0f; - SetPosition(0, pos); - } - - if ( type == OBJECT_RUINbase ) - { - pos = RetPosition(0); - pos.y -= 1.0f; - SetPosition(0, pos); - - angle = RetAngleX(0)+0.15f; - SetAngleX(0, angle); - } - - if ( type == OBJECT_RUINhead ) - { - pos = RetPosition(0); - pos.y += 8.0f; - SetPosition(0, pos); - - angle = RetAngleX(0)+PI*0.4f; - SetAngleX(0, angle); - } - - delete pModFile; - return TRUE; -} - -// Creates a gadget apollo. - -BOOL CObject::CreateApollo(D3DVECTOR pos, float angle, ObjectType type) -{ - CModFile* pModFile; - int rank, i; - - if ( m_engine->RetRestCreate() < 6 ) return FALSE; - - pModFile = new CModFile(m_iMan); - - SetType(type); - - if ( type == OBJECT_APOLLO1 ) // LEM ? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\apollol1.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetZoom(0, 1.2f); - SetFloorHeight(0.0f); - - for ( i=0 ; i<4 ; i++ ) // creates feet - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(i+1, rank); - SetObjectParent(i+1, 0); - pModFile->ReadModel("objects\\apollol2.mod"); - pModFile->CreateEngineObject(rank); - SetAngleY(i+1, PI/2.0f*i); - } - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(5, rank); - SetObjectParent(5, 0); - pModFile->ReadModel("objects\\apollol3.mod"); // ladder - pModFile->CreateEngineObject(rank); - -//? m_terrain->AddBuildingLevel(pos, 10.0f, 13.0f, 12.0f, 0.0f); - - CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 0.0f), 9.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 11.0f, 5.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-11.0f, 5.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 5.0f, -11.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 0.0f, 5.0f, 11.0f), 3.0f, SOUND_BOUMm, 0.45f); - - SetGlobalSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 9.0f); - - CreateShadowCircle(16.0f, 0.5f); - } - - if ( type == OBJECT_APOLLO2 ) // jeep - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); //it is a stationary object - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\apolloj1.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetFloorHeight(0.0f); - - // Wheels. - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(1, rank); - SetObjectParent(1, 0); - pModFile->ReadModel("objects\\apolloj4.mod"); // wheel - pModFile->CreateEngineObject(rank); - SetPosition(1, D3DVECTOR(-5.75f, 1.65f, -5.0f)); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(2, rank); - SetObjectParent(2, 0); - pModFile->ReadModel("objects\\apolloj4.mod"); // wheel - pModFile->CreateEngineObject(rank); - SetPosition(2, D3DVECTOR(-5.75f, 1.65f, 5.0f)); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(3, rank); - SetObjectParent(3, 0); - pModFile->ReadModel("objects\\apolloj4.mod"); // wheel - pModFile->CreateEngineObject(rank); - SetPosition(3, D3DVECTOR(5.75f, 1.65f, -5.0f)); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(4, rank); - SetObjectParent(4, 0); - pModFile->ReadModel("objects\\apolloj4.mod"); // wheel - pModFile->CreateEngineObject(rank); - SetPosition(4, D3DVECTOR(5.75f, 1.65f, 5.0f)); - - // Accessories: - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(5, rank); - SetObjectParent(5, 0); - pModFile->ReadModel("objects\\apolloj2.mod"); // antenna - pModFile->CreateEngineObject(rank); - SetPosition(5, D3DVECTOR(5.5f, 8.8f, 2.0f)); - SetAngleY(5, -120.0f*PI/180.0f); - SetAngleZ(5, 45.0f*PI/180.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(6, rank); - SetObjectParent(6, 0); - pModFile->ReadModel("objects\\apolloj3.mod"); // camera - pModFile->CreateEngineObject(rank); - SetPosition(6, D3DVECTOR(5.5f, 2.8f, -2.0f)); - SetAngleY(6, 30.0f*PI/180.0f); - - CreateCrashSphere(D3DVECTOR( 3.0f, 2.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR(-3.0f, 2.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); - CreateCrashSphere(D3DVECTOR( 7.0f, 9.0f, 2.0f), 2.0f, SOUND_BOUMm, 0.20f); - - CreateShadowCircle(7.0f, 0.8f); - - FloorAdjust(); - } - - if ( type == OBJECT_APOLLO3 ) // flag? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\apollof.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetFloorHeight(0.0f); - - SetJotlerSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 1.0f); - CreateShadowCircle(2.0f, 0.3f); - } - - if ( type == OBJECT_APOLLO4 ) // module? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\apollom.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetFloorHeight(0.0f); - - CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 2.0f, SOUND_BOUMm, 0.45f); - CreateShadowCircle(5.0f, 0.8f); - - FloorAdjust(); - } - - if ( type == OBJECT_APOLLO5 ) // antenna? - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object - SetObjectRank(0, rank); - pModFile->ReadModel("objects\\apolloa.mod"); - pModFile->CreateEngineObject(rank); - SetPosition(0, pos); - SetAngleY(0, angle); - SetFloorHeight(0.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); - SetObjectRank(1, rank); - SetObjectParent(1, 0); - pModFile->ReadModel("objects\\apolloj2.mod"); // antenna - pModFile->CreateEngineObject(rank); - SetPosition(1, D3DVECTOR(0.0f, 5.0f, 0.0f)); - SetAngleY(1, -120.0f*PI/180.0f); - SetAngleZ(1, 45.0f*PI/180.0f); - - CreateCrashSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.35f); - CreateShadowCircle(3.0f, 0.7f); - } - - CreateOtherObject(type); - - pos = RetPosition(0); - SetPosition(0, pos); // to display the shadows immediately - - delete pModFile; - return TRUE; -} - -// Creates all sub-objects for managing the object. - -void CObject::CreateOtherObject(ObjectType type) -{ - if ( type == OBJECT_BASE ) - { - m_auto = new CAutoBase(m_iMan, this); - } - if ( type == OBJECT_PORTICO ) - { - m_auto = new CAutoPortico(m_iMan, this); - } - if ( type == OBJECT_DERRICK ) - { - m_auto = new CAutoDerrick(m_iMan, this); - } - if ( type == OBJECT_FACTORY ) - { - m_auto = new CAutoFactory(m_iMan, this); - } - if ( type == OBJECT_REPAIR ) - { - m_auto = new CAutoRepair(m_iMan, this); - } - if ( type == OBJECT_DESTROYER ) - { - m_auto = new CAutoDestroyer(m_iMan, this); - } - if ( type == OBJECT_STATION ) - { - m_auto = new CAutoStation(m_iMan, this); - } - if ( type == OBJECT_CONVERT ) - { - m_auto = new CAutoConvert(m_iMan, this); - } - if ( type == OBJECT_TOWER ) - { - m_auto = new CAutoTower(m_iMan, this); - } - if ( type == OBJECT_RESEARCH ) - { - m_auto = new CAutoResearch(m_iMan, this); - } - if ( type == OBJECT_RADAR ) - { - m_auto = new CAutoRadar(m_iMan, this); - } - if ( type == OBJECT_INFO ) - { - m_auto = new CAutoInfo(m_iMan, this); - } - if ( type == OBJECT_ENERGY ) - { - m_auto = new CAutoEnergy(m_iMan, this); - } - if ( type == OBJECT_LABO ) - { - m_auto = new CAutoLabo(m_iMan, this); - } - if ( type == OBJECT_NUCLEAR ) - { - m_auto = new CAutoNuclear(m_iMan, this); - } - if ( type == OBJECT_PARA ) - { - m_auto = new CAutoPara(m_iMan, this); - } - if ( type == OBJECT_SAFE ) - { - m_auto = new CAutoSafe(m_iMan, this); - } - if ( type == OBJECT_HUSTON ) - { - m_auto = new CAutoHuston(m_iMan, this); - } - if ( type == OBJECT_EGG ) - { - m_auto = new CAutoEgg(m_iMan, this); - } - if ( type == OBJECT_NEST ) - { - m_auto = new CAutoNest(m_iMan, this); - } - if ( type == OBJECT_ROOT5 ) - { - m_auto = new CAutoRoot(m_iMan, this); - } - if ( type == OBJECT_MUSHROOM2 ) - { - m_auto = new CAutoMush(m_iMan, this); - } - if ( type == OBJECT_FLAGb || - type == OBJECT_FLAGr || - type == OBJECT_FLAGg || - type == OBJECT_FLAGy || - type == OBJECT_FLAGv ) - { - m_auto = new CAutoFlag(m_iMan, this); - } - if ( type == OBJECT_TEEN36 || // trunk? - type == OBJECT_TEEN37 || // boat? - type == OBJECT_TEEN38 ) // fan? - { - m_auto = new CAutoKid(m_iMan, this); - } -} - - -// Reads a program. - -BOOL CObject::ReadProgram(int rank, char* filename) -{ - if ( m_brain != 0 ) - { - return m_brain->ReadProgram(rank, filename); - } - return FALSE; -} - -// Writes a program. - -BOOL CObject::WriteProgram(int rank, char* filename) -{ - if ( m_brain != 0 ) - { - return m_brain->WriteProgram(rank, filename); - } - return FALSE; -} - -// Starts a program. - -BOOL CObject::RunProgram(int rank) -{ - if ( m_brain != 0 ) - { - m_brain->RunProgram(rank); - return TRUE; - } - if ( m_auto != 0 ) - { - m_auto->Start(rank); - return TRUE; - } - return FALSE; -} - - - - -// Calculates the matrix for transforming the object. -// Returns TRUE if the matrix has changed. -// The rotations occur in the order Y, Z and X. - -BOOL CObject::UpdateTransformObject(int part, BOOL bForceUpdate) -{ - D3DVECTOR position, angle, eye; - BOOL bModif = FALSE; - int parent; - - if ( m_truck != 0 ) // transported by truck? - { - m_objectPart[part].bTranslate = TRUE; - m_objectPart[part].bRotate = TRUE; - } - - if ( !bForceUpdate && - !m_objectPart[part].bTranslate && - !m_objectPart[part].bRotate ) return FALSE; - - position = m_objectPart[part].position; - angle = m_objectPart[part].angle; - - if ( part == 0 ) // main part? - { - position += m_linVibration; - angle += m_cirVibration+m_inclinaison; - } - - if ( m_objectPart[part].bTranslate || - m_objectPart[part].bRotate ) - { - if ( m_objectPart[part].bTranslate ) - { - D3DUtil_SetIdentityMatrix(m_objectPart[part].matTranslate); - m_objectPart[part].matTranslate._41 = position.x; - m_objectPart[part].matTranslate._42 = position.y; - m_objectPart[part].matTranslate._43 = position.z; - } - - if ( m_objectPart[part].bRotate ) - { - MatRotateZXY(m_objectPart[part].matRotate, angle); - } - - if ( m_objectPart[part].bZoom ) - { - D3DMATRIX mz; - D3DUtil_SetIdentityMatrix(mz); - mz._11 = m_objectPart[part].zoom.x; - mz._22 = m_objectPart[part].zoom.y; - mz._33 = m_objectPart[part].zoom.z; - m_objectPart[part].matTransform = mz * - m_objectPart[part].matRotate * - m_objectPart[part].matTranslate; - } - else - { - m_objectPart[part].matTransform = m_objectPart[part].matRotate * - m_objectPart[part].matTranslate; - } - bModif = TRUE; - } - - if ( bForceUpdate || - m_objectPart[part].bTranslate || - m_objectPart[part].bRotate ) - { - parent = m_objectPart[part].parentPart; - - if ( part == 0 && m_truck != 0 ) // transported by a truck? - { - D3DMATRIX* matWorldTruck; - matWorldTruck = m_truck->RetWorldMatrix(m_truckLink); - m_objectPart[part].matWorld = m_objectPart[part].matTransform * - *matWorldTruck; - } - else - { - if ( parent == -1 ) // no parent? - { - m_objectPart[part].matWorld = m_objectPart[part].matTransform; - } - else - { - m_objectPart[part].matWorld = m_objectPart[part].matTransform * - m_objectPart[parent].matWorld; - } - } - bModif = TRUE; - } - - if ( bModif ) - { - m_engine->SetObjectTransform(m_objectPart[part].object, - m_objectPart[part].matWorld); - } - - m_objectPart[part].bTranslate = FALSE; - m_objectPart[part].bRotate = FALSE; - - return bModif; -} - -// Updates all matrices to transform the object father and all his sons. -// Assume a maximum of 4 degrees of freedom. -// Appropriate, for example, to a body, an arm, forearm, hand and fingers. - -BOOL CObject::UpdateTransformObject() -{ - BOOL bUpdate1, bUpdate2, bUpdate3, bUpdate4; - int level1, level2, level3, level4, rank; - int parent1, parent2, parent3, parent4; - - if ( m_bFlat ) - { - for ( level1=0 ; level1RetLimitLOD(0); - limit[2] = limit[1]; - limit[3] = m_engine->RetLimitLOD(1); - limit[4] = limit[3]; - limit[5] = 1000000.0f; - - for ( j=0 ; j<3 ; j++ ) - { - m_engine->ChangeTextureMapping(m_objectPart[0].object, - mat, D3DSTATEPART3, "lemt.tga", "", - limit[j*2+0], limit[j*2+1], D3DMAPPING1Y, - au, bu, 1.0f, 0.0f); - } -} - - -// Manual action. - -BOOL CObject::EventProcess(const Event &event) -{ - if ( event.event == EVENT_KEYDOWN ) - { -#if ADJUST_ONBOARD - if ( m_bSelect ) - { - if ( event.param == 'E' ) debug_x += 0.1f; - if ( event.param == 'D' ) debug_x -= 0.1f; - if ( event.param == 'R' ) debug_y += 0.1f; - if ( event.param == 'F' ) debug_y -= 0.1f; - if ( event.param == 'T' ) debug_z += 0.1f; - if ( event.param == 'G' ) debug_z -= 0.1f; - } -#endif -#if ADJUST_ARM - if ( m_bSelect ) - { - if ( event.param == 'X' ) debug_arm1 += 5.0f*PI/180.0f; - if ( event.param == 'C' ) debug_arm1 -= 5.0f*PI/180.0f; - if ( event.param == 'V' ) debug_arm2 += 5.0f*PI/180.0f; - if ( event.param == 'B' ) debug_arm2 -= 5.0f*PI/180.0f; - if ( event.param == 'N' ) debug_arm3 += 5.0f*PI/180.0f; - if ( event.param == 'M' ) debug_arm3 -= 5.0f*PI/180.0f; - if ( event.param == 'X' || - event.param == 'C' || - event.param == 'V' || - event.param == 'B' || - event.param == 'N' || - event.param == 'M' ) - { - SetAngleZ(1, debug_arm1); - SetAngleZ(2, debug_arm2); - SetAngleZ(3, debug_arm3); - char s[100]; - sprintf(s, "a=%.2f b=%.2f c=%.2f", debug_arm1*180.0f/PI, debug_arm2*180.0f/PI, debug_arm3*180.0f/PI); - m_engine->SetInfoText(5, s); - } - } -#endif - } - - if ( m_physics != 0 ) - { - if ( !m_physics->EventProcess(event) ) // object destroyed? - { - if ( RetSelect() && - m_type != OBJECT_ANT && - m_type != OBJECT_SPIDER && - m_type != OBJECT_BEE ) - { - if ( !m_bDead ) m_camera->SetType(CAMERA_EXPLO); - m_main->DeselectAll(); - } - return FALSE; - } - } - - if ( m_auto != 0 ) - { - m_auto->EventProcess(event); - - if ( event.event == EVENT_FRAME && - m_auto->IsEnded() != ERR_CONTINUE ) - { - m_auto->DeleteObject(); - delete m_auto; - m_auto = 0; - } - } - - if ( m_motion != 0 ) - { - m_motion->EventProcess(event); - } - - if ( event.event == EVENT_FRAME ) - { - return EventFrame(event); - } - - return TRUE; -} - - -// Animates the object. - -BOOL CObject::EventFrame(const Event &event) -{ - if ( m_type == OBJECT_HUMAN && m_main->RetMainMovie() == MM_SATCOMopen ) - { - UpdateTransformObject(); - return TRUE; - } - - if ( m_type != OBJECT_SHOW && m_engine->RetPause() ) return TRUE; - - m_aTime += event.rTime; - m_shotTime += event.rTime; - - VirusFrame(event.rTime); - PartiFrame(event.rTime); - - UpdateMapping(); - UpdateTransformObject(); - UpdateSelectParticule(); - - if ( m_bProxyActivate ) // active if it is near? - { - CPyro* pyro; - D3DVECTOR eye; - float dist; - - eye = m_engine->RetLookatPt(); - dist = Length(eye, RetPosition(0)); - if ( dist < m_proxyDistance ) - { - m_bProxyActivate = FALSE; - m_main->CreateShortcuts(); - m_sound->Play(SOUND_FINDING); - pyro = new CPyro(m_iMan); - pyro->Create(PT_FINDING, this, 0.0f); - m_displayText->DisplayError(INFO_FINDING, this); - } - } - - return TRUE; -} - -// Updates the mapping of the object. - -void CObject::UpdateMapping() -{ - if ( m_type == OBJECT_POWER || - m_type == OBJECT_ATOMIC || - m_type == OBJECT_STATION || - m_type == OBJECT_ENERGY ) - { - UpdateEnergyMapping(); - } -} - - -// Management of viruses. - -void CObject::VirusFrame(float rTime) -{ - ParticuleType type; - D3DVECTOR pos, speed; - FPOINT dim; - int r; - - if ( !m_bVirusMode ) return; // healthy object? - - m_virusTime += rTime; - if ( m_virusTime >= VIRUS_DELAY ) - { - m_bVirusMode = FALSE; // the virus is no longer active - } - - if ( m_lastVirusParticule+m_engine->ParticuleAdapt(0.2f) <= m_aTime ) - { - m_lastVirusParticule = m_aTime; - - r = rand()%10; - if ( r == 0 ) type = PARTIVIRUS1; - if ( r == 1 ) type = PARTIVIRUS2; - if ( r == 2 ) type = PARTIVIRUS3; - if ( r == 3 ) type = PARTIVIRUS4; - if ( r == 4 ) type = PARTIVIRUS5; - if ( r == 5 ) type = PARTIVIRUS6; - if ( r == 6 ) type = PARTIVIRUS7; - if ( r == 7 ) type = PARTIVIRUS8; - if ( r == 8 ) type = PARTIVIRUS9; - if ( r == 9 ) type = PARTIVIRUS10; - - pos = RetPosition(0); - pos.x += (Rand()-0.5f)*10.0f; - pos.z += (Rand()-0.5f)*10.0f; - speed.x = (Rand()-0.5f)*2.0f; - speed.z = (Rand()-0.5f)*2.0f; - speed.y = Rand()*4.0f+4.0f; - dim.x = Rand()*0.3f+0.3f; - dim.y = dim.x; - - m_particule->CreateParticule(pos, speed, dim, type, 3.0f); - } -} - -// Management particles mistresses. - -void CObject::PartiFrame(float rTime) -{ - D3DVECTOR pos, angle, factor; - int i, channel; - - for ( i=0 ; iGetPosition(channel, pos) ) - { - m_objectPart[i].masterParti = -1; // particle no longer exists! - continue; - } - - SetPosition(i, pos); - - // Each song spins differently. - switch( i%5 ) - { - case 0: factor = D3DVECTOR( 0.5f, 0.3f, 0.6f); break; - case 1: factor = D3DVECTOR(-0.3f, 0.4f,-0.2f); break; - case 2: factor = D3DVECTOR( 0.4f,-0.6f,-0.3f); break; - case 3: factor = D3DVECTOR(-0.6f,-0.2f, 0.0f); break; - case 4: factor = D3DVECTOR( 0.4f, 0.1f,-0.7f); break; - } - - angle = RetAngle(i); - angle += rTime*PI*factor; - SetAngle(i, angle); - } -} - - -// Changes the perspective to view if it was like in the vehicle, -// or behind the vehicle. - -void CObject::SetViewFromHere(D3DVECTOR &eye, float &dirH, float &dirV, - D3DVECTOR &lookat, D3DVECTOR &upVec, - CameraType type) -{ - float speed; - int part; - - UpdateTransformObject(); - - part = 0; - if ( m_type == OBJECT_HUMAN || - m_type == OBJECT_TECH ) - { - eye.x = -0.2f; - eye.y = 3.3f; - eye.z = 0.0f; -//? eye.x = 1.0f; -//? eye.y = 3.3f; -//? eye.z = 0.0f; - } - else if ( m_type == OBJECT_MOBILErt || - m_type == OBJECT_MOBILErr || - m_type == OBJECT_MOBILErs ) - { - eye.x = -1.1f; // on the cap - eye.y = 7.9f; - eye.z = 0.0f; - } - else if ( m_type == OBJECT_MOBILEwc || - m_type == OBJECT_MOBILEtc || - m_type == OBJECT_MOBILEfc || - m_type == OBJECT_MOBILEic ) // fireball? - { -//? eye.x = -0.9f; // on the cannon -//? eye.y = 3.0f; -//? eye.z = 0.0f; -//? part = 1; - eye.x = -0.9f; // on the cannon - eye.y = 8.3f; - eye.z = 0.0f; - } - else if ( m_type == OBJECT_MOBILEwi || - m_type == OBJECT_MOBILEti || - m_type == OBJECT_MOBILEfi || - m_type == OBJECT_MOBILEii ) // orgaball ? - { -//? eye.x = -3.5f; // on the cannon -//? eye.y = 5.1f; -//? eye.z = 0.0f; -//? part = 1; - eye.x = -2.5f; // on the cannon - eye.y = 10.4f; - eye.z = 0.0f; - } - else if ( m_type == OBJECT_MOBILErc ) - { -//? eye.x = 2.0f; // in the cannon -//? eye.y = 0.0f; -//? eye.z = 0.0f; -//? part = 2; - eye.x = 4.0f; // on the cannon - eye.y = 11.0f; - eye.z = 0.0f; - } - else if ( m_type == OBJECT_MOBILEsa ) - { - eye.x = 3.0f; - eye.y = 4.5f; - eye.z = 0.0f; - } - else if ( m_type == OBJECT_MOBILEdr ) - { - eye.x = 1.0f; - eye.y = 6.5f; - eye.z = 0.0f; - } - else if ( m_type == OBJECT_APOLLO2 ) - { - eye.x = -3.0f; - eye.y = 6.0f; - eye.z = -2.0f; - } - else - { - eye.x = 0.7f; // between the brackets - eye.y = 4.8f; - eye.z = 0.0f; - } -#if ADJUST_ONBOARD - eye.x += debug_x; - eye.y += debug_y; - eye.z += debug_z; - char s[100]; - sprintf(s, "x=%.2f y=%.2f z=%.2f", eye.x, eye.y, eye.z); - m_engine->SetInfoText(4, s); -#endif - - if ( type == CAMERA_BACK ) - { - eye.x -= 20.0f; - eye.y += 1.0f; - } - - lookat.x = eye.x+1.0f; - lookat.y = eye.y+0.0f; - lookat.z = eye.z+0.0f; - - eye = Transform(m_objectPart[part].matWorld, eye); - lookat = Transform(m_objectPart[part].matWorld, lookat); - - // Camera tilts when turning. - upVec = D3DVECTOR(0.0f, 1.0f, 0.0f); - if ( m_physics != 0 ) - { - if ( m_physics->RetLand() ) // on ground? - { - speed = m_physics->RetLinMotionX(MO_REASPEED); - lookat.y -= speed*0.002f; - - speed = m_physics->RetCirMotionY(MO_REASPEED); - upVec.z -= speed*0.04f; - } - else // in flight? - { - speed = m_physics->RetLinMotionX(MO_REASPEED); - lookat.y += speed*0.002f; - - speed = m_physics->RetCirMotionY(MO_REASPEED); - upVec.z += speed*0.08f; - } - } - upVec = Transform(m_objectPart[0].matRotate, upVec); - - dirH = -(m_objectPart[part].angle.y+PI/2.0f); - dirV = 0.0f; - -} - - -// Management of features. - -void CObject::SetCharacter(Character* character) -{ - CopyMemory(&m_character, character, sizeof(Character)); -} - -void CObject::GetCharacter(Character* character) -{ - CopyMemory(character, &m_character, sizeof(Character)); -} - -Character* CObject::RetCharacter() -{ - return &m_character; -} - - -// Returns the absolute time. - -float CObject::RetAbsTime() -{ - return m_aTime; -} - - -// Management of energy contained in a battery. -// Single subject possesses the battery energy, but not the vehicle that carries the battery! - -void CObject::SetEnergy(float level) -{ - if ( level < 0.0f ) level = 0.0f; - if ( level > 1.0f ) level = 1.0f; - m_energy = level; -} - -float CObject::RetEnergy() -{ - if ( m_type != OBJECT_POWER && - m_type != OBJECT_ATOMIC && - m_type != OBJECT_STATION && - m_type != OBJECT_ENERGY ) return 0.0f; - return m_energy; -} - - -// Management of the capacity of a battery. -// Single subject possesses a battery capacity, -// but not the vehicle that carries the battery! - -void CObject::SetCapacity(float capacity) -{ - m_capacity = capacity; -} - -float CObject::RetCapacity() -{ - return m_capacity; -} - - -// Management of the shield. - -void CObject::SetShield(float level) -{ - m_shield = level; -} - -float CObject::RetShield() -{ - if ( m_type == OBJECT_FRET || - m_type == OBJECT_STONE || - m_type == OBJECT_URANIUM || - m_type == OBJECT_BULLET || - m_type == OBJECT_METAL || - m_type == OBJECT_BBOX || - m_type == OBJECT_KEYa || - m_type == OBJECT_KEYb || - m_type == OBJECT_KEYc || - m_type == OBJECT_KEYd || - m_type == OBJECT_TNT || - m_type == OBJECT_TEEN31 || // basket? - m_type == OBJECT_SCRAP1 || - m_type == OBJECT_SCRAP2 || - m_type == OBJECT_SCRAP3 || - m_type == OBJECT_SCRAP4 || - m_type == OBJECT_SCRAP5 || - m_type == OBJECT_BOMB || - m_type == OBJECT_WAYPOINT || - m_type == OBJECT_FLAGb || - m_type == OBJECT_FLAGr || - m_type == OBJECT_FLAGg || - m_type == OBJECT_FLAGy || - m_type == OBJECT_FLAGv || - m_type == OBJECT_POWER || - m_type == OBJECT_ATOMIC || - m_type == OBJECT_ANT || - m_type == OBJECT_SPIDER || - m_type == OBJECT_BEE || - m_type == OBJECT_WORM ) return 0.0f; - return m_shield; -} - - -// Management of flight range (zero = infinity). - -void CObject::SetRange(float delay) -{ - m_range = delay; -} - -float CObject::RetRange() -{ - return m_range; -} - - -// Management of transparency of the object. - -void CObject::SetTransparency(float value) -{ - int i; - - m_transparency = value; - - for ( i=0 ; iSetObjectTransparency(m_objectPart[i].object, value); - } - } -} - -float CObject::RetTransparency() -{ - return m_transparency; -} - - -// Management of the object matter. - -ObjectMaterial CObject::RetMaterial() -{ - if ( m_type == OBJECT_HUMAN ) - { - return OM_HUMAN; - } - - if ( m_type == OBJECT_SCRAP4 || - m_type == OBJECT_SCRAP5 ) - { - return OM_HUMAN; - } - - return OM_METAL; -} - - -// Indicates whether the gadget is a nonessential. - -void CObject::SetGadget(BOOL bMode) -{ - m_bGadget = bMode; -} - -BOOL CObject::RetGadget() -{ - return m_bGadget; -} - - -// Indicates whether an object is stationary (ant on the back). - -void CObject::SetFixed(BOOL bFixed) -{ - m_bFixed = bFixed; -} - -BOOL CObject::RetFixed() -{ - return m_bFixed; -} - - -// Indicates whether an object is subjected to clipping (obstacles). - -void CObject::SetClip(BOOL bClip) -{ - m_bClip = bClip; -} - -BOOL CObject::RetClip() -{ - return m_bClip; -} - - - -// Pushes an object. - -BOOL CObject::JostleObject(float force) -{ - CAutoJostle* pa; - - if ( m_type == OBJECT_FLAGb || - m_type == OBJECT_FLAGr || - m_type == OBJECT_FLAGg || - m_type == OBJECT_FLAGy || - m_type == OBJECT_FLAGv ) // flag? - { - if ( m_auto == 0 ) return FALSE; - - m_auto->Start(1); - } - else - { - if ( m_auto != 0 ) return FALSE; - - m_auto = new CAutoJostle(m_iMan, this); - pa = (CAutoJostle*)m_auto; - pa->Start(0, force); - } - - return TRUE; -} - - -// Beginning of the effect when the instruction "detect" is used. - -void CObject::StartDetectEffect(CObject *target, BOOL bFound) -{ - D3DMATRIX* mat; - D3DVECTOR pos, goal; - FPOINT dim; - - mat = RetWorldMatrix(0); - pos = Transform(*mat, D3DVECTOR(2.0f, 3.0f, 0.0f)); - - if ( target == 0 ) - { - goal = Transform(*mat, D3DVECTOR(50.0f, 3.0f, 0.0f)); - } - else - { - goal = target->RetPosition(0); - goal.y += 3.0f; - goal = SegmentDist(pos, goal, Length(pos, goal)-3.0f); - } - - dim.x = 3.0f; - dim.y = dim.x; - m_particule->CreateRay(pos, goal, PARTIRAY2, dim, 0.2f); - - if ( target != 0 ) - { - goal = target->RetPosition(0); - goal.y += 3.0f; - goal = SegmentDist(pos, goal, Length(pos, goal)-1.0f); - dim.x = 6.0f; - dim.y = dim.x; - m_particule->CreateParticule(goal, D3DVECTOR(0.0f, 0.0f, 0.0f), dim, - bFound?PARTIGLINT:PARTIGLINTr, 0.5f); - } - - m_sound->Play(bFound?SOUND_BUILD:SOUND_RECOVER); -} - - -// Management of time from which a virus is active. - -void CObject::SetVirusMode(BOOL bEnable) -{ - m_bVirusMode = bEnable; - m_virusTime = 0.0f; - - if ( m_bVirusMode && m_brain != 0 ) - { - if ( !m_brain->IntroduceVirus() ) // tries to infect - { - m_bVirusMode = FALSE; // program was not contaminated! - } - } -} - -BOOL CObject::RetVirusMode() -{ - return m_bVirusMode; -} - -float CObject::RetVirusTime() -{ - return m_virusTime; -} - - -// Management mode of the camera. - -void CObject::SetCameraType(CameraType type) -{ - m_cameraType = type; -} - -CameraType CObject::RetCameraType() -{ - return m_cameraType; -} - -void CObject::SetCameraDist(float dist) -{ - m_cameraDist = dist; -} - -float CObject::RetCameraDist() -{ - return m_cameraDist; -} - -void CObject::SetCameraLock(BOOL bLock) -{ - m_bCameraLock = bLock; -} - -BOOL CObject::RetCameraLock() -{ - return m_bCameraLock; -} - - - -// Management of the demonstration of the object. - -void CObject::SetHilite(BOOL bMode) -{ - int list[OBJECTMAXPART+1]; - int i, j; - - m_bHilite = bMode; - - if ( m_bHilite ) - { - j = 0; - for ( i=0 ; iSetHiliteRank(list); // gives the list of selected parts - } -} - -BOOL CObject::RetHilite() -{ - return m_bHilite; -} - - -// Indicates whether the object is selected or not. - -void CObject::SetSelect(BOOL bMode, BOOL bDisplayError) -{ - Error err; - - m_bSelect = bMode; - - if ( m_physics != 0 ) - { - m_physics->CreateInterface(m_bSelect); - } - - if ( m_auto != 0 ) - { - m_auto->CreateInterface(m_bSelect); - } - - CreateSelectParticule(); // creates / removes particles - - if ( !m_bSelect ) - { - SetGunGoalH(0.0f); // puts the cannon right - return; // selects if not finished - } - - err = ERR_OK; - if ( m_physics != 0 ) - { - err = m_physics->RetError(); - } - if ( m_auto != 0 ) - { - err = m_auto->RetError(); - } - if ( err != ERR_OK && bDisplayError ) - { - m_displayText->DisplayError(err, this); - } -} - -// Indicates whether the object is selected or not. - -BOOL CObject::RetSelect(BOOL bReal) -{ - if ( !bReal && m_main->RetFixScene() ) return FALSE; - return m_bSelect; -} - - -// Indicates whether the object is selectable or not. - -void CObject::SetSelectable(BOOL bMode) -{ - m_bSelectable = bMode; -} - -// Indicates whether the object is selecionnable or not. - -BOOL CObject::RetSelectable() -{ - return m_bSelectable; -} - - -// Management of the activities of an object. - -void CObject::SetActivity(BOOL bMode) -{ - if ( m_brain != 0 ) - { - m_brain->SetActivity(bMode); - } -} - -BOOL CObject::RetActivity() -{ - if ( m_brain != 0 ) - { - return m_brain->RetActivity(); - } - return FALSE; -} - - -// Indicates if necessary to check the tokens of the object. - -void CObject::SetCheckToken(BOOL bMode) -{ - m_bCheckToken = bMode; -} - -// Indicates if necessary to check the tokens of the object. - -BOOL CObject::RetCheckToken() -{ - return m_bCheckToken; -} - - -// Management of the visibility of an object. -// The object is not hidden or visually disabled, but ignores detections! -// For example: underground worm. - -void CObject::SetVisible(BOOL bVisible) -{ - m_bVisible = bVisible; -} - -BOOL CObject::RetVisible() -{ - return m_bVisible; -} - - -// Management mode of operation of an object. -// An inactive object is an object destroyed, nonexistent. -// This mode is used for objects "resetables" -// during training to simulate destruction. - -void CObject::SetEnable(BOOL bEnable) -{ - m_bEnable = bEnable; -} - -BOOL CObject::RetEnable() -{ - return m_bEnable; -} - - -// Management mode or an object is only active when you're close. - -void CObject::SetProxyActivate(BOOL bActivate) -{ - m_bProxyActivate = bActivate; -} - -BOOL CObject::RetProxyActivate() -{ - return m_bProxyActivate; -} - -void CObject::SetProxyDistance(float distance) -{ - m_proxyDistance = distance; -} - -float CObject::RetProxyDistance() -{ - return m_proxyDistance; -} - - -// Management of the method of increasing damage. - -void CObject::SetMagnifyDamage(float factor) -{ - m_magnifyDamage = factor; -} - -float CObject::RetMagnifyDamage() -{ - return m_magnifyDamage; -} - - -// Management of free parameter. - -void CObject::SetParam(float value) -{ - m_param = value; -} - -float CObject::RetParam() -{ - return m_param; -} - - -// Management of the mode "blocked" of an object. -// For example, a cube of titanium is blocked while it is used to make something, -//or a vehicle is blocked as its construction is not finished. - -void CObject::SetLock(BOOL bLock) -{ - m_bLock = bLock; -} - -BOOL CObject::RetLock() -{ - return m_bLock; -} - -// Management of the mode "current explosion" of an object. -// An object in this mode is not saving. - -void CObject::SetExplo(BOOL bExplo) -{ - m_bExplo = bExplo; -} - -BOOL CObject::RetExplo() -{ - return m_bExplo; -} - - -// Mode management "cargo ship" during movies. - -void CObject::SetCargo(BOOL bCargo) -{ - m_bCargo = bCargo; -} - -BOOL CObject::RetCargo() -{ - return m_bCargo; -} - - -// Management of the HS mode of an object. - -void CObject::SetBurn(BOOL bBurn) -{ - m_bBurn = bBurn; - -//? if ( m_botVar != 0 ) -//? { -//? if ( m_bBurn ) m_botVar->SetUserPtr(OBJECTDELETED); -//? else m_botVar->SetUserPtr(this); -//? } -} - -BOOL CObject::RetBurn() -{ - return m_bBurn; -} - -void CObject::SetDead(BOOL bDead) -{ - m_bDead = bDead; - - if ( bDead && m_brain != 0 ) - { - m_brain->StopProgram(); // stops the current task - } - -//? if ( m_botVar != 0 ) -//? { -//? if ( m_bDead ) m_botVar->SetUserPtr(OBJECTDELETED); -//? else m_botVar->SetUserPtr(this); -//? } -} - -BOOL CObject::RetDead() -{ - return m_bDead; -} - -BOOL CObject::RetRuin() -{ - return m_bBurn|m_bFlat; -} - -BOOL CObject::RetActif() -{ - return !m_bLock && !m_bBurn && !m_bFlat && m_bVisible && m_bEnable; -} - - -// Management of the point of aim. - -void CObject::SetGunGoalV(float gunGoal) -{ - if ( m_type == OBJECT_MOBILEfc || - m_type == OBJECT_MOBILEtc || - m_type == OBJECT_MOBILEwc || - m_type == OBJECT_MOBILEic ) // fireball? - { - if ( gunGoal > 10.0f*PI/180.0f ) gunGoal = 10.0f*PI/180.0f; - if ( gunGoal < -20.0f*PI/180.0f ) gunGoal = -20.0f*PI/180.0f; - SetAngleZ(1, gunGoal); - } - else if ( m_type == OBJECT_MOBILEfi || - m_type == OBJECT_MOBILEti || - m_type == OBJECT_MOBILEwi || - m_type == OBJECT_MOBILEii ) // orgaball? - { - if ( gunGoal > 20.0f*PI/180.0f ) gunGoal = 20.0f*PI/180.0f; - if ( gunGoal < -20.0f*PI/180.0f ) gunGoal = -20.0f*PI/180.0f; - SetAngleZ(1, gunGoal); - } - else if ( m_type == OBJECT_MOBILErc ) // phazer? - { - if ( gunGoal > 45.0f*PI/180.0f ) gunGoal = 45.0f*PI/180.0f; - if ( gunGoal < -20.0f*PI/180.0f ) gunGoal = -20.0f*PI/180.0f; - SetAngleZ(2, gunGoal); - } - else - { - gunGoal = 0.0f; - } - - m_gunGoalV = gunGoal; -} - -void CObject::SetGunGoalH(float gunGoal) -{ - if ( m_type == OBJECT_MOBILEfc || - m_type == OBJECT_MOBILEtc || - m_type == OBJECT_MOBILEwc || - m_type == OBJECT_MOBILEic ) // fireball? - { - if ( gunGoal > 40.0f*PI/180.0f ) gunGoal = 40.0f*PI/180.0f; - if ( gunGoal < -40.0f*PI/180.0f ) gunGoal = -40.0f*PI/180.0f; - SetAngleY(1, gunGoal); - } - else if ( m_type == OBJECT_MOBILEfi || - m_type == OBJECT_MOBILEti || - m_type == OBJECT_MOBILEwi || - m_type == OBJECT_MOBILEii ) // orgaball? - { - if ( gunGoal > 40.0f*PI/180.0f ) gunGoal = 40.0f*PI/180.0f; - if ( gunGoal < -40.0f*PI/180.0f ) gunGoal = -40.0f*PI/180.0f; - SetAngleY(1, gunGoal); - } - else if ( m_type == OBJECT_MOBILErc ) // phazer? - { - if ( gunGoal > 40.0f*PI/180.0f ) gunGoal = 40.0f*PI/180.0f; - if ( gunGoal < -40.0f*PI/180.0f ) gunGoal = -40.0f*PI/180.0f; - SetAngleY(2, gunGoal); - } - else - { - gunGoal = 0.0f; - } - - m_gunGoalH = gunGoal; -} - -float CObject::RetGunGoalV() -{ - return m_gunGoalV; -} - -float CObject::RetGunGoalH() -{ - return m_gunGoalH; -} - - - -// Shows the limits of the object. - -BOOL CObject::StartShowLimit() -{ - if ( m_showLimitRadius == 0.0f ) return FALSE; - - m_main->SetShowLimit(0, PARTILIMIT1, this, RetPosition(0), m_showLimitRadius); - m_bShowLimit = TRUE; - return TRUE; -} - -void CObject::StopShowLimit() -{ - m_bShowLimit = FALSE; -} - - - -// Indicates whether a program is under execution. - -BOOL CObject::IsProgram() -{ - if ( m_brain == 0 ) return FALSE; - return m_brain->IsProgram(); -} - - -// Creates or removes particles associated to the object. - -void CObject::CreateSelectParticule() -{ - D3DVECTOR pos, speed; - FPOINT dim; - int i; - - // Removes particles preceding. - for ( i=0 ; i<4 ; i++ ) - { - if ( m_partiSel[i] != -1 ) - { - m_particule->DeleteParticule(m_partiSel[i]); - m_partiSel[i] = -1; - } - } - - if ( m_bSelect || IsProgram() ) - { - // Creates particles lens for the headlights. - if ( m_type == OBJECT_MOBILEfa || - m_type == OBJECT_MOBILEta || - m_type == OBJECT_MOBILEwa || - m_type == OBJECT_MOBILEia || - m_type == OBJECT_MOBILEfc || - m_type == OBJECT_MOBILEtc || - m_type == OBJECT_MOBILEwc || - m_type == OBJECT_MOBILEic || - m_type == OBJECT_MOBILEfi || - m_type == OBJECT_MOBILEti || - m_type == OBJECT_MOBILEwi || - m_type == OBJECT_MOBILEii || - m_type == OBJECT_MOBILEfs || - m_type == OBJECT_MOBILEts || - m_type == OBJECT_MOBILEws || - m_type == OBJECT_MOBILEis || - m_type == OBJECT_MOBILErt || - m_type == OBJECT_MOBILErc || - m_type == OBJECT_MOBILErr || - m_type == OBJECT_MOBILErs || - m_type == OBJECT_MOBILEsa || - m_type == OBJECT_MOBILEtg || - m_type == OBJECT_MOBILEft || - m_type == OBJECT_MOBILEtt || - m_type == OBJECT_MOBILEwt || - m_type == OBJECT_MOBILEit || - m_type == OBJECT_MOBILEdr ) // vehicle? - { - pos = D3DVECTOR(0.0f, 0.0f, 0.0f); - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 0.0f; - dim.y = 0.0f; - m_partiSel[0] = m_particule->CreateParticule(pos, speed, dim, PARTISELY, 1.0f, 0.0f, 0.0f); - m_partiSel[1] = m_particule->CreateParticule(pos, speed, dim, PARTISELY, 1.0f, 0.0f, 0.0f); - m_partiSel[2] = m_particule->CreateParticule(pos, speed, dim, PARTISELR, 1.0f, 0.0f, 0.0f); - m_partiSel[3] = m_particule->CreateParticule(pos, speed, dim, PARTISELR, 1.0f, 0.0f, 0.0f); - UpdateSelectParticule(); - } - } -} - -// Updates the particles associated to the object. - -void CObject::UpdateSelectParticule() -{ - D3DVECTOR pos[4]; - FPOINT dim[4]; - float zoom[4]; - float angle; - int i; - - if ( !m_bSelect && !IsProgram() ) return; - - dim[0].x = 1.0f; - dim[1].x = 1.0f; - dim[2].x = 1.2f; - dim[3].x = 1.2f; - - // Lens front yellow. - if ( m_type == OBJECT_MOBILErt || - m_type == OBJECT_MOBILErc || - m_type == OBJECT_MOBILErr || - m_type == OBJECT_MOBILErs ) // large caterpillars? - { - pos[0] = D3DVECTOR(4.2f, 2.8f, 1.5f); - pos[1] = D3DVECTOR(4.2f, 2.8f, -1.5f); - dim[0].x = 1.5f; - dim[1].x = 1.5f; - } - else if ( m_type == OBJECT_MOBILEwt || - m_type == OBJECT_MOBILEtt || - m_type == OBJECT_MOBILEft || - m_type == OBJECT_MOBILEit ) // trainer ? - { - pos[0] = D3DVECTOR(4.2f, 2.5f, 1.2f); - pos[1] = D3DVECTOR(4.2f, 2.5f, -1.2f); - dim[0].x = 1.5f; - dim[1].x = 1.5f; - } - else if ( m_type == OBJECT_MOBILEsa ) // submarine? - { - pos[0] = D3DVECTOR(3.6f, 4.0f, 2.0f); - pos[1] = D3DVECTOR(3.6f, 4.0f, -2.0f); - } - else if ( m_type == OBJECT_MOBILEtg ) // target? - { - pos[0] = D3DVECTOR(3.4f, 6.5f, 2.0f); - pos[1] = D3DVECTOR(3.4f, 6.5f, -2.0f); - } - else if ( m_type == OBJECT_MOBILEdr ) // designer? - { - pos[0] = D3DVECTOR(4.9f, 3.5f, 2.5f); - pos[1] = D3DVECTOR(4.9f, 3.5f, -2.5f); - } - else - { - pos[0] = D3DVECTOR(4.2f, 2.5f, 1.5f); - pos[1] = D3DVECTOR(4.2f, 2.5f, -1.5f); - } - - // Red back lens - if ( m_type == OBJECT_MOBILEfa || - m_type == OBJECT_MOBILEfc || - m_type == OBJECT_MOBILEfi || - m_type == OBJECT_MOBILEfs || - m_type == OBJECT_MOBILEft ) // flying? - { - pos[2] = D3DVECTOR(-4.0f, 3.1f, 4.5f); - pos[3] = D3DVECTOR(-4.0f, 3.1f, -4.5f); - dim[2].x = 0.6f; - dim[3].x = 0.6f; - } - if ( m_type == OBJECT_MOBILEwa || - m_type == OBJECT_MOBILEwc || - m_type == OBJECT_MOBILEwi || - m_type == OBJECT_MOBILEws ) // wheels? - { - pos[2] = D3DVECTOR(-4.5f, 2.7f, 2.8f); - pos[3] = D3DVECTOR(-4.5f, 2.7f, -2.8f); - } - if ( m_type == OBJECT_MOBILEwt ) // wheels? - { - pos[2] = D3DVECTOR(-4.0f, 2.5f, 2.2f); - pos[3] = D3DVECTOR(-4.0f, 2.5f, -2.2f); - } - if ( m_type == OBJECT_MOBILEia || - m_type == OBJECT_MOBILEic || - m_type == OBJECT_MOBILEii || - m_type == OBJECT_MOBILEis || - m_type == OBJECT_MOBILEit ) // legs? - { - pos[2] = D3DVECTOR(-4.5f, 2.7f, 2.8f); - pos[3] = D3DVECTOR(-4.5f, 2.7f, -2.8f); - } - if ( m_type == OBJECT_MOBILEta || - m_type == OBJECT_MOBILEtc || - m_type == OBJECT_MOBILEti || - m_type == OBJECT_MOBILEts || - m_type == OBJECT_MOBILEtt ) // caterpillars? - { - pos[2] = D3DVECTOR(-3.6f, 4.2f, 3.0f); - pos[3] = D3DVECTOR(-3.6f, 4.2f, -3.0f); - } - if ( m_type == OBJECT_MOBILErt || - m_type == OBJECT_MOBILErc || - m_type == OBJECT_MOBILErr || - m_type == OBJECT_MOBILErs ) // large caterpillars? - { - pos[2] = D3DVECTOR(-5.0f, 5.2f, 2.5f); - pos[3] = D3DVECTOR(-5.0f, 5.2f, -2.5f); - } - if ( m_type == OBJECT_MOBILEsa ) // submarine? - { - pos[2] = D3DVECTOR(-3.6f, 4.0f, 2.0f); - pos[3] = D3DVECTOR(-3.6f, 4.0f, -2.0f); - } - if ( m_type == OBJECT_MOBILEtg ) // target? - { - pos[2] = D3DVECTOR(-2.4f, 6.5f, 2.0f); - pos[3] = D3DVECTOR(-2.4f, 6.5f, -2.0f); - } - if ( m_type == OBJECT_MOBILEdr ) // designer? - { - pos[2] = D3DVECTOR(-5.3f, 2.7f, 1.8f); - pos[3] = D3DVECTOR(-5.3f, 2.7f, -1.8f); - } - - angle = RetAngleY(0)/PI; - - zoom[0] = 1.0f; - zoom[1] = 1.0f; - zoom[2] = 1.0f; - zoom[3] = 1.0f; - - if ( IsProgram() && // current program? - Mod(m_aTime, 0.7f) < 0.3f ) - { - zoom[0] = 0.0f; // blinks - zoom[1] = 0.0f; - zoom[2] = 0.0f; - zoom[3] = 0.0f; - } - - // Updates lens. - for ( i=0 ; i<4 ; i++ ) - { - pos[i] = Transform(m_objectPart[0].matWorld, pos[i]); - dim[i].y = dim[i].x; - m_particule->SetParam(m_partiSel[i], pos[i], dim[i], zoom[i], angle, 1.0f); - } -} - - -// Gives the pointer to the current script execution. - -void CObject::SetRunScript(CScript* script) -{ - m_runScript = script; -} - -CScript* CObject::RetRunScript() -{ - return m_runScript; -} - -// Returns the variables of "this" for CBOT. - -CBotVar* CObject::RetBotVar() -{ - return m_botVar; -} - -// Returns the physics associated to the object. - -CPhysics* CObject::RetPhysics() -{ - return m_physics; -} - -// Returns the brain associated to the object. - -CBrain* CObject::RetBrain() -{ - return m_brain; -} - -// Returns the movement associated to the object. - -CMotion* CObject::RetMotion() -{ - return m_motion; -} - -// Returns the controller associated to the object. - -CAuto* CObject::RetAuto() -{ - return m_auto; -} - -void CObject::SetAuto(CAuto* automat) -{ - m_auto = automat; -} - - - -// Management of the position in the file definition. - -void CObject::SetDefRank(int rank) -{ - m_defRank = rank; -} - -int CObject::RetDefRank() -{ - return m_defRank; -} - - -// Gives the object name for the tooltip. - -BOOL CObject::GetTooltipName(char* name) -{ - GetResource(RES_OBJECT, m_type, name); - return ( name[0] != 0 ); -} - - -// Adds the object previously selected in the list. - -void CObject::AddDeselList(CObject* pObj) -{ - int i; - - if ( m_totalDesectList >= OBJECTMAXDESELLIST ) - { - for ( i=0 ; iRetTraceDown(); -} - -void CObject::SetTraceDown(BOOL bDown) -{ - CMotionVehicle* mv; - if ( m_motion == 0 ) return; - mv = (CMotionVehicle*)m_motion; - mv->SetTraceDown(bDown); -} - -int CObject::RetTraceColor() -{ - CMotionVehicle* mv; - if ( m_motion == 0 ) return 0; - mv = (CMotionVehicle*)m_motion; - return mv->RetTraceColor(); -} - -void CObject::SetTraceColor(int color) -{ - CMotionVehicle* mv; - if ( m_motion == 0 ) return; - mv = (CMotionVehicle*)m_motion; - mv->SetTraceColor(color); -} - -float CObject::RetTraceWidth() -{ - CMotionVehicle* mv; - if ( m_motion == 0 ) return 0.0f; - mv = (CMotionVehicle*)m_motion; - return mv->RetTraceWidth(); -} - -void CObject::SetTraceWidth(float width) -{ - CMotionVehicle* mv; - if ( m_motion == 0 ) return; - mv = (CMotionVehicle*)m_motion; - mv->SetTraceWidth(width); -} - - diff --git a/src/object.h b/src/object.h deleted file mode 100644 index af7a3e4..0000000 --- a/src/object.h +++ /dev/null @@ -1,781 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// object.h - -#ifndef _OBJECT_H_ -#define _OBJECT_H_ - - -#include "d3dengine.h" -#include "camera.h" -#include "sound.h" - - -class CInstanceManager; -class CLight; -class CTerrain; -class CWater; -class CParticule; -class CPhysics; -class CBrain; -class CMotion; -class CAuto; -class CDisplayText; -class CRobotMain; -class CBotVar; -class CScript; - - - -// The father of all parts must always be the part number zero! - -#define OBJECTMAXPART 40 -#define MAXCRASHSPHERE 40 -#define OBJECTMAXDESELLIST 10 -#define OBJECTMAXINFO 10 -#define OBJECTMAXCMDLINE 20 - -enum ObjectType -{ - OBJECT_NULL = 0, // object destroyed - OBJECT_FIX = 1, // stationary scenery - OBJECT_PORTICO = 2, // gantry - OBJECT_BASE = 3, // great main base - OBJECT_DERRICK = 4, // derrick set - OBJECT_FACTORY = 5, // factory set - OBJECT_STATION = 6, // recharging station - OBJECT_CONVERT = 7, // converter station - OBJECT_REPAIR = 8, // reparation - OBJECT_TOWER = 9, // defense tower - OBJECT_NEST = 10, // nest - OBJECT_RESEARCH = 11, // research center - OBJECT_RADAR = 12, // radar - OBJECT_ENERGY = 13, // energy factory - OBJECT_LABO = 14, // analytical laboratory for insect - OBJECT_NUCLEAR = 15, // nuclear power plant - OBJECT_START = 16, // starting - OBJECT_END = 17, // finish - OBJECT_INFO = 18, // information terminal - OBJECT_PARA = 19, // lightning conductor - OBJECT_TARGET1 = 20, // gate target - OBJECT_TARGET2 = 21, // center target - OBJECT_SAFE = 22, // safe - OBJECT_HUSTON = 23, // control centre - OBJECT_DESTROYER = 24, // destroyer - OBJECT_FRET = 30, // transportable - OBJECT_STONE = 31, // stone - OBJECT_URANIUM = 32, // uranium - OBJECT_METAL = 33, // metal - OBJECT_POWER = 34, // normal battery - OBJECT_ATOMIC = 35, // atomic battery - OBJECT_BULLET = 36, // bullet - OBJECT_BBOX = 37, // black-box - OBJECT_TNT = 38, // box of TNT - OBJECT_SCRAP1 = 40, // metal waste - OBJECT_SCRAP2 = 41, // metal waste - OBJECT_SCRAP3 = 42, // metal waste - OBJECT_SCRAP4 = 43, // plastic waste - OBJECT_SCRAP5 = 44, // plastic waste - OBJECT_MARKPOWER = 50, // mark underground energy source - OBJECT_MARKSTONE = 51, // mark underground ore - OBJECT_MARKURANIUM = 52, // mark underground uranium - OBJECT_MARKKEYa = 53, // mark underground key - OBJECT_MARKKEYb = 54, // mark underground key - OBJECT_MARKKEYc = 55, // mark underground key - OBJECT_MARKKEYd = 56, // mark underground key - OBJECT_BOMB = 60, // bomb - OBJECT_WINFIRE = 61, // fireworks - OBJECT_SHOW = 62, // shows a place - OBJECT_BAG = 63, // survival bag - OBJECT_PLANT0 = 70, // plant 0 - OBJECT_PLANT1 = 71, // plant 1 - OBJECT_PLANT2 = 72, // plant 2 - OBJECT_PLANT3 = 73, // plant 3 - OBJECT_PLANT4 = 74, // plant 4 - OBJECT_PLANT5 = 75, // plant 5 - OBJECT_PLANT6 = 76, // plant 6 - OBJECT_PLANT7 = 77, // plant 7 - OBJECT_PLANT8 = 78, // plant 8 - OBJECT_PLANT9 = 79, // plant 9 - OBJECT_PLANT10 = 80, // plant 10 - OBJECT_PLANT11 = 81, // plant 11 - OBJECT_PLANT12 = 82, // plant 12 - OBJECT_PLANT13 = 83, // plant 13 - OBJECT_PLANT14 = 84, // plant 14 - OBJECT_PLANT15 = 85, // plant 15 - OBJECT_PLANT16 = 86, // plant 16 - OBJECT_PLANT17 = 87, // plant 17 - OBJECT_PLANT18 = 88, // plant 18 - OBJECT_PLANT19 = 89, // plant 19 - OBJECT_TREE0 = 90, // tree 0 - OBJECT_TREE1 = 91, // tree 1 - OBJECT_TREE2 = 92, // tree 2 - OBJECT_TREE3 = 93, // tree 3 - OBJECT_TREE4 = 94, // tree 4 - OBJECT_TREE5 = 95, // tree 5 - OBJECT_TREE6 = 96, // tree 6 - OBJECT_TREE7 = 97, // tree 7 - OBJECT_TREE8 = 98, // tree 8 - OBJECT_TREE9 = 99, // tree 9 - OBJECT_MOBILEwt = 100, // wheel-trainer - OBJECT_MOBILEtt = 101, // track-trainer - OBJECT_MOBILEft = 102, // fly-trainer - OBJECT_MOBILEit = 103, // insect-trainer - OBJECT_MOBILEwa = 110, // wheel-arm - OBJECT_MOBILEta = 111, // track-arm - OBJECT_MOBILEfa = 112, // fly-arm - OBJECT_MOBILEia = 113, // insect-arm - OBJECT_MOBILEwc = 120, // wheel-cannon - OBJECT_MOBILEtc = 121, // track-cannon - OBJECT_MOBILEfc = 122, // fly-cannon - OBJECT_MOBILEic = 123, // insect-cannon - OBJECT_MOBILEwi = 130, // wheel-insect-cannon - OBJECT_MOBILEti = 131, // track-insect-cannon - OBJECT_MOBILEfi = 132, // fly-insect-cannon - OBJECT_MOBILEii = 133, // insect-insect-cannon - OBJECT_MOBILEws = 140, // wheel-search - OBJECT_MOBILEts = 141, // track-search - OBJECT_MOBILEfs = 142, // fly-search - OBJECT_MOBILEis = 143, // insect-search - OBJECT_MOBILErt = 200, // roller-terraform - OBJECT_MOBILErc = 201, // roller-canon - OBJECT_MOBILErr = 202, // roller-recover - OBJECT_MOBILErs = 203, // roller-shield - OBJECT_MOBILEsa = 210, // submarine - OBJECT_MOBILEtg = 211, // training target - OBJECT_MOBILEdr = 212, // robot drawing - OBJECT_WAYPOINT = 250, // waypoint - OBJECT_FLAGb = 260, // blue flag - OBJECT_FLAGr = 261, // red flag - OBJECT_FLAGg = 262, // green flag - OBJECT_FLAGy = 263, // yellow flag - OBJECT_FLAGv = 264, // violet flag - OBJECT_KEYa = 270, // key a - OBJECT_KEYb = 271, // key b - OBJECT_KEYc = 272, // key c - OBJECT_KEYd = 273, // key d - OBJECT_HUMAN = 300, // human - OBJECT_TOTO = 301, // toto - OBJECT_TECH = 302, // technician - OBJECT_BARRIER0 = 400, // barrier - OBJECT_BARRIER1 = 401, // barrier - OBJECT_BARRIER2 = 402, // barrier - OBJECT_BARRIER3 = 403, // barrier - OBJECT_BARRIER4 = 404, // barrier - OBJECT_MOTHER = 500, // insect queen - OBJECT_EGG = 501, // egg - OBJECT_ANT = 502, // ant - OBJECT_SPIDER = 503, // spider - OBJECT_BEE = 504, // bee - OBJECT_WORM = 505, // worm - OBJECT_RUINmobilew1 = 600, // ruin 1 - OBJECT_RUINmobilew2 = 601, // ruin 1 - OBJECT_RUINmobilet1 = 602, // ruin 2 - OBJECT_RUINmobilet2 = 603, // ruin 2 - OBJECT_RUINmobiler1 = 604, // ruin 3 - OBJECT_RUINmobiler2 = 605, // ruin 3 - OBJECT_RUINfactory = 606, // ruin 4 - OBJECT_RUINdoor = 607, // ruin 5 - OBJECT_RUINsupport = 608, // ruin 6 - OBJECT_RUINradar = 609, // ruin 7 - OBJECT_RUINconvert = 610, // ruin 8 - OBJECT_RUINbase = 611, // ruin 9 - OBJECT_RUINhead = 612, // ruin 10 - OBJECT_TEEN0 = 620, // toy - OBJECT_TEEN1 = 621, // toy - OBJECT_TEEN2 = 622, // toy - OBJECT_TEEN3 = 623, // toy - OBJECT_TEEN4 = 624, // toy - OBJECT_TEEN5 = 625, // toy - OBJECT_TEEN6 = 626, // toy - OBJECT_TEEN7 = 627, // toy - OBJECT_TEEN8 = 628, // toy - OBJECT_TEEN9 = 629, // toy - OBJECT_TEEN10 = 630, // toy - OBJECT_TEEN11 = 631, // toy - OBJECT_TEEN12 = 632, // toy - OBJECT_TEEN13 = 633, // toy - OBJECT_TEEN14 = 634, // toy - OBJECT_TEEN15 = 635, // toy - OBJECT_TEEN16 = 636, // toy - OBJECT_TEEN17 = 637, // toy - OBJECT_TEEN18 = 638, // toy - OBJECT_TEEN19 = 639, // toy - OBJECT_TEEN20 = 640, // toy - OBJECT_TEEN21 = 641, // toy - OBJECT_TEEN22 = 642, // toy - OBJECT_TEEN23 = 643, // toy - OBJECT_TEEN24 = 644, // toy - OBJECT_TEEN25 = 645, // toy - OBJECT_TEEN26 = 646, // toy - OBJECT_TEEN27 = 647, // toy - OBJECT_TEEN28 = 648, // toy - OBJECT_TEEN29 = 649, // toy - OBJECT_TEEN30 = 650, // toy - OBJECT_TEEN31 = 651, // toy - OBJECT_TEEN32 = 652, // toy - OBJECT_TEEN33 = 653, // toy - OBJECT_TEEN34 = 654, // toy - OBJECT_TEEN35 = 655, // toy - OBJECT_TEEN36 = 656, // toy - OBJECT_TEEN37 = 657, // toy - OBJECT_TEEN38 = 658, // toy - OBJECT_TEEN39 = 659, // toy - OBJECT_TEEN40 = 660, // toy - OBJECT_TEEN41 = 661, // toy - OBJECT_TEEN42 = 662, // toy - OBJECT_TEEN43 = 663, // toy - OBJECT_TEEN44 = 664, // toy - OBJECT_TEEN45 = 665, // toy - OBJECT_TEEN46 = 666, // toy - OBJECT_TEEN47 = 667, // toy - OBJECT_TEEN48 = 668, // toy - OBJECT_TEEN49 = 669, // toy - OBJECT_QUARTZ0 = 700, // crystal 0 - OBJECT_QUARTZ1 = 701, // crystal 1 - OBJECT_QUARTZ2 = 702, // crystal 2 - OBJECT_QUARTZ3 = 703, // crystal 3 - OBJECT_QUARTZ4 = 704, // crystal 4 - OBJECT_QUARTZ5 = 705, // crystal 5 - OBJECT_QUARTZ6 = 706, // crystal 6 - OBJECT_QUARTZ7 = 707, // crystal 7 - OBJECT_QUARTZ8 = 708, // crystal 8 - OBJECT_QUARTZ9 = 709, // crystal 9 - OBJECT_ROOT0 = 710, // root 0 - OBJECT_ROOT1 = 711, // root 1 - OBJECT_ROOT2 = 712, // root 2 - OBJECT_ROOT3 = 713, // root 3 - OBJECT_ROOT4 = 714, // root 4 - OBJECT_ROOT5 = 715, // root 5 - OBJECT_ROOT6 = 716, // root 6 - OBJECT_ROOT7 = 717, // root 7 - OBJECT_ROOT8 = 718, // root 8 - OBJECT_ROOT9 = 719, // root 9 - OBJECT_SEAWEED0 = 720, // seaweed 0 - OBJECT_SEAWEED1 = 721, // seaweed 1 - OBJECT_SEAWEED2 = 722, // seaweed 2 - OBJECT_SEAWEED3 = 723, // seaweed 3 - OBJECT_SEAWEED4 = 724, // seaweed 4 - OBJECT_SEAWEED5 = 725, // seaweed 5 - OBJECT_SEAWEED6 = 726, // seaweed 6 - OBJECT_SEAWEED7 = 727, // seaweed 7 - OBJECT_SEAWEED8 = 728, // seaweed 8 - OBJECT_SEAWEED9 = 729, // seaweed 9 - OBJECT_MUSHROOM0 = 730, // mushroom 0 - OBJECT_MUSHROOM1 = 731, // mushroom 1 - OBJECT_MUSHROOM2 = 732, // mushroom 2 - OBJECT_MUSHROOM3 = 733, // mushroom 3 - OBJECT_MUSHROOM4 = 734, // mushroom 4 - OBJECT_MUSHROOM5 = 735, // mushroom 5 - OBJECT_MUSHROOM6 = 736, // mushroom 6 - OBJECT_MUSHROOM7 = 737, // mushroom 7 - OBJECT_MUSHROOM8 = 738, // mushroom 8 - OBJECT_MUSHROOM9 = 739, // mushroom 9 - OBJECT_APOLLO1 = 900, // apollo lem - OBJECT_APOLLO2 = 901, // apollo jeep - OBJECT_APOLLO3 = 902, // apollo flag - OBJECT_APOLLO4 = 903, // apollo module - OBJECT_APOLLO5 = 904, // apollo antenna - OBJECT_HOME1 = 910, // home 1 - OBJECT_MAX = 1000, -}; - -enum ObjectMaterial -{ - OM_METAL = 0, // metal - OM_PLASTIC = 1, // plastic - OM_HUMAN = 2, // cosmonaut - OM_ANIMAL = 3, // insect - OM_VEGETAL = 4, // plant - OM_MINERAL = 5, // stone -}; - -typedef struct -{ - char bUsed; - int object; // number of the object in CD3DEngine - int parentPart; // number of father part - int masterParti; // master canal of the particle - D3DVECTOR position; - D3DVECTOR angle; - D3DVECTOR zoom; - char bTranslate; - char bRotate; - char bZoom; - D3DMATRIX matTranslate; - D3DMATRIX matRotate; - D3DMATRIX matTransform; - D3DMATRIX matWorld; -} -ObjectPart; - -typedef struct -{ - float wheelFront; // position X of the front wheels - float wheelBack; // position X of the back wheels - float wheelLeft; // position Z of the left wheels - float wheelRight; // position Z of the right wheels - float height; // normal height on top of ground - D3DVECTOR posPower; // position of the battery -} -Character; - -typedef struct -{ - char name[20]; // name of the information - float value; // value of the information -} -Info; - -enum ExploType -{ - EXPLO_BOUM = 1, - EXPLO_BURN = 2, - EXPLO_WATER = 3, -}; - -enum ResetCap -{ - RESET_NONE = 0, - RESET_MOVE = 1, - RESET_DELETE = 2, -}; - -enum RadarFilter -{ - FILTER_NONE = 0, - FILTER_ONLYLANDING = 1, - FILTER_ONLYFLYING = 2, -}; - - - - -class CObject -{ -public: - CObject(CInstanceManager* iMan); - ~CObject(); - - void DeleteObject(BOOL bAll=FALSE); - void Simplify(); - BOOL ExploObject(ExploType type, float force, float decay=1.0f); - - BOOL EventProcess(const Event &event); - void UpdateMapping(); - - int CreatePart(); - void DeletePart(int part); - void SetObjectRank(int part, int objRank); - int RetObjectRank(int part); - void SetObjectParent(int part, int parent); - void SetType(ObjectType type); - ObjectType RetType(); - char* RetName(); - void SetOption(int option); - int RetOption(); - - void SetID(int id); - int RetID(); - - BOOL Write(char *line); - BOOL Read(char *line); - - void SetDrawWorld(BOOL bDraw); - void SetDrawFront(BOOL bDraw); - - BOOL CreateVehicle(D3DVECTOR pos, float angle, ObjectType type, float power, BOOL bTrainer, BOOL bToy); - BOOL CreateInsect(D3DVECTOR pos, float angle, ObjectType type); - BOOL CreateBuilding(D3DVECTOR pos, float angle, float height, ObjectType type, float power=1.0f); - BOOL CreateResource(D3DVECTOR pos, float angle, ObjectType type, float power=1.0f); - BOOL CreateFlag(D3DVECTOR pos, float angle, ObjectType type); - BOOL CreateBarrier(D3DVECTOR pos, float angle, float height, ObjectType type); - BOOL CreatePlant(D3DVECTOR pos, float angle, float height, ObjectType type); - BOOL CreateMushroom(D3DVECTOR pos, float angle, float height, ObjectType type); - BOOL CreateTeen(D3DVECTOR pos, float angle, float zoom, float height, ObjectType type); - BOOL CreateQuartz(D3DVECTOR pos, float angle, float height, ObjectType type); - BOOL CreateRoot(D3DVECTOR pos, float angle, float height, ObjectType type); - BOOL CreateHome(D3DVECTOR pos, float angle, float height, ObjectType type); - BOOL CreateRuin(D3DVECTOR pos, float angle, float height, ObjectType type); - BOOL CreateApollo(D3DVECTOR pos, float angle, ObjectType type); - - BOOL ReadProgram(int rank, char* filename); - BOOL WriteProgram(int rank, char* filename); - BOOL RunProgram(int rank); - - int RetShadowLight(); - int RetEffectLight(); - - void FlushCrashShere(); - int CreateCrashSphere(D3DVECTOR pos, float radius, Sound sound, float hardness=0.45f); - int RetCrashSphereTotal(); - BOOL GetCrashSphere(int rank, D3DVECTOR &pos, float &radius); - float RetCrashSphereHardness(int rank); - Sound RetCrashSphereSound(int rank); - void DeleteCrashSphere(int rank); - void SetGlobalSphere(D3DVECTOR pos, float radius); - void GetGlobalSphere(D3DVECTOR &pos, float &radius); - void SetJotlerSphere(D3DVECTOR pos, float radius); - void GetJotlerSphere(D3DVECTOR &pos, float &radius); - void SetShieldRadius(float radius); - float RetShieldRadius(); - - void SetFloorHeight(float height); - void FloorAdjust(); - - void SetLinVibration(D3DVECTOR dir); - D3DVECTOR RetLinVibration(); - void SetCirVibration(D3DVECTOR dir); - D3DVECTOR RetCirVibration(); - void SetInclinaison(D3DVECTOR dir); - D3DVECTOR RetInclinaison(); - - void SetPosition(int part, const D3DVECTOR &pos); - D3DVECTOR RetPosition(int part); - void SetAngle(int part, const D3DVECTOR &angle); - D3DVECTOR RetAngle(int part); - void SetAngleY(int part, float angle); - void SetAngleX(int part, float angle); - void SetAngleZ(int part, float angle); - float RetAngleY(int part); - float RetAngleX(int part); - float RetAngleZ(int part); - void SetZoom(int part, float zoom); - void SetZoom(int part, D3DVECTOR zoom); - D3DVECTOR RetZoom(int part); - void SetZoomX(int part, float zoom); - float RetZoomX(int part); - void SetZoomY(int part, float zoom); - float RetZoomY(int part); - void SetZoomZ(int part, float zoom); - float RetZoomZ(int part); - - float RetWaterLevel(); - - void SetTrainer(BOOL bEnable); - BOOL RetTrainer(); - - void SetToy(BOOL bEnable); - BOOL RetToy(); - - void SetManual(BOOL bManual); - BOOL RetManual(); - - void SetResetCap(ResetCap cap); - ResetCap RetResetCap(); - void SetResetBusy(BOOL bBusy); - BOOL RetResetBusy(); - void SetResetPosition(const D3DVECTOR &pos); - D3DVECTOR RetResetPosition(); - void SetResetAngle(const D3DVECTOR &angle); - D3DVECTOR RetResetAngle(); - void SetResetRun(int run); - int RetResetRun(); - - void SetMasterParticule(int part, int parti); - int RetMasterParticule(int part); - - void SetPower(CObject* power); - CObject* RetPower(); - void SetFret(CObject* fret); - CObject* RetFret(); - void SetTruck(CObject* truck); - CObject* RetTruck(); - void SetTruckPart(int part); - int RetTruckPart(); - - void InfoFlush(); - void DeleteInfo(int rank); - void SetInfo(int rank, Info info); - Info RetInfo(int rank); - int RetInfoTotal(); - void SetInfoReturn(float value); - float RetInfoReturn(); - void SetInfoUpdate(BOOL bUpdate); - BOOL RetInfoUpdate(); - - BOOL SetCmdLine(int rank, float value); - float RetCmdLine(int rank); - - D3DMATRIX* RetRotateMatrix(int part); - D3DMATRIX* RetTranslateMatrix(int part); - D3DMATRIX* RetTransformMatrix(int part); - D3DMATRIX* RetWorldMatrix(int part); - - void SetViewFromHere(D3DVECTOR &eye, float &dirH, float &dirV, D3DVECTOR &lookat, D3DVECTOR &upVec, CameraType type); - - void SetCharacter(Character* character); - void GetCharacter(Character* character); - Character* RetCharacter(); - - float RetAbsTime(); - - void SetEnergy(float level); - float RetEnergy(); - - void SetCapacity(float capacity); - float RetCapacity(); - - void SetShield(float level); - float RetShield(); - - void SetRange(float delay); - float RetRange(); - - void SetTransparency(float value); - float RetTransparency(); - - ObjectMaterial RetMaterial(); - - void SetGadget(BOOL bMode); - BOOL RetGadget(); - - void SetFixed(BOOL bFixed); - BOOL RetFixed(); - - void SetClip(BOOL bClip); - BOOL RetClip(); - - BOOL JostleObject(float force); - - void StartDetectEffect(CObject *target, BOOL bFound); - - void SetVirusMode(BOOL bEnable); - BOOL RetVirusMode(); - float RetVirusTime(); - - void SetCameraType(CameraType type); - CameraType RetCameraType(); - void SetCameraDist(float dist); - float RetCameraDist(); - void SetCameraLock(BOOL bLock); - BOOL RetCameraLock(); - - void SetHilite(BOOL bMode); - BOOL RetHilite(); - - void SetSelect(BOOL bMode, BOOL bDisplayError=TRUE); - BOOL RetSelect(BOOL bReal=FALSE); - - void SetSelectable(BOOL bMode); - BOOL RetSelectable(); - - void SetActivity(BOOL bMode); - BOOL RetActivity(); - - void SetVisible(BOOL bVisible); - BOOL RetVisible(); - - void SetEnable(BOOL bEnable); - BOOL RetEnable(); - - void SetCheckToken(BOOL bMode); - BOOL RetCheckToken(); - - void SetProxyActivate(BOOL bActivate); - BOOL RetProxyActivate(); - void SetProxyDistance(float distance); - float RetProxyDistance(); - - void SetMagnifyDamage(float factor); - float RetMagnifyDamage(); - - void SetParam(float value); - float RetParam(); - - void SetExplo(BOOL bExplo); - BOOL RetExplo(); - void SetLock(BOOL bLock); - BOOL RetLock(); - void SetCargo(BOOL bCargo); - BOOL RetCargo(); - void SetBurn(BOOL bBurn); - BOOL RetBurn(); - void SetDead(BOOL bDead); - BOOL RetDead(); - BOOL RetRuin(); - BOOL RetActif(); - - void SetGunGoalV(float gunGoal); - void SetGunGoalH(float gunGoal); - float RetGunGoalV(); - float RetGunGoalH(); - - BOOL StartShowLimit(); - void StopShowLimit(); - - BOOL IsProgram(); - void CreateSelectParticule(); - - void SetRunScript(CScript* script); - CScript* RetRunScript(); - CBotVar* RetBotVar(); - CPhysics* RetPhysics(); - CBrain* RetBrain(); - CMotion* RetMotion(); - CAuto* RetAuto(); - void SetAuto(CAuto* automat); - - void SetDefRank(int rank); - int RetDefRank(); - - BOOL GetTooltipName(char* name); - - void AddDeselList(CObject* pObj); - CObject* SubDeselList(); - void DeleteDeselList(CObject* pObj); - - BOOL CreateShadowCircle(float radius, float intensity, D3DShadowType type=D3DSHADOWNORM); - BOOL CreateShadowLight(float height, D3DCOLORVALUE color); - BOOL CreateEffectLight(float height, D3DCOLORVALUE color); - - void FlatParent(); - - BOOL RetTraceDown(); - void SetTraceDown(BOOL bDown); - int RetTraceColor(); - void SetTraceColor(int color); - float RetTraceWidth(); - void SetTraceWidth(float width); - -protected: - BOOL EventFrame(const Event &event); - void VirusFrame(float rTime); - void PartiFrame(float rTime); - void CreateOtherObject(ObjectType type); - void InitPart(int part); - void UpdateTotalPart(); - int SearchDescendant(int parent, int n); - void UpdateEnergyMapping(); - BOOL UpdateTransformObject(int part, BOOL bForceUpdate); - BOOL UpdateTransformObject(); - void UpdateSelectParticule(); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CLight* m_light; - CTerrain* m_terrain; - CWater* m_water; - CCamera* m_camera; - CParticule* m_particule; - CPhysics* m_physics; - CBrain* m_brain; - CMotion* m_motion; - CAuto* m_auto; - CDisplayText* m_displayText; - CRobotMain* m_main; - CSound* m_sound; - CBotVar* m_botVar; - CScript* m_runScript; - - ObjectType m_type; // OBJECT_* - int m_id; // unique identifier - char m_name[50]; // name of the object - Character m_character; // characteristic - int m_option; // option - int m_partiReactor; // number of the particle of the reactor - int m_shadowLight; // number of light from the shadows - float m_shadowHeight; // height of light from the shadows - int m_effectLight; // number of light effects - float m_effectHeight; // height of light effects - D3DVECTOR m_linVibration; // linear vibration - D3DVECTOR m_cirVibration; // circular vibration - D3DVECTOR m_inclinaison; // tilt - CObject* m_power; // battery used by the vehicle - CObject* m_fret; // object transported - CObject* m_truck; // object with the latter - int m_truckLink; // part - float m_energy; // energy contained (if battery) - float m_lastEnergy; - float m_capacity; // capacity (if battery) - float m_shield; // shield - float m_range; // flight range - float m_transparency; // transparency (0..1) - int m_material; // matter(0..n) - float m_aTime; - float m_shotTime; // time since last shot - BOOL m_bVirusMode; // virus activated/triggered - float m_virusTime; // lifetime of the virus - float m_lastVirusParticule; - float m_lastParticule; - BOOL m_bHilite; - BOOL m_bSelect; // object selected - BOOL m_bSelectable; // selectable object - BOOL m_bCheckToken; // object with audited tokens - BOOL m_bVisible; // object active but undetectable - BOOL m_bEnable; // dead object - BOOL m_bProxyActivate; // active object so close - BOOL m_bGadget; // object nonessential - BOOL m_bLock; - BOOL m_bExplo; - BOOL m_bCargo; - BOOL m_bBurn; - BOOL m_bDead; - BOOL m_bFlat; - BOOL m_bTrainer; // drive vehicle (without remote) - BOOL m_bToy; // toy key - BOOL m_bManual; // manual control (Scribbler) - BOOL m_bFixed; - BOOL m_bClip; - BOOL m_bShowLimit; - float m_showLimitRadius; - float m_gunGoalV; - float m_gunGoalH; - CameraType m_cameraType; - float m_cameraDist; - BOOL m_bCameraLock; - int m_defRank; - float m_magnifyDamage; - float m_proxyDistance; - float m_param; - - int m_crashSphereUsed; // number of spheres used - D3DVECTOR m_crashSpherePos[MAXCRASHSPHERE]; - float m_crashSphereRadius[MAXCRASHSPHERE]; - float m_crashSphereHardness[MAXCRASHSPHERE]; - Sound m_crashSphereSound[MAXCRASHSPHERE]; - D3DVECTOR m_globalSpherePos; - float m_globalSphereRadius; - D3DVECTOR m_jotlerSpherePos; - float m_jotlerSphereRadius; - float m_shieldRadius; - - int m_totalPart; - ObjectPart m_objectPart[OBJECTMAXPART]; - - int m_totalDesectList; - CObject* m_objectDeselectList[OBJECTMAXDESELLIST]; - - int m_partiSel[4]; - - ResetCap m_resetCap; - BOOL m_bResetBusy; - D3DVECTOR m_resetPosition; - D3DVECTOR m_resetAngle; - int m_resetRun; - - int m_infoTotal; - Info m_info[OBJECTMAXINFO]; - float m_infoReturn; - BOOL m_bInfoUpdate; - - float m_cmdLine[OBJECTMAXCMDLINE]; -}; - - -#endif //_OBJECT_H_ diff --git a/src/object/README.txt b/src/object/README.txt new file mode 100644 index 0000000..f4c25d0 --- /dev/null +++ b/src/object/README.txt @@ -0,0 +1,3 @@ +src/object + +Contains modules of robots and buildings. diff --git a/src/object/auto/auto.cpp b/src/object/auto/auto.cpp new file mode 100644 index 0000000..9711423 --- /dev/null +++ b/src/object/auto/auto.cpp @@ -0,0 +1,461 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "light.h" +#include "terrain.h" +#include "water.h" +#include "cloud.h" +#include "planet.h" +#include "blitz.h" +#include "camera.h" +#include "object.h" +#include "modfile.h" +#include "interface.h" +#include "button.h" +#include "list.h" +#include "label.h" +#include "gauge.h" +#include "window.h" +#include "robotmain.h" +#include "displaytext.h" +#include "sound.h" +#include "cmdtoken.h" +#include "auto.h" + + + + +// Object's constructor. + +CAuto::CAuto(CInstanceManager* iMan, CObject* object) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_AUTO, this, 100); + + m_object = object; + m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); + m_cloud = (CCloud*)m_iMan->SearchInstance(CLASS_CLOUD); + m_planet = (CPlanet*)m_iMan->SearchInstance(CLASS_PLANET); + m_blitz = (CBlitz*)m_iMan->SearchInstance(CLASS_BLITZ); + m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); + m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + + m_type = m_object->RetType(); + m_time = 0.0f; + m_lastUpdateTime = 0.0f; + m_bMotor = FALSE; + m_progressTime = 0.0f; + m_progressTotal = 1.0f; + + Init(); +} + +// Object's destructor. + +CAuto::~CAuto() +{ + m_iMan->DeleteInstance(CLASS_AUTO, this); +} + + +// Destroys the object. + +void CAuto::DeleteObject(BOOL bAll) +{ +} + + +// Initialize the object. + +void CAuto::Init() +{ + m_bBusy = FALSE; +} + +// Starts the object. + +void CAuto::Start(int param) +{ +} + + +// Give a type. + +BOOL CAuto::SetType(ObjectType type) +{ + return FALSE; +} + +// Gives a value. + +BOOL CAuto::SetValue(int rank, float value) +{ + return FALSE; +} + +// Gives the string. + +BOOL CAuto::SetString(char *string) +{ + return FALSE; +} + + +// Management of an event. + +BOOL CAuto::EventProcess(const Event &event) +{ + if ( event.event == EVENT_FRAME && + !m_engine->RetPause() ) + { + m_time += event.rTime; + UpdateInterface(event.rTime); + } + + if ( !m_object->RetSelect() ) // robot not selected? + { + return TRUE; + } + + return TRUE; +} + +// Indicates whether the controller has finished its activity. + +Error CAuto::IsEnded() +{ + return ERR_CONTINUE; +} + +// Stops the controller + +BOOL CAuto::Abort() +{ + return FALSE; +} + + +// Creates all the interface when the object is selected. + +BOOL CAuto::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, dim, ddim; + float ox, oy, sx, sy; + char name[100]; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw != 0 ) + { + pw->Flush(); // destroys the window buttons + m_interface->DeleteControl(EVENT_WINDOW0); // destroys the window + } + + if ( !bSelect ) return TRUE; + + pos.x = 0.0f; + pos.y = 0.0f; + dim.x = 540.0f/640.0f; +//? dim.y = 70.0f/480.0f; + dim.y = 86.0f/480.0f; + m_interface->CreateWindows(pos, dim, 3, EVENT_WINDOW0); + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + m_object->GetTooltipName(name); + pos.x = 0.0f; + pos.y = 64.0f/480.0f; + ddim.x = 540.0f/640.0f; + ddim.y = 16.0f/480.0f; + pw->CreateLabel(pos, ddim, 0, EVENT_LABEL0, name); + + dim.x = 33.0f/640.0f; + dim.y = 33.0f/480.0f; + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*7.0f; + pos.y = oy+sy*0.6f; + ddim.x = 160.0f/640.0f; + ddim.y = 26.0f/480.0f; + pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GPROGRESS); + + if ( m_type != OBJECT_BASE && + m_type != OBJECT_SAFE && + m_type != OBJECT_HUSTON ) + { + pos.x = ox+sx*2.1f; + pos.y = oy+sy*0; + ddim.x = dim.x*0.6f; + ddim.y = dim.y*0.6f; + pw->CreateButton(pos, ddim, 12, EVENT_OBJECT_DELETE); + } + +#if 0 + pos.x = ox+sx*12.4f; + pos.y = oy+sy*1; + pw->CreateButton(pos, dim, 63, EVENT_OBJECT_BHELP); + + pos.x = ox+sx*12.4f; + pos.y = oy+sy*0; + pw->CreateButton(pos, dim, 19, EVENT_OBJECT_HELP); + + if ( m_main->RetSceneSoluce() ) + { + pos.x = ox+sx*13.4f; + pos.y = oy+sy*1; + pw->CreateButton(pos, dim, 20, EVENT_OBJECT_SOLUCE); + } + + pos.x = ox+sx*13.4f; + pos.y = oy+sy*0; + pw->CreateButton(pos, dim, 10, EVENT_OBJECT_DESELECT); +#else + pos.x = ox+sx*12.3f; + pos.y = oy+sy*-0.1f; + ddim.x = dim.x*1.0f; + ddim.y = dim.y*2.1f; + pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue background + + pos.x = ox+sx*12.3f; + pos.y = oy+sy*1; + pw->CreateGroup(pos, dim, 19, EVENT_NULL); // sign SatCom + + pos.x = ox+sx*12.4f; + pos.y = oy+sy*0.5f; + ddim.x = dim.x*0.8f; + ddim.y = dim.y*0.5f; + pw->CreateButton(pos, ddim, 18, EVENT_OBJECT_BHELP); + pos.y = oy+sy*0.0f; + pw->CreateButton(pos, ddim, 19, EVENT_OBJECT_HELP); + + pos.x = ox+sx*13.4f; + pos.y = oy+sy*0; + pw->CreateButton(pos, dim, 10, EVENT_OBJECT_DESELECT); +#endif + + pos.x = ox+sx*14.9f; + pos.y = oy+sy*0; + ddim.x = 14.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGauge(pos, ddim, 3, EVENT_OBJECT_GSHIELD); + + UpdateInterface(); + m_lastUpdateTime = 0.0f; + UpdateInterface(0.0f); + + return TRUE; +} + +// Change the state of a button interface. + +void CAuto::CheckInterface(CWindow *pw, EventMsg event, BOOL bState) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + control->SetState(STATE_CHECK, bState); +} + +// Change the state of a button interface. + +void CAuto::EnableInterface(CWindow *pw, EventMsg event, BOOL bState) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + control->SetState(STATE_ENABLE, bState); +} + +// Change the state of a button interface. + +void CAuto::VisibleInterface(CWindow *pw, EventMsg event, BOOL bState) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + control->SetState(STATE_VISIBLE, bState); +} + +// Change the state of a button interface. + +void CAuto::DeadInterface(CWindow *pw, EventMsg event, BOOL bState) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + control->SetState(STATE_DEAD, !bState); +} + +// Change the state of a button interface. + +void CAuto::UpdateInterface() +{ + CWindow* pw; + + if ( !m_object->RetSelect() ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + VisibleInterface(pw, EVENT_OBJECT_GPROGRESS, m_bBusy); +} + +// Updates the state of all buttons on the interface, +// following the time that elapses ... + +void CAuto::UpdateInterface(float rTime) +{ + CWindow* pw; + CGauge* pg; + + if ( m_time < m_lastUpdateTime+0.1f ) return; + m_lastUpdateTime = m_time; + + if ( !m_object->RetSelect() ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GSHIELD); + if ( pg != 0 ) + { + pg->SetLevel(m_object->RetShield()); + } + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GPROGRESS); + if ( pg != 0 ) + { + pg->SetLevel(m_progressTime); + } +} + + +// Returns an error due the state of the automation. + +Error CAuto::RetError() +{ + return ERR_OK; +} + + +// Management of the occupation. + +BOOL CAuto::RetBusy() +{ + return m_bBusy; +} + +void CAuto::SetBusy(BOOL bBusy) +{ + m_bBusy = bBusy; +} + +void CAuto::InitProgressTotal(float total) +{ + m_progressTime = 0.0f; + m_progressTotal = total; +} + +void CAuto::EventProgress(float rTime) +{ + m_progressTime += rTime/m_progressTotal; +} + + +// Engine management. + +BOOL CAuto::RetMotor() +{ + return m_bMotor; +} + +void CAuto::SetMotor(BOOL bMotor) +{ + m_bMotor = bMotor; +} + + +// Saves all parameters of the controller. + +BOOL CAuto::Write(char *line) +{ + char name[100]; + + sprintf(name, " aType=%d", m_type); + strcat(line, name); + + sprintf(name, " aBusy=%d", m_bBusy); + strcat(line, name); + + sprintf(name, " aTime=%.2f", m_time); + strcat(line, name); + + sprintf(name, " aProgressTime=%.2f", m_progressTime); + strcat(line, name); + + sprintf(name, " aProgressTotal=%.2f", m_progressTotal); + strcat(line, name); + + return FALSE; +} + +// Return all settings to the controller. + +BOOL CAuto::Read(char *line) +{ + m_type = (ObjectType)OpInt(line, "aType", OBJECT_NULL); + m_bBusy = OpInt(line, "aBusy", 0); + m_time = OpFloat(line, "aTime", 0.0f); + m_progressTime = OpFloat(line, "aProgressTime", 0.0f); + m_progressTotal = OpFloat(line, "aProgressTotal", 0.0f); + + return FALSE; +} + diff --git a/src/object/auto/auto.h b/src/object/auto/auto.h new file mode 100644 index 0000000..4cc9389 --- /dev/null +++ b/src/object/auto/auto.h @@ -0,0 +1,114 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// auto.h + +#ifndef _AUTO_H_ +#define _AUTO_H_ + + +#include "object.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CLight; +class CTerrain; +class CWater; +class CCloud; +class CPlanet; +class CBlitz; +class CCamera; +class CObject; +class CInterface; +class CRobotMain; +class CDisplayText; +class CWindow; +class CSound; + + + + +class CAuto +{ +public: + CAuto(CInstanceManager* iMan, CObject* object); + ~CAuto(); + + virtual void DeleteObject(BOOL bAll=FALSE); + + virtual void Init(); + virtual void Start(int param); + virtual BOOL EventProcess(const Event &event); + virtual Error IsEnded(); + virtual BOOL Abort(); + + virtual BOOL SetType(ObjectType type); + virtual BOOL SetValue(int rank, float value); + virtual BOOL SetString(char *string); + + virtual BOOL CreateInterface(BOOL bSelect); + virtual Error RetError(); + + virtual BOOL RetBusy(); + virtual void SetBusy(BOOL bBuse); + virtual void InitProgressTotal(float total); + virtual void EventProgress(float rTime); + + virtual BOOL RetMotor(); + virtual void SetMotor(BOOL bMotor); + + virtual BOOL Write(char *line); + virtual BOOL Read(char *line); + +protected: + void CheckInterface(CWindow *pw, EventMsg event, BOOL bState); + void EnableInterface(CWindow *pw, EventMsg event, BOOL bState); + void VisibleInterface(CWindow *pw, EventMsg event, BOOL bState); + void DeadInterface(CWindow *pw, EventMsg event, BOOL bState); + void UpdateInterface(); + void UpdateInterface(float rTime); + +protected: + CInstanceManager* m_iMan; + CEvent* m_event; + CD3DEngine* m_engine; + CParticule* m_particule; + CLight* m_light; + CTerrain* m_terrain; + CWater* m_water; + CCloud * m_cloud; + CPlanet * m_planet; + CBlitz* m_blitz; + CCamera* m_camera; + CInterface* m_interface; + CRobotMain* m_main; + CDisplayText* m_displayText; + CObject* m_object; + CSound* m_sound; + + ObjectType m_type; + BOOL m_bBusy; + BOOL m_bMotor; + float m_time; + float m_lastUpdateTime; + float m_progressTime; + float m_progressTotal; +}; + + +#endif //_AUTO_H_ diff --git a/src/object/auto/autobase.cpp b/src/object/auto/autobase.cpp new file mode 100644 index 0000000..fada8d5 --- /dev/null +++ b/src/object/auto/autobase.cpp @@ -0,0 +1,1459 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "language.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "terrain.h" +#include "cloud.h" +#include "planet.h" +#include "blitz.h" +#include "camera.h" +#include "object.h" +#include "physics.h" +#include "interface.h" +#include "button.h" +#include "window.h" +#include "displaytext.h" +#include "robotmain.h" +#include "sound.h" +#include "auto.h" +#include "autobase.h" + + + +#define BASE_LAND_TIME 7.5f // hard landing +#define BASE_TAKO_TIME 10.0f // hard landing +#define BASE_DOOR_TIME 6.0f // time opening / closing +#define BASE_DOOR_TIME2 2.0f // time opening / closing suppl. +#define BASE_PORTICO_TIME_MOVE 16.0f // gate advance time +#define BASE_PORTICO_TIME_DOWN 4.0f // gate length down +#define BASE_PORTICO_TIME_OPEN 4.0f // gate opening duration +#define BASE_TRANSIT_TIME 15.0f // transit duration + + + + +// Object's constructor. + +CAutoBase::CAutoBase(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + m_fogStart = m_engine->RetFogStart(); + m_deepView = m_engine->RetDeepView(); + Init(); + m_phase = ABP_WAIT; + m_soundChannel = -1; +} + +// Object's destructor. + +CAutoBase::~CAutoBase() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoBase::DeleteObject(BOOL bAll) +{ + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoBase::Init() +{ + m_bOpen = FALSE; + m_time = 0.0f; + m_lastParticule = 0.0f; + m_lastMotorParticule = 0.0f; + + m_pos = m_object->RetPosition(0); + m_lastPos = m_pos; + + m_phase = ABP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; +} + + +// Start the object. + +void CAutoBase::Start(int param) +{ + m_phase = ABP_START; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + m_param = param; +} + + +// Management of an event. + +BOOL CAutoBase::EventProcess(const Event &event) +{ + D3DMATRIX* mat; + Event newEvent; + CObject* pObj; + D3DVECTOR pos, speed, vibCir, iPos; + FPOINT dim, p; + Error err; + float angle, dist, time, h, len, vSpeed; + int i, max; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + +begin: + iPos = m_object->RetPosition(0); + + if ( m_phase == ABP_START ) + { + if ( m_param != PARAM_STOP && // not placed on the ground? + m_param != PARAM_FIXSCENE ) + { + FreezeCargo(TRUE); // freeze whole cargo + } + + if ( m_param == PARAM_STOP ) // raises the ground? + { + m_phase = ABP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, PI/2.0f-124.0f*PI/180.0f); + m_object->SetAngleX(10+i, -10.0f*PI/180.0f); + m_object->SetAngleX(18+i, 10.0f*PI/180.0f); + m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, -11.5f)); + m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, 11.5f)); + } + + pObj = m_main->RetSelectObject(); + m_main->SelectObject(pObj); + m_camera->SetObject(pObj); + if ( pObj == 0 ) + { + m_camera->SetType(CAMERA_BACK); + } + else + { + m_camera->SetType(pObj->RetCameraType()); + m_camera->SetDist(pObj->RetCameraDist()); + } + + m_main->StartMusic(); + } + + if ( m_param == PARAM_FIXSCENE ) // raises the ground? + { + m_phase = ABP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, PI/2.0f-124.0f*PI/180.0f); + m_object->SetAngleX(10+i, -10.0f*PI/180.0f); + m_object->SetAngleX(18+i, 10.0f*PI/180.0f); + m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, -11.5f)); + m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, 11.5f)); + } + } + + if ( m_param == PARAM_LANDING ) // Landing? + { + m_phase = ABP_LAND; + m_progress = 0.0f; + m_speed = 1.0f/BASE_LAND_TIME; + + m_main->SetMovieLock(TRUE); // blocks everything until the end of the landing + m_bMotor = TRUE; // lights the jet engine + + m_camera->SetType(CAMERA_SCRIPT); + + pos = m_pos; + pos.x -= 150.0f; + m_terrain->MoveOnFloor(pos); + pos.y += 10.0f; + m_camera->SetScriptEye(pos); + m_posSound = pos; + + pos = m_object->RetPosition(0); + pos.y += 300.0f+50.0f; + m_camera->SetScriptLookat(pos); + + m_camera->FixCamera(); + m_engine->SetFocus(2.0f); + + m_engine->SetFogStart(0.9f); + + if ( m_soundChannel == -1 ) + { + m_soundChannel = m_sound->Play(SOUND_FLY, m_posSound, 0.3f, 2.0f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, BASE_LAND_TIME, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 2.0f, SOPER_STOP); + } + + m_main->StartMusic(); + } + + if ( m_param == PARAM_PORTICO ) // gate on the porch? + { + pos = m_object->RetPosition(0); + m_finalPos = pos; + pos.z += BASE_PORTICO_TIME_MOVE*5.0f; // back + pos.y += 10.0f; // rises (the gate) + m_object->SetPosition(0, pos); + MoveCargo(); // all cargo moves + + m_phase = ABP_PORTICO_MOVE; + m_progress = 0.0f; + m_speed = 1.0f/BASE_PORTICO_TIME_MOVE; + + m_main->StartMusic(); + } + + if ( m_param == PARAM_TRANSIT1 || + m_param == PARAM_TRANSIT2 || + m_param == PARAM_TRANSIT3 ) // transit in space? + { + m_phase = ABP_TRANSIT_MOVE; + m_progress = 0.0f; + m_speed = 1.0f/BASE_TRANSIT_TIME; + + m_object->SetAngleZ(0, -PI/2.0f); + pos = m_object->RetPosition(0); + pos.y += 10000.0f; // in space + m_finalPos = pos; + m_object->SetPosition(0, pos); + + m_main->SetMovieLock(TRUE); // blocks everything until the end of the landing + m_bMotor = TRUE; // lights the jet engine + + m_camera->SetType(CAMERA_SCRIPT); + pos.x += 1000.0f; + pos.z -= 60.0f; + pos.y += 80.0f; + m_camera->SetScriptEye(pos); + m_posSound = pos; + m_camera->FixCamera(); + m_engine->SetFocus(1.0f); + + BeginTransit(); + + mat = m_object->RetWorldMatrix(0); + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 10.0f; + dim.y = dim.x; + pos = D3DVECTOR(42.0f, -2.0f, 17.0f); + pos = Transform(*mat, pos); + m_partiChannel[0] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + pos = D3DVECTOR(17.0f, -2.0f, 42.0f); + pos = Transform(*mat, pos); + m_partiChannel[1] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + pos = D3DVECTOR(42.0f, -2.0f, -17.0f); + pos = Transform(*mat, pos); + m_partiChannel[2] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + pos = D3DVECTOR(17.0f, -2.0f, -42.0f); + pos = Transform(*mat, pos); + m_partiChannel[3] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + pos = D3DVECTOR(-42.0f, -2.0f, 17.0f); + pos = Transform(*mat, pos); + m_partiChannel[4] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + pos = D3DVECTOR(-17.0f, -2.0f, 42.0f); + pos = Transform(*mat, pos); + m_partiChannel[5] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + pos = D3DVECTOR(-42.0f, -2.0f, -17.0f); + pos = Transform(*mat, pos); + m_partiChannel[6] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + pos = D3DVECTOR(-17.0f, -2.0f, -42.0f); + pos = Transform(*mat, pos); + m_partiChannel[7] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + + if ( m_soundChannel == -1 ) + { + m_soundChannel = m_sound->Play(SOUND_FLY, m_posSound, 0.0f, 1.2f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, BASE_TRANSIT_TIME*0.55f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.8f, BASE_TRANSIT_TIME*0.45f, SOPER_STOP); + } + } + } + + if ( event.event == EVENT_UPDINTERFACE ) + { + if ( m_object->RetSelect() ) CreateInterface(TRUE); + } + + if ( event.event == EVENT_OBJECT_BTAKEOFF ) + { + err = CheckCloseDoor(); + if ( err != ERR_OK ) + { + m_displayText->DisplayError(err, m_object); + return FALSE; + } + + err = m_main->CheckEndMission(FALSE); + if ( err != ERR_OK ) + { + m_displayText->DisplayError(err, m_object); + return FALSE; + } + + FreezeCargo(TRUE); // freeze whole cargo + m_main->SetMovieLock(TRUE); // blocks everything until the end + m_main->DeselectAll(); + + m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); + m_event->AddEvent(newEvent); + + m_camera->SetType(CAMERA_SCRIPT); + + pos = m_pos; + pos.x -= 110.0f; + m_terrain->MoveOnFloor(pos); + pos.y += 10.0f; + m_camera->SetScriptEye(pos); + m_posSound = pos; + + pos = m_object->RetPosition(0); + pos.y += 50.0f; + m_camera->SetScriptLookat(pos); + + m_engine->SetFocus(1.0f); + + m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.3f, 1.5f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.5f, BASE_DOOR_TIME2, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.5f, 0.5f, SOPER_STOP); + + m_phase = ABP_CLOSE2; + m_progress = 0.0f; + m_speed = 1.0f/BASE_DOOR_TIME2; + return TRUE; + } + + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_phase == ABP_WAIT ) return TRUE; + + m_progress += event.rTime*m_speed; + + if ( m_phase == ABP_LAND ) + { + if ( m_progress < 1.0f ) + { + pos = m_pos; + pos.y += powf(1.0f-m_progress, 2.0f)*300.0f; + m_object->SetPosition(0, pos); + MoveCargo(); // all cargo moves + + vibCir.z = sinf(m_time*PI* 2.01f)*(PI/150.0f)+ + sinf(m_time*PI* 2.51f)*(PI/200.0f)+ + sinf(m_time*PI*19.01f)*(PI/400.0f); + vibCir.x = sinf(m_time*PI* 2.03f)*(PI/150.0f)+ + sinf(m_time*PI* 2.52f)*(PI/200.0f)+ + sinf(m_time*PI*19.53f)*(PI/400.0f); + vibCir.y = 0.0f; + vibCir *= Min(1.0f, (1.0f-m_progress)*3.0f); + m_object->SetCirVibration(vibCir); + + pos = m_pos; + pos.x -= 150.0f; + m_terrain->MoveOnFloor(pos); + pos.y += 10.0f; + m_camera->SetScriptEye(pos); + + pos = m_object->RetPosition(0); + pos.y += 50.0f; + m_camera->SetScriptLookat(pos); + + m_engine->SetFocus(1.0f+(1.0f-m_progress)); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + // Dust thrown to the ground. + pos = m_pos; + pos.x += (Rand()-0.5f)*10.0f; + pos.z += (Rand()-0.5f)*10.0f; + angle = Rand()*(PI*2.0f); + dist = m_progress*50.0f; + p = RotatePoint(angle, dist); + speed.x = p.x; + speed.z = p.y; + speed.y = 0.0f; + dim.x = (Rand()*15.0f+15.0f)*m_progress; + dim.y = dim.x; + if ( dim.x >= 1.0f ) + { + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 2.0f); + } + + // Particles are ejected from the jet engine. + pos = m_object->RetPosition(0); + pos.y += 6.0f; + h = m_terrain->RetFloorHeight(pos)/300.0f; + speed.x = (Rand()-0.5f)*(80.0f-50.0f*h); + speed.z = (Rand()-0.5f)*(80.0f-50.0f*h); + speed.y = -(Rand()*(h+1.0f)*40.0f+(h+1.0f)*40.0f); + dim.x = Rand()*2.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 2.0f, 10.0f, 2.0f); + + // Black smoke from the jet engine. + if ( m_progress > 0.8f ) + { + pos = m_pos; + pos.x += (Rand()-0.5f)*8.0f; + pos.z += (Rand()-0.5f)*8.0f; + pos.y += 3.0f; + speed.x = (Rand()-0.5f)*8.0f; + speed.z = (Rand()-0.5f)*8.0f; + speed.y = 0.0f; + dim.x = Rand()*4.0f+4.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 2.0f); + } + } + } + else + { + m_bMotor = FALSE; // put out the reactor + + m_object->SetPosition(0, m_pos); // setting down + m_object->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); + MoveCargo(); // all cargo moves + + // Impact with the ground. + max = (int)(50.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; iCreateParticule(pos, speed, dim, PARTICRASH, time, 0.0f, 2.0f); + } + +//? m_camera->StartEffect(CE_CRASH, m_pos, 1.0f); + m_camera->StartEffect(CE_EXPLO, m_pos, 2.0f); + m_engine->SetFocus(1.0f); + m_sound->Play(SOUND_BOUM, m_posSound, 0.6f, 0.5f); + + m_phase = ABP_OPENWAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == ABP_OPENWAIT ) + { + if ( m_progress < 1.0f ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + // Black smoke from the reactor. + pos = m_pos; + pos.x += (Rand()-0.5f)*8.0f; + pos.z += (Rand()-0.5f)*8.0f; + pos.y += 3.0f; + speed.x = (Rand()-0.5f)*8.0f; + speed.z = (Rand()-0.5f)*8.0f; + speed.y = 0.0f; + dim.x = Rand()*4.0f+4.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 2.0f); + } + } + else + { + m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.0f, 0.3f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.3f, 1.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.0f, BASE_DOOR_TIME-1.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 1.0f, SOPER_STOP); + + m_phase = ABP_OPEN; + m_progress = 0.0f; + m_speed = 1.0f/BASE_DOOR_TIME; + } + } + + if ( m_phase == ABP_OPEN ) + { + if ( m_progress < 1.0f ) + { + angle = -m_progress*124.0f*PI/180.0f; + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, PI/2.0f+angle); + } + + if ( m_param != PARAM_PORTICO ) + { + angle = m_progress*PI*2.0f; + p = RotatePoint(angle, -150.0f); + pos = m_pos; + pos.x += p.x; + pos.z += p.y; + m_terrain->MoveOnFloor(pos); + pos.y += 10.0f; + pos.y += m_progress*40.0f; + m_camera->SetScriptEye(pos); + + m_engine->SetFogStart(0.9f-(0.9f-m_fogStart)*m_progress); + } + } + else + { + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, PI/2.0f-124.0f*PI/180.0f); + } + + // Clash the doors with the ground. + max = (int)(20.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; iCreateParticule(pos, speed, dim, PARTICRASH, time, 0.0f, 2.0f); + } + + m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.3f, 1.5f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.5f, BASE_DOOR_TIME2, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.5f, 0.5f, SOPER_STOP); + + m_phase = ABP_OPEN2; + m_progress = 0.0f; + m_speed = 1.0f/BASE_DOOR_TIME2; + } + } + + if ( m_phase == ABP_OPEN2 ) + { + if ( m_progress < 1.0f ) + { + len = 7.0f-m_progress*(7.0f+11.5f); + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, len)); + m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, -len)); + m_object->SetAngleX(10+i, -10.0f*PI/180.0f*m_progress); + m_object->SetAngleX(18+i, 10.0f*PI/180.0f*m_progress); + } + + if ( m_param != PARAM_PORTICO ) + { + angle = m_progress*PI/2.0f; + p = RotatePoint(angle, -150.0f); + pos = m_pos; + pos.x += p.x; + pos.z += p.y; + m_terrain->MoveOnFloor(pos); + pos.y += 10.0f; + pos.y += m_progress*40.0f; + m_camera->SetScriptEye(pos); + + m_engine->SetFogStart(0.9f-(0.9f-m_fogStart)*m_progress); + } + } + else + { + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, -11.5f)); + m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, 11.5f)); + m_object->SetAngleX(10+i, -10.0f*PI/180.0f); + m_object->SetAngleX(18+i, 10.0f*PI/180.0f); + } + + m_phase = ABP_LDWAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ABP_LDWAIT ) + { + if ( m_progress >= 1.0f ) + { + FreezeCargo(FALSE); // frees all cargo + + if ( m_param != PARAM_PORTICO ) + { + m_main->SetMovieLock(FALSE); // you can play! + + pObj = m_main->RetSelectObject(); + m_main->SelectObject(pObj); + m_camera->SetObject(pObj); + if ( pObj == 0 ) + { + m_camera->SetType(CAMERA_BACK); + } + else + { + m_camera->SetType(pObj->RetCameraType()); + m_camera->SetDist(pObj->RetCameraDist()); + } + m_sound->Play(SOUND_BOUM, m_object->RetPosition(0)); + m_soundChannel = -1; + + m_engine->SetFogStart(m_fogStart); + } + + m_bOpen = TRUE; + m_phase = ABP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ABP_CLOSE2 ) + { + if ( m_progress < 1.0f ) + { + len = 7.0f-(1.0f-m_progress)*(7.0f+11.5f); + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, len)); + m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, -len)); + m_object->SetAngleX(10+i, -10.0f*PI/180.0f*(1.0f-m_progress)); + m_object->SetAngleX(18+i, 10.0f*PI/180.0f*(1.0f-m_progress)); + } + } + else + { + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, 7.0f)); + m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, -7.0f)); + m_object->SetAngleX(10+i, 0.0f); + m_object->SetAngleX(18+i, 0.0f); + } + + m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.0f, 0.3f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.3f, 1.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.0f, BASE_DOOR_TIME-1.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 1.0f, SOPER_STOP); + + m_phase = ABP_CLOSE; + m_progress = 0.0f; + m_speed = 1.0f/BASE_DOOR_TIME; + } + } + + if ( m_phase == ABP_CLOSE ) + { + if ( m_progress < 1.0f ) + { + angle = -(1.0f-m_progress)*124.0f*PI/180.0f; + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, PI/2.0f+angle); + } + } + else + { + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, PI/2.0f); + } + m_bMotor = TRUE; // lights the jet engine + + // Shock of the closing doors. + max = (int)(20.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; iCreateParticule(pos, speed, dim, PARTICRASH, time); + } + m_sound->Play(SOUND_BOUM, m_object->RetPosition(0)); + + m_soundChannel = -1; + m_bOpen = FALSE; + m_phase = ABP_TOWAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == ABP_TOWAIT ) + { + if ( m_progress < 1.0f ) + { + if ( m_soundChannel == -1 ) + { + m_soundChannel = m_sound->Play(SOUND_FLY, m_posSound, 0.0f, 0.5f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 2.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 2.0f, BASE_TAKO_TIME, SOPER_STOP); + } + + vibCir.z = sinf(m_time*PI*19.01f)*(PI/400.0f); + vibCir.x = sinf(m_time*PI*19.53f)*(PI/400.0f); + vibCir.y = 0.0f; + vibCir *= m_progress*1.0f; + m_object->SetCirVibration(vibCir); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + // Particles are ejected from the reactor. + pos = m_object->RetPosition(0); + pos.y += 6.0f; + speed.x = (Rand()-0.5f)*160.0f; + speed.z = (Rand()-0.5f)*160.0f; + speed.y = -(Rand()*10.0f+10.0f); + dim.x = Rand()*2.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 2.0f, 10.0f, 2.0f); + } + + m_engine->SetFogStart(m_fogStart+(0.9f-m_fogStart)*m_progress); + } + else + { + m_engine->SetFogStart(0.9f); + + m_phase = ABP_TAKEOFF; + m_progress = 0.0f; + m_speed = 1.0f/BASE_TAKO_TIME; + } + } + + if ( m_phase == ABP_TAKEOFF ) + { + if ( m_progress < 1.0f ) + { + pos = m_pos; + pos.y += powf(m_progress, 2.0f)*600.0f; + m_object->SetPosition(0, pos); + MoveCargo(); // all cargo moves + + vibCir.z = sinf(m_time*PI*19.01f)*(PI/400.0f); + vibCir.x = sinf(m_time*PI*19.53f)*(PI/400.0f); + vibCir.y = 0.0f; + m_object->SetCirVibration(vibCir); + + pos = m_pos; + pos.x -= 110.0f+m_progress*250.0f; + m_terrain->MoveOnFloor(pos); + pos.y += 10.0f; + m_camera->SetScriptEye(pos); + + pos = m_object->RetPosition(0); + pos.y += 50.0f; + m_camera->SetScriptLookat(pos); + + m_engine->SetFocus(1.0f+m_progress); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + // Dust thrown to the ground. + pos = m_pos; + pos.x += (Rand()-0.5f)*10.0f; + pos.z += (Rand()-0.5f)*10.0f; + angle = Rand()*(PI*2.0f); + dist = (1.0f-m_progress)*50.0f; + p = RotatePoint(angle, dist); + speed.x = p.x; + speed.z = p.y; + speed.y = 0.0f; + dim.x = (Rand()*10.0f+10.0f)*(1.0f-m_progress); + dim.y = dim.x; + if ( dim.x >= 1.0f ) + { + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 2.0f); + } + + // Particles are ejected from the reactor. + pos = m_object->RetPosition(0); + pos.y += 6.0f; + speed.x = (Rand()-0.5f)*40.0f; + speed.z = (Rand()-0.5f)*40.0f; + time = 5.0f+150.0f*m_progress; + speed.y = -(Rand()*time+time); + time = 2.0f+m_progress*12.0f; + dim.x = Rand()*time+time; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 2.0f, 10.0f, 2.0f); + + // Black smoke from the reactor. + pos = m_object->RetPosition(0); + pos.y += 3.0f; + speed.x = (Rand()-0.5f)*10.0f*(4.0f-m_progress*3.0f); + speed.z = (Rand()-0.5f)*10.0f*(4.0f-m_progress*3.0f); + speed.y = 0.0f; + dim.x = Rand()*20.0f+20.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 10.0f, 0.0f, 2.0f); + } + } + else + { + m_soundChannel = -1; + m_event->MakeEvent(newEvent, EVENT_WIN); + m_event->AddEvent(newEvent); + + m_phase = ABP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == ABP_PORTICO_MOVE ) // advance of the gate? + { + if ( m_progress < 1.0f ) + { + pos = m_object->RetPosition(0); + pos.z -= event.rTime*5.0f; + m_object->SetPosition(0, pos); + MoveCargo(); // all cargo moves + } + else + { + m_phase = ABP_PORTICO_WAIT1; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ABP_PORTICO_WAIT1 ) // expectation the gate? + { + if ( m_progress >= 1.0f ) + { + m_phase = ABP_PORTICO_DOWN; + m_progress = 0.0f; + m_speed = 1.0f/BASE_PORTICO_TIME_DOWN; + } + } + + if ( m_phase == ABP_PORTICO_DOWN ) // down the gate? + { + if ( m_progress < 1.0f ) + { + pos = m_object->RetPosition(0); + pos.y -= event.rTime*(10.0f/BASE_PORTICO_TIME_DOWN); + m_object->SetPosition(0, pos); + MoveCargo(); // all cargo moves + } + else + { + // Impact with the ground. + max = (int)(50.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; iCreateParticule(pos, speed, dim, PARTICRASH, time, 0.0f, 2.0f); + } + + m_phase = ABP_PORTICO_WAIT2; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ABP_PORTICO_WAIT2 ) // expectation the gate? + { + if ( m_progress >= 1.0f ) + { + m_phase = ABP_PORTICO_OPEN; + m_progress = 0.0f; + m_speed = 1.0f/BASE_PORTICO_TIME_OPEN; + } + } + + if ( m_phase == ABP_PORTICO_OPEN ) // opening the gate? + { + if ( m_progress < 1.0f ) + { + } + else + { + m_phase = ABP_OPEN; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == ABP_TRANSIT_MOVE ) // transit in space? + { + if ( m_progress < 1.0f ) + { + pos = m_object->RetPosition(0); + pos.x += event.rTime*(2000.0f/BASE_TRANSIT_TIME); + m_object->SetPosition(0, pos); + pos.x += 60.0f; + m_camera->SetScriptLookat(pos); + } + else + { + m_object->SetAngleZ(0, 0.0f); + + m_param = PARAM_LANDING; + m_phase = ABP_START; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + EndTransit(); + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.8f, 0.01f, SOPER_STOP); + m_soundChannel = -1; + } + goto begin; + } + } + + if ( m_bMotor ) + { + if ( m_lastMotorParticule+m_engine->ParticuleAdapt(0.02f) <= m_time ) + { + m_lastMotorParticule = m_time; + + mat = m_object->RetWorldMatrix(0); + + if ( event.rTime == 0.0f ) + { + vSpeed = 0.0f; + } + else + { + pos = m_object->RetPosition(0); + if ( m_phase == ABP_TRANSIT_MOVE ) + { + vSpeed = (pos.x-iPos.x)/event.rTime; + } + else + { + vSpeed = (pos.y-iPos.y)/event.rTime; + } + if ( vSpeed < 0.0f ) vSpeed *= 1.5f; + } + + pos = D3DVECTOR(0.0f, 6.0f, 0.0f); + speed.x = (Rand()-0.5f)*4.0f; + speed.z = (Rand()-0.5f)*4.0f; + speed.y = vSpeed*0.8f-(8.0f+Rand()*6.0f); + speed += pos; + pos = Transform(*mat, pos); + speed = Transform(*mat, speed); + speed -= pos; + + dim.x = 4.0f+Rand()*4.0f; + dim.y = dim.x; + + m_particule->CreateParticule(pos, speed, dim, PARTIBASE, 3.0f, 0.0f, 0.0f); + + if ( m_phase == ABP_TRANSIT_MOVE ) + { + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 12.0f; + dim.y = dim.x; + pos = D3DVECTOR(0.0f, 7.0f, 0.0f); + pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 1.0f, 0.0f, 0.0f); + + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 4.0f; + dim.y = dim.x; + pos = D3DVECTOR(42.0f, 0.0f, 17.0f); + pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + pos = D3DVECTOR(17.0f, 0.0f, 42.0f); + pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + pos = D3DVECTOR(42.0f, 0.0f, -17.0f); + pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + pos = D3DVECTOR(17.0f, 0.0f, -42.0f); + pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + pos = D3DVECTOR(-42.0f, 0.0f, 17.0f); + pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + pos = D3DVECTOR(-17.0f, 0.0f, 42.0f); + pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + pos = D3DVECTOR(-42.0f, 0.0f, -17.0f); + pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + pos = D3DVECTOR(-17.0f, 0.0f, -42.0f); + pos.x += (Rand()-0.5f)*2.0f; pos.z += (Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + + pos = D3DVECTOR(42.0f, -2.0f, 17.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[0], pos); + pos = D3DVECTOR(17.0f, -2.0f, 42.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[1], pos); + pos = D3DVECTOR(42.0f, -2.0f, -17.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[2], pos); + pos = D3DVECTOR(17.0f, -2.0f, -42.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[3], pos); + pos = D3DVECTOR(-42.0f, -2.0f, 17.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[4], pos); + pos = D3DVECTOR(-17.0f, -2.0f, 42.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[5], pos); + pos = D3DVECTOR(-42.0f, -2.0f, -17.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[6], pos); + pos = D3DVECTOR(-17.0f, -2.0f, -42.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[7], pos); + } + } + } + + if ( m_soundChannel != -1 ) + { + pos = m_engine->RetEyePt(); + m_sound->Position(m_soundChannel, pos); + } + + return TRUE; +} + +// Stops the controller. + +BOOL CAutoBase::Abort() +{ + Event newEvent; + CObject* pObj; + int i; + + if ( m_phase == ABP_TRANSIT_MOVE ) // transit ? + { + m_object->SetAngleZ(0, 0.0f); + + m_param = PARAM_LANDING; + m_phase = ABP_START; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + EndTransit(); + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.8f, 0.01f, SOPER_STOP); + m_soundChannel = -1; + } + return TRUE; + } + + if ( m_param == PARAM_PORTICO ) // gate on the porch? + { + m_object->SetPosition(0, m_finalPos); + MoveCargo(); // all cargo moves + + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, PI/2.0f-124.0f*PI/180.0f); + m_object->SetAngleX(10+i, -10.0f*PI/180.0f); + m_object->SetAngleX(18+i, 10.0f*PI/180.0f); + m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, -11.5f)); + m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, 11.5f)); + } + } + else + { + if ( m_phase == ABP_LAND || + m_phase == ABP_OPENWAIT || + m_phase == ABP_OPEN || + m_phase == ABP_OPEN2 ) // Landing? + { + m_bMotor = FALSE; // put out the jet engine + m_bOpen = TRUE; + + m_object->SetPosition(0, m_pos); // setting down + m_object->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); + MoveCargo(); // all cargo moves + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, PI/2.0f-124.0f*PI/180.0f); + m_object->SetAngleX(10+i, -10.0f*PI/180.0f); + m_object->SetAngleX(18+i, 10.0f*PI/180.0f); + m_object->SetPosition(10+i, D3DVECTOR(23.5f, 0.0f, -11.5f)); + m_object->SetPosition(18+i, D3DVECTOR(23.5f, 0.0f, 11.5f)); + } + + m_main->SetMovieLock(FALSE); // you can play! + + pObj = m_main->RetSelectObject(); + m_main->SelectObject(pObj); + m_camera->SetObject(pObj); + if ( pObj == 0 ) + { + m_camera->SetType(CAMERA_BACK); + } + else + { + m_camera->SetType(pObj->RetCameraType()); + m_camera->SetDist(pObj->RetCameraDist()); + } + + m_engine->SetFogStart(m_fogStart); + } + + if ( m_phase == ABP_CLOSE2 || + m_phase == ABP_CLOSE || + m_phase == ABP_TOWAIT || + m_phase == ABP_TAKEOFF ) // off? + { + m_event->MakeEvent(newEvent, EVENT_WIN); + m_event->AddEvent(newEvent); + } + } + + m_object->SetAngleZ(0, 0.0f); + FreezeCargo(FALSE); // frees all cargo + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + m_phase = ABP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + return TRUE; +} + + +// Returns an error due the state of the automation. + +Error CAutoBase::RetError() +{ + return ERR_OK; +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoBase::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, dim, ddim; + float ox, oy, sx, sy; + float sleep, delay, magnetic, progress; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + dim.x = 33.0f/640.0f; + dim.y = 33.0f/480.0f; + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + ddim.x = dim.x*1.5f; + ddim.y = dim.y*1.5f; + +//? pos.x = ox+sx*7.25f; +//? pos.y = oy+sy*0.25f; +//? pw->CreateButton(pos, ddim, 63, EVENT_OBJECT_BHELP); + + pos.x = ox+sx*8.00f; + pos.y = oy+sy*0.25f; + pw->CreateButton(pos, ddim, 28, EVENT_OBJECT_BTAKEOFF); + + if ( m_blitz->GetStatus(sleep, delay, magnetic, progress) ) + { + pos.x = ox+sx*10.2f; + pos.y = oy+sy*0.5f; + ddim.x = dim.x*1.0f; + ddim.y = dim.y*1.0f; + pw->CreateButton(pos, ddim, 41, EVENT_OBJECT_LIMIT); + } + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 100, EVENT_OBJECT_TYPE); + + UpdateInterface(); + + return TRUE; +} + +// Updates the status of all interface buttons. + +void CAutoBase::UpdateInterface() +{ + CWindow* pw; + + if ( !m_object->RetSelect() ) return; + + CAuto::UpdateInterface(); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); +} + + +// Freeze or frees all cargo. + +void CAutoBase::FreezeCargo(BOOL bFreeze) +{ + CObject* pObj; + CPhysics* physics; + D3DVECTOR oPos; + float dist; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + pObj->SetCargo(FALSE); + + if ( pObj == m_object ) continue; // yourself? + if ( pObj->RetTruck() != 0 ) continue; // transport object? + + oPos = pObj->RetPosition(0); + dist = Length2d(m_pos, oPos); + if ( dist < 32.0f ) + { + if ( bFreeze ) + { + pObj->SetCargo(TRUE); + } + + physics = pObj->RetPhysics(); + if ( physics != 0 ) + { + physics->SetFreeze(bFreeze); + } + } + } +} + +// All cargo moves vertically with the ship. + +void CAutoBase::MoveCargo() +{ + CObject* pObj; + D3DVECTOR oPos, sPos; + int i; + + sPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetCargo() ) continue; + + oPos = pObj->RetPosition(0); + oPos.y = sPos.y+30.0f; + oPos.y += pObj->RetCharacter()->height; + oPos.x += sPos.x-m_lastPos.x; + oPos.z += sPos.z-m_lastPos.z; + pObj->SetPosition(0, oPos); + } + + m_lastPos = sPos; +} + + +// Checks whether it is possible to close the doors. + +Error CAutoBase::CheckCloseDoor() +{ + CObject* pObj; + D3DVECTOR oPos; + ObjectType type; + float oRad, dist; + int i, j; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj == m_object ) continue; // yourself? + if ( !pObj->RetActif() ) continue; // inactive? + + type = pObj->RetType(); + if ( type == OBJECT_PORTICO ) continue; + + j = 0; + while ( pObj->GetCrashSphere(j++, oPos, oRad) ) + { + dist = Length2d(m_pos, oPos); + if ( dist+oRad > 32.0f && + dist-oRad < 72.0f ) + { + return ERR_BASE_DLOCK; + } + + if ( type == OBJECT_HUMAN && + dist+oRad > 32.0f ) + { + return ERR_BASE_DHUMAN; + } + } + } + return ERR_OK; +} + + +// Start a transit. + +void CAutoBase::BeginTransit() +{ + BOOL bFull, bQuarter; + + if ( m_param == PARAM_TRANSIT2 ) + { + strcpy(m_bgBack, "back01.tga"); // clouds orange / blue + } + else if ( m_param == PARAM_TRANSIT3 ) + { + strcpy(m_bgBack, "back22.tga"); // blueberries clouds + } + else + { +#if _DEMO + strcpy(m_bgBack, "back46b.tga"); // paintings +#else + strcpy(m_bgBack, "back46.tga"); // paintings +#endif + } + + m_engine->SetFogStart(0.9f); // hardly any fog + m_engine->SetDeepView(2000.0f); // we see very far + m_engine->ApplyChange(); + + m_engine->RetBackground(m_bgName, m_bgUp, m_bgDown, m_bgCloudUp, m_bgCloudDown, bFull, bQuarter); + m_engine->FreeTexture(m_bgName); + + m_engine->SetBackground(m_bgBack, 0x00000000, 0x00000000, 0x00000000, 0x00000000); + m_engine->LoadTexture(m_bgBack); + + m_cloud->SetEnable(FALSE); // cache clouds + m_planet->SetMode(1); +} + +// End of a transit. + +void CAutoBase::EndTransit() +{ + m_engine->SetFogStart(m_fogStart); // gives initial fog + m_engine->SetDeepView(m_deepView); // gives initial depth + m_engine->ApplyChange(); + + m_engine->FreeTexture(m_bgBack); + + m_engine->SetBackground(m_bgName, m_bgUp, m_bgDown, m_bgCloudUp, m_bgCloudDown); + m_engine->LoadTexture(m_bgName); + + m_cloud->SetEnable(TRUE); // gives the clouds + m_planet->SetMode(0); + + m_main->StartMusic(); +} + diff --git a/src/object/auto/autobase.h b/src/object/auto/autobase.h new file mode 100644 index 0000000..7e0093a --- /dev/null +++ b/src/object/auto/autobase.h @@ -0,0 +1,122 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autobase.h + +#ifndef _AUTOBASE_H_ +#define _AUTOBASE_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +#define PARAM_STOP 0 // run=0 -> stops and open +#define PARAM_LANDING 1 // run=1 -> landing +#define PARAM_PORTICO 2 // run=2 -> gate on the ground +#define PARAM_FIXSCENE 3 // run=3 -> open and stops to win / lost +#define PARAM_TRANSIT1 11 // run=11 -> transit in space +#define PARAM_TRANSIT2 12 // run=12 -> transit in space +#define PARAM_TRANSIT3 13 // run=13 -> transit in space + + +enum AutoBasePhase +{ + ABP_WAIT = 1, // expected + ABP_START = 2, // start-up + + ABP_LAND = 3, // landing + ABP_OPENWAIT = 4, // wait before opening + ABP_OPEN = 5, // opens the gate + ABP_OPEN2 = 6, // opens supplements + ABP_LDWAIT = 7, // expected + + ABP_CLOSE2 = 8, // closes supplements + ABP_CLOSE = 9, // closes gate + ABP_TOWAIT = 10, // wait before takeoff + ABP_TAKEOFF = 11, // take-off + + ABP_PORTICO_MOVE = 12, // gate advance + ABP_PORTICO_WAIT1= 13, // gate expected + ABP_PORTICO_DOWN = 14, // gate down + ABP_PORTICO_WAIT2= 15, // gate expected + ABP_PORTICO_OPEN = 16, // gate opens + + ABP_TRANSIT_MOVE = 17, // transit - moving +}; + + + +class CAutoBase : public CAuto +{ +public: + CAutoBase(CInstanceManager* iMan, CObject* object); + ~CAutoBase(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + void Start(int param); + BOOL EventProcess(const Event &event); + BOOL Abort(); + Error RetError(); + + BOOL CreateInterface(BOOL bSelect); + +protected: + void UpdateInterface(); + void FreezeCargo(BOOL bFreeze); + void MoveCargo(); + Error CheckCloseDoor(); + void BeginTransit(); + void EndTransit(); + +protected: + AutoBasePhase m_phase; + BOOL m_bOpen; + float m_progress; + float m_speed; + float m_lastParticule; + float m_lastMotorParticule; + float m_fogStart; + float m_deepView; + D3DVECTOR m_pos; + D3DVECTOR m_posSound; + D3DVECTOR m_finalPos; + D3DVECTOR m_lastPos; + int m_param; + int m_soundChannel; + int m_partiChannel[8]; + + char m_bgBack[100]; + char m_bgName[100]; + D3DCOLOR m_bgUp; + D3DCOLOR m_bgDown; + D3DCOLOR m_bgCloudUp; + D3DCOLOR m_bgCloudDown; +}; + + +#endif //_AUTOBASE_H_ diff --git a/src/object/auto/autoconvert.cpp b/src/object/auto/autoconvert.cpp new file mode 100644 index 0000000..ae213e3 --- /dev/null +++ b/src/object/auto/autoconvert.cpp @@ -0,0 +1,546 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "light.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "interface.h" +#include "button.h" +#include "window.h" +#include "sound.h" +#include "displaytext.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autoconvert.h" + + + + +// Object's constructor. + +CAutoConvert::CAutoConvert(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + Init(); + m_phase = ACP_STOP; + m_bResetDelete = FALSE; + m_soundChannel = -1; +} + +// Object's destructor. + +CAutoConvert::~CAutoConvert() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoConvert::DeleteObject(BOOL bAll) +{ + CObject* fret; + + if ( !bAll ) + { + fret = SearchStone(OBJECT_STONE); + if ( fret != 0 ) + { + fret->DeleteObject(); // destroy the stone + delete fret; + } + } + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoConvert::Init() +{ + m_phase = ACP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + + CAuto::Init(); +} + + +// Management of an event. + +BOOL CAutoConvert::EventProcess(const Event &event) +{ + CObject* fret; + D3DVECTOR pos, speed; + FPOINT dim, c, p; + float angle; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Rand()*0.3f; + + angle = (Rand()-0.5f)*0.3f; + m_object->SetAngleY(1, angle); + m_object->SetAngleY(2, angle); + m_object->SetAngleY(3, angle+PI); + + m_object->SetAngleX(2, -PI*0.35f*(0.8f+Rand()*0.2f)); + m_object->SetAngleX(3, -PI*0.35f*(0.8f+Rand()*0.2f)); + } + return TRUE; + } + + EventProgress(event.rTime); + + if ( m_phase == ACP_STOP ) return TRUE; + + if ( m_phase == ACP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + fret = SearchStone(OBJECT_STONE); // Has stone transformed? + if ( fret == 0 || SearchVehicle() ) + { + m_phase = ACP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + else + { + fret->SetLock(TRUE); // stone usable + + SetBusy(TRUE); + InitProgressTotal(3.0f+10.0f+1.5f); + UpdateInterface(); + + m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.0f); + m_bSoundClose = FALSE; + + m_phase = ACP_CLOSE; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + } + } + + if ( m_phase == ACP_CLOSE ) + { + if ( m_progress < 1.0f ) + { + if ( m_progress >= 0.8f && !m_bSoundClose ) + { + m_bSoundClose = TRUE; + m_sound->Play(SOUND_CLOSE, m_object->RetPosition(0), 1.0f, 0.8f); + } + angle = -PI*0.35f*(1.0f-Bounce(m_progress, 0.85f, 0.05f)); + m_object->SetAngleX(2, angle); + m_object->SetAngleX(3, angle); + } + else + { + m_object->SetAngleX(2, 0.0f); + m_object->SetAngleX(3, 0.0f); + + m_soundChannel = m_sound->Play(SOUND_CONVERT, m_object->RetPosition(0), 0.0f, 0.25f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.25f, 0.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.00f, 4.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.25f, 4.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.25f, 0.5f, SOPER_STOP); + + m_phase = ACP_ROTATE; + m_progress = 0.0f; + m_speed = 1.0f/10.0f; + } + } + + if ( m_phase == ACP_ROTATE ) + { + if ( m_progress < 1.0f ) + { + if ( m_progress < 0.5f ) + { + angle = powf((m_progress*2.0f)*5.0f, 2.0f); // accelerates + } + else + { + angle = -powf((2.0f-m_progress*2.0f)*5.0f, 2.0f); // slows + } + m_object->SetAngleY(1, angle); + m_object->SetAngleY(2, angle); + m_object->SetAngleY(3, angle+PI); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + c.x = pos.x; + c.y = pos.z; + p.x = c.x; + p.y = c.y+6.0f; + p = RotatePoint(c, Rand()*PI*2.0f, p); + pos.x = p.x; + pos.z = p.y; + pos.y += 1.0f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = Rand()*2.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 1.0f, 0.0f, 0.0f); + } + } + else + { + m_object->SetAngleY(1, 0.0f); + m_object->SetAngleY(2, 0.0f); + m_object->SetAngleY(3, PI); + + fret = SearchStone(OBJECT_STONE); + if ( fret != 0 ) + { + m_bResetDelete = ( fret->RetResetCap() != RESET_NONE ); + fret->DeleteObject(); // destroy the stone + delete fret; + } + + CreateMetal(); // Create the metal + m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.5f); + + m_phase = ACP_OPEN; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + + if ( m_phase == ACP_OPEN ) + { + if ( m_progress < 1.0f ) + { + angle = -PI*0.35f*Bounce(m_progress, 0.7f, 0.2f); + m_object->SetAngleX(2, angle); + m_object->SetAngleX(3, angle); + + if ( m_progress < 0.9f && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.x += (Rand()-0.5f)*6.0f; + pos.z += (Rand()-0.5f)*6.0f; + pos.y += Rand()*4.0f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = Rand()*4.0f+3.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); + } + } + else + { + m_soundChannel = -1; + m_object->SetAngleX(2, -PI*0.35f); + m_object->SetAngleX(3, -PI*0.35f); + + SetBusy(FALSE); + UpdateInterface(); + + m_phase = ACP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + return TRUE; +} + +// Returns an error due the state of the automation. + +Error CAutoConvert::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + if ( m_phase == ACP_WAIT ) return ERR_CONVERT_EMPTY; + return ERR_OK; +} + +// Cancels the current transformation. + +BOOL CAutoConvert::Abort() +{ + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + m_object->SetAngleY(1, 0.0f); + m_object->SetAngleY(2, 0.0f); + m_object->SetAngleY(3, PI); + m_object->SetAngleX(2, -PI*0.35f); + m_object->SetAngleX(3, -PI*0.35f); + + m_phase = ACP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + SetBusy(FALSE); + UpdateInterface(); + + return TRUE; +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoConvert::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 103, EVENT_OBJECT_TYPE); + + return TRUE; +} + + +// Saves all parameters of the controller. + +BOOL CAutoConvert::Write(char *line) +{ + char name[100]; + + if ( m_phase == ACP_STOP || + m_phase == ACP_WAIT ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller. + +BOOL CAutoConvert::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoConvertPhase)OpInt(line, "aPhase", ACP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return TRUE; +} + + +// Searches for the object before or during processing. + +CObject* CAutoConvert::SearchStone(ObjectType type) +{ + CObject* pObj; + D3DVECTOR cPos, oPos; + ObjectType oType; + float dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( oType != type ) continue; + if ( pObj->RetTruck() != 0 ) continue; + + oPos = pObj->RetPosition(0); + dist = Length(oPos, cPos); + + if ( dist <= 5.0f ) return pObj; + } + + return 0; +} + +// Search if a vehicle is too close. + +BOOL CAutoConvert::SearchVehicle() +{ + CObject* pObj; + D3DVECTOR cPos, oPos; + ObjectType type; + float oRadius, dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_HUMAN && + type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr && + type != OBJECT_METAL && + type != OBJECT_URANIUM && + type != OBJECT_POWER && + type != OBJECT_ATOMIC && + type != OBJECT_BULLET && + type != OBJECT_BBOX && + type != OBJECT_TNT && + type != OBJECT_MOTHER && + type != OBJECT_ANT && + type != OBJECT_SPIDER && + type != OBJECT_BEE && + type != OBJECT_WORM ) continue; + + if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; + dist = Length(oPos, cPos)-oRadius; + + if ( dist < 8.0f ) return TRUE; + } + + return FALSE; +} + +// Creates an object metal. + +void CAutoConvert::CreateMetal() +{ + D3DVECTOR pos; + float angle; + CObject* fret; + + pos = m_object->RetPosition(0); + angle = m_object->RetAngleY(0); + + fret = new CObject(m_iMan); + if ( !fret->CreateResource(pos, angle, OBJECT_METAL) ) + { + delete fret; + m_displayText->DisplayError(ERR_TOOMANY, m_object); + return; + } + + if ( m_bResetDelete ) + { + fret->SetResetCap(RESET_DELETE); + } + + m_displayText->DisplayError(INFO_CONVERT, m_object); +} + diff --git a/src/object/auto/autoconvert.h b/src/object/auto/autoconvert.h new file mode 100644 index 0000000..2e35e24 --- /dev/null +++ b/src/object/auto/autoconvert.h @@ -0,0 +1,82 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autoconvert.h + +#ifndef _AUTOCONVERT_H_ +#define _AUTOCONVERT_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoConvertPhase +{ + ACP_STOP = 1, + ACP_WAIT = 2, + ACP_CLOSE = 3, // close the cover + ACP_ROTATE = 4, // turn the cover + ACP_OPEN = 5, // opens the cover +}; + + + +class CAutoConvert : public CAuto +{ +public: + CAutoConvert(CInstanceManager* iMan, CObject* object); + ~CAutoConvert(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + BOOL Abort(); + + BOOL CreateInterface(BOOL bSelect); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + CObject* SearchStone(ObjectType type); + BOOL SearchVehicle(); + void CreateMetal(); + +protected: + AutoConvertPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + BOOL m_bResetDelete; + BOOL m_bSoundClose; + int m_soundChannel; +}; + + +#endif //_AUTOCONVERT_H_ diff --git a/src/object/auto/autoderrick.cpp b/src/object/auto/autoderrick.cpp new file mode 100644 index 0000000..d2541c5 --- /dev/null +++ b/src/object/auto/autoderrick.cpp @@ -0,0 +1,605 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "interface.h" +#include "button.h" +#include "window.h" +#include "sound.h" +#include "displaytext.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autoderrick.h" + + + +#define DERRICK_DELAY 10.0f // duration of the extraction +#define DERRICK_DELAYu 30.0f // same, but for uranium + + + + +// Object's constructor. + +CAutoDerrick::CAutoDerrick(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + Init(); + m_phase = ADP_WAIT; // paused until the first Init () + m_soundChannel = -1; +} + +// Object's destructor. + +CAutoDerrick::~CAutoDerrick() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoDerrick::DeleteObject(BOOL bAll) +{ + CObject* fret; + + if ( !bAll ) + { + fret = SearchFret(); + if ( fret != 0 && fret->RetLock() ) + { + fret->DeleteObject(); + delete fret; + } + } + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoDerrick::Init() +{ + D3DMATRIX* mat; + D3DVECTOR pos; + TerrainRes res; + + pos = m_object->RetPosition(0); + res = m_terrain->RetResource(pos); + + if ( res == TR_STONE || + res == TR_URANIUM || + res == TR_KEYa || + res == TR_KEYb || + res == TR_KEYc || + res == TR_KEYd ) + { + m_type = OBJECT_FRET; + if ( res == TR_STONE ) m_type = OBJECT_STONE; + if ( res == TR_URANIUM ) m_type = OBJECT_URANIUM; + if ( res == TR_KEYa ) m_type = OBJECT_KEYa; + if ( res == TR_KEYb ) m_type = OBJECT_KEYb; + if ( res == TR_KEYc ) m_type = OBJECT_KEYc; + if ( res == TR_KEYd ) m_type = OBJECT_KEYd; + + m_phase = ADP_EXCAVATE; + m_progress = 0.0f; + m_speed = 1.0f/(m_type==OBJECT_URANIUM?DERRICK_DELAYu:DERRICK_DELAY); + } + else + { + m_phase = ADP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f; + } + + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + m_lastTrack = 0.0f; + + pos = D3DVECTOR(7.0f, 0.0f, 0.0f); + mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, pos); + m_terrain->MoveOnFloor(pos); + m_fretPos = pos; +} + + +// Management of an event. + +BOOL CAutoDerrick::EventProcess(const Event &event) +{ + CObject* fret; + D3DVECTOR pos, speed; + FPOINT dim; + float angle, duration, factor; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_phase == ADP_WAIT ) return TRUE; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Rand()*0.3f; + + pos.x = 0.0f; + pos.z = 0.0f; + pos.y = -2.0f*Rand(); + m_object->SetPosition(1, pos); // up / down the drill + + m_object->SetAngleY(1, Rand()*0.5f); // rotates the drill + } + return TRUE; + } + + if ( m_phase == ADP_EXCAVATE ) + { + if ( m_soundChannel == -1 ) + { + if ( m_type == OBJECT_URANIUM ) + { + factor = DERRICK_DELAYu/DERRICK_DELAY; + } + else + { + factor = 1.0f; + } + m_soundChannel = m_sound->Play(SOUND_DERRICK, m_object->RetPosition(0), 1.0f, 0.5f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 4.0f*factor, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.3f, 6.0f*factor, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 1.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 4.0f, SOPER_STOP); + } + + if ( m_progress >= 6.0f/16.0f && // penetrates into the ground? + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + speed.x = (Rand()-0.5f)*10.0f; + speed.z = (Rand()-0.5f)*10.0f; + speed.y = Rand()*5.0f; + dim.x = Rand()*3.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + + if ( m_progress >= 6.0f/16.0f && // penetrates into the ground? + m_lastTrack+m_engine->ParticuleAdapt(0.5f) <= m_time ) + { + m_lastTrack = m_time; + + pos = m_object->RetPosition(0); + speed.x = (Rand()-0.5f)*12.0f; + speed.z = (Rand()-0.5f)*12.0f; + speed.y = Rand()*10.0f+10.0f; + dim.x = 0.6f; + dim.y = dim.x; + pos.y += dim.y; + duration = Rand()*2.0f+2.0f; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK5, + duration, Rand()*10.0f+15.0f, + duration*0.2f, 1.0f); + } + + if ( m_progress < 1.0f ) + { + pos.x = 0.0f; + pos.z = 0.0f; + pos.y = -m_progress*16.0f; + m_object->SetPosition(1, pos); // down the drill + + angle = m_object->RetAngleY(1); + angle += event.rTime*8.0f; + m_object->SetAngleY(1, angle); // rotates the drill + } + else + { + m_phase = ADP_ASCEND; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + } + } + + if ( m_phase == ADP_ASCEND ) + { + if ( m_progress <= 7.0f/16.0f && + m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + speed.x = (Rand()-0.5f)*10.0f; + speed.z = (Rand()-0.5f)*10.0f; + speed.y = Rand()*5.0f; + dim.x = Rand()*3.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + + if ( m_progress <= 4.0f/16.0f && + m_lastTrack+m_engine->ParticuleAdapt(1.0f) <= m_time ) + { + m_lastTrack = m_time; + + pos = m_object->RetPosition(0); + speed.x = (Rand()-0.5f)*12.0f; + speed.z = (Rand()-0.5f)*12.0f; + speed.y = Rand()*10.0f+10.0f; + dim.x = 0.6f; + dim.y = dim.x; + pos.y += dim.y; + duration = Rand()*2.0f+2.0f; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK5, + duration, Rand()*10.0f+15.0f, + duration*0.2f, 1.0f); + } + + if ( m_progress < 1.0f ) + { + pos.x = 0.0f; + pos.z = 0.0f; + pos.y = -(1.0f-m_progress)*16.0f; + m_object->SetPosition(1, pos); // back the drill + + angle = m_object->RetAngleY(1); + angle -= event.rTime*2.0f; + m_object->SetAngleY(1, angle); // rotates the drill + } + else + { + m_soundChannel = -1; + m_bSoundFall = FALSE; + + m_phase = ADP_EXPORT; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + } + } + + if ( m_phase == ADP_ISFREE ) + { + if ( m_progress >= 1.0f ) + { + m_bSoundFall = FALSE; + + m_phase = ADP_EXPORT; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + } + } + + if ( m_phase == ADP_EXPORT ) + { + if ( m_progress == 0.0f ) + { + if ( SearchFree(m_fretPos) ) + { + angle = m_object->RetAngleY(0); + CreateFret(m_fretPos, angle, m_type, 16.0f); + } + else + { + m_phase = ADP_ISFREE; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + return TRUE; + } + } + + fret = SearchFret(); + + if ( fret != 0 && + m_progress <= 0.5f && + m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) + { + m_lastParticule = m_time; + + if ( m_progress < 0.3f ) + { + pos = fret->RetPosition(0); + pos.x += (Rand()-0.5f)*5.0f; + pos.z += (Rand()-0.5f)*5.0f; + pos.y += (Rand()-0.5f)*5.0f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 3.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFIRE, 1.0f, 0.0f, 0.0f); + } + else + { + pos = fret->RetPosition(0); + pos.x += (Rand()-0.5f)*5.0f; + pos.z += (Rand()-0.5f)*5.0f; + pos.y += Rand()*2.5f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f); + } + } + + if ( m_progress < 1.0f ) + { + if ( fret != 0 ) + { + pos = fret->RetPosition(0); + pos.y -= event.rTime*20.0f; // grave + if ( !m_bSoundFall && pos.y < m_fretPos.y ) + { + m_sound->Play(SOUND_BOUM, m_fretPos); + m_bSoundFall = TRUE; + } + if ( pos.y < m_fretPos.y ) + { + pos.y = m_fretPos.y; + fret->SetLock(FALSE); // object usable + } + fret->SetPosition(0, pos); + } + } + else + { + if ( ExistKey() ) // key already exists? + { + m_phase = ADP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/10.0f; + } + else + { + m_phase = ADP_EXCAVATE; + m_progress = 0.0f; + m_speed = 1.0f/(m_type==OBJECT_URANIUM?DERRICK_DELAYu:DERRICK_DELAY); + } + } + } + + return TRUE; +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoDerrick::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 109, EVENT_OBJECT_TYPE); + + return TRUE; +} + + +// Saves all parameters of the controller. + +BOOL CAutoDerrick::Write(char *line) +{ + char name[100]; + + if ( m_phase == ADP_WAIT ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller. + +BOOL CAutoDerrick::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoDerrickPhase)OpInt(line, "aPhase", ADP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return TRUE; +} + + +// Seeks the subject cargo. + +CObject* CAutoDerrick::SearchFret() +{ + CObject* pObj; + D3DVECTOR oPos; + ObjectType type; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type == OBJECT_DERRICK ) continue; + + oPos = pObj->RetPosition(0); + + if ( oPos.x == m_fretPos.x && + oPos.z == m_fretPos.z ) return pObj; + } + + return 0; +} + +// Seeks if a site is free. + +BOOL CAutoDerrick::SearchFree(D3DVECTOR pos) +{ + CObject* pObj; + D3DVECTOR sPos; + ObjectType type; + float sRadius, distance; + int i, j; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type == OBJECT_DERRICK ) continue; + + j = 0; + while ( pObj->GetCrashSphere(j++, sPos, sRadius) ) + { + distance = Length(sPos, pos); + distance -= sRadius; + if ( distance < 2.0f ) return FALSE; // location occupied + } + } + + return TRUE; // location free +} + +// Create a transportable object. + +void CAutoDerrick::CreateFret(D3DVECTOR pos, float angle, ObjectType type, + float height) +{ + CObject* fret; + + fret = new CObject(m_iMan); + if ( !fret->CreateResource(pos, angle, type) ) + { + delete fret; + m_displayText->DisplayError(ERR_TOOMANY, m_object); + return; + } + fret->SetLock(TRUE); // object not yet usable + + if ( m_object->RetResetCap() == RESET_MOVE ) + { + fret->SetResetCap(RESET_DELETE); + } + + pos = fret->RetPosition(0); + pos.y += height; + fret->SetPosition(0, pos); +} + +// Look if there is already a key. + +BOOL CAutoDerrick::ExistKey() +{ + CObject* pObj; + ObjectType type; + int i; + + if ( m_type != OBJECT_KEYa && + m_type != OBJECT_KEYb && + m_type != OBJECT_KEYc && + m_type != OBJECT_KEYd ) return FALSE; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type == m_type ) return TRUE; + } + + return FALSE; +} + + +// Returns an error due the state of the automaton. + +Error CAutoDerrick::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + if ( m_phase == ADP_WAIT ) return ERR_DERRICK_NULL; + return ERR_OK; +} + + diff --git a/src/object/auto/autoderrick.h b/src/object/auto/autoderrick.h new file mode 100644 index 0000000..6c9293d --- /dev/null +++ b/src/object/auto/autoderrick.h @@ -0,0 +1,84 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autoderrick.h + +#ifndef _AUTODERRICK_H_ +#define _AUTODERRICK_H_ + + +#include "object.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + + +enum AutoDerrickPhase +{ + ADP_WAIT = 1, + ADP_EXCAVATE = 2, // down the drill + ADP_ASCEND = 3, // up the drill + ADP_EXPORT = 4, // exports matter + ADP_ISFREE = 5, // expected material loss +}; + + + +class CAutoDerrick : public CAuto +{ +public: + CAutoDerrick(CInstanceManager* iMan, CObject* object); + ~CAutoDerrick(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + + BOOL CreateInterface(BOOL bSelect); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + CObject* SearchFret(); + BOOL SearchFree(D3DVECTOR pos); + void CreateFret(D3DVECTOR pos, float angle, ObjectType type, float height); + BOOL ExistKey(); + +protected: + AutoDerrickPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + float m_lastTrack; + D3DVECTOR m_fretPos; + int m_soundChannel; + BOOL m_bSoundFall; +}; + + +#endif //_AUTODERRICK_H_ diff --git a/src/object/auto/autodestroyer.cpp b/src/object/auto/autodestroyer.cpp new file mode 100644 index 0000000..11dc0ba --- /dev/null +++ b/src/object/auto/autodestroyer.cpp @@ -0,0 +1,397 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "light.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "physics.h" +#include "pyro.h" +#include "sound.h" +#include "interface.h" +#include "button.h" +#include "window.h" +#include "robotmain.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autodestroyer.h" + + + + +// Object's constructor. + +CAutoDestroyer::CAutoDestroyer(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + Init(); + m_phase = ADEP_WAIT; // paused until the first Init () +} + +// Destructive of the object. + +CAutoDestroyer::~CAutoDestroyer() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoDestroyer::DeleteObject(BOOL bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoDestroyer::Init() +{ + m_phase = ADEP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/0.5f; + + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + + CAuto::Init(); +} + + +// Management of an event. + +BOOL CAutoDestroyer::EventProcess(const Event &event) +{ + CObject* scrap; + CPyro* pyro; + D3DVECTOR pos, speed; + FPOINT dim; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Rand()*0.3f; + } + return TRUE; + } + + if ( m_phase == ADEP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + scrap = SearchPlastic(); + if ( scrap == 0 ) + { + m_phase = ADEP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/0.5f; + } + else + { + scrap->SetLock(TRUE); // usable waste +//? scrap->SetTruck(m_object); // usable waste + + if ( SearchVehicle() ) + { + m_phase = ADEP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/0.5f; + } + else + { + m_sound->Play(SOUND_PSHHH2, m_object->RetPosition(0), 1.0f, 1.0f); + + m_phase = ADEP_DOWN; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + m_bExplo = FALSE; + } + } + } + } + + if ( m_phase == ADEP_DOWN ) + { + if ( m_progress >= 0.3f-0.05f && !m_bExplo ) + { + scrap = SearchPlastic(); + if ( scrap != 0 ) + { + pyro = new CPyro(m_iMan); + pyro->Create(PT_FRAGT, scrap); + } + m_bExplo = TRUE; + } + + if ( m_progress < 1.0f ) + { + pos = D3DVECTOR(0.0f, -10.0f, 0.0f); + pos.y = -Bounce(m_progress, 0.3f)*10.0f; + m_object->SetPosition(1, pos); + } + else + { + m_object->SetPosition(1, D3DVECTOR(0.0f, -10.0f, 0.0f)); + m_sound->Play(SOUND_REPAIR, m_object->RetPosition(0)); + + m_phase = ADEP_REPAIR; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ADEP_REPAIR ) + { + if ( m_progress < 1.0f ) + { + } + else + { + m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 0.8f); + + m_phase = ADEP_UP; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + } + + if ( m_phase == ADEP_UP ) + { + if ( m_progress < 1.0f ) + { + pos = D3DVECTOR(0.0f, -10.0f, 0.0f); + pos.y = -(1.0f-m_progress)*10.0f; + m_object->SetPosition(1, pos); + } + else + { + m_object->SetPosition(1, D3DVECTOR(0.0f, 0.0f, 0.0f)); + + m_phase = ADEP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/0.5f; + } + } + + return TRUE; +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoDestroyer::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 106, EVENT_OBJECT_TYPE); + + return TRUE; +} + + +// Seeks plate waste in the destroyer. + +CObject* CAutoDestroyer::SearchPlastic() +{ + CObject* pObj; + D3DVECTOR sPos, oPos; + ObjectType type; + float dist; + int i; + + sPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_SCRAP4 && + type != OBJECT_SCRAP5 ) continue; + + oPos = pObj->RetPosition(0); + dist = Length(oPos, sPos); + if ( dist <= 5.0f ) return pObj; + } + + return 0; +} + +// Seeks if one vehicle is too close. + +BOOL CAutoDestroyer::SearchVehicle() +{ + CObject* pObj; + D3DVECTOR cPos, oPos; + ObjectType type; + float oRadius, dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_HUMAN && + type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr && + type != OBJECT_MOTHER && + type != OBJECT_ANT && + type != OBJECT_SPIDER && + type != OBJECT_BEE && + type != OBJECT_WORM ) continue; + + if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; + dist = Length(oPos, cPos)-oRadius; + + if ( dist < 20.0f ) return TRUE; + } + + return FALSE; +} + + +// Returns an error due the state of the automation. + +Error CAutoDestroyer::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + return ERR_OK; +} + + +// Saves all parameters of the controller. + +BOOL CAutoDestroyer::Write(char *line) +{ + char name[100]; + + if ( m_phase == ADEP_WAIT ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller. + +BOOL CAutoDestroyer::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoDestroyerPhase)OpInt(line, "aPhase", ADEP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return TRUE; +} + + diff --git a/src/object/auto/autodestroyer.h b/src/object/auto/autodestroyer.h new file mode 100644 index 0000000..a69f832 --- /dev/null +++ b/src/object/auto/autodestroyer.h @@ -0,0 +1,76 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autodestroyer.h + +#ifndef _AUTODESTROYER_H_ +#define _AUTODESTROYER_H_ + + +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoDestroyerPhase +{ + ADEP_WAIT = 1, // expected metal + ADEP_DOWN = 2, // down the cover + ADEP_REPAIR = 3, // built the vehicle + ADEP_UP = 4, // up the cover +}; + + + +class CAutoDestroyer : public CAuto +{ +public: + CAutoDestroyer(CInstanceManager* iMan, CObject* object); + ~CAutoDestroyer(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + + BOOL CreateInterface(BOOL bSelect); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + CObject* SearchPlastic(); + BOOL SearchVehicle(); + +protected: + AutoDestroyerPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + BOOL m_bExplo; +}; + + +#endif //_AUTODESTROYER_H_ diff --git a/src/object/auto/autoegg.cpp b/src/object/auto/autoegg.cpp new file mode 100644 index 0000000..6e57fcc --- /dev/null +++ b/src/object/auto/autoegg.cpp @@ -0,0 +1,375 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "pyro.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autoegg.h" + + + +// Object's constructor. + +CAutoEgg::CAutoEgg(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + m_type = OBJECT_NULL; + m_value = 0.0f; + m_string[0] = 0; + + m_param = 0; + m_phase = AEP_NULL; + Init(); +} + +// Object's destructor. + +CAutoEgg::~CAutoEgg() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoEgg::DeleteObject(BOOL bAll) +{ + CObject* alien; + + CAuto::DeleteObject(bAll); + + if ( !bAll ) + { + alien = SearchAlien(); + if ( alien != 0 ) + { + // Probably the intended action + // Original code: ( alien->RetZoom(0) == 1.0f ) + if ( alien->RetZoomY(0) == 1.0f ) + { + alien->SetLock(FALSE); + alien->SetActivity(TRUE); // the insect is active + } + else + { + alien->DeleteObject(); + delete alien; + } + } + } +} + + +// Initialize the object. + +void CAutoEgg::Init() +{ + CObject* alien; + + alien = SearchAlien(); + if ( alien == 0 ) + { + m_phase = AEP_NULL; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + m_time = 0.0f; + return; + } + + m_phase = AEP_INCUB; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + m_time = 0.0f; + + m_type = alien->RetType(); + + if ( m_type == OBJECT_ANT || + m_type == OBJECT_SPIDER || + m_type == OBJECT_BEE ) + { + alien->SetZoom(0, 0.2f); + } + if ( m_type == OBJECT_WORM ) + { + alien->SetZoom(0, 0.01f); // invisible ! + } + alien->SetLock(TRUE); + alien->SetActivity(FALSE); +} + + +// Gives a value. + +BOOL CAutoEgg::SetType(ObjectType type) +{ + m_type = type; + return TRUE; +} + +// Gives a value. + +BOOL CAutoEgg::SetValue(int rank, float value) +{ + if ( rank != 0 ) return FALSE; + m_value = value; + return TRUE; +} + +// Gives the string. + +BOOL CAutoEgg::SetString(char *string) +{ + strcpy(m_string, string); + return TRUE; +} + + +// Start object. + +void CAutoEgg::Start(int param) +{ + if ( m_type == OBJECT_NULL ) return; + if ( m_value == 0.0f ) return; + + m_phase = AEP_DELAY; + m_progress = 0.0f; + m_speed = 1.0f/m_value; + + m_param = param; +} + + +// Management of an event. + +BOOL CAutoEgg::EventProcess(const Event &event) +{ + CObject* alien; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_phase == AEP_NULL ) return TRUE; + + if ( m_phase == AEP_DELAY ) + { + m_progress += event.rTime*m_speed; + if ( m_progress < 1.0f ) return TRUE; + + alien = new CObject(m_iMan); + if ( !alien->CreateInsect(m_object->RetPosition(0), m_object->RetAngleY(0), m_type) ) + { + delete alien; + m_phase = AEP_DELAY; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + return TRUE; + } + alien->SetActivity(FALSE); + alien->ReadProgram(0, m_string); + alien->RunProgram(0); + Init(); + } + + alien = SearchAlien(); + if ( alien == 0 ) return TRUE; + alien->SetActivity(FALSE); + + m_progress += event.rTime*m_speed; + + if ( m_phase == AEP_ZOOM ) + { + if ( m_type == OBJECT_ANT || + m_type == OBJECT_SPIDER || + m_type == OBJECT_BEE ) + { + alien->SetZoom(0, 0.2f+m_progress*0.8f); // Others push + } + } + + return TRUE; +} + +// Indicates whether the controller has completed its activity. + +Error CAutoEgg::IsEnded() +{ + CObject* alien; + CPyro* pyro; + + if ( m_phase == AEP_DELAY ) + { + return ERR_CONTINUE; + } + + alien = SearchAlien(); + if ( alien == 0 ) return ERR_STOP; + + if ( m_phase == AEP_INCUB ) + { + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + m_phase = AEP_ZOOM; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + } + + if ( m_phase == AEP_ZOOM ) + { + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + pyro = new CPyro(m_iMan); + pyro->Create(PT_EGG, m_object); // exploding egg + + alien->SetZoom(0, 1.0f); // this is a big boy now + + m_phase = AEP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + + if ( m_phase == AEP_WAIT ) + { + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + alien->SetLock(FALSE); + alien->SetActivity(TRUE); // the insect is active + } + + return ERR_STOP; +} + + +// Returns an error due the state of the automation. + +Error CAutoEgg::RetError() +{ + return ERR_OK; +} + + +// Seeking the insect that starts in the egg. + +CObject* CAutoEgg::SearchAlien() +{ + CObject* pObj; + CObject* pBest; + D3DVECTOR cPos, oPos; + ObjectType type; + float dist, min; + int i; + + cPos = m_object->RetPosition(0); + min = 100000.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj->RetTruck() != 0 ) continue; + + type = pObj->RetType(); + if ( type != OBJECT_ANT && + type != OBJECT_BEE && + type != OBJECT_SPIDER && + type != OBJECT_WORM ) continue; + + oPos = pObj->RetPosition(0); + dist = Length2d(oPos, cPos); + if ( dist < 8.0f && dist < min ) + { + min = dist; + pBest = pObj; + } + } + return pBest; +} + + +// Saves all parameters of the controller. + +BOOL CAutoEgg::Write(char *line) +{ + char name[100]; + + if ( m_phase == AEP_NULL ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.5f", m_speed); + strcat(line, name); + + sprintf(name, " aParamType=%s", GetTypeObject(m_type)); + strcat(line, name); + + sprintf(name, " aParamValue1=%.2f", m_value); + strcat(line, name); + + sprintf(name, " aParamString=\"%s\"", m_string); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller. + +BOOL CAutoEgg::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoEggPhase)OpInt(line, "aPhase", AEP_NULL); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + m_type = OpTypeObject(line, "aParamType", OBJECT_NULL); + m_value = OpFloat(line, "aParamValue1", 0.0f); + OpString(line, "aParamString", m_string); + + return TRUE; +} + diff --git a/src/object/auto/autoegg.h b/src/object/auto/autoegg.h new file mode 100644 index 0000000..4340a9b --- /dev/null +++ b/src/object/auto/autoegg.h @@ -0,0 +1,83 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autoegg.h + +#ifndef _AUTOEGG_H_ +#define _AUTOEGG_H_ + + +#include "object.h" +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoEggPhase +{ + AEP_NULL = 0, + AEP_DELAY = 1, + AEP_INCUB = 3, + AEP_ZOOM = 4, + AEP_WAIT = 5, +}; + + + +class CAutoEgg : public CAuto +{ +public: + CAutoEgg(CInstanceManager* iMan, CObject* object); + ~CAutoEgg(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + void Start(int param); + BOOL EventProcess(const Event &event); + Error IsEnded(); + Error RetError(); + + BOOL SetType(ObjectType type); + BOOL SetValue(int rank, float value); + BOOL SetString(char *string); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + CObject* SearchAlien(); + +protected: + ObjectType m_type; + float m_value; + char m_string[100]; + int m_param; + AutoEggPhase m_phase; + float m_progress; + float m_speed; +}; + + +#endif //_AUTOEGG_H_ diff --git a/src/object/auto/autoenergy.cpp b/src/object/auto/autoenergy.cpp new file mode 100644 index 0000000..023a185 --- /dev/null +++ b/src/object/auto/autoenergy.cpp @@ -0,0 +1,665 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "light.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "interface.h" +#include "button.h" +#include "gauge.h" +#include "window.h" +#include "displaytext.h" +#include "sound.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autoenergy.h" + + + +#define ENERGY_POWER 0.4f // Necessary energy for a battery +#define ENERGY_DELAY 12.0f // processing time + + + + +// Object's constructor. + +CAutoEnergy::CAutoEnergy(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + m_partiSphere = -1; + Init(); +} + +// Object's destructor. + +CAutoEnergy::~CAutoEnergy() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoEnergy::DeleteObject(BOOL bAll) +{ + CObject* fret; + + if ( m_partiSphere != -1 ) + { + m_particule->DeleteParticule(m_partiSphere); + m_partiSphere = -1; + } + + if ( !bAll ) + { + fret = SearchMetal(); + if ( fret != 0 ) + { + fret->DeleteObject(); // destroys the metal + delete fret; + } + + fret = SearchPower(); + if ( fret != 0 ) + { + fret->DeleteObject(); // destroys the cell + delete fret; + } + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoEnergy::Init() +{ + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastUpdateTime = 0.0f; + m_lastParticule = 0.0f; + + m_phase = AENP_WAIT; // waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + CAuto::Init(); +} + + +// Management of an event. + +BOOL CAutoEnergy::EventProcess(const Event &event) +{ + CObject* fret; + D3DVECTOR pos, ppos, speed; + FPOINT dim, c, p; + TerrainRes res; + float big; + BOOL bGO; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Rand()*0.3f; + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + pos = m_object->RetPosition(0); + pos.y += 10.0f; + speed.x = (Rand()-0.5f)*10.0f; + speed.z = (Rand()-0.5f)*10.0f; + speed.y = -7.0f; + dim.x = Rand()*0.5f+0.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ, 1.0f, 0.0f, 0.0f); + } + } + return TRUE; + } + + UpdateInterface(event.rTime); + EventProgress(event.rTime); + + big = m_object->RetEnergy(); + + res = m_terrain->RetResource(m_object->RetPosition(0)); + if ( res == TR_POWER ) + { + big += event.rTime*0.01f; // recharges the big pile + } + + if ( m_phase == AENP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + bGO = FALSE; + fret = SearchMetal(); // transform metal? + if ( fret != 0 ) + { + if ( fret->RetType() == OBJECT_METAL ) + { + if ( big > ENERGY_POWER ) bGO = TRUE; + } + else + { + if ( !SearchVehicle() ) bGO = TRUE; + } + } + + if ( bGO ) + { + if ( fret->RetType() == OBJECT_METAL ) + { + fret->SetLock(TRUE); // usable metal + CreatePower(); // creates the battery + } + + SetBusy(TRUE); + InitProgressTotal(ENERGY_DELAY); + CAuto::UpdateInterface(); + + pos = m_object->RetPosition(0); + pos.y += 4.0f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 3.0f; + dim.y = dim.x; + m_partiSphere = m_particule->CreateParticule(pos, speed, dim, PARTISPHERE1, ENERGY_DELAY, 0.0f, 0.0f); + + m_phase = AENP_CREATE; + m_progress = 0.0f; + m_speed = 1.0f/ENERGY_DELAY; + } + else + { + if ( rand()%3 == 0 && big > 0.01f ) + { + m_phase = AENP_BLITZ; + m_progress = 0.0f; + m_speed = 1.0f/Rand()*1.0f+1.0f; + } + else + { + m_phase = AENP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + } + } + + if ( m_phase == AENP_BLITZ ) + { + if ( m_progress < 1.0f && big > 0.01f ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + pos = m_object->RetPosition(0); + pos.y += 10.0f; + speed.x = (Rand()-0.5f)*1.0f; + speed.z = (Rand()-0.5f)*1.0f; + speed.y = -7.0f; + dim.x = Rand()*0.5f+0.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ, 1.0f, 0.0f, 0.0f); + } + } + else + { + m_phase = AENP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == AENP_CREATE ) + { + if ( m_progress < 1.0f ) + { + fret = SearchMetal(); + if ( fret != 0 ) + { + if ( fret->RetType() == OBJECT_METAL ) + { + big -= event.rTime/ENERGY_DELAY*ENERGY_POWER; + } + else + { + big += event.rTime/ENERGY_DELAY*0.25f; + } + fret->SetZoom(0, 1.0f-m_progress); + } + + fret = SearchPower(); + if ( fret != 0 ) + { + fret->SetZoom(0, m_progress); + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + c.x = pos.x; + c.y = pos.z; + p.x = c.x; + p.y = c.y+2.0f; + p = RotatePoint(c, Rand()*PI*2.0f, p); + pos.x = p.x; + pos.z = p.y; + pos.y += 2.5f+Rand()*3.0f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = Rand()*2.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 1.0f, 0.0f, 0.0f); + + pos = m_object->RetPosition(0); + pos.y += 3.0f; + speed.x = (Rand()-0.5f)*30.0f; + speed.z = (Rand()-0.5f)*30.0f; + speed.y = Rand()*20.0f+10.0f; + dim.x = Rand()*0.4f+0.4f; + dim.y = dim.x; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK2, 2.0f, 50.0f, 1.2f, 1.2f); + + pos = m_object->RetPosition(0); + pos.y += 10.0f; + speed.x = (Rand()-0.5f)*1.5f; + speed.z = (Rand()-0.5f)*1.5f; + speed.y = -6.0f; + dim.x = Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ, 1.0f, 0.0f, 0.0f); + + m_sound->Play(SOUND_ENERGY, m_object->RetPosition(0), + 1.0f, 1.0f+Rand()*1.5f); + } + } + else + { + fret = SearchMetal(); + if ( fret != 0 ) + { + m_object->SetPower(0); + fret->DeleteObject(); // destroys the metal + delete fret; + } + + fret = SearchPower(); + if ( fret != 0 ) + { + fret->SetZoom(0, 1.0f); + fret->SetLock(FALSE); // usable battery + fret->SetTruck(m_object); + fret->SetPosition(0, D3DVECTOR(0.0f, 3.0f, 0.0f)); + m_object->SetPower(fret); + + m_displayText->DisplayError(INFO_ENERGY, m_object); + } + + SetBusy(FALSE); + CAuto::UpdateInterface(); + + m_phase = AENP_SMOKE; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + } + } + + if ( m_phase == AENP_SMOKE ) + { + if ( m_progress < 1.0f ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.y += 17.0f; + pos.x += (Rand()-0.5f)*3.0f; + pos.z += (Rand()-0.5f)*3.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 6.0f+Rand()*6.0f; + dim.x = Rand()*1.5f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); + } + } + else + { + m_phase = AENP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( big < 0.0f ) big = 0.0f; + if ( big > 1.0f ) big = 1.0f; + m_object->SetEnergy(big); // shift the big pile + + return TRUE; +} + + +// Seeking the metal object. + +CObject* CAutoEnergy::SearchMetal() +{ + CObject* pObj; + ObjectType type; + + pObj = m_object->RetPower(); + if ( pObj == 0 ) return 0; + + type = pObj->RetType(); + if ( type == OBJECT_METAL || + type == OBJECT_SCRAP1 || + type == OBJECT_SCRAP2 || + type == OBJECT_SCRAP3 ) return pObj; + + return 0; +} + +// Search if a vehicle is too close. + +BOOL CAutoEnergy::SearchVehicle() +{ + CObject* pObj; + D3DVECTOR cPos, oPos; + ObjectType type; + float oRadius, dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_HUMAN && + type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr && + type != OBJECT_MOTHER && + type != OBJECT_ANT && + type != OBJECT_SPIDER && + type != OBJECT_BEE && + type != OBJECT_WORM ) continue; + + if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; + dist = Length(oPos, cPos)-oRadius; + + if ( dist < 10.0f ) return TRUE; + } + + return FALSE; +} + +// Create a cell. + +void CAutoEnergy::CreatePower() +{ + CObject* power; + D3DVECTOR pos; + float angle; + + pos = m_object->RetPosition(0); + angle = m_object->RetAngleY(0); + + power = new CObject(m_iMan); + if ( !power->CreateResource(pos, angle, OBJECT_POWER) ) + { + delete power; + m_displayText->DisplayError(ERR_TOOMANY, m_object); + return; + } + power->SetLock(TRUE); // battery not yet usable + + pos = power->RetPosition(0); + pos.y += 3.0f; + power->SetPosition(0, pos); +} + +// Seeking the battery during manufacture. + +CObject* CAutoEnergy::SearchPower() +{ + CObject* pObj; + D3DVECTOR cPos, oPos; + ObjectType type; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetLock() ) continue; + + type = pObj->RetType(); + if ( type != OBJECT_POWER ) continue; + + oPos = pObj->RetPosition(0); + if ( oPos.x == cPos.x && + oPos.z == cPos.z ) + { + return pObj; + } + } + + return 0; +} + + +// Returns an error due the state of the automation. + +Error CAutoEnergy::RetError() +{ + CObject* pObj; + ObjectType type; + TerrainRes res; + + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + if ( m_phase != AENP_WAIT && + m_phase != AENP_BLITZ ) return ERR_OK; + + res = m_terrain->RetResource(m_object->RetPosition(0)); + if ( res != TR_POWER ) return ERR_ENERGY_NULL; + + if ( m_object->RetEnergy() < ENERGY_POWER ) return ERR_ENERGY_LOW; + + pObj = m_object->RetPower(); + if ( pObj == 0 ) return ERR_ENERGY_EMPTY; + type = pObj->RetType(); + if ( type == OBJECT_POWER ) return ERR_OK; + if ( type != OBJECT_METAL && + type != OBJECT_SCRAP1 && + type != OBJECT_SCRAP2 && + type != OBJECT_SCRAP3 ) return ERR_ENERGY_BAD; + + return ERR_OK; +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoEnergy::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*14.5f; + pos.y = oy+sy*0; + ddim.x = 14.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 108, EVENT_OBJECT_TYPE); + + return TRUE; +} + +// Updates the state of all buttons on the interface, +// following the time that elapses ... + +void CAutoEnergy::UpdateInterface(float rTime) +{ + CWindow* pw; + CGauge* pg; + + CAuto::UpdateInterface(rTime); + + if ( m_time < m_lastUpdateTime+0.1f ) return; + m_lastUpdateTime = m_time; + + if ( !m_object->RetSelect() ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); + if ( pg != 0 ) + { + pg->SetLevel(m_object->RetEnergy()); + } +} + + +// Saves all parameters of the controller. + +BOOL CAutoEnergy::Write(char *line) +{ + char name[100]; + + if ( m_phase == AENP_STOP || + m_phase == AENP_WAIT ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller. + +BOOL CAutoEnergy::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoEnergyPhase)OpInt(line, "aPhase", AENP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastUpdateTime = 0.0f; + m_lastParticule = 0.0f; + + return TRUE; +} diff --git a/src/object/auto/autoenergy.h b/src/object/auto/autoenergy.h new file mode 100644 index 0000000..dd920fb --- /dev/null +++ b/src/object/auto/autoenergy.h @@ -0,0 +1,83 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autoenergy.h + +#ifndef _AUTOENERGY_H_ +#define _AUTOENERGY_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoEnergyPhase +{ + AENP_STOP = 1, + AENP_WAIT = 2, + AENP_BLITZ = 3, + AENP_CREATE = 4, + AENP_SMOKE = 5, +}; + + + +class CAutoEnergy : public CAuto +{ +public: + CAutoEnergy(CInstanceManager* iMan, CObject* object); + ~CAutoEnergy(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + + BOOL CreateInterface(BOOL bSelect); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + void UpdateInterface(float rTime); + + CObject* SearchMetal(); + BOOL SearchVehicle(); + void CreatePower(); + CObject* SearchPower(); + +protected: + AutoEnergyPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastUpdateTime; + float m_lastParticule; + int m_partiSphere; +}; + + +#endif //_AUTOENERGY_H_ diff --git a/src/object/auto/autofactory.cpp b/src/object/auto/autofactory.cpp new file mode 100644 index 0000000..7fab2fb --- /dev/null +++ b/src/object/auto/autofactory.cpp @@ -0,0 +1,961 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "restext.h" +#include "global.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "light.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "interface.h" +#include "button.h" +#include "window.h" +#include "displaytext.h" +#include "robotmain.h" +#include "sound.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autofactory.h" + + + + +// Object's constructor. + +CAutoFactory::CAutoFactory(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + Init(); + m_type = OBJECT_MOBILEws; + m_phase = AFP_WAIT; // paused until the first Init () + m_channelSound = -1; +} + +// Object's destructor. + +CAutoFactory::~CAutoFactory() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoFactory::DeleteObject(BOOL bAll) +{ + CObject* fret; + CObject* vehicle; + + if ( !bAll ) + { + fret = SearchFret(); // transform metal? + if ( fret != 0 ) + { + fret->DeleteObject(); // destroys the metal + delete fret; + } + + vehicle = SearchVehicle(); + if ( vehicle != 0 ) + { + vehicle->DeleteObject(); // destroys the vehicle + delete vehicle; + } + } + + if ( m_channelSound != -1 ) + { + m_sound->FlushEnvelope(m_channelSound); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_channelSound = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoFactory::Init() +{ + m_phase = AFP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + m_time = 0.0f; + m_lastParticule = 0.0f; + + m_fretPos = m_object->RetPosition(0); + + CAuto::Init(); +} + + +// Management of an event. + +BOOL CAutoFactory::EventProcess(const Event &event) +{ + CObject* fret; + CObject* vehicle; + D3DMATRIX* mat; + CPhysics* physics; + D3DVECTOR pos, speed; + FPOINT dim; + ObjectType type; + float zoom, angle, prog; + int i; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + + if ( m_object->RetSelect() ) // factory selected? + { + if ( event.event == EVENT_UPDINTERFACE ) + { + CreateInterface(TRUE); + } + + type = OBJECT_NULL; + if ( event.event == EVENT_OBJECT_FACTORYwa ) type = OBJECT_MOBILEwa; + if ( event.event == EVENT_OBJECT_FACTORYta ) type = OBJECT_MOBILEta; + if ( event.event == EVENT_OBJECT_FACTORYfa ) type = OBJECT_MOBILEfa; + if ( event.event == EVENT_OBJECT_FACTORYia ) type = OBJECT_MOBILEia; + if ( event.event == EVENT_OBJECT_FACTORYws ) type = OBJECT_MOBILEws; + if ( event.event == EVENT_OBJECT_FACTORYts ) type = OBJECT_MOBILEts; + if ( event.event == EVENT_OBJECT_FACTORYfs ) type = OBJECT_MOBILEfs; + if ( event.event == EVENT_OBJECT_FACTORYis ) type = OBJECT_MOBILEis; + if ( event.event == EVENT_OBJECT_FACTORYwc ) type = OBJECT_MOBILEwc; + if ( event.event == EVENT_OBJECT_FACTORYtc ) type = OBJECT_MOBILEtc; + if ( event.event == EVENT_OBJECT_FACTORYfc ) type = OBJECT_MOBILEfc; + if ( event.event == EVENT_OBJECT_FACTORYic ) type = OBJECT_MOBILEic; + if ( event.event == EVENT_OBJECT_FACTORYwi ) type = OBJECT_MOBILEwi; + if ( event.event == EVENT_OBJECT_FACTORYti ) type = OBJECT_MOBILEti; + if ( event.event == EVENT_OBJECT_FACTORYfi ) type = OBJECT_MOBILEfi; + if ( event.event == EVENT_OBJECT_FACTORYii ) type = OBJECT_MOBILEii; + if ( event.event == EVENT_OBJECT_FACTORYrt ) type = OBJECT_MOBILErt; + if ( event.event == EVENT_OBJECT_FACTORYrc ) type = OBJECT_MOBILErc; + if ( event.event == EVENT_OBJECT_FACTORYrr ) type = OBJECT_MOBILErr; + if ( event.event == EVENT_OBJECT_FACTORYrs ) type = OBJECT_MOBILErs; + if ( event.event == EVENT_OBJECT_FACTORYsa ) type = OBJECT_MOBILEsa; + + if ( type != OBJECT_NULL ) + { + m_type = type; + + if ( m_phase != AFP_WAIT ) + { + return FALSE; + } + + fret = SearchFret(); // transform metal? + if ( fret == 0 ) + { + m_displayText->DisplayError(ERR_FACTORY_NULL, m_object); + return FALSE; + } + if ( NearestVehicle() ) + { + m_displayText->DisplayError(ERR_FACTORY_NEAR, m_object); + return FALSE; + } + + SetBusy(TRUE); + InitProgressTotal(3.0f+2.0f+15.0f+2.0f+3.0f); + UpdateInterface(); + + fret->SetLock(TRUE); // usable metal + SoundManip(3.0f, 1.0f, 0.5f); + + m_phase = AFP_CLOSE_S; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + return TRUE; + } + } + + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_speed; + EventProgress(event.rTime); + + if ( m_phase == AFP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + m_phase = AFP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == AFP_CLOSE_S ) + { + if ( m_progress < 1.0f ) + { + for ( i=0 ; i<9 ; i++ ) + { + zoom = 0.30f+(m_progress-0.5f+i/16.0f)*2.0f*0.70f; + if ( zoom < 0.30f ) zoom = 0.30f; + if ( zoom > 1.00f ) zoom = 1.00f; + m_object->SetZoomZ( 1+i, zoom); + m_object->SetZoomZ(10+i, zoom); + } + } + else + { + for ( i=0 ; i<9 ; i++ ) + { + m_object->SetZoomZ( 1+i, 1.0f); + m_object->SetZoomZ(10+i, 1.0f); + } + + SoundManip(2.0f, 1.0f, 1.2f); + + m_phase = AFP_CLOSE_T; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == AFP_CLOSE_T ) + { + if ( m_progress < 1.0f ) + { + for ( i=0 ; i<9 ; i++ ) + { + angle = -m_progress*(PI/2.0f)+PI/2.0f; + m_object->SetAngleZ( 1+i, angle); + m_object->SetAngleZ(10+i, -angle); + } + } + else + { + for ( i=0 ; i<9 ; i++ ) + { + m_object->SetAngleZ( 1+i, 0.0f); + m_object->SetAngleZ(10+i, 0.0f); + } + + m_channelSound = m_sound->Play(SOUND_FACTORY, m_object->RetPosition(0), 0.0f, 1.0f, TRUE); + m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 2.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 11.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 2.0f, SOPER_STOP); + + m_phase = AFP_BUILD; + m_progress = 0.0f; + m_speed = 1.0f/15.0f; + } + } + + if ( m_phase == AFP_BUILD ) + { + if ( m_progress == 0.0f ) + { + if ( !CreateVehicle() ) + { + fret = SearchFret(); // transform metal? + if ( fret != 0 ) + { + fret->SetLock(FALSE); // metal usable again + } + + if ( m_channelSound != -1 ) + { + m_sound->FlushEnvelope(m_channelSound); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_channelSound = -1; + } + + m_phase = AFP_OPEN_T; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + return TRUE; + } + } + + if ( m_progress < 1.0f ) + { + if ( m_type == OBJECT_MOBILErt || + m_type == OBJECT_MOBILErc || + m_type == OBJECT_MOBILErr || + m_type == OBJECT_MOBILErs ) + { + prog = 1.0f-m_progress*1.5f; + if ( prog < 0.0f ) prog = 0.0f; + } + else + { + prog = 1.0f-m_progress; + } + angle = powf(prog*10.0f, 2.0f)+m_object->RetAngleY(0); + + vehicle = SearchVehicle(); + if ( vehicle != 0 ) + { + vehicle->SetAngleY(0, angle+PI); + vehicle->SetZoom(0, m_progress); + } + + fret = SearchFret(); // transform metal? + if ( fret != 0 ) + { + fret->SetZoom(0, 1.0f-m_progress); + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + +#if 0 + pos = m_fretPos; + pos.x += (Rand()-0.5f)*20.0f; + pos.z += (Rand()-0.5f)*20.0f; + pos.y += 1.0f; + speed.x = (Rand()-0.5f)*12.0f; + speed.z = (Rand()-0.5f)*12.0f; + speed.y = Rand()*12.0f; + dim.x = Rand()*12.0f+10.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); +#else + mat = m_object->RetWorldMatrix(0); + pos = D3DVECTOR(-12.0f, 20.0f, -4.0f); // position of chimney + pos = Transform(*mat, pos); + pos.y += 2.0f; + pos.x += (Rand()-0.5f)*2.0f; + pos.z += (Rand()-0.5f)*2.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 6.0f+Rand()*6.0f; + dim.x = Rand()*1.5f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); +#endif + } + } + else + { + m_displayText->DisplayError(INFO_FACTORY, m_object); + SoundManip(2.0f, 1.0f, 1.2f); + + fret = SearchFret(); // transform metal? + if ( fret != 0 ) + { + fret->DeleteObject(); // removes the metal + delete fret; + } + + vehicle = SearchVehicle(); + if ( vehicle != 0 ) + { + physics = vehicle->RetPhysics(); + if ( physics != 0 ) + { + physics->SetFreeze(FALSE); // can move + } + + vehicle->SetLock(FALSE); // vehicle useable +//? vehicle->RetPhysics()->RetBrain()->StartTaskAdvance(16.0f); + vehicle->SetAngleY(0, m_object->RetAngleY(0)+PI); + vehicle->SetZoom(0, 1.0f); + } + + m_main->CreateShortcuts(); + + m_phase = AFP_OPEN_T; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == AFP_OPEN_T ) + { + if ( m_progress < 1.0f ) + { + for ( i=0 ; i<9 ; i++ ) + { + angle = -(1.0f-m_progress)*(PI/2.0f)+PI/2.0f; + m_object->SetAngleZ( 1+i, angle); + m_object->SetAngleZ(10+i, -angle); + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_fretPos; + pos.x += (Rand()-0.5f)*10.0f; + pos.z += (Rand()-0.5f)*10.0f; + pos.y += Rand()*10.0f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f); + } + } + else + { + for ( i=0 ; i<9 ; i++ ) + { + m_object->SetAngleZ( 1+i, PI/2.0f); + m_object->SetAngleZ(10+i, -PI/2.0f); + } + + SoundManip(3.0f, 1.0f, 0.5f); + + m_phase = AFP_OPEN_S; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + } + + if ( m_phase == AFP_OPEN_S ) + { + if ( m_progress < 1.0f ) + { + for ( i=0 ; i<9 ; i++ ) + { + zoom = 0.30f+((1.0f-m_progress)-0.5f+i/16.0f)*2.0f*0.70f; + if ( zoom < 0.30f ) zoom = 0.30f; + if ( zoom > 1.00f ) zoom = 1.00f; + m_object->SetZoomZ( 1+i, zoom); + m_object->SetZoomZ(10+i, zoom); + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_fretPos; + pos.x += (Rand()-0.5f)*10.0f; + pos.z += (Rand()-0.5f)*10.0f; + pos.y += Rand()*10.0f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f); + } + } + else + { + for ( i=0 ; i<9 ; i++ ) + { + m_object->SetZoomZ( 1+i, 0.30f); + m_object->SetZoomZ(10+i, 0.30f); + } + + SetBusy(FALSE); + UpdateInterface(); + + m_phase = AFP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + return TRUE; +} + + +// Saves all parameters of the controller. + +BOOL CAutoFactory::Write(char *line) +{ + char name[100]; + + if ( m_phase == AFP_WAIT ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller + +BOOL CAutoFactory::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoFactoryPhase)OpInt(line, "aPhase", AFP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + m_fretPos = m_object->RetPosition(0); + + return TRUE; +} + + +//Seeks the cargo. + +CObject* CAutoFactory::SearchFret() +{ + CObject* pObj; + D3DVECTOR oPos; + ObjectType type; + float dist; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_METAL ) continue; + if ( pObj->RetTruck() != 0 ) continue; + + oPos = pObj->RetPosition(0); + dist = Length(oPos, m_fretPos); + + if ( dist < 8.0f ) return pObj; + } + + return 0; +} + +// Search if a vehicle is too close. + +BOOL CAutoFactory::NearestVehicle() +{ + CObject* pObj; + D3DVECTOR cPos, oPos; + ObjectType type; + float oRadius, dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_HUMAN && + type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr && + type != OBJECT_MOTHER && + type != OBJECT_ANT && + type != OBJECT_SPIDER && + type != OBJECT_BEE && + type != OBJECT_WORM ) continue; + + if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; + dist = Length(oPos, cPos)-oRadius; + + if ( dist < 10.0f ) return TRUE; + } + + return FALSE; +} + + +// Creates a vehicle. + +BOOL CAutoFactory::CreateVehicle() +{ + CObject* vehicle; + D3DMATRIX* mat; + CPhysics* physics; + D3DVECTOR pos; + float angle; + char* name; + int i; + + angle = m_object->RetAngleY(0); + + mat = m_object->RetWorldMatrix(0); + if ( m_type == OBJECT_MOBILErt || + m_type == OBJECT_MOBILErc || + m_type == OBJECT_MOBILErr || + m_type == OBJECT_MOBILErs ) + { + pos = D3DVECTOR(2.0f, 0.0f, 0.0f); + } + else + { + pos = D3DVECTOR(4.0f, 0.0f, 0.0f); + } + pos = Transform(*mat, pos); + + vehicle = new CObject(m_iMan); + if ( !vehicle->CreateVehicle(pos, angle, m_type, -1.0f, FALSE, FALSE) ) + { + delete vehicle; + m_displayText->DisplayError(ERR_TOOMANY, m_object); + return FALSE; + } + vehicle->UpdateMapping(); + vehicle->SetLock(TRUE); // not usable + vehicle->SetRange(30.0f); + + physics = vehicle->RetPhysics(); + if ( physics != 0 ) + { + physics->SetFreeze(TRUE); // it doesn't move + } + + for ( i=0 ; i<10 ; i++ ) + { + name = m_main->RetNewScriptName(m_type, i); + if ( name == 0 ) break; + vehicle->ReadProgram(i, name); + } + + return TRUE; +} + +// Seeking the vehicle during manufacture. + +CObject* CAutoFactory::SearchVehicle() +{ + CObject* pObj; + D3DVECTOR oPos; + ObjectType type; + float dist; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetLock() ) continue; + + type = pObj->RetType(); + if ( type != m_type ) continue; + if ( pObj->RetTruck() != 0 ) continue; + + oPos = pObj->RetPosition(0); + dist = Length(oPos, m_fretPos); + + if ( dist < 8.0f ) return pObj; + } + + return 0; +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoFactory::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, dim, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + dim.x = 33.0f/640.0f; + dim.y = 33.0f/480.0f; + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = 0.0f; + pos.y = oy+sy*2.6f; + ddim.x = 138.0f/640.0f; + ddim.y = 222.0f/480.0f; + pw->CreateGroup(pos, ddim, 6, EVENT_WINDOW3); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*8.2f; + pw->CreateButton(pos, dim, 128+9, EVENT_OBJECT_FACTORYwa); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+10, EVENT_OBJECT_FACTORYta); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+11, EVENT_OBJECT_FACTORYfa); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+22, EVENT_OBJECT_FACTORYia); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*7.1f; + pw->CreateButton(pos, dim, 128+12, EVENT_OBJECT_FACTORYws); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+13, EVENT_OBJECT_FACTORYts); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+14, EVENT_OBJECT_FACTORYfs); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+24, EVENT_OBJECT_FACTORYis); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*6.0f; + pw->CreateButton(pos, dim, 128+15, EVENT_OBJECT_FACTORYwc); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+16, EVENT_OBJECT_FACTORYtc); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+17, EVENT_OBJECT_FACTORYfc); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+23, EVENT_OBJECT_FACTORYic); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*4.9f; + pw->CreateButton(pos, dim, 128+25, EVENT_OBJECT_FACTORYwi); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+26, EVENT_OBJECT_FACTORYti); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+27, EVENT_OBJECT_FACTORYfi); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+28, EVENT_OBJECT_FACTORYii); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*3.8f; + pw->CreateButton(pos, dim, 128+18, EVENT_OBJECT_FACTORYrt); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+19, EVENT_OBJECT_FACTORYrc); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+20, EVENT_OBJECT_FACTORYrr); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+29, EVENT_OBJECT_FACTORYrs); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*2.7f; + pw->CreateButton(pos, dim, 128+21, EVENT_OBJECT_FACTORYsa); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 101, EVENT_OBJECT_TYPE); + + UpdateInterface(); + return TRUE; +} + +// Updates the status of all interface buttons. + +void CAutoFactory::UpdateInterface() +{ + CWindow* pw; + + if ( !m_object->RetSelect() ) return; + + CAuto::UpdateInterface(); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + + UpdateButton(pw, EVENT_OBJECT_FACTORYwa, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYta, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYfa, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYia, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYws, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYts, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYfs, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYis, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYwc, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYtc, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYfc, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYic, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYwi, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYti, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYfi, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYii, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYrt, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYrc, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYrr, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYrs, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYsa, m_bBusy); +} + +// Updates the status of one interface button. + +void CAutoFactory::UpdateButton(CWindow *pw, EventMsg event, BOOL bBusy) +{ + BOOL bEnable = TRUE; + + EnableInterface(pw, event, !bBusy); + + if ( event == EVENT_OBJECT_FACTORYta ) + { + bEnable = g_researchDone&RESEARCH_TANK; + } + if ( event == EVENT_OBJECT_FACTORYfa ) + { + bEnable = g_researchDone&RESEARCH_FLY; + } + if ( event == EVENT_OBJECT_FACTORYia ) + { + bEnable = g_researchDone&RESEARCH_iPAW; + } + + if ( event == EVENT_OBJECT_FACTORYws ) + { + bEnable = g_researchDone&RESEARCH_SNIFFER; + } + if ( event == EVENT_OBJECT_FACTORYts ) + { + bEnable = ( (g_researchDone&RESEARCH_SNIFFER) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( event == EVENT_OBJECT_FACTORYfs ) + { + bEnable = ( (g_researchDone&RESEARCH_SNIFFER) && + (g_researchDone&RESEARCH_FLY) ); + } + if ( event == EVENT_OBJECT_FACTORYis ) + { + bEnable = ( (g_researchDone&RESEARCH_SNIFFER) && + (g_researchDone&RESEARCH_iPAW) ); + } + + if ( event == EVENT_OBJECT_FACTORYwc ) + { + bEnable = g_researchDone&RESEARCH_CANON; + } + if ( event == EVENT_OBJECT_FACTORYtc ) + { + bEnable = ( (g_researchDone&RESEARCH_CANON) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( event == EVENT_OBJECT_FACTORYfc ) + { + bEnable = ( (g_researchDone&RESEARCH_CANON) && + (g_researchDone&RESEARCH_FLY) ); + } + if ( event == EVENT_OBJECT_FACTORYic ) + { + bEnable = ( (g_researchDone&RESEARCH_CANON) && + (g_researchDone&RESEARCH_iPAW) ); + } + + if ( event == EVENT_OBJECT_FACTORYwi ) + { + bEnable = g_researchDone&RESEARCH_iGUN; + } + if ( event == EVENT_OBJECT_FACTORYti ) + { + bEnable = ( (g_researchDone&RESEARCH_iGUN) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( event == EVENT_OBJECT_FACTORYfi ) + { + bEnable = ( (g_researchDone&RESEARCH_iGUN) && + (g_researchDone&RESEARCH_FLY) ); + } + if ( event == EVENT_OBJECT_FACTORYii ) + { + bEnable = ( (g_researchDone&RESEARCH_iGUN) && + (g_researchDone&RESEARCH_iPAW) ); + } + + if ( event == EVENT_OBJECT_FACTORYrt ) + { + bEnable = ( (g_researchDone&RESEARCH_THUMP) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( event == EVENT_OBJECT_FACTORYrc ) + { + bEnable = ( (g_researchDone&RESEARCH_PHAZER) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( event == EVENT_OBJECT_FACTORYrr ) + { + bEnable = ( (g_researchDone&RESEARCH_RECYCLER) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( event == EVENT_OBJECT_FACTORYrs ) + { + bEnable = ( (g_researchDone&RESEARCH_SHIELD) && + (g_researchDone&RESEARCH_TANK) ); + } + + if ( event == EVENT_OBJECT_FACTORYsa ) + { + bEnable = g_researchDone&RESEARCH_SUBM; + } + + DeadInterface(pw, event, bEnable); +} + +// Plays the sound of the manipulator arm. + +void CAutoFactory::SoundManip(float time, float amplitude, float frequency) +{ + int i; + + i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f*frequency, TRUE); + m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, 0.1f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP); +} + diff --git a/src/object/auto/autofactory.h b/src/object/auto/autofactory.h new file mode 100644 index 0000000..bcfc43e --- /dev/null +++ b/src/object/auto/autofactory.h @@ -0,0 +1,85 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autofactory.h + +#ifndef _AUTOFACTORY_H_ +#define _AUTOFACTORY_H_ + + +#include "auto.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoFactoryPhase +{ + AFP_WAIT = 1, // expected metal + AFP_CLOSE_S = 2, // closes doors (shift) + AFP_CLOSE_T = 3, // closes doors (turn) + AFP_BUILD = 4, // building the vehicle + AFP_OPEN_T = 5, // opens the doors (turn) + AFP_OPEN_S = 6, // opens the doors (shift) + AFP_ADVANCE = 7, // advance at the door +}; + + + +class CAutoFactory : public CAuto +{ +public: + CAutoFactory(CInstanceManager* iMan, CObject* object); + ~CAutoFactory(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + + BOOL CreateInterface(BOOL bSelect); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + void UpdateInterface(); + void UpdateButton(CWindow *pw, EventMsg event, BOOL bBusy); + + CObject* SearchFret(); + BOOL NearestVehicle(); + BOOL CreateVehicle(); + CObject* SearchVehicle(); + + void SoundManip(float time, float amplitude, float frequency); + +protected: + AutoFactoryPhase m_phase; + float m_progress; + float m_speed; + float m_lastParticule; + D3DVECTOR m_fretPos; + int m_channelSound; +}; + + +#endif //_AUTOFACTORY_H_ diff --git a/src/object/auto/autoflag.cpp b/src/object/auto/autoflag.cpp new file mode 100644 index 0000000..5cd4bf2 --- /dev/null +++ b/src/object/auto/autoflag.cpp @@ -0,0 +1,178 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "auto.h" +#include "autoflag.h" + + + +#define ADJUST_ANGLE FALSE // TRUE -> adjusts the angles of the members + + +#if ADJUST_ANGLE +static float g_flag1 = 6.00f; +static float g_flag2 = 0.10f; +static float g_flag3 = 2.00f; +#endif + + +// Object's constructor. + +CAutoFlag::CAutoFlag(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + Init(); +} + +// Object's destructor. + +CAutoFlag::~CAutoFlag() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoFlag::DeleteObject(BOOL bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoFlag::Init() +{ + D3DVECTOR wind; + float angle; + + m_time = 0.0f; + m_param = 0; + m_progress = 0.0f; + + wind = m_terrain->RetWind(); + angle = RotateAngle(wind.x, -wind.z); + m_object->SetAngleY(0, angle); // directs the flag in the wind + + m_strong = Length(wind); +} + + +// Beginning of an action (1 = shakes). + +void CAutoFlag::Start(int param) +{ + if ( m_param == 0 ) + { + m_param = param; + m_progress = 0.0f; + } +} + + +// Management of an event. + +BOOL CAutoFlag::EventProcess(const Event &event) +{ + float angle; + int i; + + CAuto::EventProcess(event); + +#if ADJUST_ANGLE + if ( event.event == EVENT_KEYDOWN ) + { + if ( event.param == 'E' ) g_flag1 += 0.1f; + if ( event.param == 'D' ) g_flag1 -= 0.1f; + if ( event.param == 'R' ) g_flag2 += 0.1f; + if ( event.param == 'F' ) g_flag2 -= 0.1f; + if ( event.param == 'T' ) g_flag3 += 0.1f; + if ( event.param == 'G' ) g_flag3 -= 0.1f; + } +#endif + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + if ( m_param == 1 ) // shakes? + { + m_progress += event.rTime*(1.0f/2.0f); + if ( m_progress < 1.0f ) + { + angle = sinf(m_progress*PI*8.0f)*0.3f*(1.0f-m_progress); + m_object->SetAngleX(0, angle); + angle = sinf(m_progress*PI*4.0f)*0.3f*(1.0f-m_progress); + m_object->SetAngleZ(0, angle); + } + else + { + m_object->SetAngleX(0, 0.0f); + m_object->SetAngleZ(0, 0.0f); + m_param = 0; + m_progress = 0.0f; + } + } + + if ( m_strong == 0.0f ) return TRUE; // no wind? + + for ( i=0 ; i<4 ; i++ ) + { +#if ADJUST_ANGLE + angle = sinf(m_time*g_flag1+i*2.0f)*((i+g_flag3)*g_flag2); +#else + angle = sinf(m_time*6.0f+i*2.0f)*((i+2.0f)*0.1f); +#endif + m_object->SetAngleY(1+i, angle); + } + +#if ADJUST_ANGLE + char s[100]; + sprintf(s, "a=%.2f b=%.2f c=%.2f", g_flag1, g_flag2, g_flag3); + m_engine->SetInfoText(4, s); +#endif + return TRUE; +} + + +// Returns an error due the state of the automation + +Error CAutoFlag::RetError() +{ + return ERR_OK; +} + + diff --git a/src/object/auto/autoflag.h b/src/object/auto/autoflag.h new file mode 100644 index 0000000..4ef0fe4 --- /dev/null +++ b/src/object/auto/autoflag.h @@ -0,0 +1,58 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autoflag.h + +#ifndef _AUTOFLAG_H_ +#define _AUTOFLAG_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +class CAutoFlag : public CAuto +{ +public: + CAutoFlag(CInstanceManager* iMan, CObject* object); + ~CAutoFlag(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + void Start(int param); + BOOL EventProcess(const Event &event); + Error RetError(); + +protected: + +protected: + float m_strong; + int m_param; + float m_progress; +}; + + +#endif //_AUTOFLAG_H_ diff --git a/src/object/auto/autohuston.cpp b/src/object/auto/autohuston.cpp new file mode 100644 index 0000000..ad66702 --- /dev/null +++ b/src/object/auto/autohuston.cpp @@ -0,0 +1,315 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "interface.h" +#include "button.h" +#include "window.h" +#include "auto.h" +#include "autohuston.h" + + + + +// Object's constructor. + +CAutoHuston::CAutoHuston(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + D3DVECTOR pos; + int i; + + CAuto::CAuto(iMan, object); + + for ( i=0 ; iRetPosition(0); + m_lens[0].type = PARTISELR; + m_lens[1].type = PARTISELR; + m_lens[2].type = PARTISELR; + m_lens[3].type = PARTISELR; + m_lens[0].pos = pos+D3DVECTOR(0.0f+13.0f, 34.0f, 30.0f ); + m_lens[1].pos = pos+D3DVECTOR(0.0f-13.0f, 34.0f, 30.0f ); + m_lens[2].pos = pos+D3DVECTOR(0.0f , 34.0f, 30.0f+13.0f); + m_lens[3].pos = pos+D3DVECTOR(0.0f , 34.0f, 30.0f-13.0f); + m_lens[0].dim = 4.0f; + m_lens[1].dim = 4.0f; + m_lens[2].dim = 4.0f; + m_lens[3].dim = 4.0f; + m_lens[0].total = 1.0f; + m_lens[1].total = 1.0f; + m_lens[2].total = 1.0f; + m_lens[3].total = 1.0f; + m_lens[0].off = 0.4f; + m_lens[1].off = 0.4f; + m_lens[2].off = 0.4f; + m_lens[3].off = 0.4f; + + // Part under the radar. + i = 4; + m_lens[i].type = PARTISELR; + m_lens[i].pos = pos+D3DVECTOR(-7.0f, 9.9f, 40.1f); + m_lens[i].dim = 1.8f; + m_lens[i].total = 0.4f; + m_lens[i].off = 0.2f; + i ++; + + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+D3DVECTOR(-7.0f, 7.2f, 34.8f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 0.7f; + m_lens[i].off = 0.3f; + i ++; + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+D3DVECTOR(-7.0f, 6.5f, 34.3f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 0.7f; + m_lens[i].off = 0.3f; + i ++; + m_lens[i].type = PARTISELR; + m_lens[i].pos = pos+D3DVECTOR(-7.0f, 6.5f, 33.4f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 0.0f; + m_lens[i].off = 0.0f; + i ++; + m_lens[i].type = PARTISELR; + m_lens[i].pos = pos+D3DVECTOR(-7.0f, 6.5f, 33.0f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 1.0f; + m_lens[i].off = 0.5f; + i ++; + + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+D3DVECTOR(-7.0f, 8.5f, 14.0f); + m_lens[i].dim = 1.2f; + m_lens[i].total = 0.8f; + m_lens[i].off = 0.2f; + i ++; + + m_lens[i].type = PARTISELR; + m_lens[i].pos = pos+D3DVECTOR(4.0f, 6.0f, 8.6f); + m_lens[i].dim = 1.0f; + m_lens[i].total = 0.9f; + m_lens[i].off = 0.7f; + i ++; + + // Part with three windows. + m_lens[i].type = PARTISELR; + m_lens[i].pos = pos+D3DVECTOR(-7.0f, 9.9f, -19.9f); + m_lens[i].dim = 1.0f; + m_lens[i].total = 0.6f; + m_lens[i].off = 0.3f; + i ++; + + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+D3DVECTOR(-7.0f, 7.2f, 34.8f-60.0f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 0.7f; + m_lens[i].off = 0.3f; + i ++; + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+D3DVECTOR(-7.0f, 6.5f, 34.3f-60.0f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 0.0f; + m_lens[i].off = 0.0f; + i ++; + m_lens[i].type = PARTISELR; + m_lens[i].pos = pos+D3DVECTOR(-7.0f, 6.5f, 33.4f-60.0f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 0.6f; + m_lens[i].off = 0.4f; + i ++; + m_lens[i].type = PARTISELR; + m_lens[i].pos = pos+D3DVECTOR(-7.0f, 6.5f, 33.0f-60.0f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 0.8f; + m_lens[i].off = 0.2f; + i ++; + + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+D3DVECTOR(-6.5f, 13.5f, -37.0f); + m_lens[i].dim = 1.0f; + m_lens[i].total = 0.0f; + m_lens[i].off = 0.0f; + i ++; + + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+D3DVECTOR(-7.0f, 12.2f, -39.8f); + m_lens[i].dim = 1.8f; + m_lens[i].total = 1.5f; + m_lens[i].off = 0.5f; + i ++; + + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+D3DVECTOR(-7.0f, 8.5f, -47.0f); + m_lens[i].dim = 0.6f; + m_lens[i].total = 0.7f; + m_lens[i].off = 0.5f; + i ++; + + m_lensTotal = i; + + Init(); +} + +// Object's destructor. + +CAutoHuston::~CAutoHuston() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoHuston::DeleteObject(BOOL bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoHuston::Init() +{ + m_time = 0.0f; + + m_progress = 0.0f; + m_speed = 1.0f/2.0f; +} + + +// Start the object. + +void CAutoHuston::Start(int param) +{ +} + + +// Management of an event. + +BOOL CAutoHuston::EventProcess(const Event &event) +{ + D3DVECTOR speed; + FPOINT dim; + float angle; + int i; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + + angle = -m_time*1.0f; + m_object->SetAngleY(1, angle); // rotates the radar + angle = sinf(m_time*4.0f)*0.3f; + m_object->SetAngleX(2, angle); + + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_speed; + + // Flashes the keys. + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + for ( i=0 ; iDeleteParticule(m_lens[i].parti); + m_lens[i].parti = -1; + } + } + else + { + if ( m_lens[i].parti == -1 ) + { + dim.x = m_lens[i].dim; + dim.y = dim.x; + m_lens[i].parti = m_particule->CreateParticule(m_lens[i].pos, speed, dim, m_lens[i].type, 1.0f, 0.0f, 0.0f); + } + } + } + + return TRUE; +} + +// Stops the controller. + +BOOL CAutoHuston::Abort() +{ + return TRUE; +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoHuston::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 115, EVENT_OBJECT_TYPE); + + return TRUE; +} + + +// Returns an error due to state of the automation. + +Error CAutoHuston::RetError() +{ + return ERR_OK; +} + diff --git a/src/object/auto/autohuston.h b/src/object/auto/autohuston.h new file mode 100644 index 0000000..0611eb2 --- /dev/null +++ b/src/object/auto/autohuston.h @@ -0,0 +1,77 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autohuston.h + +#ifndef _AUTOHUSTON_H_ +#define _AUTOHUSTON_H_ + + +#include "auto.h" +#include "particule.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +typedef struct +{ + int parti; + ParticuleType type; + D3DVECTOR pos; + float dim; + float total; + float off; +} +HustonLens; + + +#define HUSTONMAXLENS 20 + + +class CAutoHuston : public CAuto +{ +public: + CAutoHuston(CInstanceManager* iMan, CObject* object); + ~CAutoHuston(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + void Start(int param); + BOOL EventProcess(const Event &event); + BOOL Abort(); + Error RetError(); + + BOOL CreateInterface(BOOL bSelect); + +protected: + +protected: + float m_progress; + float m_speed; + HustonLens m_lens[HUSTONMAXLENS]; + int m_lensTotal; +}; + + +#endif //_AUTOHUSTON_H_ diff --git a/src/object/auto/autoinfo.cpp b/src/object/auto/autoinfo.cpp new file mode 100644 index 0000000..e9708e0 --- /dev/null +++ b/src/object/auto/autoinfo.cpp @@ -0,0 +1,537 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "light.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "interface.h" +#include "button.h" +#include "list.h" +#include "window.h" +#include "sound.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autoinfo.h" + + + + +// Object's constructor. + +CAutoInfo::CAutoInfo(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + Init(); +} + +// Object's destructor. + +CAutoInfo::~CAutoInfo() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoInfo::DeleteObject(BOOL bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoInfo::Init() +{ + m_phase = AIP_WAIT; + m_time = 0.0f; + m_timeVirus = 0.0f; + m_bLastVirus = FALSE; + + CAuto::Init(); +} + + +// Start a emission. + +void CAutoInfo::Start(int param) +{ + D3DVECTOR pos, speed; + FPOINT dim; + + if ( param == 0 ) // instruction "receive" ? + { + m_phase = AIP_EMETTE; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + else if ( param == 2 ) // instruction "send" ? + { + m_phase = AIP_RECEIVE; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + else + { + m_phase = AIP_ERROR; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + + m_lastParticule = 0; + m_goal = m_object->RetPosition(0); + + if ( m_phase == AIP_EMETTE ) + { + pos = m_goal; + pos.y += 9.5f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 30.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISPHERE4, 1.5f, 0.0f, 0.0f); + + m_sound->Play(SOUND_LABO, pos, 1.0f, 2.0f); + } + if ( m_phase == AIP_RECEIVE ) + { + pos = m_goal; + pos.y += 9.5f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 50.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISPHERE6, 1.5f, 0.0f, 0.0f); + + m_sound->Play(SOUND_LABO, pos, 1.0f, 2.0f); + } + if ( m_phase == AIP_ERROR ) + { + m_sound->Play(SOUND_GGG, pos, 1.0f, 0.5f); + } +} + + +// Management of an event. + +BOOL CAutoInfo::EventProcess(const Event &event) +{ + D3DVECTOR pos, speed; + FPOINT dim; + float duration, angle, rTime; + int i; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Rand()*0.3f; + + angle = m_object->RetAngleY(1); + angle += Rand()*0.3f; + m_object->SetAngleY(1, angle); + + m_object->SetAngleX(2, (Rand()-0.5f)*0.3f); + m_object->SetAngleX(4, (Rand()-0.5f)*0.3f); + m_object->SetAngleX(6, (Rand()-0.5f)*0.3f); + + m_object->SetAngleZ(2, (Rand()-0.5f)*0.3f); + m_object->SetAngleZ(4, (Rand()-0.5f)*0.3f); + m_object->SetAngleZ(6, (Rand()-0.5f)*0.3f); + + UpdateListVirus(); + } + m_bLastVirus = TRUE; + return TRUE; + } + else + { + if ( m_bLastVirus ) + { + m_bLastVirus = FALSE; + UpdateList(); // normally returns the list + } + else + { + if ( m_object->RetInfoUpdate() ) + { + UpdateList(); // updates the list + } + } + } + + UpdateInterface(event.rTime); + + rTime = event.rTime; + + if ( m_phase == AIP_EMETTE ) // instruction "receive" ? + { + if ( m_progress < 0.5f && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + for ( i=0 ; i<4 ; i++ ) + { + pos = m_goal; + pos.y += 9.5f; + speed.x = (Rand()-0.5f)*50.0f; + speed.z = (Rand()-0.5f)*50.0f; + speed.y = (Rand()-0.5f)*50.0f; + speed *= 0.5f+m_progress*0.5f; + dim.x = 0.6f; + dim.y = dim.x; + duration = Rand()*0.5f+0.5f; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK6, + duration, 0.0f, + duration*0.9f, 0.7f); + } + } + + if ( m_progress < 1.0f ) + { + m_progress += rTime*m_speed; + + m_object->SetAngleZ(2, m_progress*2.0f*PI); + m_object->SetAngleZ(4, m_progress*2.0f*PI); + m_object->SetAngleZ(6, m_progress*2.0f*PI); + } + else + { + m_phase = AIP_WAIT; + + m_object->SetAngleX(2, 0.0f); + m_object->SetAngleX(4, 0.0f); + m_object->SetAngleX(6, 0.0f); + + m_object->SetAngleZ(2, 0.0f); + m_object->SetAngleZ(4, 0.0f); + m_object->SetAngleZ(6, 0.0f); + } + } + + if ( m_phase == AIP_RECEIVE ) // instruction "send" ? + { + if ( m_progress < 0.5f && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + for ( i=0 ; i<4 ; i++ ) + { + pos = m_goal; + pos.y += 9.5f; + speed = pos; + pos.x += (Rand()-0.5f)*40.0f; + pos.y += (Rand()-0.5f)*40.0f; + pos.z += (Rand()-0.5f)*40.0f; + speed = (speed-pos)*1.0f; +//? speed *= 0.5f+m_progress*0.5f; + dim.x = 0.6f; + dim.y = dim.x; + duration = Rand()*0.5f+0.5f; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK6, + duration, 0.0f, + duration*0.9f, 0.7f); + } + } + + if ( m_progress < 1.0f ) + { + m_progress += rTime*m_speed; + + m_object->SetAngleZ(2, m_progress*2.0f*PI); + m_object->SetAngleZ(4, m_progress*2.0f*PI); + m_object->SetAngleZ(6, m_progress*2.0f*PI); + } + else + { + m_phase = AIP_WAIT; + + m_object->SetAngleX(2, 0.0f); + m_object->SetAngleX(4, 0.0f); + m_object->SetAngleX(6, 0.0f); + + m_object->SetAngleZ(2, 0.0f); + m_object->SetAngleZ(4, 0.0f); + m_object->SetAngleZ(6, 0.0f); + } + } + + if ( m_phase == AIP_ERROR ) + { + if ( m_progress < 0.5f && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_goal; + speed.x = (Rand()-0.5f)*5.0f; + speed.z = (Rand()-0.5f)*5.0f; + speed.y = 5.0f+Rand()*5.0f; + dim.x = 5.0f+Rand()*5.0f; + dim.y = dim.x; + duration = Rand()*0.5f+0.5f; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 4.0f); + } + + if ( m_progress < 1.0f ) + { + m_progress += rTime*m_speed; + rTime = 0.0f; // stops the rotation + + if ( m_progress < 0.5f ) + { + angle = m_progress/0.5f; + } + else + { + angle = 1.0f-(m_progress-0.5f)/0.5f; + } + m_object->SetAngleX(2, angle*0.5f); + m_object->SetAngleX(4, angle*0.5f); + m_object->SetAngleX(6, angle*0.5f); + + m_object->SetAngleZ(2, (Rand()-0.5f)*0.2f); + m_object->SetAngleZ(4, (Rand()-0.5f)*0.2f); + m_object->SetAngleZ(6, (Rand()-0.5f)*0.2f); + } + else + { + m_phase = AIP_WAIT; + + m_object->SetAngleX(2, 0.0f); + m_object->SetAngleX(4, 0.0f); + m_object->SetAngleX(6, 0.0f); + + m_object->SetAngleZ(2, 0.0f); + m_object->SetAngleZ(4, 0.0f); + m_object->SetAngleZ(6, 0.0f); + } + } + + angle = m_object->RetAngleY(1); + angle += rTime*0.5f; + m_object->SetAngleY(1, angle); + + m_object->SetAngleX(3, sinf(m_time*6.0f+PI*0.0f/3.0f)*0.3f); + m_object->SetAngleX(5, sinf(m_time*6.0f+PI*2.0f/3.0f)*0.3f); + m_object->SetAngleX(7, sinf(m_time*6.0f+PI*4.0f/3.0f)*0.3f); + + return TRUE; +} + + +// Returns an error due the state of the automation. + +Error CAutoInfo::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + return ERR_OK; +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoInfo::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + CList* pl; + FPOINT pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*7.0f; + pos.y = oy+sy*0.0f; + ddim.x = 160.0f/640.0f; + ddim.y = 66.0f/480.0f; + pl = pw->CreateList(pos, ddim, 1, EVENT_OBJECT_GINFO, 1.10f); + pl->SetSelectCap(FALSE); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 112, EVENT_OBJECT_TYPE); + + UpdateList(); + return TRUE; +} + +// Updates the state of all buttons on the interface, +// following the time that elapses ... + +void CAutoInfo::UpdateInterface(float rTime) +{ + CAuto::UpdateInterface(rTime); +} + + +// Updates the contents of the list. + +void CAutoInfo::UpdateList() +{ + CWindow* pw; + CList* pl; + Info info; + int total, i; + char text[100]; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pl = (CList*)pw->SearchControl(EVENT_OBJECT_GINFO); + if ( pl == 0 ) return; + + pl->Flush(); + total = m_object->RetInfoTotal(); + if ( total == 0 ) + { + pl->ClearState(STATE_ENABLE); + } + else + { + pl->SetState(STATE_ENABLE); + + for ( i=0 ; iRetInfo(i); + sprintf(text, "%s = %.2f", info.name, info.value); + pl->SetName(i, text); + } + } + + m_object->SetInfoUpdate(FALSE); +} + +// Updates the content of contaminating the list. + +void CAutoInfo::UpdateListVirus() +{ + CWindow* pw; + CList* pl; + int i, j, max; + char text[100]; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pl = (CList*)pw->SearchControl(EVENT_OBJECT_GINFO); + if ( pl == 0 ) return; + + pl->SetState(STATE_ENABLE); + + pl->Flush(); + for ( i=0 ; i<4 ; i++ ) + { + max = (int)(2.0f+Rand()*10.0f); + for ( j=0 ; jSetName(i, text); + } +} + + +// Saves all parameters of the controller. + +BOOL CAutoInfo::Write(char *line) +{ + char name[100]; + + if ( m_phase == AIP_WAIT ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller. + +BOOL CAutoInfo::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoInfoPhase)OpInt(line, "aPhase", AIP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return TRUE; +} + + diff --git a/src/object/auto/autoinfo.h b/src/object/auto/autoinfo.h new file mode 100644 index 0000000..28fc9ab --- /dev/null +++ b/src/object/auto/autoinfo.h @@ -0,0 +1,80 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autoinfo.h + +#ifndef _AUTOINFO_H_ +#define _AUTOINFO_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoInfoPhase +{ + AIP_WAIT = 1, + AIP_EMETTE = 2, + AIP_RECEIVE = 3, + AIP_ERROR = 4, +}; + + + +class CAutoInfo : public CAuto +{ +public: + CAutoInfo(CInstanceManager* iMan, CObject* object); + ~CAutoInfo(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + void Start(int param); + BOOL EventProcess(const Event &event); + Error RetError(); + + BOOL CreateInterface(BOOL bSelect); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + void UpdateInterface(float rTime); + void UpdateList(); + void UpdateListVirus(); + +protected: + AutoInfoPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + D3DVECTOR m_goal; + BOOL m_bLastVirus; +}; + + +#endif //_AUTOINFO_H_ diff --git a/src/object/auto/autojostle.cpp b/src/object/auto/autojostle.cpp new file mode 100644 index 0000000..1bcd11e --- /dev/null +++ b/src/object/auto/autojostle.cpp @@ -0,0 +1,167 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "light.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "interface.h" +#include "button.h" +#include "list.h" +#include "window.h" +#include "sound.h" +#include "auto.h" +#include "autojostle.h" + + + + +// Object's constructor. + +CAutoJostle::CAutoJostle(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + Init(); +} + +// Object's destructor. + +CAutoJostle::~CAutoJostle() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoJostle::DeleteObject(BOOL bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoJostle::Init() +{ + m_time = 0.0f; + m_error = ERR_CONTINUE; + + CAuto::Init(); +} + + +// Start an emission. + +void CAutoJostle::Start(int param, float force) +{ + ObjectType type; + + if ( force < 0.0f ) force = 0.0f; + if ( force > 1.0f ) force = 1.0f; + + m_force = force; + m_progress = 0.0f; + m_speed = 1.0f/(0.5f+force*1.0f); // 0.5 .. 1.5 + m_time = 0.0f; + m_error = ERR_CONTINUE; + + type = m_object->RetType(); + if ( type >= OBJECT_PLANT5 && + type <= OBJECT_PLANT7 ) // clover? + { + m_force *= 3.0f; + } +} + + +// Management of an event. + +BOOL CAutoJostle::EventProcess(const Event &event) +{ + D3DVECTOR dir; + float factor, angle, zoom; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + if ( m_progress < 1.0f ) + { + m_progress += event.rTime*m_speed; + + if ( m_progress < 0.5f ) + { + factor = m_progress/0.5f; + } + else + { + factor = 2.0f-m_progress/0.5f; + } + factor *= m_force; + + dir.x = sinf(m_progress*PI*4.0f); + dir.z = cosf(m_progress*PI*4.0f); + + angle = sinf(m_time*10.0f)*factor*0.04f; + m_object->SetAngleX(0, angle*dir.z); + m_object->SetAngleZ(0, angle*dir.x); + + zoom = 1.0f+sinf(m_time*8.0f)*factor*0.06f; + m_object->SetZoomX(0, zoom); + zoom = 1.0f+sinf(m_time*5.0f)*factor*0.06f; + m_object->SetZoomY(0, zoom); + zoom = 1.0f+sinf(m_time*7.0f)*factor*0.06f; + m_object->SetZoomZ(0, zoom); + } + else + { + m_object->SetAngleX(0, 0.0f); + m_object->SetAngleZ(0, 0.0f); + m_object->SetZoom(0, D3DVECTOR(1.0f, 1.0f, 1.0f)); + m_error = ERR_STOP; + } + + return TRUE; +} + + +// Indicates whether the controller has completed its activity. + +Error CAutoJostle::IsEnded() +{ + return m_error; +} + + diff --git a/src/object/auto/autojostle.h b/src/object/auto/autojostle.h new file mode 100644 index 0000000..18027a0 --- /dev/null +++ b/src/object/auto/autojostle.h @@ -0,0 +1,60 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autojostle.h + +#ifndef _AUTOJOSTLE_H_ +#define _AUTOJOSTLE_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +class CAutoJostle : public CAuto +{ +public: + CAutoJostle(CInstanceManager* iMan, CObject* object); + ~CAutoJostle(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + void Start(int param, float force); + BOOL EventProcess(const Event &event); + Error IsEnded(); + +protected: + +protected: + float m_force; + float m_progress; + float m_speed; + float m_lastParticule; + Error m_error; +}; + + +#endif //_AUTOJOSTLE_H_ diff --git a/src/object/auto/autokid.cpp b/src/object/auto/autokid.cpp new file mode 100644 index 0000000..98c0f45 --- /dev/null +++ b/src/object/auto/autokid.cpp @@ -0,0 +1,222 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "terrain.h" +#include "water.h" +#include "camera.h" +#include "object.h" +#include "sound.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autokid.h" + + + + +// Object's constructor. + +CAutoKid::CAutoKid(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + m_soundChannel = -1; + Init(); +} + +// Object's constructor. + +CAutoKid::~CAutoKid() +{ + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoKid::DeleteObject(BOOL bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoKid::Init() +{ + D3DVECTOR pos; + + m_speed = 1.0f/1.0f; + m_progress = 0.0f; + m_lastParticule = 0.0f; + + if ( m_type == OBJECT_TEEN36 ) // trunk ? + { + pos = m_object->RetPosition(0); + m_speed = 1.0f/(1.0f+(Mod(pos.x/10.0f-0.5f, 1.0f)*0.2f)); + m_progress = Mod(pos.x/10.0f, 1.0f); + } + + if ( m_type == OBJECT_TEEN37 ) // boat? + { + pos = m_object->RetPosition(0); + m_speed = 1.0f/(1.0f+(Mod(pos.x/10.0f-0.5f, 1.0f)*0.2f))*2.5f; + m_progress = Mod(pos.x/10.0f, 1.0f); + } + + if ( m_type == OBJECT_TEEN38 ) // fan? + { + if ( m_soundChannel == -1 ) + { +//? m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 1.0f, 0.5f, TRUE); + m_bSilent = FALSE; + } + } +} + + +// Management of an event. + +BOOL CAutoKid::EventProcess(const Event &event) +{ + D3DVECTOR vib, pos, speed; + FPOINT dim; + + CAuto::EventProcess(event); + + if ( m_soundChannel != -1 ) + { + if ( m_engine->RetPause() ) + { + if ( !m_bSilent ) + { + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.1f, SOPER_CONTINUE); + m_bSilent = TRUE; + } + } + else + { + if ( m_bSilent ) + { + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 0.1f, SOPER_CONTINUE); + m_bSilent = FALSE; + } + } + } + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_speed; + + if ( m_type == OBJECT_TEEN36 ) // trunk? + { + vib.x = 0.0f; + vib.y = sinf(m_progress)*1.0f; + vib.z = 0.0f; + m_object->SetLinVibration(vib); + + vib.x = 0.0f; + vib.y = 0.0f; + vib.z = sinf(m_progress*0.5f)*0.05f; + m_object->SetCirVibration(vib); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.15f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.y = m_water->RetLevel()+1.0f; + pos.x += (Rand()-0.5f)*50.0f; + pos.z += (Rand()-0.5f)*50.0f; + speed.y = 0.0f; + speed.x = 0.0f; + speed.z = 0.0f; + dim.x = 50.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFLIC, 3.0f, 0.0f, 0.0f); + } + } + + if ( m_type == OBJECT_TEEN37 ) // boat? + { + vib.x = 0.0f; + vib.y = sinf(m_progress)*1.0f; + vib.z = 0.0f; + m_object->SetLinVibration(vib); + + vib.x = 0.0f; + vib.y = 0.0f; + vib.z = sinf(m_progress*0.5f)*0.15f; + m_object->SetCirVibration(vib); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.15f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.y = m_water->RetLevel()+1.0f; + pos.x += (Rand()-0.5f)*20.0f; + pos.z += (Rand()-0.5f)*20.0f; + speed.y = 0.0f; + speed.x = 0.0f; + speed.z = 0.0f; + dim.x = 20.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFLIC, 3.0f, 0.0f, 0.0f); + } + } + + if ( m_type == OBJECT_TEEN38 ) // fan? + { + m_object->SetAngleY(1, sinf(m_progress*0.6f)*0.4f); + m_object->SetAngleX(2, m_progress*5.0f); + } + + return TRUE; +} + + +// Returns an error due the state of the automation. + +Error CAutoKid::RetError() +{ + return ERR_OK; +} + + diff --git a/src/object/auto/autokid.h b/src/object/auto/autokid.h new file mode 100644 index 0000000..dc5305b --- /dev/null +++ b/src/object/auto/autokid.h @@ -0,0 +1,59 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autokid.h + +#ifndef _AUTOKID_H_ +#define _AUTOKID_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +class CAutoKid : public CAuto +{ +public: + CAutoKid(CInstanceManager* iMan, CObject* object); + ~CAutoKid(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + +protected: + +protected: + float m_speed; + float m_progress; + float m_lastParticule; + int m_soundChannel; + BOOL m_bSilent; +}; + + +#endif //_AUTOKID_H_ diff --git a/src/object/auto/autolabo.cpp b/src/object/auto/autolabo.cpp new file mode 100644 index 0000000..ce6214c --- /dev/null +++ b/src/object/auto/autolabo.cpp @@ -0,0 +1,629 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "global.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "light.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "interface.h" +#include "button.h" +#include "window.h" +#include "displaytext.h" +#include "sound.h" +#include "robotmain.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autolabo.h" + + + +#define LABO_DELAY 20.0f // duration of the analysis + + + + +// Object's constructor. + +CAutoLabo::CAutoLabo(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + int i; + + CAuto::CAuto(iMan, object); + + for ( i=0 ; i<3 ; i++ ) + { + m_partiRank[i] = -1; + } + m_partiSphere = -1; + + m_soundChannel = -1; + Init(); +} + +// Object's destructor. + +CAutoLabo::~CAutoLabo() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoLabo::DeleteObject(BOOL bAll) +{ + int i; + + for ( i=0 ; i<3 ; i++ ) + { + if ( m_partiRank[i] != -1 ) + { + m_particule->DeleteParticule(m_partiRank[i]); + m_partiRank[i] = -1; + } + } + + if ( m_partiSphere != -1 ) + { + m_particule->DeleteParticule(m_partiSphere); + m_partiSphere = -1; + } + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoLabo::Init() +{ + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + + m_phase = ALAP_WAIT; // waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + CAuto::Init(); +} + + +// Management of an event. + +BOOL CAutoLabo::EventProcess(const Event &event) +{ + CObject* power; + D3DVECTOR pos, goal, speed; + FPOINT dim, rot; + float angle; + int i; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + + if ( event.event == EVENT_UPDINTERFACE ) + { + if ( m_object->RetSelect() ) CreateInterface(TRUE); + } + + if ( m_object->RetSelect() && // center selected? + (event.event == EVENT_OBJECT_RiPAW || + event.event == EVENT_OBJECT_RiGUN) ) + { + if ( m_phase != ALAP_WAIT ) + { + return FALSE; + } + + m_research = event.event; + + if ( TestResearch(m_research) ) + { + m_displayText->DisplayError(ERR_LABO_ALREADY, m_object); + return FALSE; + } + + power = m_object->RetPower(); + if ( power == 0 ) + { + m_displayText->DisplayError(ERR_LABO_NULL, m_object); + return FALSE; + } + if ( power->RetType() != OBJECT_BULLET ) + { + m_displayText->DisplayError(ERR_LABO_BAD, m_object); + return FALSE; + } + + SetBusy(TRUE); + InitProgressTotal(1.0f+1.5f+1.5f+LABO_DELAY+1.5f+1.5f+1.0f); + UpdateInterface(); + + power->SetLock(TRUE); // ball longer usable + + SoundManip(1.0f, 1.0f, 1.0f); + m_phase = ALAP_OPEN1; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + return TRUE; + } + + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Rand()*0.3f; + } + return TRUE; + } + + EventProgress(event.rTime); + + if ( m_phase == ALAP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + m_phase = ALAP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == ALAP_OPEN1 ) + { + if ( m_progress < 1.0f ) + { + angle = 80.0f-(35.0f*m_progress); + m_object->SetAngleZ(3, angle*PI/180.0f); + m_object->SetAngleZ(4, angle*PI/180.0f); + m_object->SetAngleZ(5, angle*PI/180.0f); + } + else + { + m_object->SetAngleZ(3, 45.0f*PI/180.0f); + m_object->SetAngleZ(4, 45.0f*PI/180.0f); + m_object->SetAngleZ(5, 45.0f*PI/180.0f); + + SoundManip(1.5f, 1.0f, 0.7f); + m_phase = ALAP_OPEN2; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + + if ( m_phase == ALAP_OPEN2 ) + { + if ( m_progress < 1.0f ) + { + pos.x = -9.0f; + pos.y = 3.0f+m_progress*10.0f; + pos.z = 0.0f; + m_object->SetPosition(1, pos); + } + else + { + m_object->SetPosition(1, D3DVECTOR(-9.0f, 13.0f, 0.0f)); + + SoundManip(1.5f, 1.0f, 0.5f); + m_phase = ALAP_OPEN3; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + + if ( m_phase == ALAP_OPEN3 ) + { + if ( m_progress < 1.0f ) + { + angle = (1.0f-m_progress)*PI/2.0f; + m_object->SetAngleZ(1, angle); + } + else + { + m_object->SetAngleZ(1, 0.0f); + + goal = m_object->RetPosition(0); + goal.y += 3.0f; + pos = goal; + pos.x -= 4.0f; + pos.y += 4.0f; + for ( i=0 ; i<3 ; i++ ) + { + m_partiRank[i] = m_particule->CreateRay(pos, goal, + PARTIRAY2, + FPOINT(2.9f, 2.9f), + LABO_DELAY); + } + + m_soundChannel = m_sound->Play(SOUND_LABO, m_object->RetPosition(0), 0.0f, 0.25f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.60f, 2.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 2.00f, 8.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.60f, 8.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.25f, 2.0f, SOPER_STOP); + + pos = m_object->RetPosition(0); + pos.y += 4.0f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 4.0f; + dim.y = dim.x; + m_partiSphere = m_particule->CreateParticule(pos, speed, dim, PARTISPHERE2, LABO_DELAY, 0.0f, 0.0f); + + m_phase = ALAP_ANALYSE; + m_progress = 0.0f; + m_speed = 1.0f/LABO_DELAY; + } + } + + if ( m_phase == ALAP_ANALYSE ) + { + if ( m_progress < 1.0f ) + { + power = m_object->RetPower(); + if ( power != 0 ) + { + power->SetZoom(0, 1.0f-m_progress); + } + + angle = m_object->RetAngleY(2); + if ( m_progress < 0.5f ) + { + angle -= event.rTime*m_progress*20.0f; + } + else + { + angle -= event.rTime*(20.0f-m_progress*20.0f); + } + m_object->SetAngleY(2, angle); // rotates the analyzer + + angle += m_object->RetAngleY(0); + for ( i=0 ; i<3 ; i++ ) + { + rot = RotatePoint(-angle, -4.0f); + pos = m_object->RetPosition(0); + pos.x += rot.x; + pos.z += rot.y; + pos.y += 3.0f+4.0f;; + m_particule->SetPosition(m_partiRank[i], pos); // adjusts ray + + angle += PI*2.0f/3.0f; + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + if ( m_progress > 0.25f && + m_progress < 0.80f ) + { + pos = m_object->RetPosition(0); + pos.y += 3.0f; + pos.x += (Rand()-0.5f)*2.0f; + pos.z += (Rand()-0.5f)*2.0f; + speed.y = Rand()*5.0f+5.0f; + speed.x = (Rand()-0.5f)*10.0f; + speed.z = (Rand()-0.5f)*10.0f; + dim.x = Rand()*0.4f*m_progress+1.0f; + dim.y = dim.x; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK2, + 2.0f+2.0f*m_progress, 10.0f, 1.5f, 1.4f); + } + } + } + else + { + SetResearch(m_research); // research done + + power = m_object->RetPower(); + if ( power != 0 ) + { + m_object->SetPower(0); + power->DeleteObject(); // destroys the ball + delete power; + } + + m_displayText->DisplayError(INFO_LABO, m_object); + + SoundManip(1.5f, 1.0f, 0.5f); + m_phase = ALAP_CLOSE1; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + + if ( m_phase == ALAP_CLOSE1 ) + { + if ( m_progress < 1.0f ) + { + angle = m_progress*PI/2.0f; + m_object->SetAngleZ(1, angle); + } + else + { + m_object->SetAngleZ(1, PI/2.0f); + + SoundManip(1.5f, 1.0f, 0.7f); + m_phase = ALAP_CLOSE2; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + + if ( m_phase == ALAP_CLOSE2 ) + { + if ( m_progress < 1.0f ) + { + pos.x = -9.0f; + pos.y = 3.0f+(1.0f-m_progress)*10.0f;; + pos.z = 0.0f; + m_object->SetPosition(1, pos); + } + else + { + m_object->SetPosition(1, D3DVECTOR(-9.0f, 3.0f, 0.0f)); + + SoundManip(1.0f, 1.0f, 1.0f); + m_phase = ALAP_CLOSE3; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ALAP_CLOSE3 ) + { + if ( m_progress < 1.0f ) + { + angle = 45.0f+(35.0f*m_progress); + m_object->SetAngleZ(3, angle*PI/180.0f); + m_object->SetAngleZ(4, angle*PI/180.0f); + m_object->SetAngleZ(5, angle*PI/180.0f); + } + else + { + m_object->SetAngleZ(3, 80.0f*PI/180.0f); + m_object->SetAngleZ(4, 80.0f*PI/180.0f); + m_object->SetAngleZ(5, 80.0f*PI/180.0f); + + SetBusy(FALSE); + UpdateInterface(); + + m_phase = ALAP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + return TRUE; +} + + +// Returns an error due the state of the automation. + +Error CAutoLabo::RetError() +{ + CObject* pObj; + ObjectType type; + + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + pObj = m_object->RetPower(); + if ( pObj == 0 ) return ERR_LABO_NULL; + type = pObj->RetType(); + if ( type != OBJECT_BULLET ) return ERR_LABO_BAD; + + return ERR_OK; +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoLabo::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, dim, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + dim.x = 33.0f/640.0f; + dim.y = 33.0f/480.0f; + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*7.0f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 64+45, EVENT_OBJECT_RiPAW); + + pos.x = ox+sx*8.0f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 64+46, EVENT_OBJECT_RiGUN); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 111, EVENT_OBJECT_TYPE); + + UpdateInterface(); + + return TRUE; +} + +// Updates the status of all interface buttons. + +void CAutoLabo::UpdateInterface() +{ + CWindow* pw; + + if ( !m_object->RetSelect() ) return; + + CAuto::UpdateInterface(); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + DeadInterface(pw, EVENT_OBJECT_RiPAW, g_researchEnable&RESEARCH_iPAW); + DeadInterface(pw, EVENT_OBJECT_RiGUN, g_researchEnable&RESEARCH_iGUN); + + OkayButton(pw, EVENT_OBJECT_RiPAW); + OkayButton(pw, EVENT_OBJECT_RiGUN); + + VisibleInterface(pw, EVENT_OBJECT_RiPAW, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RiGUN, !m_bBusy); +} + +// Indicates the research conducted for a button. + +void CAutoLabo::OkayButton(CWindow *pw, EventMsg event) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + control->SetState(STATE_OKAY, TestResearch(event)); +} + + +// Test whether a search has already been done. + +BOOL CAutoLabo::TestResearch(EventMsg event) +{ + if ( event == EVENT_OBJECT_RiPAW ) return (g_researchDone & RESEARCH_iPAW); + if ( event == EVENT_OBJECT_RiGUN ) return (g_researchDone & RESEARCH_iGUN); + + return FALSE; +} + +// Indicates a search as made. + +void CAutoLabo::SetResearch(EventMsg event) +{ + Event newEvent; + + if ( event == EVENT_OBJECT_RiPAW ) g_researchDone |= RESEARCH_iPAW; + if ( event == EVENT_OBJECT_RiGUN ) g_researchDone |= RESEARCH_iGUN; + + m_main->WriteFreeParam(); + + m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); + m_event->AddEvent(newEvent); + UpdateInterface(); +} + +// Plays the sound of the manipulator arm. + +void CAutoLabo::SoundManip(float time, float amplitude, float frequency) +{ + int i; + + i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f*frequency, TRUE); + m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, 0.1f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP); +} + + +// Saves all parameters of the controller. + +BOOL CAutoLabo::Write(char *line) +{ + D3DVECTOR pos; + char name[100]; + + if ( m_phase == ALAP_WAIT ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + sprintf(name, " aResearch=%d", m_research); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller. + +BOOL CAutoLabo::Read(char *line) +{ + D3DVECTOR pos; + + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoLaboPhase)OpInt(line, "aPhase", ALAP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + m_research = (EventMsg)OpInt(line, "aResearch", 0); + + m_lastParticule = 0.0f; + + return TRUE; +} + + diff --git a/src/object/auto/autolabo.h b/src/object/auto/autolabo.h new file mode 100644 index 0000000..997bc55 --- /dev/null +++ b/src/object/auto/autolabo.h @@ -0,0 +1,87 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autolabo.h + +#ifndef _AUTOLABO_H_ +#define _AUTOLABO_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoLaboPhase +{ + ALAP_WAIT = 1, + ALAP_OPEN1 = 2, + ALAP_OPEN2 = 3, + ALAP_OPEN3 = 4, + ALAP_ANALYSE = 5, + ALAP_CLOSE1 = 6, + ALAP_CLOSE2 = 7, + ALAP_CLOSE3 = 8, +}; + + + +class CAutoLabo : public CAuto +{ +public: + CAutoLabo(CInstanceManager* iMan, CObject* object); + ~CAutoLabo(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + + BOOL CreateInterface(BOOL bSelect); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + void UpdateInterface(); + void OkayButton(CWindow *pw, EventMsg event); + BOOL TestResearch(EventMsg event); + void SetResearch(EventMsg event); + void SoundManip(float time, float amplitude, float frequency); + +protected: + AutoLaboPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + EventMsg m_research; + int m_partiRank[3]; + int m_partiSphere; + int m_soundChannel; +}; + + +#endif //_AUTOLABO_H_ diff --git a/src/object/auto/automush.cpp b/src/object/auto/automush.cpp new file mode 100644 index 0000000..d1107ed --- /dev/null +++ b/src/object/auto/automush.cpp @@ -0,0 +1,362 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "cmdtoken.h" +#include "sound.h" +#include "auto.h" +#include "automush.h" + + + + +// Object's constructor. + +CAutoMush::CAutoMush(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + Init(); +} + +// Object's destructor. + +CAutoMush::~CAutoMush() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoMush::DeleteObject(BOOL bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoMush::Init() +{ + m_phase = AMP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/4.0f; + + m_time = 0.0f; + m_lastParticule = 0.0f; +} + + +// Management of an event. + +BOOL CAutoMush::EventProcess(const Event &event) +{ + D3DVECTOR pos, speed, dir; + FPOINT dim; + float factor, zoom, size, angle; + int i, channel; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_speed; + + factor = 0.0f; + size = 1.0f; + + if ( m_phase == AMP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + if ( !SearchTarget() ) + { + m_phase = AMP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/(2.0f+Rand()*2.0f); + } + else + { + m_phase = AMP_SNIF; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + } + + if ( m_phase == AMP_SNIF ) + { + if ( m_progress < 1.0f ) + { + factor = m_progress; + } + else + { + m_phase = AMP_ZOOM; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == AMP_ZOOM ) + { + if ( m_progress < 1.0f ) + { + factor = 1.0f; + size = 1.0f+m_progress*0.3f; + } + else + { + m_sound->Play(SOUND_MUSHROOM, m_object->RetPosition(0)); + + m_phase = AMP_FIRE; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == AMP_FIRE ) + { + if ( m_progress < 1.0f ) + { + factor = 1.0f-m_progress; + size = 1.0f+(1.0f-m_progress)*0.3f; + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + for ( i=0 ; i<10 ; i++ ) + { + pos = m_object->RetPosition(0); + pos.y += 5.0f; + speed.x = (Rand()-0.5f)*200.0f; + speed.z = (Rand()-0.5f)*200.0f; + speed.y = -(20.0f+Rand()*20.0f); + dim.x = 1.0f; + dim.y = dim.x; + channel = m_particule->CreateParticule(pos, speed, dim, PARTIGUN2, 2.0f, 100.0f, 0.0f); + m_particule->SetObjectFather(channel, m_object); + } + } + } + else + { + m_phase = AMP_SMOKE; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == AMP_SMOKE ) + { + if ( m_progress < 1.0f ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.y += 5.0f; + speed.x = (Rand()-0.5f)*4.0f; + speed.z = (Rand()-0.5f)*4.0f; + speed.y = -(0.5f+Rand()*0.5f); + dim.x = Rand()*2.5f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 0.0f); + } + } + else + { + m_phase = AMP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/(2.0f+Rand()*2.0f); + } + } + + if ( factor != 0.0f || size != 1.0f ) + { + dir.x = sinf(m_time*PI*4.0f); + dir.z = cosf(m_time*PI*4.0f); + + angle = sinf(m_time*10.0f)*factor*0.04f; + m_object->SetAngleX(0, angle*dir.z); + m_object->SetAngleZ(0, angle*dir.x); + + zoom = 1.0f+sinf(m_time*8.0f)*factor*0.06f; + m_object->SetZoomX(0, zoom*size); + zoom = 1.0f+sinf(m_time*5.0f)*factor*0.06f; + m_object->SetZoomY(0, zoom*size); + zoom = 1.0f+sinf(m_time*7.0f)*factor*0.06f; + m_object->SetZoomZ(0, zoom*size); + } + else + { + m_object->SetAngleX(0, 0.0f); + m_object->SetAngleZ(0, 0.0f); + m_object->SetZoom(0, D3DVECTOR(1.0f, 1.0f, 1.0f)); + } + + return TRUE; +} + + +// Seeking a nearby target. + +BOOL CAutoMush::SearchTarget() +{ + CObject* pObj; + D3DVECTOR iPos, oPos; + ObjectType type; + float dist; + int i; + + iPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj->RetLock() ) continue; + + type = pObj->RetType(); + if ( type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr && + type != OBJECT_DERRICK && + type != OBJECT_STATION && + type != OBJECT_FACTORY && + type != OBJECT_REPAIR && + type != OBJECT_DESTROYER&& + type != OBJECT_CONVERT && + type != OBJECT_TOWER && + type != OBJECT_RESEARCH && + type != OBJECT_RADAR && + type != OBJECT_INFO && + type != OBJECT_ENERGY && + type != OBJECT_LABO && + type != OBJECT_NUCLEAR && + type != OBJECT_PARA && + type != OBJECT_HUMAN ) continue; + + oPos = pObj->RetPosition(0); + dist = Length(oPos, iPos); + if ( dist < 50.0f ) return TRUE; + } + + return FALSE; +} + + +// Returns an error due the state of the automation. + +Error CAutoMush::RetError() +{ + return ERR_OK; +} + + +// Saves all parameters of the controller. + +BOOL CAutoMush::Write(char *line) +{ + D3DVECTOR pos; + char name[100]; + + if ( m_phase == AMP_WAIT ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller. + +BOOL CAutoMush::Read(char *line) +{ + D3DVECTOR pos; + + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoMushPhase)OpInt(line, "aPhase", AMP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return TRUE; +} + + diff --git a/src/object/auto/automush.h b/src/object/auto/automush.h new file mode 100644 index 0000000..81314ee --- /dev/null +++ b/src/object/auto/automush.h @@ -0,0 +1,73 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// automush.h + +#ifndef _AUTOMUSH_H_ +#define _AUTOMUSH_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoMushPhase +{ + AMP_WAIT = 1, + AMP_SNIF = 2, + AMP_ZOOM = 3, + AMP_FIRE = 4, + AMP_SMOKE = 5, +}; + + + +class CAutoMush : public CAuto +{ +public: + CAutoMush(CInstanceManager* iMan, CObject* object); + ~CAutoMush(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + BOOL SearchTarget(); + +protected: + AutoMushPhase m_phase; + float m_progress; + float m_speed; + float m_lastParticule; +}; + + +#endif //_AUTOMUSH_H_ diff --git a/src/object/auto/autonest.cpp b/src/object/auto/autonest.cpp new file mode 100644 index 0000000..a86e7b8 --- /dev/null +++ b/src/object/auto/autonest.cpp @@ -0,0 +1,291 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autonest.h" + + + + +// Object's constructor. + +CAutoNest::CAutoNest(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + Init(); +} + +// Object's destructor. + +CAutoNest::~CAutoNest() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoNest::DeleteObject(BOOL bAll) +{ + CObject* fret; + + if ( !bAll ) + { + fret = SearchFret(); + if ( fret != 0 ) + { + fret->DeleteObject(); + delete fret; + } + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoNest::Init() +{ + D3DVECTOR pos; + + m_phase = ANP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/4.0f; + + m_time = 0.0f; + m_lastParticule = 0.0f; + + pos = m_object->RetPosition(0); + m_terrain->MoveOnFloor(pos); + m_fretPos = pos; +} + + +// Management of an event. + +BOOL CAutoNest::EventProcess(const Event &event) +{ + CObject* fret; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_speed; + + if ( m_phase == ANP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + if ( !SearchFree(m_fretPos) ) + { + m_phase = ANP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/4.0f; + } + else + { + CreateFret(m_fretPos, 0.0f, OBJECT_BULLET); + m_phase = ANP_BIRTH; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + } + } + } + + if ( m_phase == ANP_BIRTH ) + { + fret = SearchFret(); + + if ( m_progress < 1.0f ) + { + if ( fret != 0 ) + { + fret->SetZoom(0, m_progress); + } + } + else + { + if ( fret != 0 ) + { + fret->SetZoom(0, 1.0f); + fret->SetLock(FALSE); + } + + m_phase = ANP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + } + } + + return TRUE; +} + + +// Seeks if a site is free. + +BOOL CAutoNest::SearchFree(D3DVECTOR pos) +{ + CObject* pObj; + D3DVECTOR sPos; + ObjectType type; + float sRadius, distance; + int i, j; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type == OBJECT_NEST ) continue; + + j = 0; + while ( pObj->GetCrashSphere(j++, sPos, sRadius) ) + { + distance = Length(sPos, pos); + distance -= sRadius; + if ( distance < 2.0f ) return FALSE; // location occupied + } + } + + return TRUE; // free location +} + +// Create a transportable object. + +void CAutoNest::CreateFret(D3DVECTOR pos, float angle, ObjectType type) +{ + CObject* fret; + + fret = new CObject(m_iMan); + if ( !fret->CreateResource(pos, angle, type) ) + { + delete fret; + return; + } + fret->SetLock(TRUE); // not usable + fret->SetZoom(0, 0.0f); +} + +// Looking for the ball during manufacture. + +CObject* CAutoNest::SearchFret() +{ + CObject* pObj; + D3DVECTOR oPos; + ObjectType type; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetLock() ) continue; + + type = pObj->RetType(); + if ( type != OBJECT_BULLET ) continue; + + oPos = pObj->RetPosition(0); + if ( oPos.x == m_fretPos.x && + oPos.z == m_fretPos.z ) + { + return pObj; + } + } + + return 0; +} + + +// Returns an error due the state of the automation. + +Error CAutoNest::RetError() +{ + return ERR_OK; +} + + +// Saves all parameters of the controller. + +BOOL CAutoNest::Write(char *line) +{ + D3DVECTOR pos; + char name[100]; + + if ( m_phase == ANP_WAIT ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller. + +BOOL CAutoNest::Read(char *line) +{ + D3DVECTOR pos; + + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoNestPhase)OpInt(line, "aPhase", ANP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return TRUE; +} + + diff --git a/src/object/auto/autonest.h b/src/object/auto/autonest.h new file mode 100644 index 0000000..0c6febc --- /dev/null +++ b/src/object/auto/autonest.h @@ -0,0 +1,73 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autonest.h + +#ifndef _AUTONEST_H_ +#define _AUTONEST_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoNestPhase +{ + ANP_WAIT = 1, + ANP_BIRTH = 2, // appearance of a ball +}; + + + +class CAutoNest : public CAuto +{ +public: + CAutoNest(CInstanceManager* iMan, CObject* object); + ~CAutoNest(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + BOOL SearchFree(D3DVECTOR pos); + void CreateFret(D3DVECTOR pos, float angle, ObjectType type); + CObject* SearchFret(); + +protected: + AutoNestPhase m_phase; + float m_progress; + float m_speed; + float m_lastParticule; + D3DVECTOR m_fretPos; +}; + + +#endif //_AUTONEST_H_ diff --git a/src/object/auto/autonuclear.cpp b/src/object/auto/autonuclear.cpp new file mode 100644 index 0000000..824bfca --- /dev/null +++ b/src/object/auto/autonuclear.cpp @@ -0,0 +1,504 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "global.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "light.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "interface.h" +#include "button.h" +#include "window.h" +#include "sound.h" +#include "displaytext.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autonuclear.h" + + + +#define NUCLEAR_DELAY 30.0f // duration of the generation + + + + +// Object's constructor. + +CAutoNuclear::CAutoNuclear(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + m_channelSound = -1; + Init(); +} + +// Object's destructor. + +CAutoNuclear::~CAutoNuclear() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoNuclear::DeleteObject(BOOL bAll) +{ + CObject* fret; + + if ( !bAll ) + { + fret = SearchUranium(); + if ( fret != 0 ) + { + fret->DeleteObject(); // destroys the metal + delete fret; + } + } + + if ( m_channelSound != -1 ) + { + m_sound->FlushEnvelope(m_channelSound); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_channelSound = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoNuclear::Init() +{ + D3DMATRIX* mat; + + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + + mat = m_object->RetWorldMatrix(0); + m_pos = Transform(*mat, D3DVECTOR(22.0f, 4.0f, 0.0f)); + + m_phase = ANUP_WAIT; // waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + CAuto::Init(); +} + + +// Management of an event. + +BOOL CAutoNuclear::EventProcess(const Event &event) +{ + CObject* fret; + D3DMATRIX* mat; + D3DVECTOR pos, goal, speed; + FPOINT dim, rot; + float angle; + int i, max; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Rand()*0.3f; + } + return TRUE; + } + + EventProgress(event.rTime); + + if ( m_phase == ANUP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + fret = SearchUranium(); // transform uranium? + if ( fret == 0 || SearchVehicle() ) + { + m_phase = ANUP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + else + { + fret->SetLock(TRUE); // usable uranium + + SetBusy(TRUE); + InitProgressTotal(1.5f+NUCLEAR_DELAY+1.5f); + UpdateInterface(); + + m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.4f); + + m_phase = ANUP_CLOSE; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + } + + if ( m_phase == ANUP_CLOSE ) + { + if ( m_progress < 1.0f ) + { + angle = (1.0f-m_progress)*(135.0f*PI/180.0f); + m_object->SetAngleZ(1, angle); + } + else + { + m_object->SetAngleZ(1, 0.0f); + + mat = m_object->RetWorldMatrix(0); + max = (int)(10.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; iCreateParticule(pos, speed, dim, PARTICRASH); + } + + m_sound->Play(SOUND_CLOSE, m_object->RetPosition(0), 1.0f, 1.0f); + + m_channelSound = m_sound->Play(SOUND_NUCLEAR, m_object->RetPosition(0), 1.0f, 0.1f, TRUE); + m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, NUCLEAR_DELAY-1.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 2.0f, SOPER_STOP); + + m_phase = ANUP_GENERATE; + m_progress = 0.0f; + m_speed = 1.0f/NUCLEAR_DELAY; + } + } + + if ( m_phase == ANUP_GENERATE ) + { + if ( m_progress < 1.0f ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.y += 30.0f; + pos.x += (Rand()-0.5f)*6.0f; + pos.z += (Rand()-0.5f)*6.0f; + speed.y = Rand()*15.0f+15.0f; + speed.x = 0.0f; + speed.z = 0.0f; + dim.x = Rand()*8.0f+8.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH); + + pos = m_pos; + speed.x = (Rand()-0.5f)*20.0f; + speed.y = (Rand()-0.5f)*20.0f; + speed.z = (Rand()-0.5f)*20.0f; + dim.x = 2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 1.0f, 0.0f, 0.0f); + } + } + else + { + fret = SearchUranium(); + if ( fret != 0 ) + { + fret->DeleteObject(); // destroyed uranium + delete fret; + m_object->SetPower(0); + } + + CreatePower(); // creates the atomic cell + + max = (int)(20.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; iCreateParticule(pos, speed, dim, PARTIBLUE, Rand()*5.0f+5.0f, 0.0f, 0.0f); + } + + m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.4f); + + m_phase = ANUP_OPEN; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + + if ( m_phase == ANUP_OPEN ) + { + if ( m_progress < 1.0f ) + { + angle = m_progress*(135.0f*PI/180.0f); + m_object->SetAngleZ(1, angle); + } + else + { + m_object->SetAngleZ(1, 135.0f*PI/180.0f); + + SetBusy(FALSE); + UpdateInterface(); + + m_displayText->DisplayError(INFO_NUCLEAR, m_object); + + m_phase = ANUP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + return TRUE; +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoNuclear::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 110, EVENT_OBJECT_TYPE); + + return TRUE; +} + + +// Seeking the uranium. + +CObject* CAutoNuclear::SearchUranium() +{ + CObject* pObj; + + pObj = m_object->RetPower(); + if ( pObj == 0 ) return 0; + if ( pObj->RetType() == OBJECT_URANIUM ) return pObj; + return 0; +} + +// Seeks if a vehicle is too close. + +BOOL CAutoNuclear::SearchVehicle() +{ + CObject* pObj; + D3DVECTOR oPos; + ObjectType type; + float oRadius, dist; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_HUMAN && + type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr && + type != OBJECT_MOTHER && + type != OBJECT_ANT && + type != OBJECT_SPIDER && + type != OBJECT_BEE && + type != OBJECT_WORM ) continue; + + if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; + dist = Length(oPos, m_pos)-oRadius; + + if ( dist < 10.0f ) return TRUE; + } + + return FALSE; +} + +// Creates an object stack. + +void CAutoNuclear::CreatePower() +{ + CObject* power; + D3DVECTOR pos; + float angle; + + pos = m_object->RetPosition(0); + angle = m_object->RetAngleY(0); + + power = new CObject(m_iMan); + if ( !power->CreateResource(pos, angle, OBJECT_ATOMIC) ) + { + delete power; + m_displayText->DisplayError(ERR_TOOMANY, m_object); + return; + } + + power->SetTruck(m_object); + power->SetPosition(0, D3DVECTOR(22.0f, 3.0f, 0.0f)); + m_object->SetPower(power); +} + + +// Returns an error due the state of the automation. + +Error CAutoNuclear::RetError() +{ + CObject* pObj; + ObjectType type; +//? TerrainRes res; + + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + +//? res = m_terrain->RetResource(m_object->RetPosition(0)); +//? if ( res != TR_POWER ) return ERR_NUCLEAR_NULL; + +//? if ( m_object->RetEnergy() < ENERGY_POWER ) return ERR_NUCLEAR_LOW; + + pObj = m_object->RetPower(); + if ( pObj == 0 ) return ERR_NUCLEAR_EMPTY; + if ( pObj->RetLock() ) return ERR_OK; + type = pObj->RetType(); + if ( type == OBJECT_ATOMIC ) return ERR_OK; + if ( type != OBJECT_URANIUM ) return ERR_NUCLEAR_BAD; + + return ERR_OK; +} + + +// Saves all parameters of the controller. + +BOOL CAutoNuclear::Write(char *line) +{ + char name[100]; + + if ( m_phase == ANUP_STOP || + m_phase == ANUP_WAIT ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller. + +BOOL CAutoNuclear::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoNuclearPhase)OpInt(line, "aPhase", ANUP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return TRUE; +} + + diff --git a/src/object/auto/autonuclear.h b/src/object/auto/autonuclear.h new file mode 100644 index 0000000..e62282a --- /dev/null +++ b/src/object/auto/autonuclear.h @@ -0,0 +1,80 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autonuclear.h + +#ifndef _AUTONUCLEAR_H_ +#define _AUTONUCLEAR_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoNuclearPhase +{ + ANUP_STOP = 1, + ANUP_WAIT = 2, + ANUP_CLOSE = 3, + ANUP_GENERATE = 4, + ANUP_OPEN = 5, +}; + + + +class CAutoNuclear : public CAuto +{ +public: + CAutoNuclear(CInstanceManager* iMan, CObject* object); + ~CAutoNuclear(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + + BOOL CreateInterface(BOOL bSelect); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + CObject* SearchUranium(); + BOOL SearchVehicle(); + void CreatePower(); + +protected: + AutoNuclearPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + D3DVECTOR m_pos; + int m_channelSound; +}; + + +#endif //_AUTONUCLEAR_H_ diff --git a/src/object/auto/autopara.cpp b/src/object/auto/autopara.cpp new file mode 100644 index 0000000..cb42e6d --- /dev/null +++ b/src/object/auto/autopara.cpp @@ -0,0 +1,347 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "global.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "light.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "interface.h" +#include "button.h" +#include "window.h" +#include "sound.h" +#include "displaytext.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autopara.h" + + + + +// Object's constructor. + +CAutoPara::CAutoPara(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + m_channelSound = -1; + Init(); +} + +// Object's destructor. + +CAutoPara::~CAutoPara() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoPara::DeleteObject(BOOL bAll) +{ + if ( m_channelSound != -1 ) + { + m_sound->FlushEnvelope(m_channelSound); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_channelSound = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoPara::Init() +{ + D3DMATRIX* mat; + + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + + mat = m_object->RetWorldMatrix(0); + m_pos = Transform(*mat, D3DVECTOR(22.0f, 4.0f, 0.0f)); + + m_phase = APAP_WAIT; // waiting ... + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + CAuto::Init(); +} + + +// Reception of lightning. + +void CAutoPara::StartBlitz() +{ + m_phase = APAP_BLITZ; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; +} + + +// Management of an event. + +BOOL CAutoPara::EventProcess(const Event &event) +{ + D3DVECTOR pos, speed; + FPOINT dim; + int i; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Rand()*0.3f; + } + return TRUE; + } + + EventProgress(event.rTime); + + if ( m_phase == APAP_BLITZ ) + { + if ( m_progress < 1.0f ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + for ( i=0 ; i<10 ; i++ ) + { + pos = m_object->RetPosition(0); + pos.x += (Rand()-0.5f)*m_progress*40.0f; + pos.z += (Rand()-0.5f)*m_progress*40.0f; + pos.y += 50.0f-m_progress*50.0f; + speed.x = (Rand()-0.5f)*20.0f; + speed.z = (Rand()-0.5f)*20.0f; + speed.y = 5.0f+Rand()*5.0f; + dim.x = 2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 1.0f, 20.0f, 0.5f); + } + } + } + else + { + m_phase = APAP_CHARGE; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == APAP_CHARGE ) + { + if ( m_progress < 1.0f ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + for ( i=0 ; i<2 ; i++ ) + { + pos = m_object->RetPosition(0); + pos.y += 16.0f; + speed.x = (Rand()-0.5f)*10.0f; + speed.z = (Rand()-0.5f)*10.0f; + speed.y = -Rand()*30.0f; + dim.x = 1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 1.0f, 0.0f, 0.0f); + } + } + + ChargeObject(event.rTime); + } + else + { + m_phase = APAP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + return TRUE; +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoPara::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 113, EVENT_OBJECT_TYPE); + + pos.x = ox+sx*10.2f; + pos.y = oy+sy*0.5f; + ddim.x = 33.0f/640.0f; + ddim.y = 33.0f/480.0f; + pw->CreateButton(pos, ddim, 41, EVENT_OBJECT_LIMIT); + + return TRUE; +} + + +// Returns an error due the state of the automation. + +Error CAutoPara::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + return ERR_OK; +} + + +// Load all objects under the lightning rod. + +void CAutoPara::ChargeObject(float rTime) +{ + CObject* pObj; + CObject* power; + D3DVECTOR sPos, oPos; + float dist, energy; + int i; + + sPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oPos = pObj->RetPosition(0); + dist = Length(oPos, sPos); + if ( dist > 20.0f ) continue; + + if ( pObj->RetTruck() == 0 && pObj->RetType() == OBJECT_POWER ) + { + energy = pObj->RetEnergy(); + energy += rTime/2.0f; + if ( energy > 1.0f ) energy = 1.0f; + pObj->SetEnergy(energy); + } + + power = pObj->RetPower(); + if ( power != 0 && power->RetType() == OBJECT_POWER ) + { + energy = power->RetEnergy(); + energy += rTime/2.0f; + if ( energy > 1.0f ) energy = 1.0f; + power->SetEnergy(energy); + } + + power = pObj->RetFret(); + if ( power != 0 && power->RetType() == OBJECT_POWER ) + { + energy = power->RetEnergy(); + energy += rTime/2.0f; + if ( energy > 1.0f ) energy = 1.0f; + power->SetEnergy(energy); + } + } +} + + +// Saves all parameters of the controller. + +BOOL CAutoPara::Write(char *line) +{ + char name[100]; + + if ( m_phase == APAP_WAIT ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller. + +BOOL CAutoPara::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoParaPhase)OpInt(line, "aPhase", APAP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return TRUE; +} + + diff --git a/src/object/auto/autopara.h b/src/object/auto/autopara.h new file mode 100644 index 0000000..9a7c0c4 --- /dev/null +++ b/src/object/auto/autopara.h @@ -0,0 +1,77 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autopara.h + +#ifndef _AUTOPARA_H_ +#define _AUTOPARA_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoParaPhase +{ + APAP_WAIT = 1, + APAP_BLITZ = 2, + APAP_CHARGE = 3, +}; + + + +class CAutoPara : public CAuto +{ +public: + CAutoPara(CInstanceManager* iMan, CObject* object); + ~CAutoPara(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + void StartBlitz(); + + BOOL CreateInterface(BOOL bSelect); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + void ChargeObject(float rTime); + +protected: + AutoParaPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + D3DVECTOR m_pos; + int m_channelSound; +}; + + +#endif //_AUTOPARA_H_ diff --git a/src/object/auto/autoportico.cpp b/src/object/auto/autoportico.cpp new file mode 100644 index 0000000..c02348d --- /dev/null +++ b/src/object/auto/autoportico.cpp @@ -0,0 +1,446 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "interface.h" +#include "button.h" +#include "window.h" +#include "displaytext.h" +#include "robotmain.h" +#include "sound.h" +#include "auto.h" +#include "autoportico.h" + + + +#define PARAM_DEPOSE 2 // run=2 -> deposits the spaceship + +#define PORTICO_POSa 75.0f +#define PORTICO_POSb 65.0f +#define PORTICO_ANGLE1a ( 25.0f*PI/180.0f) +#define PORTICO_ANGLE1b ( 70.0f*PI/180.0f) +#define PORTICO_ANGLE2a (-37.5f*PI/180.0f) +#define PORTICO_ANGLE2b (-62.5f*PI/180.0f) +#define PORTICO_ANGLE3a (-77.5f*PI/180.0f) +#define PORTICO_ANGLE3b (-30.0f*PI/180.0f) + +#define PORTICO_TIME_MOVE 16.0f +#define PORTICO_TIME_DOWN 4.0f +#define PORTICO_TIME_OPEN 12.0f + + + + +// Si progress=0, return a. +// Si progress=1, return b. + +float Progress(float a, float b, float progress) +{ + return a+(b-a)*progress; +} + + + +// Object's constructor. + +CAutoPortico::CAutoPortico(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + Init(); + m_phase = APOP_WAIT; + m_soundChannel = -1; +} + +// Object's destructor. + +CAutoPortico::~CAutoPortico() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoPortico::DeleteObject(BOOL bAll) +{ + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoPortico::Init() +{ + m_time = 0.0f; + m_lastParticule = 0.0f; + m_posTrack = 0.0f; + + m_phase = APOP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + m_cameraProgress = 0.0f; + m_cameraSpeed = 1.0f/(PORTICO_TIME_MOVE-2.0f); +} + + +// Starts the object. + +void CAutoPortico::Start(int param) +{ + D3DVECTOR pos; + + pos = m_object->RetPosition(0); + m_finalPos = pos; + pos.z += PORTICO_TIME_MOVE*5.0f; // back to start + m_object->SetPosition(0, pos); + m_finalPos.z += PORTICO_TIME_OPEN*5.3f; + + m_object->SetPosition(1, D3DVECTOR(0.0f, PORTICO_POSa, 0.0f)); + m_object->SetAngleY(2, PORTICO_ANGLE1a); + m_object->SetAngleY(3, PORTICO_ANGLE2a); + m_object->SetAngleY(4, PORTICO_ANGLE3a); + m_object->SetAngleY(5, -PORTICO_ANGLE1a); + m_object->SetAngleY(6, -PORTICO_ANGLE2a); + m_object->SetAngleY(7, -PORTICO_ANGLE3a); + + m_phase = APOP_START; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + m_param = param; +} + + +// Management of an event. + +BOOL CAutoPortico::EventProcess(const Event &event) +{ + CObject* pObj; + D3DVECTOR pos; + float angle; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + + if ( m_phase == APOP_START ) + { + if ( m_param == PARAM_DEPOSE ) // deposits the ship? + { + m_startPos = m_object->RetPosition(0); + + m_soundChannel = m_sound->Play(SOUND_MOTORr, m_object->RetPosition(0), 0.0f, 0.3f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, 0.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, PORTICO_TIME_MOVE-0.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 0.5f, SOPER_STOP); + + m_phase = APOP_MOVE; + m_progress = 0.0f; + m_speed = 1.0f/PORTICO_TIME_MOVE; + + m_main->SetMovieLock(TRUE); // blocks everything until the end of the landing + + m_camera->SetType(CAMERA_SCRIPT); + + pos = m_startPos; + pos.x += -100.0f; + pos.y += 9.0f; + pos.z += -200.0f; + m_camera->SetScriptEye(pos); + + pos = m_object->RetPosition(0); + pos.x += 0.0f; + pos.y += 10.0f; + pos.z += -40.0f; + m_camera->SetScriptLookat(pos); + + m_camera->FixCamera(); + } + } + + angle = -m_time*1.0f; + m_object->SetAngleY(8, angle); // rotates the radar right + angle = sinf(m_time*4.0f)*0.3f; + m_object->SetAngleX(9, angle); + + angle = -m_time*1.0f+PI/2.3f; + m_object->SetAngleY(10, angle); // turns the left side radar + angle = sinf(m_time*4.0f)*0.3f; + m_object->SetAngleX(11, angle); + + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_phase == APOP_WAIT ) return TRUE; + + m_progress += event.rTime*m_speed; + m_cameraProgress += event.rTime*m_cameraSpeed; + + if ( m_phase == APOP_MOVE ) + { + if ( m_progress < 1.0f ) + { + pos = m_object->RetPosition(0); + pos.z -= event.rTime*5.0f; // advance + m_object->SetPosition(0, pos); + + m_posTrack += event.rTime*0.5f; + UpdateTrackMapping(m_posTrack, m_posTrack); + } + else + { + m_phase = APOP_WAIT1; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == APOP_WAIT1 ) + { + if ( m_progress >= 1.0f ) + { + m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.5f, 1.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.6f, PORTICO_TIME_DOWN-1.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 1.0f, SOPER_STOP); + + m_phase = APOP_DOWN; + m_progress = 0.0f; + m_speed = 1.0f/PORTICO_TIME_DOWN; + } + } + + if ( m_phase == APOP_DOWN ) + { + if ( m_progress < 1.0f ) + { + pos.x = 0.0f; + pos.y = Progress(PORTICO_POSa, PORTICO_POSb, m_progress); + pos.z = 0.0f; + m_object->SetPosition(1, pos); + } + else + { + pos.x = 0.0f; + pos.y = PORTICO_POSb; + pos.z = 0.0f; + m_object->SetPosition(1, pos); + + m_phase = APOP_WAIT2; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == APOP_WAIT2 ) + { + if ( m_progress >= 1.0f ) + { + m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.5f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 0.5f, 1.0f, 0.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.5f, 1.0f, PORTICO_TIME_OPEN/2.0f-0.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.5f, SOPER_STOP); + + m_soundChannel = m_sound->Play(SOUND_MOTORr, m_object->RetPosition(0), 0.0f, 0.3f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, 0.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, PORTICO_TIME_OPEN-0.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 0.5f, SOPER_STOP); + + m_phase = APOP_OPEN; + m_progress = 0.0f; + m_speed = 1.0f/PORTICO_TIME_OPEN; + } + } + + if ( m_phase == APOP_OPEN ) + { + if ( m_progress < 1.0f ) + { + pos = m_object->RetPosition(0); + pos.z += event.rTime*5.3f; // back + m_object->SetPosition(0, pos); + + m_posTrack -= event.rTime*1.0f; + UpdateTrackMapping(m_posTrack, m_posTrack); + + if ( m_progress < 0.5f ) + { + angle = Progress(PORTICO_ANGLE1a, PORTICO_ANGLE1b, m_progress/0.5f); + m_object->SetAngleY(2, angle); + m_object->SetAngleY(5, -angle); + angle = Progress(PORTICO_ANGLE2a, PORTICO_ANGLE2b, m_progress/0.5f); + m_object->SetAngleY(3, angle); + m_object->SetAngleY(6, -angle); + angle = Progress(PORTICO_ANGLE3a, PORTICO_ANGLE3b, m_progress/0.5f); + m_object->SetAngleY(4, angle); + m_object->SetAngleY(7, -angle); + } + else + { + m_object->SetAngleY(2, PORTICO_ANGLE1b); + m_object->SetAngleY(3, PORTICO_ANGLE2b); + m_object->SetAngleY(4, PORTICO_ANGLE3b); + m_object->SetAngleY(5, -PORTICO_ANGLE1b); + m_object->SetAngleY(6, -PORTICO_ANGLE2b); + m_object->SetAngleY(7, -PORTICO_ANGLE3b); + } + } + else + { + m_main->SetMovieLock(FALSE); // you can play! + + pObj = m_main->SearchHuman(); + m_main->SelectObject(pObj); + m_camera->SetObject(pObj); + m_camera->SetType(CAMERA_BACK); + + m_phase = APOP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_soundChannel != -1 ) + { +//? m_sound->Position(m_soundChannel, m_object->RetPosition(0)); + pos = m_engine->RetEyePt(); + m_sound->Position(m_soundChannel, pos); + } + + if ( m_cameraProgress < 1.0f ) + { + if ( m_cameraProgress < 0.5f ) + { + } + else + { + pos = m_startPos; + pos.x += -100.0f-(m_cameraProgress-0.5f)*1.0f*120.0f; + pos.y += 9.0f; + pos.z += -200.0f+(m_cameraProgress-0.5f)*1.0f*210.0f; + m_camera->SetScriptEye(pos); + } + + pos = m_object->RetPosition(0); + pos.x += 0.0f; + pos.y += 10.0f; + pos.z += -40.0f; + m_camera->SetScriptLookat(pos); + } + + return TRUE; +} + +// Stops the controller. + +BOOL CAutoPortico::Abort() +{ + CObject* pObj; + + m_object->SetPosition(0, m_finalPos); + m_object->SetPosition(1, D3DVECTOR(0.0f, PORTICO_POSb, 0.0f)); + m_object->SetAngleY(2, PORTICO_ANGLE1b); + m_object->SetAngleY(3, PORTICO_ANGLE2b); + m_object->SetAngleY(4, PORTICO_ANGLE3b); + m_object->SetAngleY(5, -PORTICO_ANGLE1b); + m_object->SetAngleY(6, -PORTICO_ANGLE2b); + m_object->SetAngleY(7, -PORTICO_ANGLE3b); + + m_main->SetMovieLock(FALSE); // you can play! + + pObj = m_main->SearchHuman(); + m_main->SelectObject(pObj); + m_camera->SetObject(pObj); + m_camera->SetType(CAMERA_BACK); + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + m_phase = APOP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + return TRUE; +} + + +// Returns an error due the state of the automation. + +Error CAutoPortico::RetError() +{ + return ERR_OK; +} + + +// Updates the mapping of the texture of the caterpillars. + +void CAutoPortico::UpdateTrackMapping(float left, float right) +{ + D3DMATERIAL7 mat; + float limit[2]; + int rank; + + ZeroMemory( &mat, sizeof(D3DMATERIAL7) ); + mat.diffuse.r = 1.0f; + mat.diffuse.g = 1.0f; + mat.diffuse.b = 1.0f; // blank + mat.ambient.r = 0.5f; + mat.ambient.g = 0.5f; + mat.ambient.b = 0.5f; + + rank = m_object->RetObjectRank(0); + + limit[0] = 0.0f; + limit[1] = 1000000.0f; + + m_engine->TrackTextureMapping(rank, mat, D3DSTATEPART1, "lemt.tga", "", + limit[0], limit[1], D3DMAPPINGX, + right, 8.0f, 8.0f, 192.0f, 256.0f); + + m_engine->TrackTextureMapping(rank, mat, D3DSTATEPART2, "lemt.tga", "", + limit[0], limit[1], D3DMAPPINGX, + left, 8.0f, 8.0f, 192.0f, 256.0f); +} + diff --git a/src/object/auto/autoportico.h b/src/object/auto/autoportico.h new file mode 100644 index 0000000..7ed2e70 --- /dev/null +++ b/src/object/auto/autoportico.h @@ -0,0 +1,81 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autoportico.h + +#ifndef _AUTOPORTICO_H_ +#define _AUTOPORTICO_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoPorticoPhase +{ + APOP_WAIT = 1, // waits + APOP_START = 2, // start of the action + APOP_MOVE = 3, // advance + APOP_WAIT1 = 4, // waits + APOP_DOWN = 5, // down + APOP_WAIT2 = 6, // waits + APOP_OPEN = 7, // opens +}; + + + +class CAutoPortico : public CAuto +{ +public: + CAutoPortico(CInstanceManager* iMan, CObject* object); + ~CAutoPortico(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + void Start(int param); + BOOL EventProcess(const Event &event); + BOOL Abort(); + Error RetError(); + +protected: + void UpdateTrackMapping(float left, float right); + +protected: + AutoPorticoPhase m_phase; + float m_progress; + float m_speed; + float m_cameraProgress; + float m_cameraSpeed; + float m_lastParticule; + D3DVECTOR m_finalPos; + D3DVECTOR m_startPos; + float m_posTrack; + int m_param; + int m_soundChannel; +}; + + +#endif //_AUTOPORTICO_H_ diff --git a/src/object/auto/autoradar.cpp b/src/object/auto/autoradar.cpp new file mode 100644 index 0000000..2353149 --- /dev/null +++ b/src/object/auto/autoradar.cpp @@ -0,0 +1,326 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "interface.h" +#include "button.h" +#include "window.h" +#include "gauge.h" +#include "sound.h" +#include "auto.h" +#include "autoradar.h" + + + + +// Object's constructor. + +CAutoRadar::CAutoRadar(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + Init(); + m_phase = ARAP_WAIT; + m_totalDetect = 0; +} + +// Object's destructor. + +CAutoRadar::~CAutoRadar() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoRadar::DeleteObject(BOOL bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoRadar::Init() +{ + m_phase = ARAP_SEARCH; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + + m_aTime = 0.0f; + m_time = 0.0f; + m_timeVirus = 0.0f; +} + + +// Management of an event. + +BOOL CAutoRadar::EventProcess(const Event &event) +{ + D3DVECTOR pos, ePos; + float speed, angle, prog, freq, ampl; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_phase == ARAP_WAIT ) return TRUE; + + m_progress += event.rTime*m_speed; + m_aTime += event.rTime; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Rand()*0.3f; + + angle = m_object->RetAngleY(1); + angle += (Rand()-0.2f)*0.5f; + m_object->SetAngleY(1, angle); + + angle = m_object->RetAngleY(2); + angle += (Rand()-0.8f)*1.0f; + m_object->SetAngleY(2, angle); + + m_object->SetAngleX(3, (Rand()-0.5f)*0.3f); + + m_totalDetect = (int)(Rand()*10.0f); + UpdateInterface(); + } + return TRUE; + } + + if ( m_phase == ARAP_SEARCH ) + { + if ( m_progress < 1.0f ) + { + speed = Min(10.0f, m_progress*50.0f); + angle = m_object->RetAngleY(1); + angle += event.rTime*speed; + m_object->SetAngleY(1, angle); + } + else + { + if ( !SearchEnemy(ePos) ) + { + m_phase = ARAP_SEARCH; + m_progress = 10.0f/50.0f; // full speed immediately + m_speed = 1.0f/3.0f; + } + else + { + pos = m_object->RetPosition(0); + m_start = m_object->RetAngleY(1); + m_angle = m_start-NormAngle(m_start)+PI*2.0f; + m_angle += RotateAngle(pos.x-ePos.x, ePos.z-pos.z); + m_angle += PI-m_object->RetAngleY(0); + + m_phase = ARAP_SHOW; + m_progress = 0.0f; + m_speed = 1.0f/(Abs(m_angle-m_start)/10.0f); + } + } + } + + if ( m_phase == ARAP_SHOW ) + { + if ( m_progress < 1.0f ) + { + angle = m_start + (m_angle-m_start)*m_progress; + m_object->SetAngleY(1, angle); + } + else + { + m_sound->Play(SOUND_RADAR, m_object->RetPosition(0)); + + m_phase = ARAP_SINUS; + m_progress = 0.0f; + m_speed = 1.0f/4.0f; + m_time = 0.0f; + } + } + + if ( m_phase == ARAP_SINUS ) + { + if ( m_progress < 1.0f ) + { + prog = Min(1.0f, m_progress*2.0f); + freq = 16.0f*(prog+1.0f); + ampl = 0.2f-prog*0.2f; + angle = m_angle + sinf(m_time*freq)*ampl; + m_object->SetAngleY(1, angle); + } + else + { + m_phase = ARAP_SEARCH; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + } + + angle = -m_aTime*2.0f; + m_object->SetAngleY(2, angle); + + angle = sinf(m_aTime*4.0f)*0.3f; + m_object->SetAngleX(3, angle); + + return TRUE; +} + + +// Returns an error due the state of the automation. + +Error CAutoRadar::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + return ERR_OK; +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoRadar::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, dim, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*7.0f; + pos.y = oy+sy*0.6f; + dim.x = 160.0f/640.0f; + dim.y = 26.0f/480.0f; + pw->CreateGauge(pos, dim, 1, EVENT_OBJECT_GRADAR); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 105, EVENT_OBJECT_TYPE); + + UpdateInterface(); + return TRUE; +} + +// Updates the status of all interface buttons. + +void CAutoRadar::UpdateInterface() +{ + CWindow* pw; + CGauge* pg; + float level; + + if ( !m_object->RetSelect() ) return; + + CAuto::UpdateInterface(); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GRADAR); + if ( pg != 0 ) + { + level = (float)m_totalDetect*(1.0f/8.0f); + if ( level > 1.0f ) level = 1.0f; + pg->SetLevel(level); + } +} + + +// Seeking the position of an enemy. + +BOOL CAutoRadar::SearchEnemy(D3DVECTOR &pos) +{ + CObject* pObj; + CObject* pBest = 0; + D3DVECTOR iPos, oPos; + ObjectType oType; + float distance, min; + int i; + + iPos = m_object->RetPosition(0); + min = 1000000.0f; + m_totalDetect = 0; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetActif() ) continue; + + oType = pObj->RetType(); + if ( oType != OBJECT_ANT && + oType != OBJECT_SPIDER && + oType != OBJECT_BEE && + oType != OBJECT_WORM && + oType != OBJECT_MOTHER ) continue; + + m_totalDetect ++; + + oPos = pObj->RetPosition(0); + distance = Length(oPos, iPos); + if ( distance < min ) + { + min = distance; + pBest = pObj; + } + } + + UpdateInterface(); + + if ( pBest == 0 ) return FALSE; + pos = pBest->RetPosition(0); + return TRUE; +} + + diff --git a/src/object/auto/autoradar.h b/src/object/auto/autoradar.h new file mode 100644 index 0000000..298d011 --- /dev/null +++ b/src/object/auto/autoradar.h @@ -0,0 +1,76 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autoradar.h + +#ifndef _AUTORADAR_H_ +#define _AUTORADAR_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoRadarPhase +{ + ARAP_WAIT = 1, // waiting + ARAP_SEARCH = 2, // seeking + ARAP_SHOW = 3, // watching + ARAP_SINUS = 4, // oscillates +}; + + + +class CAutoRadar : public CAuto +{ +public: + CAutoRadar(CInstanceManager* iMan, CObject* object); + ~CAutoRadar(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + BOOL CreateInterface(BOOL bSelect); + Error RetError(); + +protected: + void UpdateInterface(); + BOOL SearchEnemy(D3DVECTOR &pos); + +protected: + AutoRadarPhase m_phase; + float m_progress; + float m_speed; + float m_aTime; + float m_timeVirus; + float m_lastParticule; + float m_angle; + float m_start; + int m_totalDetect; +}; + + +#endif //_AUTORADAR_H_ diff --git a/src/object/auto/autorepair.cpp b/src/object/auto/autorepair.cpp new file mode 100644 index 0000000..6994842 --- /dev/null +++ b/src/object/auto/autorepair.cpp @@ -0,0 +1,362 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "light.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "physics.h" +#include "sound.h" +#include "interface.h" +#include "button.h" +#include "window.h" +#include "robotmain.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autorepair.h" + + + + +// Object's constructor. + +CAutoRepair::CAutoRepair(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + Init(); + m_phase = ARP_WAIT; // paused until the first Init () +} + +// Object's destructor. + +CAutoRepair::~CAutoRepair() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoRepair::DeleteObject(BOOL bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoRepair::Init() +{ + m_phase = ARP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + + CAuto::Init(); +} + + +// Management of an event. + +BOOL CAutoRepair::EventProcess(const Event &event) +{ + CObject* vehicule; + D3DVECTOR pos, speed; + FPOINT dim; + float angle, shield; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Rand()*0.3f; + } + return TRUE; + } + + if ( m_phase == ARP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + if ( SearchVehicle() == 0 ) + { + m_phase = ARP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + else + { + m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 0.8f); + + m_phase = ARP_DOWN; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + } + } + + if ( m_phase == ARP_DOWN ) + { + if ( m_progress < 1.0f ) + { + angle = -m_progress*(PI/2.0f)+PI/2.0f; + m_object->SetAngleZ(1, angle); + } + else + { + m_object->SetAngleZ(1, 0.0f); + m_sound->Play(SOUND_REPAIR, m_object->RetPosition(0)); + + m_phase = ARP_REPAIR; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ARP_REPAIR ) + { + vehicule = SearchVehicle(); + if ( m_progress < 1.0f || + (vehicule != 0 && vehicule->RetShield() < 1.0f) ) + { + if ( vehicule != 0 ) + { + shield = vehicule->RetShield(); + shield += event.rTime*0.2f; + if ( shield > 1.0f ) shield = 1.0f; + vehicule->SetShield(shield); + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.x += (Rand()-0.5f)*5.0f; + pos.z += (Rand()-0.5f)*5.0f; + pos.y += 1.0f; + speed.x = (Rand()-0.5f)*12.0f; + speed.z = (Rand()-0.5f)*12.0f; + speed.y = Rand()*15.0f; + dim.x = Rand()*6.0f+4.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); + } + } + else + { + m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 0.8f); + + m_phase = ARP_UP; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + } + + if ( m_phase == ARP_UP ) + { + if ( m_progress < 1.0f ) + { + angle = -(1.0f-m_progress)*(PI/2.0f)+PI/2.0f; + m_object->SetAngleZ(1, angle); + } + else + { + m_object->SetAngleZ(1, PI/2.0f); + + m_phase = ARP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + return TRUE; +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoRepair::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 106, EVENT_OBJECT_TYPE); + + return TRUE; +} + + +// Seeking the vehicle on the station. + +CObject* CAutoRepair::SearchVehicle() +{ + CObject* pObj; + CPhysics* physics; + D3DVECTOR sPos, oPos; + ObjectType type; + float dist; + int i; + + sPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr ) continue; + + physics = pObj->RetPhysics(); + if ( physics != 0 && !physics->RetLand() ) continue; // in flight? + + oPos = pObj->RetPosition(0); + dist = Length(oPos, sPos); + if ( dist <= 5.0f ) return pObj; + } + + return 0; +} + + +// Returns an error due the state of the automation. + +Error CAutoRepair::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + return ERR_OK; +} + + +// Saves all parameters of the controller. + +BOOL CAutoRepair::Write(char *line) +{ + char name[100]; + + if ( m_phase == ARP_WAIT ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller. + +BOOL CAutoRepair::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoRepairPhase)OpInt(line, "aPhase", ARP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return TRUE; +} + + diff --git a/src/object/auto/autorepair.h b/src/object/auto/autorepair.h new file mode 100644 index 0000000..1383fc7 --- /dev/null +++ b/src/object/auto/autorepair.h @@ -0,0 +1,76 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autorepair.h + +#ifndef _AUTOREPAIR_H_ +#define _AUTOREPAIR_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoRepairPhase +{ + ARP_WAIT = 1, // expected metal + ARP_DOWN = 2, // down the cover + ARP_REPAIR = 3, // repair the vehicle + ARP_UP = 4, // back cover + +}; + + + +class CAutoRepair : public CAuto +{ +public: + CAutoRepair(CInstanceManager* iMan, CObject* object); + ~CAutoRepair(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + + BOOL CreateInterface(BOOL bSelect); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + CObject* SearchVehicle(); + +protected: + AutoRepairPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; +}; + + +#endif //_AUTOREPAIR_H_ diff --git a/src/object/auto/autoresearch.cpp b/src/object/auto/autoresearch.cpp new file mode 100644 index 0000000..b15a9b8 --- /dev/null +++ b/src/object/auto/autoresearch.cpp @@ -0,0 +1,627 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "global.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "interface.h" +#include "button.h" +#include "gauge.h" +#include "window.h" +#include "displaytext.h" +#include "sound.h" +#include "robotmain.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autoresearch.h" + + + +#define SEARCH_TIME 30.0f // duration of a research + + + +// Object's constructor. + +CAutoResearch::CAutoResearch(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + int i; + + CAuto::CAuto(iMan, object); + + for ( i=0 ; i<6 ; i++ ) + { + m_partiStop[i] = -1; + } + m_channelSound = -1; + + Init(); +} + +// Object's destructor. + +CAutoResearch::~CAutoResearch() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoResearch::DeleteObject(BOOL bAll) +{ + if ( m_channelSound != -1 ) + { + m_sound->FlushEnvelope(m_channelSound); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_channelSound = -1; + } + + FireStopUpdate(0.0f, FALSE); + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoResearch::Init() +{ + m_phase = ALP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastUpdateTime = 0.0f; + m_lastParticule = 0.0f; +} + + +// Management of an event. + +BOOL CAutoResearch::EventProcess(const Event &event) +{ + CObject* power; + D3DVECTOR pos, speed; + Error message; + FPOINT dim; + float angle, time; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + + if ( event.event == EVENT_UPDINTERFACE ) + { + if ( m_object->RetSelect() ) CreateInterface(TRUE); + } + + if ( m_object->RetSelect() && // center selected? + (event.event == EVENT_OBJECT_RTANK || + event.event == EVENT_OBJECT_RFLY || + event.event == EVENT_OBJECT_RTHUMP || + event.event == EVENT_OBJECT_RCANON || + event.event == EVENT_OBJECT_RTOWER || + event.event == EVENT_OBJECT_RPHAZER || + event.event == EVENT_OBJECT_RSHIELD || + event.event == EVENT_OBJECT_RATOMIC ) ) + { + if ( m_phase != ALP_WAIT ) + { + return FALSE; + } + + m_research = event.event; + + if ( TestResearch(m_research) ) + { + m_displayText->DisplayError(ERR_RESEARCH_ALREADY, m_object); + return FALSE; + } + + power = m_object->RetPower(); + if ( power == 0 ) + { + m_displayText->DisplayError(ERR_RESEARCH_POWER, m_object); + return FALSE; + } + if ( power->RetCapacity() > 1.0f ) + { + m_displayText->DisplayError(ERR_RESEARCH_TYPE, m_object); + return FALSE; + } + if ( power->RetEnergy() < 1.0f ) + { + m_displayText->DisplayError(ERR_RESEARCH_ENERGY, m_object); + return FALSE; + } + + time = SEARCH_TIME; + if ( event.event == EVENT_OBJECT_RTANK ) time *= 0.3f; + if ( event.event == EVENT_OBJECT_RFLY ) time *= 0.3f; + if ( event.event == EVENT_OBJECT_RATOMIC ) time *= 2.0f; + + SetBusy(TRUE); + InitProgressTotal(time); + UpdateInterface(); + + m_channelSound = m_sound->Play(SOUND_RESEARCH, m_object->RetPosition(0), 0.0f, 1.0f, TRUE); + m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 2.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, time-4.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 2.0f, SOPER_STOP); + + m_phase = ALP_SEARCH; + m_progress = 0.0f; + m_speed = 1.0f/time; + return TRUE; + } + + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Rand()*0.3f; + } + return TRUE; + } + + UpdateInterface(event.rTime); + EventProgress(event.rTime); + + angle = m_time*0.1f; + m_object->SetAngleY(1, angle); // rotates the antenna + + angle = (30.0f+sinf(m_time*0.3f)*20.0f)*PI/180.0f; + m_object->SetAngleZ(2, angle); // directs the antenna + + if ( m_phase == ALP_WAIT ) + { + FireStopUpdate(m_progress, FALSE); // extinguished + return TRUE; + } + + if ( m_phase == ALP_SEARCH ) + { + FireStopUpdate(m_progress, TRUE); // flashes + if ( m_progress < 1.0f ) + { + power = m_object->RetPower(); + if ( power == 0 ) // more battery? + { + SetBusy(FALSE); + UpdateInterface(); + + m_phase = ALP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + return TRUE; + } + power->SetEnergy(1.0f-m_progress); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.x += (Rand()-0.5f)*6.0f; + pos.z += (Rand()-0.5f)*6.0f; + pos.y += 11.0f; + speed.x = (Rand()-0.5f)*2.0f; + speed.z = (Rand()-0.5f)*2.0f; + speed.y = Rand()*20.0f; + dim.x = Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIVAPOR); + } + } + else + { + SetResearch(m_research); // research done + m_displayText->DisplayError(INFO_RESEARCH, m_object); + + message = ERR_OK; + if ( m_research == EVENT_OBJECT_RTANK ) message = INFO_RESEARCHTANK; + if ( m_research == EVENT_OBJECT_RFLY ) message = INFO_RESEARCHFLY; + if ( m_research == EVENT_OBJECT_RTHUMP ) message = INFO_RESEARCHTHUMP; + if ( m_research == EVENT_OBJECT_RCANON ) message = INFO_RESEARCHCANON; + if ( m_research == EVENT_OBJECT_RTOWER ) message = INFO_RESEARCHTOWER; + if ( m_research == EVENT_OBJECT_RPHAZER ) message = INFO_RESEARCHPHAZER; + if ( m_research == EVENT_OBJECT_RSHIELD ) message = INFO_RESEARCHSHIELD; + if ( m_research == EVENT_OBJECT_RATOMIC ) message = INFO_RESEARCHATOMIC; + if ( message != ERR_OK ) + { + m_displayText->DisplayError(message, m_object); + } + + SetBusy(FALSE); + UpdateInterface(); + + m_phase = ALP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + return TRUE; +} + + +// Returns an error due the state of the automation. + +Error CAutoResearch::RetError() +{ + CObject* power; + + if ( m_phase == ALP_SEARCH ) + { + return ERR_OK; + } + + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + power = m_object->RetPower(); + if ( power == 0 ) + { + return ERR_RESEARCH_POWER; + } + if ( power != 0 && power->RetCapacity() > 1.0f ) + { + return ERR_RESEARCH_TYPE; + } + if ( power != 0 && power->RetEnergy() < 1.0f ) + { + return ERR_RESEARCH_ENERGY; + } + + return ERR_OK; +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoResearch::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, dim, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + dim.x = 33.0f/640.0f; + dim.y = 33.0f/480.0f; + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*7.0f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, dim, 64+0, EVENT_OBJECT_RTANK); + + pos.x = ox+sx*8.0f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, dim, 64+1, EVENT_OBJECT_RFLY); + + pos.x = ox+sx*9.0f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, dim, 64+3, EVENT_OBJECT_RCANON); + + pos.x = ox+sx*10.0f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, dim, 64+4, EVENT_OBJECT_RTOWER); + + pos.x = ox+sx*7.0f; + pos.y = oy+sy*0.0f; + pw->CreateButton(pos, dim, 64+7, EVENT_OBJECT_RATOMIC); + + pos.x = ox+sx*8.0f; + pos.y = oy+sy*0.0f; + pw->CreateButton(pos, dim, 64+2, EVENT_OBJECT_RTHUMP); + + pos.x = ox+sx*9.0f; + pos.y = oy+sy*0.0f; + pw->CreateButton(pos, dim, 64+6, EVENT_OBJECT_RSHIELD); + + pos.x = ox+sx*10.0f; + pos.y = oy+sy*0.0f; + pw->CreateButton(pos, dim, 64+5, EVENT_OBJECT_RPHAZER); + + pos.x = ox+sx*14.5f; + pos.y = oy+sy*0; + ddim.x = 14.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 102, EVENT_OBJECT_TYPE); + + UpdateInterface(); + + return TRUE; +} + +// Updates the status of all interface buttons. + +void CAutoResearch::UpdateInterface() +{ + CWindow* pw; + + if ( !m_object->RetSelect() ) return; + + CAuto::UpdateInterface(); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + DeadInterface(pw, EVENT_OBJECT_RTANK, g_researchEnable&RESEARCH_TANK); + DeadInterface(pw, EVENT_OBJECT_RFLY, g_researchEnable&RESEARCH_FLY); + DeadInterface(pw, EVENT_OBJECT_RTHUMP, g_researchEnable&RESEARCH_THUMP); + DeadInterface(pw, EVENT_OBJECT_RCANON, g_researchEnable&RESEARCH_CANON); + DeadInterface(pw, EVENT_OBJECT_RTOWER, g_researchEnable&RESEARCH_TOWER); + DeadInterface(pw, EVENT_OBJECT_RPHAZER, g_researchEnable&RESEARCH_PHAZER); + DeadInterface(pw, EVENT_OBJECT_RSHIELD, g_researchEnable&RESEARCH_SHIELD); + DeadInterface(pw, EVENT_OBJECT_RATOMIC, g_researchEnable&RESEARCH_ATOMIC); + + OkayButton(pw, EVENT_OBJECT_RTANK); + OkayButton(pw, EVENT_OBJECT_RFLY); + OkayButton(pw, EVENT_OBJECT_RTHUMP); + OkayButton(pw, EVENT_OBJECT_RCANON); + OkayButton(pw, EVENT_OBJECT_RTOWER); + OkayButton(pw, EVENT_OBJECT_RPHAZER); + OkayButton(pw, EVENT_OBJECT_RSHIELD); + OkayButton(pw, EVENT_OBJECT_RATOMIC); + + VisibleInterface(pw, EVENT_OBJECT_RTANK, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RFLY, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RTHUMP, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RCANON, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RTOWER, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RPHAZER, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RSHIELD, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RATOMIC, !m_bBusy); +} + +// Updates the state of all buttons on the interface, +// following the time that elapses ... + +void CAutoResearch::UpdateInterface(float rTime) +{ + CWindow* pw; + CGauge* pg; + CObject* power; + float energy; + + CAuto::UpdateInterface(rTime); + + if ( m_time < m_lastUpdateTime+0.1f ) return; + m_lastUpdateTime = m_time; + + if ( !m_object->RetSelect() ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); + if ( pg != 0 ) + { + energy = 0.0f; + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + } + pg->SetLevel(energy); + } +} + +// Research shows already performed button. + +void CAutoResearch::OkayButton(CWindow *pw, EventMsg event) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + control->SetState(STATE_OKAY, TestResearch(event)); +} + + +// Test whether a search has already been done. + +BOOL CAutoResearch::TestResearch(EventMsg event) +{ + if ( event == EVENT_OBJECT_RTANK ) return (g_researchDone & RESEARCH_TANK ); + if ( event == EVENT_OBJECT_RFLY ) return (g_researchDone & RESEARCH_FLY ); + if ( event == EVENT_OBJECT_RTHUMP ) return (g_researchDone & RESEARCH_THUMP ); + if ( event == EVENT_OBJECT_RCANON ) return (g_researchDone & RESEARCH_CANON ); + if ( event == EVENT_OBJECT_RTOWER ) return (g_researchDone & RESEARCH_TOWER ); + if ( event == EVENT_OBJECT_RPHAZER ) return (g_researchDone & RESEARCH_PHAZER ); + if ( event == EVENT_OBJECT_RSHIELD ) return (g_researchDone & RESEARCH_SHIELD); + if ( event == EVENT_OBJECT_RATOMIC ) return (g_researchDone & RESEARCH_ATOMIC); + + return FALSE; +} + +// Indicates a search as made. + +void CAutoResearch::SetResearch(EventMsg event) +{ + Event newEvent; + + if ( event == EVENT_OBJECT_RTANK ) g_researchDone |= RESEARCH_TANK; + if ( event == EVENT_OBJECT_RFLY ) g_researchDone |= RESEARCH_FLY; + if ( event == EVENT_OBJECT_RTHUMP ) g_researchDone |= RESEARCH_THUMP; + if ( event == EVENT_OBJECT_RCANON ) g_researchDone |= RESEARCH_CANON; + if ( event == EVENT_OBJECT_RTOWER ) g_researchDone |= RESEARCH_TOWER; + if ( event == EVENT_OBJECT_RPHAZER ) g_researchDone |= RESEARCH_PHAZER; + if ( event == EVENT_OBJECT_RSHIELD ) g_researchDone |= RESEARCH_SHIELD; + if ( event == EVENT_OBJECT_RATOMIC ) g_researchDone |= RESEARCH_ATOMIC; + + m_main->WriteFreeParam(); + + m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); + m_event->AddEvent(newEvent); + UpdateInterface(); +} + + +// Updates the stop lights. + +void CAutoResearch::FireStopUpdate(float progress, BOOL bLightOn) +{ + D3DMATRIX* mat; + D3DVECTOR pos, speed; + FPOINT dim; + int i; + + static float listpos[12] = + { + 9.5f, 0.0f, + 4.7f, 8.2f, + -4.7f, 8.2f, + -9.5f, 0.0f, + -4.7f, -8.2f, + 4.7f, -8.2f, + }; + + if ( !bLightOn ) // �teint ? + { + for ( i=0 ; i<6 ; i++ ) + { + if ( m_partiStop[i] != -1 ) + { + m_particule->DeleteParticule(m_partiStop[i]); + m_partiStop[i] = -1; + } + } + return; + } + + mat = m_object->RetWorldMatrix(0); + + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 2.0f; + dim.y = dim.x; + + for ( i=0 ; i<6 ; i++ ) + { + if ( Mod(progress, 0.025f) < 0.005f ) + { + if ( m_partiStop[i] != -1 ) + { + m_particule->DeleteParticule(m_partiStop[i]); + m_partiStop[i] = -1; + } + } + else + { + if ( m_partiStop[i] == -1 ) + { + pos.x = listpos[i*2+0]; + pos.y = 11.5f; + pos.z = listpos[i*2+1]; + pos = Transform(*mat, pos); + m_partiStop[i] = m_particule->CreateParticule(pos, speed, + dim, PARTISELY, + 1.0f, 0.0f, 0.0f); + } + } + } +} + + +// Saves all parameters of the controller. + +BOOL CAutoResearch::Write(char *line) +{ + char name[100]; + + if ( m_phase == ALP_WAIT ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + sprintf(name, " aResearch=%d", m_research); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller. + +BOOL CAutoResearch::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoResearchPhase)OpInt(line, "aPhase", ALP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + m_research = (EventMsg)OpInt(line, "aResearch", 0); + + m_lastUpdateTime = 0.0f; + m_lastParticule = 0.0f; + + return TRUE; +} + + diff --git a/src/object/auto/autoresearch.h b/src/object/auto/autoresearch.h new file mode 100644 index 0000000..f773084 --- /dev/null +++ b/src/object/auto/autoresearch.h @@ -0,0 +1,82 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autoresearch.h + +#ifndef _AUTORESEARCH_H_ +#define _AUTORESEARCH_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoResearchPhase +{ + ALP_WAIT = 1, + ALP_SEARCH = 2, // research in progress +}; + + + +class CAutoResearch : public CAuto +{ +public: + CAutoResearch(CInstanceManager* iMan, CObject* object); + ~CAutoResearch(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + + BOOL CreateInterface(BOOL bSelect); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + void UpdateInterface(); + void UpdateInterface(float rTime); + void OkayButton(CWindow *pw, EventMsg event); + BOOL TestResearch(EventMsg event); + void SetResearch(EventMsg event); + void FireStopUpdate(float progress, BOOL bLightOn); + +protected: + AutoResearchPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastUpdateTime; + float m_lastParticule; + EventMsg m_research; + int m_partiStop[6]; + int m_channelSound; +}; + + +#endif //_AUTORESEARCH_H_ diff --git a/src/object/auto/autoroot.cpp b/src/object/auto/autoroot.cpp new file mode 100644 index 0000000..5f1afad --- /dev/null +++ b/src/object/auto/autoroot.cpp @@ -0,0 +1,135 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "auto.h" +#include "autoroot.h" + + + + +// Object's constructor. + +CAutoRoot::CAutoRoot(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + Init(); +} + +// Object's destructor. + +CAutoRoot::~CAutoRoot() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoRoot::DeleteObject(BOOL bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoRoot::Init() +{ + D3DMATRIX* mat; + D3DVECTOR pos, speed; + FPOINT dim; + + m_time = 0.0f; + m_lastParticule = 0.0f; + + mat = m_object->RetWorldMatrix(0); + pos = D3DVECTOR(-5.0f, 28.0f, -4.0f); // peak position + pos = Transform(*mat, pos); + m_center = pos; + + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 100.0f; + dim.y = dim.x; + m_particule->CreateParticule(m_center, speed, dim, PARTISPHERE5, 0.5f, 0.0f, 0.0f); + + m_terrain->AddFlyingLimit(pos, 100.0f, 80.0f, pos.y-60.0f); +} + + +// Management of an event. + +BOOL CAutoRoot::EventProcess(const Event &event) +{ + D3DVECTOR pos, speed; + FPOINT dim; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_object->SetZoomX(1, 1.0f+sinf(m_time*2.0f)*0.2f); + m_object->SetZoomY(1, 1.0f+sinf(m_time*2.3f)*0.2f); + m_object->SetZoomZ(1, 1.0f+sinf(m_time*2.7f)*0.2f); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_center; + pos.x += (Rand()-0.5f)*8.0f; + pos.z += (Rand()-0.5f)*8.0f; + pos.y += 0.0f; + speed.x = (Rand()-0.5f)*12.0f; + speed.z = (Rand()-0.5f)*12.0f; + speed.y = Rand()*12.0f; + dim.x = Rand()*6.0f+4.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIROOT, 1.0f, 0.0f, 0.0f); + } + + return TRUE; +} + + +// Returns an error due the state of the automation. + +Error CAutoRoot::RetError() +{ + return ERR_OK; +} + + diff --git a/src/object/auto/autoroot.h b/src/object/auto/autoroot.h new file mode 100644 index 0000000..85bdb69 --- /dev/null +++ b/src/object/auto/autoroot.h @@ -0,0 +1,56 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autoroot.h + +#ifndef _AUTOROOT_H_ +#define _AUTOROOT_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +class CAutoRoot : public CAuto +{ +public: + CAutoRoot(CInstanceManager* iMan, CObject* object); + ~CAutoRoot(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + +protected: + +protected: + float m_lastParticule; + D3DVECTOR m_center; +}; + + +#endif //_AUTOROOT_H_ diff --git a/src/object/auto/autosafe.cpp b/src/object/auto/autosafe.cpp new file mode 100644 index 0000000..bdc6d32 --- /dev/null +++ b/src/object/auto/autosafe.cpp @@ -0,0 +1,636 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "global.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "light.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "interface.h" +#include "button.h" +#include "robotmain.h" +#include "window.h" +#include "sound.h" +#include "displaytext.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autosafe.h" + + + +#define OPEN_DELAY 8.0f // duration of opening + + + + +// Object's constructor. + +CAutoSafe::CAutoSafe(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + int i; + + CAuto::CAuto(iMan, object); + + for ( i=0 ; i<4 ; i++ ) + { + m_bKey[i] = FALSE; + m_keyParti[i] = -1; + } + + m_bLock = FALSE; + m_lastParticule = 0.0f; + m_channelSound = -1; + Init(); +} + +// Object's destructor. + +CAutoSafe::~CAutoSafe() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoSafe::DeleteObject(BOOL bAll) +{ + CObject* pObj; + + pObj = SearchVehicle(); + if ( pObj != 0 ) + { + pObj->DeleteObject(); + delete pObj; + } + + if ( m_channelSound != -1 ) + { + m_sound->FlushEnvelope(m_channelSound); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_channelSound = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoSafe::Init() +{ + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + + m_countKeys = 0; + m_actualAngle = 0.0f; + m_finalAngle = 0.0f; + + m_phase = ASAP_WAIT; // waiting ... + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + CAuto::Init(); +} + + +// Management of an event. + +BOOL CAutoSafe::EventProcess(const Event &event) +{ + CObject* pObj; + D3DVECTOR pos, speed; + FPOINT dim; + int i, count; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Rand()*0.3f; + } + return TRUE; + } + + EventProgress(event.rTime); + + if ( !m_bLock ) + { + pObj = SearchVehicle(); + if ( pObj != 0 ) + { + pObj->SetLock(TRUE); // object not yet usable + m_main->CreateShortcuts(); + m_bLock = TRUE; + } + } + + if ( m_phase == ASAP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + count = CountKeys(); // count these key + if ( count != m_countKeys ) + { + m_countKeys = count; + + if ( count == 0 ) m_finalAngle = 0.0f*PI/180.0f; + if ( count == 1 ) m_finalAngle = 5.0f*PI/180.0f; + if ( count == 2 ) m_finalAngle = 10.0f*PI/180.0f; + if ( count == 3 ) m_finalAngle = 15.0f*PI/180.0f; + if ( count == 4 ) m_finalAngle = 120.0f*PI/180.0f; + + if ( count == 4 ) // all the keys? + { + LockKeys(); + + m_channelSound = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 1.0f, 0.25f, TRUE); + m_sound->AddEnvelope(m_channelSound, 1.0f, 2.00f, OPEN_DELAY, SOPER_STOP); + + m_phase = ASAP_OPEN; + m_progress = 0.0f; + m_speed = 1.0f/OPEN_DELAY; + return TRUE; + } + else + { + m_channelSound = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 1.0f, 0.25f, TRUE); + m_sound->AddEnvelope(m_channelSound, 1.0f, 0.35f, 0.5f, SOPER_STOP); + } + } + + m_phase = ASAP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ASAP_OPEN ) + { + if ( m_progress < 1.0f ) + { + DownKeys(m_progress); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + for ( i=0 ; i<10 ; i++ ) + { + pos = m_object->RetPosition(0); + pos.x += (Rand()-0.5f)*10.0f; + pos.z += (Rand()-0.5f)*10.0f; + speed.x = (Rand()-0.5f)*4.0f; + speed.z = (Rand()-0.5f)*4.0f; + speed.y = Rand()*15.0f; + dim.x = Rand()*6.0f+4.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); + } + + pos = m_object->RetPosition(0); + pos.x += (Rand()-0.5f)*10.0f; + pos.z += (Rand()-0.5f)*10.0f; + speed.x = (Rand()-0.5f)*4.0f; + speed.z = (Rand()-0.5f)*4.0f; + speed.y = Rand()*10.0f; + dim.x = Rand()*3.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 1.0f, 0.0f, 0.0f); + + for ( i=0 ; i<4 ; i++ ) + { + pos = m_keyPos[i]; + speed.x = (Rand()-0.5f)*2.0f; + speed.z = (Rand()-0.5f)*2.0f; + speed.y = 1.0f+Rand()*1.0f; + dim.x = Rand()*1.5f+1.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 0.0f); + } + } + } + else + { + DeleteKeys(); + + pObj = SearchVehicle(); + if ( pObj != 0 ) + { + pObj->SetLock(FALSE); // object usable + m_main->CreateShortcuts(); + } + + m_object->FlushCrashShere(); + m_object->SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 0.0f); + + m_sound->Play(SOUND_FINDING, m_object->RetPosition(0)); + + m_phase = ASAP_FINISH; + m_progress = 0.0f; + m_speed = 1.0f/100.0f; + } + } + + if ( m_phase == ASAP_FINISH ) + { + if ( m_progress >= 1.0f ) + { + m_phase = ASAP_FINISH; + m_progress = 0.0f; + m_speed = 1.0f/100.0f; + } + } + + // Opens or closes the doors. + if ( m_actualAngle != m_finalAngle ) + { + if ( m_actualAngle < m_finalAngle ) + { + m_actualAngle += (105.0f*PI/180.0f)*event.rTime/OPEN_DELAY; + if ( m_actualAngle > m_finalAngle ) m_actualAngle = m_finalAngle; + } + else + { + m_actualAngle -= (105.0f*PI/180.0f)*event.rTime/OPEN_DELAY; + if ( m_actualAngle < m_finalAngle ) m_actualAngle = m_finalAngle; + } + m_object->SetAngleZ(1, m_actualAngle); + m_object->SetAngleZ(2, -m_actualAngle); + } + + // Blinks the keys. + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 2.0f; + dim.y = dim.x; + for ( i=0 ; i<4 ; i++ ) + { + if ( m_phase != ASAP_WAIT || !m_bKey[i] || Mod(m_time, 1.0f) < 0.4f ) + { + if ( m_keyParti[i] != -1 ) + { + m_particule->DeleteParticule(m_keyParti[i]); + m_keyParti[i] = -1; + } + } + else + { + if ( m_keyParti[i] == -1 ) + { + pos = m_keyPos[i]; + pos.y += 2.2f; + m_keyParti[i] = m_particule->CreateParticule(pos, speed, dim, PARTISELY, 1.0f, 0.0f, 0.0f); + } + } + } + + return TRUE; +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoSafe::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 114, EVENT_OBJECT_TYPE); + + return TRUE; +} + + +// Returns an error due the state of the automation. + +Error CAutoSafe::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + return ERR_OK; +} + + +// Saves all parameters of the controller. + +BOOL CAutoSafe::Write(char *line) +{ + char name[100]; + + if ( m_phase == ASAP_WAIT ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller. + +BOOL CAutoSafe::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoSafePhase)OpInt(line, "aPhase", ASAP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return TRUE; +} + + +// Counts the number of keys + +int CAutoSafe::CountKeys() +{ + CObject* pObj; + D3DVECTOR cPos, oPos; + FPOINT rot; + ObjectType oType; + float dist, angle, limit, cAngle, oAngle; + int i, index; + + cPos = m_object->RetPosition(0); + cAngle = m_object->RetAngleY(0); + + for ( index=0 ; index<4 ; index++ ) + { + m_bKey[index] = FALSE; + m_keyPos[index] = cPos; + } + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( pObj->RetTruck() != 0 ) continue; + + if ( oType != OBJECT_KEYa && + oType != OBJECT_KEYb && + oType != OBJECT_KEYc && + oType != OBJECT_KEYd ) continue; + + oPos = pObj->RetPosition(0); + dist = Length2d(oPos, cPos); + if ( dist > 20.0f ) continue; + + if ( oType == OBJECT_KEYa ) + { + limit = PI*1.0f; + oAngle = PI*0.0f; + index = 0; + } + if ( oType == OBJECT_KEYb ) + { + limit = PI*0.0f; + oAngle = PI*1.0f; + index = 1; + } + if ( oType == OBJECT_KEYc ) + { + limit = PI*1.5f; + oAngle = PI*0.5f; + index = 2; + } + if ( oType == OBJECT_KEYd ) + { + limit = PI*0.5f; + oAngle = PI*0.0f; + index = 3; + } + + angle = RotateAngle(oPos.x-cPos.x, oPos.z-cPos.z)+cAngle; + if ( !TestAngle(angle, limit-8.0f*PI/180.0f, limit+8.0f*PI/180.0f) ) continue; + + // Key changes the shape of the base. + rot = RotatePoint(FPOINT(cPos.x, cPos.z), limit-cAngle, FPOINT(cPos.x+16.0f, cPos.z)); + oPos.x = rot.x; + oPos.z = rot.y; + oPos.y = cPos.y+1.0f; + pObj->SetPosition(0, oPos); + pObj->SetAngleY(0, oAngle+cAngle); + m_keyPos[index] = oPos; + + m_bKey[index] = TRUE; + } + + i = 0; + for ( index=0 ; index<4 ; index++ ) + { + if ( m_bKey[index] ) i++; + } + return i; +} + +// Blocks all keys. + +void CAutoSafe::LockKeys() +{ + CObject* pObj; + D3DVECTOR cPos, oPos; + ObjectType oType; + float dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( pObj->RetTruck() != 0 ) continue; + + if ( oType != OBJECT_KEYa && + oType != OBJECT_KEYb && + oType != OBJECT_KEYc && + oType != OBJECT_KEYd ) continue; + + oPos = pObj->RetPosition(0); + dist = Length2d(oPos, cPos); + if ( dist > 20.0f ) continue; + + pObj->SetLock(TRUE); + } +} + +// Sent down all the keys. + +void CAutoSafe::DownKeys(float progress) +{ + CObject* pObj; + D3DVECTOR cPos, oPos; + ObjectType oType; + float dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( pObj->RetTruck() != 0 ) continue; + + if ( oType != OBJECT_KEYa && + oType != OBJECT_KEYb && + oType != OBJECT_KEYc && + oType != OBJECT_KEYd ) continue; + + oPos = pObj->RetPosition(0); + dist = Length2d(oPos, cPos); + if ( dist > 20.0f ) continue; + + oPos.y = cPos.y+1.0f-progress*2.2f; + pObj->SetPosition(0, oPos); + } +} + +// Delete all the keys. + +void CAutoSafe::DeleteKeys() +{ + CObject* pObj; + D3DVECTOR cPos, oPos; + ObjectType oType; + float dist; + int i; + BOOL bDelete; + + cPos = m_object->RetPosition(0); + + do + { + bDelete = FALSE; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( pObj->RetTruck() != 0 ) continue; + + if ( oType != OBJECT_KEYa && + oType != OBJECT_KEYb && + oType != OBJECT_KEYc && + oType != OBJECT_KEYd ) continue; + + oPos = pObj->RetPosition(0); + dist = Length2d(oPos, cPos); + if ( dist > 20.0f ) continue; + + pObj->DeleteObject(); + delete pObj; + bDelete = TRUE; + } + } + while ( bDelete ); +} + +// Seeking a vehicle in the safe. + +CObject* CAutoSafe::SearchVehicle() +{ + CObject* pObj; + D3DVECTOR cPos, oPos; + ObjectType oType; + float dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( pObj == m_object ) continue; + if ( pObj->RetTruck() != 0 ) continue; + + oPos = pObj->RetPosition(0); + dist = Length2d(oPos, cPos); + if ( dist <= 4.0f ) return pObj; + } + return 0; +} + + + diff --git a/src/object/auto/autosafe.h b/src/object/auto/autosafe.h new file mode 100644 index 0000000..b60472d --- /dev/null +++ b/src/object/auto/autosafe.h @@ -0,0 +1,86 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autosafe.h + +#ifndef _AUTOSAFE_H_ +#define _AUTOSAFE_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoSafePhase +{ + ASAP_WAIT = 1, + ASAP_OPEN = 2, + ASAP_FINISH = 3, +}; + + + +class CAutoSafe : public CAuto +{ +public: + CAutoSafe(CInstanceManager* iMan, CObject* object); + ~CAutoSafe(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + + BOOL CreateInterface(BOOL bSelect); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + int CountKeys(); + void LockKeys(); + void DownKeys(float progress); + void DeleteKeys(); + CObject* SearchVehicle(); + +protected: + AutoSafePhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + int m_channelSound; + BOOL m_bLock; + int m_countKeys; + float m_actualAngle; + float m_finalAngle; + BOOL m_bKey[4]; + D3DVECTOR m_keyPos[4]; + int m_keyParti[4]; +}; + + +#endif //_AUTOSAFE_H_ diff --git a/src/object/auto/autostation.cpp b/src/object/auto/autostation.cpp new file mode 100644 index 0000000..1e23e1d --- /dev/null +++ b/src/object/auto/autostation.cpp @@ -0,0 +1,387 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "light.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "interface.h" +#include "button.h" +#include "gauge.h" +#include "window.h" +#include "sound.h" +#include "auto.h" +#include "autostation.h" + + + + +// Object's constructor. + +CAutoStation::CAutoStation(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + CAuto::CAuto(iMan, object); + + Init(); +} + +// Object's destructor. + +CAutoStation::~CAutoStation() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoStation::DeleteObject(BOOL bAll) +{ + if ( m_soundChannel != -1 ) + { + m_sound->Stop(m_soundChannel); + m_soundChannel = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoStation::Init() +{ + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastUpdateTime = 0.0f; + m_lastParticule = 0.0f; + m_soundChannel = -1; + m_bLastVirus = FALSE; + + CAuto::Init(); +} + + +// Management of an event. + +BOOL CAutoStation::EventProcess(const Event &event) +{ + D3DMATRIX* mat; + D3DVECTOR pos, ppos, speed; + FPOINT dim; + CObject* vehicule; + CObject* power; + TerrainRes res; + float big, energy, used, add, freq; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( !m_bLastVirus ) + { + m_bLastVirus = TRUE; + m_energyVirus = m_object->RetEnergy(); + } + + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Rand()*0.3f; + + m_object->SetEnergy(Rand()); + } + return TRUE; + } + else + { + if ( m_bLastVirus ) + { + m_bLastVirus = FALSE; + m_object->SetEnergy(m_energyVirus); + } + } + + UpdateInterface(event.rTime); + + big = m_object->RetEnergy(); + + res = m_terrain->RetResource(m_object->RetPosition(0)); + if ( res == TR_POWER ) + { + big += event.rTime*0.01f; // recharges the large battery + } + + used = big; + freq = 1.0f; + if ( big > 0.0f ) + { + vehicule = SearchVehicle(); + if ( vehicule != 0 ) + { + power = vehicule->RetPower(); + if ( power != 0 && power->RetCapacity() == 1.0f ) + { + energy = power->RetEnergy(); + add = event.rTime*0.2f; + if ( add > big*4.0f ) add = big*4.0f; + if ( add > 1.0f-energy ) add = 1.0f-energy; + energy += add; // Charging the battery + power->SetEnergy(energy); + if ( energy < freq ) freq = energy; + big -= add/4.0f; // discharge the large battery + } + + power = vehicule->RetFret(); + if ( power != 0 && power->RetType() == OBJECT_POWER ) + { + energy = power->RetEnergy(); + add = event.rTime*0.2f; + if ( add > big*4.0f ) add = big*4.0f; + if ( add > 1.0f-energy ) add = 1.0f-energy; + energy += add; // Charging the battery + power->SetEnergy(energy); + if ( energy < freq ) freq = energy; + big -= add/4.0f; // discharge the large battery + } + } + } + used -= big; // energy used + + if ( freq < 1.0f ) // charging in progress? + { + freq = 1.0f+3.0f*freq; + if ( m_soundChannel == -1 ) + { + m_soundChannel = m_sound->Play(SOUND_STATION, m_object->RetPosition(0), + 0.3f, freq, TRUE); + } + m_sound->Frequency(m_soundChannel, freq); + } + else + { + if ( m_soundChannel != -1 ) + { + m_sound->Stop(m_soundChannel); + m_soundChannel = -1; + } + } + + if ( used != 0.0f && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + mat = m_object->RetWorldMatrix(0); + pos = D3DVECTOR(-15.0f, 7.0f, 0.0f); // battery position + pos = Transform(*mat, pos); + speed.x = (Rand()-0.5f)*20.0f; + speed.y = (Rand()-0.5f)*20.0f; + speed.z = (Rand()-0.5f)*20.0f; + ppos.x = pos.x; + ppos.y = pos.y+(Rand()-0.5f)*4.0f; + ppos.z = pos.z; + dim.x = 1.5f; + dim.y = 1.5f; + m_particule->CreateParticule(ppos, speed, dim, PARTIBLITZ, 1.0f, 0.0f, 0.0f); + +#if 0 + ppos = pos; + ppos.y += 1.0f; + ppos.x += (Rand()-0.5f)*3.0f; + ppos.z += (Rand()-0.5f)*3.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 2.5f+Rand()*6.0f; + dim.x = Rand()*1.5f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(ppos, speed, dim, PARTISMOKE3, 4.0f); +#else + ppos = pos; + ppos.y += 1.0f; + ppos.x += (Rand()-0.5f)*3.0f; + ppos.z += (Rand()-0.5f)*3.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 2.5f+Rand()*5.0f; + dim.x = Rand()*1.0f+0.6f; + dim.y = dim.x; + m_particule->CreateParticule(ppos, speed, dim, PARTIVAPOR, 3.0f); +#endif + } + + if ( big < 0.0f ) big = 0.0f; + if ( big > 1.0f ) big = 1.0f; + m_object->SetEnergy(big); // Shift the large battery + + return TRUE; +} + + +// Seeking the vehicle on the station. + +CObject* CAutoStation::SearchVehicle() +{ + CObject* pObj; + D3DVECTOR sPos, oPos; + ObjectType type; + float dist; + int i; + + sPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_HUMAN && + type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr ) continue; + + oPos = pObj->RetPosition(0); + dist = Length(oPos, sPos); + if ( dist <= 5.0f ) return pObj; + } + + return 0; +} + + +// Returns an error due the state of the automation. + +Error CAutoStation::RetError() +{ + TerrainRes res; + + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + res = m_terrain->RetResource(m_object->RetPosition(0)); + if ( res != TR_POWER ) return ERR_STATION_NULL; + + return ERR_OK; +} + + +// Crée toute l'interface lorsque l'objet est sélectionné . + +BOOL CAutoStation::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*14.5f; + pos.y = oy+sy*0; + ddim.x = 14.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 104, EVENT_OBJECT_TYPE); + + return TRUE; +} + +// Updates the state of all buttons on the interface, +// following the time that elapses ... + +void CAutoStation::UpdateInterface(float rTime) +{ + CWindow* pw; + CGauge* pg; + + CAuto::UpdateInterface(rTime); + + if ( m_time < m_lastUpdateTime+0.1f ) return; + m_lastUpdateTime = m_time; + + if ( !m_object->RetSelect() ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); + if ( pg != 0 ) + { + pg->SetLevel(m_object->RetEnergy()); + } +} + + diff --git a/src/object/auto/autostation.h b/src/object/auto/autostation.h new file mode 100644 index 0000000..d783cc9 --- /dev/null +++ b/src/object/auto/autostation.h @@ -0,0 +1,68 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autostation.h + +#ifndef _AUTOSTATION_H_ +#define _AUTOSTATION_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +class CAutoStation : public CAuto +{ +public: + CAutoStation(CInstanceManager* iMan, CObject* object); + ~CAutoStation(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + + BOOL CreateInterface(BOOL bSelect); + +protected: + void UpdateInterface(float rTime); + + CObject* SearchVehicle(); + +protected: + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastUpdateTime; + float m_lastParticule; + int m_soundChannel; + D3DVECTOR m_fretPos; + BOOL m_bLastVirus; + float m_energyVirus; +}; + + +#endif //_AUTOSTATION_H_ diff --git a/src/object/auto/autotower.cpp b/src/object/auto/autotower.cpp new file mode 100644 index 0000000..7dcdb05 --- /dev/null +++ b/src/object/auto/autotower.cpp @@ -0,0 +1,561 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "global.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "particule.h" +#include "terrain.h" +#include "camera.h" +#include "object.h" +#include "physics.h" +#include "interface.h" +#include "button.h" +#include "gauge.h" +#include "window.h" +#include "sound.h" +#include "displaytext.h" +#include "cmdtoken.h" +#include "auto.h" +#include "autotower.h" + + + +#define TOWER_SCOPE 200.0f // range of beam +#define ENERGY_FIRE 0.125f // energy consumed by fire + + +// Object's constructor. + +CAutoTower::CAutoTower(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + int i; + + CAuto::CAuto(iMan, object); + + for ( i=0 ; i<4 ; i++ ) + { + m_partiStop[i] = -1; + } + + Init(); + m_phase = ATP_WAIT; // paused until the first Init () + m_time = 0.0f; + m_lastUpdateTime = 0.0f; +} + +// Object's destructor. + +CAutoTower::~CAutoTower() +{ + this->CAuto::~CAuto(); +} + + +// Destroys the object. + +void CAutoTower::DeleteObject(BOOL bAll) +{ + FireStopUpdate(0.0f, FALSE); + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoTower::Init() +{ + m_phase = ATP_ZERO; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastUpdateTime = 0.0f; + m_lastParticule = 0.0f; +} + + +// Management of an event. + +BOOL CAutoTower::EventProcess(const Event &event) +{ + CObject* power; + CObject* target; + D3DVECTOR pos; + float angle, energy, quick; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Rand()*0.3f; + + angle = m_object->RetAngleY(1); + angle += Rand()*0.5f; + m_object->SetAngleY(1, angle); + + m_object->SetAngleZ(2, Rand()*0.5f); + } + return TRUE; + } + + UpdateInterface(event.rTime); + + if ( m_phase == ATP_WAIT ) return TRUE; + + m_progress += event.rTime*m_speed; + + if ( m_phase == ATP_ZERO ) + { + FireStopUpdate(m_progress, TRUE); // blinks + if ( m_progress < 1.0f ) + { + energy = 0.0f; + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + } + if ( energy >= ENERGY_FIRE ) + { + m_phase = ATP_SEARCH; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + } + else + { + m_phase = ATP_ZERO; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ATP_SEARCH ) + { + FireStopUpdate(m_progress, FALSE); // extinguished + if ( m_progress < 1.0f ) + { + quick = 1.0f; +//? if ( g_researchDone & RESEARCH_QUICK ) quick = 3.0f; + + angle = m_object->RetAngleY(1); + angle -= event.rTime*quick*2.0f; + m_object->SetAngleY(1, angle); + + angle = m_object->RetAngleZ(2); + angle += event.rTime*quick*0.5f; + if ( angle > 0.0f ) angle = 0.0f; + m_object->SetAngleZ(2, angle); + } + else + { + energy = 0.0f; + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + } + + target = SearchTarget(m_targetPos); + if ( energy < ENERGY_FIRE ) + { + m_displayText->DisplayError(ERR_TOWER_ENERGY, m_object); + } + if ( target == 0 || energy < ENERGY_FIRE ) + { + m_phase = ATP_ZERO; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + else + { + pos = m_object->RetPosition(0); + pos.y += 24.5f; + m_angleYfinal = RotateAngle(m_targetPos.x-pos.x, pos.z-m_targetPos.z); // CW ! + m_angleYfinal += PI*2.0f; + m_angleYfinal -= m_object->RetAngleY(0); + m_angleYactual = NormAngle(m_object->RetAngleY(1)); + + m_angleZfinal = -PI/2.0f; + m_angleZfinal -= RotateAngle(Length2d(m_targetPos, pos), pos.y-m_targetPos.y); // CW ! + m_angleZactual = m_object->RetAngleZ(2); + + m_phase = ATP_TURN; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; +//? if ( g_researchDone & RESEARCH_QUICK ) m_speed = 1.0f/0.2f; + } + } + } + + if ( m_phase == ATP_TURN ) + { + if ( m_progress < 1.0f ) + { + angle = m_angleYactual+(m_angleYfinal-m_angleYactual)*m_progress; + m_object->SetAngleY(1, angle); + + angle = m_angleZactual+(m_angleZfinal-m_angleZactual)*m_progress; + m_object->SetAngleZ(2, angle); + } + else + { + m_object->SetAngleY(1, m_angleYfinal); + m_object->SetAngleZ(2, m_angleZfinal); + + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + energy -= ENERGY_FIRE/power->RetCapacity(); + power->SetEnergy(energy); + } + + m_sound->Play(SOUND_GGG, m_object->RetPosition(0)); + + m_phase = ATP_FIRE; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + + if ( m_phase == ATP_FIRE ) + { + if ( m_progress == 0.0f ) + { + pos = m_object->RetPosition(0); + pos.y += 24.5f; + m_particule->CreateRay(pos, m_targetPos, PARTIRAY1, + FPOINT(5.0f, 5.0f), 1.5f); + } + if ( m_progress >= 1.0f ) + { + m_phase = ATP_ZERO; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + return TRUE; +} + + +// Seeks the nearest target object. + +CObject* CAutoTower::SearchTarget(D3DVECTOR &impact) +{ + CObject* pObj; + CObject* pBest = 0; + CPhysics* physics; + D3DVECTOR iPos, oPos; + ObjectType oType; + float distance, min, radius, speed; + int i; + + iPos = m_object->RetPosition(0); + min = 1000000.0f; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( oType != OBJECT_MOTHER && + oType != OBJECT_ANT && + oType != OBJECT_SPIDER && + oType != OBJECT_BEE && + oType != OBJECT_WORM ) continue; + + if ( !pObj->RetActif() ) continue; // inactive? + +//? if ( g_researchDone & RESEARCH_QUICK ) + if ( FALSE ) + { + physics = pObj->RetPhysics(); + if ( physics != 0 ) + { + speed = Abs(physics->RetLinMotionX(MO_REASPEED)); + if ( speed > 20.0f ) continue; // moving too fast? + } + } + + if ( !pObj->GetCrashSphere(0, oPos, radius) ) continue; + distance = Length(oPos, iPos); + if ( distance > TOWER_SCOPE ) continue; // too far + if ( distance < min ) + { + min = distance; + pBest = pObj; + } + } + if ( pBest == 0 ) return 0; + + impact = pBest->RetPosition(0); + return pBest; +} + + +// Returns an error due the state of the automation. + +Error CAutoTower::RetError() +{ + CObject* power; + + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + power = m_object->RetPower(); + if ( power == 0 ) + { + return ERR_TOWER_POWER; // no battery + } + else + { + if ( power->RetEnergy() < ENERGY_FIRE ) + { + return ERR_TOWER_ENERGY; // not enough energy + } + } + return ERR_OK; +} + + +// Updates the stop lights. + +void CAutoTower::FireStopUpdate(float progress, BOOL bLightOn) +{ + D3DMATRIX* mat; + D3DVECTOR pos, speed; + FPOINT dim; + int i; + + static float listpos[8] = + { + 4.5f, 0.0f, + 0.0f, 4.5f, + -4.5f, 0.0f, + 0.0f, -4.5f, + }; + + if ( !bLightOn ) // extinguished? + { + for ( i=0 ; i<4 ; i++ ) + { + if ( m_partiStop[i] != -1 ) + { + m_particule->DeleteParticule(m_partiStop[i]); + m_partiStop[i] = -1; + } + } + return; + } + + mat = m_object->RetWorldMatrix(0); + + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 2.0f; + dim.y = dim.x; + + for ( i=0 ; i<4 ; i++ ) + { + if ( Mod(progress+i*0.125f, 0.5f) < 0.2f ) + { + if ( m_partiStop[i] != -1 ) + { + m_particule->DeleteParticule(m_partiStop[i]); + m_partiStop[i] = -1; + } + } + else + { + if ( m_partiStop[i] == -1 ) + { + pos.x = listpos[i*2+0]; + pos.y = 18.0f; + pos.z = listpos[i*2+1]; + pos = Transform(*mat, pos); + m_partiStop[i] = m_particule->CreateParticule(pos, speed, + dim, PARTISELR, + 1.0f, 0.0f, 0.0f); + } + } + } +} + + +// Creates all the interface when the object is selected. + +BOOL CAutoTower::CreateInterface(BOOL bSelect) +{ + CWindow* pw; + FPOINT pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*14.5f; + pos.y = oy+sy*0; + ddim.x = 14.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 107, EVENT_OBJECT_TYPE); + + pos.x = ox+sx*10.2f; + pos.y = oy+sy*0.5f; + ddim.x = 33.0f/640.0f; + ddim.y = 33.0f/480.0f; + pw->CreateButton(pos, ddim, 41, EVENT_OBJECT_LIMIT); + + return TRUE; +} + +// Updates the state of all buttons on the interface, +// following the time that elapses ... + +void CAutoTower::UpdateInterface(float rTime) +{ + CWindow* pw; + CGauge* pg; + CObject* power; + float energy; + + CAuto::UpdateInterface(rTime); + + if ( m_time < m_lastUpdateTime+0.1f ) return; + m_lastUpdateTime = m_time; + + if ( !m_object->RetSelect() ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); + if ( pg != 0 ) + { + energy = 0.0f; + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + } + pg->SetLevel(energy); + } +} + + +// Saves all parameters of the controller. + +BOOL CAutoTower::Write(char *line) +{ + char name[100]; + + if ( m_phase == ATP_WAIT ) return FALSE; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + sprintf(name, " aTargetPos=%.2f;%.2f;%.2f", m_targetPos.x, m_targetPos.y, m_targetPos.z); + strcat(line, name); + + sprintf(name, " aAngleYactual=%.2f", m_angleYactual); + strcat(line, name); + + sprintf(name, " aAngleZactual=%.2f", m_angleZactual); + strcat(line, name); + + sprintf(name, " aAngleYfinal=%.2f", m_angleYfinal); + strcat(line, name); + + sprintf(name, " aAngleZfinal=%.2f", m_angleZfinal); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the controller. + +BOOL CAutoTower::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return FALSE; + + CAuto::Read(line); + + m_phase = (AutoTowerPhase)OpInt(line, "aPhase", ATP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + m_targetPos = OpDir(line, "aTargetPos"); + m_angleYactual = OpFloat(line, "aAngleYactual", 0.0f); + m_angleZactual = OpFloat(line, "aAngleZactual", 0.0f); + m_angleYfinal = OpFloat(line, "aAngleYfinal", 0.0f); + m_angleZfinal = OpFloat(line, "aAngleZfinal", 0.0f); + + m_lastUpdateTime = 0.0f; + + return TRUE; +} + + diff --git a/src/object/auto/autotower.h b/src/object/auto/autotower.h new file mode 100644 index 0000000..fa7e6cb --- /dev/null +++ b/src/object/auto/autotower.h @@ -0,0 +1,86 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// autotower.h + +#ifndef _AUTOTOWER_H_ +#define _AUTOTOWER_H_ + + +#include "auto.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CTerrain; +class CCamera; +class CObject; + + + +enum AutoTowerPhase +{ + ATP_WAIT = 1, + ATP_ZERO = 2, // more energy + ATP_SEARCH = 3, // search a target + ATP_TURN = 4, // turns to the target + ATP_FIRE = 5, // shoots on the target +}; + + + +class CAutoTower : public CAuto +{ +public: + CAutoTower(CInstanceManager* iMan, CObject* object); + ~CAutoTower(); + + void DeleteObject(BOOL bAll=FALSE); + + void Init(); + BOOL EventProcess(const Event &event); + Error RetError(); + + BOOL CreateInterface(BOOL bSelect); + + BOOL Write(char *line); + BOOL Read(char *line); + +protected: + void UpdateInterface(float rTime); + + CObject* SearchTarget(D3DVECTOR &impact); + void FireStopUpdate(float progress, BOOL bLightOn); + +protected: + AutoTowerPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastUpdateTime; + float m_lastParticule; + D3DVECTOR m_targetPos; + float m_angleYactual; + float m_angleZactual; + float m_angleYfinal; + float m_angleZfinal; + int m_partiStop[4]; +}; + + +#endif //_AUTOTOWER_H_ diff --git a/src/object/brain.cpp b/src/object/brain.cpp new file mode 100644 index 0000000..e942e5d --- /dev/null +++ b/src/object/brain.cpp @@ -0,0 +1,3000 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "CBot/CBotDll.h" +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "language.h" +#include "global.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "restext.h" +#include "math3d.h" +#include "robotmain.h" +#include "terrain.h" +#include "water.h" +#include "camera.h" +#include "object.h" +#include "physics.h" +#include "motion.h" +#include "motionspider.h" +#include "pyro.h" +#include "taskmanager.h" +#include "task.h" +#include "taskmanip.h" +#include "taskflag.h" +#include "taskshield.h" +#include "script.h" +#include "studio.h" +#include "interface.h" +#include "button.h" +#include "color.h" +#include "edit.h" +#include "list.h" +#include "label.h" +#include "group.h" +#include "gauge.h" +#include "slider.h" +#include "compass.h" +#include "target.h" +#include "window.h" +#include "displaytext.h" +#include "text.h" +#include "sound.h" +#include "particule.h" +#include "cmdtoken.h" +#include "brain.h" + + + +#define MAXTRACERECORD 1000 + + + +// Object's constructor. + +CBrain::CBrain(CInstanceManager* iMan, CObject* object) +{ + int i; + + m_iMan = iMan; + m_iMan->AddInstance(CLASS_BRAIN, this, 100); + + m_object = object; + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); + m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); + m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); + m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_physics = 0; + m_motion = 0; + m_primaryTask = 0; + m_secondaryTask = 0; + m_studio = 0; + + m_program = -1; + m_bActivity = TRUE; + m_bBurn = FALSE; + m_bActiveVirus = FALSE; + m_time = 0.0f; + m_burnTime = 0.0f; + m_lastUpdateTime = 0.0f; + m_lastHumanTime = 0.0f; + m_lastWormTime = 0.0f; + m_antTarget = 0; + m_beeBullet = 0; + m_lastAlarmTime = 0.0f; + m_soundChannelAlarm = -1; + m_flagColor = 0; + + m_buttonAxe = EVENT_NULL; + m_defaultEnter = EVENT_NULL; + m_manipStyle = EVENT_OBJECT_MFRONT; + + for ( i=0 ; iDeleteInstance(CLASS_BRAIN, this); +} + + +// Destroys the object. + +void CBrain::DeleteObject(BOOL bAll) +{ + if ( m_soundChannelAlarm != -1 ) + { + m_sound->FlushEnvelope(m_soundChannelAlarm); + m_sound->AddEnvelope(m_soundChannelAlarm, 0.0f, 0.5f, 0.5f, SOPER_STOP); + m_soundChannelAlarm = -1; + } + + if ( !bAll ) + { + if ( m_beeBullet != 0 ) + { + m_beeBullet->DeleteObject(); + delete m_beeBullet; + m_beeBullet = 0; + } + } + + if ( m_studio != 0 ) // current edition? + { + StopEditScript(TRUE); + } +} + + +void CBrain::SetPhysics(CPhysics* physics) +{ + m_physics = physics; +} + +void CBrain::SetMotion(CMotion* motion) +{ + m_motion = motion; +} + + +// Saves all parameters of the object. + +BOOL CBrain::Write(char *line) +{ + char name[100]; + + sprintf(name, " bVirusActive=%d", m_bActiveVirus); + strcat(line, name); + + return TRUE; +} + +// Restores all parameters of the object. + +BOOL CBrain::Read(char *line) +{ + m_bActiveVirus = OpInt(line, "bVirusActive", 0); + + return TRUE; +} + + +// Management of an event. + +BOOL CBrain::EventProcess(const Event &event) +{ + CWindow* pw; + CControl* pc; + CSlider* ps; + EventMsg action; + ObjectType type; + Error err; + float axeX, axeY, axeZ, factor; + + type = m_object->RetType(); + + if ( m_primaryTask != 0 ) // current task? + { + m_primaryTask->EventProcess(event); + } + + if ( m_secondaryTask != 0 ) // current task? + { + m_secondaryTask->EventProcess(event); + } + + action = EVENT_NULL; + + if ( event.event == EVENT_KEYDOWN && + (event.param == m_engine->RetKey(KEYRANK_ACTION, 0) || + event.param == m_engine->RetKey(KEYRANK_ACTION, 1) ) && + !m_main->RetEditLock() ) + { + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw != 0 ) + { + pc = pw->SearchControl(m_defaultEnter); + if ( pc != 0 ) + { + if ( pc->TestState(STATE_ENABLE) ) + { + action = m_defaultEnter; + } + } + } + } + else + { + action = event.event; + } + + if ( action == EVENT_NULL ) return TRUE; + + if ( action == EVENT_UPDINTERFACE ) + { + if ( m_object->RetSelect() ) CreateInterface(TRUE); + } + + if ( action == EVENT_FRAME ) + { + EventFrame(event); + } + + if ( m_object->RetSelect() && // robot selected? + m_studio != 0 ) // current issue? + { + m_studio->EventProcess(event); + + if ( action == EVENT_OBJECT_PROGRUN ) + { + if ( m_program == -1 ) + { + RunProgram(m_selScript); + } + else + { + StopProgram(); + } + } + if ( action == EVENT_OBJECT_PROGSTART ) + { + m_main->SaveOneScript(m_object); + RunProgram(m_selScript); + } + if ( action == EVENT_OBJECT_PROGSTOP ) + { + StopProgram(); + } + if ( action == EVENT_STUDIO_OK ) + { + StopEditScript(FALSE); + m_main->SaveOneScript(m_object); + } + if ( action == EVENT_STUDIO_CANCEL ) + { + StopEditScript(TRUE); + m_main->SaveOneScript(m_object); + } + return TRUE; + } + + if ( !m_object->RetSelect() && // robot pas sélectionné ? + m_program == -1 && + m_primaryTask == 0 ) + { + axeX = 0.0f; + axeY = 0.0f; + axeZ = 0.0f; + if ( m_object->RetBurn() ) // Gifted? + { + if ( !m_bBurn ) // beginning? + { + m_bBurn = TRUE; + m_burnTime = 0.0f; + } + + axeZ = -1.0f; // tomb + + if ( !m_object->RetFixed() && + (type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_WORM ) ) + { + axeY = 2.0f; // zigzag disorganized fast + if ( type == OBJECT_WORM ) axeY = 5.0f; + axeX = 0.5f+sinf(m_time* 1.0f)*0.5f+ + sinf(m_time* 6.0f)*2.0f+ + sinf(m_time*21.0f)*0.2f; + factor = 1.0f-m_burnTime/15.0f; // slow motion + if ( factor < 0.0f ) factor = 0.0f; + axeY *= factor; + axeX *= factor; + } + } + m_physics->SetMotorSpeedX(axeY); // move forward/move back + m_physics->SetMotorSpeedY(axeZ); // up / down + m_physics->SetMotorSpeedZ(axeX); // rotate + return TRUE; + } + + if ( m_program != -1 && + m_object->RetRuin() ) + { + StopProgram(); + return TRUE; + } + + if ( !m_object->RetSelect() ) // robot not selected? + { + return TRUE; + } + + if ( m_secondaryTask != 0 ) // current task? + { + if ( action == EVENT_OBJECT_ENDSHIELD ) + { + m_secondaryTask->StartTaskShield(TSM_DOWN, 0.0f); + } + } + if ( m_primaryTask != 0 || // current task? + m_program != -1 ) + { + if ( action == EVENT_OBJECT_PROGRUN ) + { + StopProgram(); + } + if ( action == EVENT_OBJECT_PROGEDIT ) + { + StartEditScript(m_selScript, m_main->RetScriptName()); + } + if ( m_primaryTask == 0 || !m_primaryTask->IsPilot() ) return TRUE; + } + + if ( action == EVENT_OBJECT_LEFT || + action == EVENT_OBJECT_RIGHT || + action == EVENT_OBJECT_UP || + action == EVENT_OBJECT_DOWN || + action == EVENT_OBJECT_GASUP || + action == EVENT_OBJECT_GASDOWN ) + { + m_buttonAxe = action; + } + if ( action == EVENT_LBUTTONUP || + action == EVENT_RBUTTONUP ) + { + m_buttonAxe = EVENT_NULL; + } + + axeX = event.axeX; + axeY = event.axeY; + axeZ = event.axeZ; + + if ( !m_main->RetTrainerPilot() && + m_object->RetTrainer() ) // drive vehicle? + { + axeX = 0.0f; + axeY = 0.0f; + axeZ = 0.0f; // Remote control impossible! + } + + if ( m_buttonAxe == EVENT_OBJECT_LEFT ) axeX = -1.0f; + if ( m_buttonAxe == EVENT_OBJECT_RIGHT ) axeX = 1.0f; + if ( m_buttonAxe == EVENT_OBJECT_UP ) axeY = 1.0f; + if ( m_buttonAxe == EVENT_OBJECT_DOWN ) axeY = -1.0f; + if ( m_buttonAxe == EVENT_OBJECT_GASUP ) axeZ = 1.0f; + if ( m_buttonAxe == EVENT_OBJECT_GASDOWN ) axeZ = -1.0f; + + if ( m_object->RetManual() ) // scribbler in manual mode? + { + if ( axeX != 0.0f ) axeY = 0.0f; // if running -> not moving! + axeX *= 0.5f; + axeY *= 0.5f; + } + + if ( (g_researchDone&RESEARCH_FLY) == 0 ) + { + axeZ = -1.0f; // tomb + } + + axeX += m_camera->RetMotorTurn(); // additional power according to camera + if ( axeX > 1.0f ) axeX = 1.0f; + if ( axeX < -1.0f ) axeX = -1.0f; + + m_physics->SetMotorSpeedX(axeY); // move forward/move back + m_physics->SetMotorSpeedY(axeZ); // up/down + m_physics->SetMotorSpeedZ(axeX); // rotate + + if ( action == EVENT_OBJECT_PROGLIST ) + { + m_selScript = RetSelScript(); + UpdateInterface(); + } + + if ( action == EVENT_OBJECT_PROGEDIT ) + { + StartEditScript(m_selScript, m_main->RetScriptName()); + } + + if ( action == EVENT_OBJECT_PROGRUN ) + { + StopProgram(); // stops the current program + RunProgram(m_selScript); + UpdateInterface(); + } + + err = ERR_OK; + + if ( m_program == -1 ) + { + if ( action == EVENT_OBJECT_HTAKE ) + { + err = StartTaskTake(); + } + + if ( action == EVENT_OBJECT_MFRONT || + action == EVENT_OBJECT_MBACK || + action == EVENT_OBJECT_MPOWER ) + { + m_manipStyle = action; + UpdateInterface(); + } + + if ( action == EVENT_OBJECT_MTAKE ) + { + if ( m_manipStyle == EVENT_OBJECT_MFRONT ) + { + err = StartTaskManip(TMO_AUTO, TMA_FFRONT); + } + if ( m_manipStyle == EVENT_OBJECT_MBACK ) + { + err = StartTaskManip(TMO_AUTO, TMA_FBACK); + if ( err == ERR_OK ) + { + m_manipStyle = EVENT_OBJECT_MFRONT; + UpdateInterface(); + } + } + if ( m_manipStyle == EVENT_OBJECT_MPOWER ) + { + err = StartTaskManip(TMO_AUTO, TMA_POWER); + if ( err == ERR_OK ) + { + m_manipStyle = EVENT_OBJECT_MFRONT; + UpdateInterface(); + } + } + } + + if ( action == EVENT_OBJECT_BDERRICK ) + { + err = StartTaskBuild(OBJECT_DERRICK); + } + if ( action == EVENT_OBJECT_BSTATION ) + { + err = StartTaskBuild(OBJECT_STATION); + } + if ( action == EVENT_OBJECT_BFACTORY ) + { + err = StartTaskBuild(OBJECT_FACTORY); + } + if ( action == EVENT_OBJECT_BREPAIR ) + { + err = StartTaskBuild(OBJECT_REPAIR); + } + if ( action == EVENT_OBJECT_BCONVERT ) + { + err = StartTaskBuild(OBJECT_CONVERT); + } + if ( action == EVENT_OBJECT_BTOWER ) + { + err = StartTaskBuild(OBJECT_TOWER); + } + if ( action == EVENT_OBJECT_BRESEARCH ) + { + err = StartTaskBuild(OBJECT_RESEARCH); + } + if ( action == EVENT_OBJECT_BRADAR ) + { + err = StartTaskBuild(OBJECT_RADAR); + } + if ( action == EVENT_OBJECT_BENERGY ) + { + err = StartTaskBuild(OBJECT_ENERGY); + } + if ( action == EVENT_OBJECT_BLABO ) + { + err = StartTaskBuild(OBJECT_LABO); + } + if ( action == EVENT_OBJECT_BNUCLEAR ) + { + err = StartTaskBuild(OBJECT_NUCLEAR); + } + if ( action == EVENT_OBJECT_BPARA ) + { + err = StartTaskBuild(OBJECT_PARA); + } + if ( action == EVENT_OBJECT_BINFO ) + { + err = StartTaskBuild(OBJECT_INFO); + } + + if ( action == EVENT_OBJECT_GFLAT ) + { + GroundFlat(); + } + if ( action == EVENT_OBJECT_FCREATE ) + { + err = StartTaskFlag(TFL_CREATE, m_flagColor); + } + if ( action == EVENT_OBJECT_FDELETE ) + { + err = StartTaskFlag(TFL_DELETE, m_flagColor); + } + if ( action == EVENT_OBJECT_FCOLORb || + action == EVENT_OBJECT_FCOLORr || + action == EVENT_OBJECT_FCOLORg || + action == EVENT_OBJECT_FCOLORy || + action == EVENT_OBJECT_FCOLORv ) + { + ColorFlag(action-EVENT_OBJECT_FCOLORb); + } + + if ( action == EVENT_OBJECT_SEARCH ) + { + err = StartTaskSearch(); + } + + if ( action == EVENT_OBJECT_TERRAFORM ) + { + err = StartTaskTerraform(); + } + + if ( action == EVENT_OBJECT_RECOVER ) + { + err = StartTaskRecover(); + } + + if ( action == EVENT_OBJECT_BEGSHIELD ) + { + err = StartTaskShield(TSM_UP); + } + + if ( action == EVENT_OBJECT_DIMSHIELD ) + { + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw != 0 ) + { + ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_DIMSHIELD); + if ( ps != 0 ) + { + m_object->SetParam((ps->RetVisibleValue()-(RADIUS_SHIELD_MIN/g_unit))/((RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)/g_unit)); + } + } + } + + if ( action == EVENT_OBJECT_FIRE && m_primaryTask == 0 && !m_object->RetTrainer()) + { + if ( m_camera->RetType() != CAMERA_ONBOARD ) + { + m_camera->SetType(CAMERA_ONBOARD); + } + err = StartTaskFire(0.0f); + } + if ( action == EVENT_OBJECT_TARGET && !m_object->RetTrainer() ) + { + err = StartTaskGunGoal((event.pos.y-0.50f)*1.3f, (event.pos.x-0.50f)*2.0f); + } + + if ( action == EVENT_OBJECT_FIREANT ) + { +//? err = StartTaskFireAnt(); + } + + if ( action == EVENT_OBJECT_PEN0 ) // up + { + err = StartTaskPen(FALSE, m_object->RetTraceColor()); + m_object->SetTraceDown(FALSE); + } + if ( action == EVENT_OBJECT_PEN1 ) // black + { + err = StartTaskPen(TRUE, 1); + m_object->SetTraceDown(TRUE); + m_object->SetTraceColor(1); + } + if ( action == EVENT_OBJECT_PEN2 ) // yellow + { + err = StartTaskPen(TRUE, 8); + m_object->SetTraceDown(TRUE); + m_object->SetTraceColor(8); + } + if ( action == EVENT_OBJECT_PEN3 ) // orange + { + err = StartTaskPen(TRUE, 7); + m_object->SetTraceDown(TRUE); + m_object->SetTraceColor(7); + } + if ( action == EVENT_OBJECT_PEN4 ) // red + { + err = StartTaskPen(TRUE, 4); + m_object->SetTraceDown(TRUE); + m_object->SetTraceColor(4); + } + if ( action == EVENT_OBJECT_PEN5 ) // violet + { + err = StartTaskPen(TRUE, 6); + m_object->SetTraceDown(TRUE); + m_object->SetTraceColor(6); + } + if ( action == EVENT_OBJECT_PEN6 ) // blue + { + err = StartTaskPen(TRUE, 14); + m_object->SetTraceDown(TRUE); + m_object->SetTraceColor(14); + } + if ( action == EVENT_OBJECT_PEN7 ) // green + { + err = StartTaskPen(TRUE, 12); + m_object->SetTraceDown(TRUE); + m_object->SetTraceColor(12); + } + if ( action == EVENT_OBJECT_PEN8 ) // brown + { + err = StartTaskPen(TRUE, 10); + m_object->SetTraceDown(TRUE); + m_object->SetTraceColor(10); + } + + if ( action == EVENT_OBJECT_REC ) // registered? + { + if ( m_bTraceRecord ) + { + m_bTraceRecord = FALSE; + TraceRecordStop(); + } + else + { + m_bTraceRecord = TRUE; + TraceRecordStart(); + } + UpdateInterface(); + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw != 0 ) + { + UpdateScript(pw); + } + } + if ( action == EVENT_OBJECT_STOP ) // stops? + { + if ( m_bTraceRecord ) + { + m_bTraceRecord = FALSE; + TraceRecordStop(); + } + UpdateInterface(); + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw != 0 ) + { + UpdateScript(pw); + } + } + + if ( action == EVENT_OBJECT_RESET ) + { + m_main->ResetObject(); // reset all objects + UpdateInterface(); + } + +#if 0 + if ( event.param == 'T' ) + { + D3DVECTOR p1, p2; + float h; + p1 = m_object->RetPosition(0); + h = m_terrain->RetFloorLevel(p1); + p2 = p1; + p1.x -= 20.0f; + p1.z -= 20.0f; + p2.x += 20.0f; + p2.z += 20.0f; + m_terrain->Terraform(p1, p2, h+1.0f); + } + if ( event.param == 'R' ) + { + D3DVECTOR p1, p2; + float h; + p1 = m_object->RetPosition(0); + h = m_terrain->RetFloorLevel(p1); + p2 = p1; + p1.x -= 20.0f; + p1.z -= 20.0f; + p2.x += 20.0f; + p2.z += 20.0f; + m_terrain->Terraform(p1, p2, h-1.0f); + } +#endif + } + + if ( err != ERR_OK ) + { + m_displayText->DisplayError(err, m_object); + } + + return TRUE; +} + + +// The brain is changing by time. + +BOOL CBrain::EventFrame(const Event &event) +{ + m_time += event.rTime; + if ( m_bBurn ) m_burnTime += event.rTime; + + if ( m_soundChannelAlarm != -1 ) + { + m_sound->Position(m_soundChannelAlarm, m_object->RetPosition(0)); + } + + if ( m_studio != 0 ) // �urrent edition? + { + m_studio->EventProcess(event); + } + + UpdateInterface(event.rTime); + + if ( m_engine->RetPause() ) return TRUE; + if ( !m_bActivity ) return TRUE; // expected if idle + if ( EndedTask() == ERR_CONTINUE ) return TRUE; // expected if not finished ... + + if ( m_program != -1 ) // current program? + { + if ( m_script[m_program]->Continue(event) ) + { + StopProgram(); + } + } + + if ( m_bTraceRecord ) // registration of the design in progress? + { + TraceRecordFrame(); + } + + return TRUE; +} + + +// Stops the running program. + +void CBrain::StopProgram() +{ + StopTask(); + + if ( m_object->RetType() == OBJECT_HUMAN || + m_object->RetType() == OBJECT_TECH ) return; + + if ( m_program != -1 && + m_script[m_program] != 0 ) + { + m_script[m_program]->Stop(); + } + + BlinkScript(FALSE); // stops flashing + + m_program = -1; + + m_physics->SetMotorSpeedX(0.0f); + m_physics->SetMotorSpeedY(0.0f); + m_physics->SetMotorSpeedZ(0.0f); + + m_motion->SetAction(-1); + + UpdateInterface(); + m_main->UpdateShortcuts(); + m_object->CreateSelectParticule(); +} + +// Stops the current task. + +void CBrain::StopTask() +{ + if ( m_primaryTask != 0 ) + { + m_primaryTask->Abort(); + delete m_primaryTask; // stops the current task + m_primaryTask = 0; + } +} + + +// Introduces a virus into a program. +// Returns TRUE if it was inserted. + +BOOL CBrain::IntroduceVirus() +{ + int i, j; + + for ( i=0 ; i<50 ; i++ ) + { + j = rand()%BRAINMAXSCRIPT; + if ( m_script[j] != 0 ) + { + if ( m_script[j]->IntroduceVirus() ) // tries to introduce + { + m_bActiveVirus = TRUE; // active virus + return TRUE; + } + } + } + return FALSE; +} + +// Active Virus indicates that the object is contaminated. Unlike ch'tites (??? - Programerus) +// letters which automatically disappear after a while, +// ActiveVirus does not disappear after you edit the program +// (Even if the virus is not fixed). + + +void CBrain::SetActiveVirus(BOOL bActive) +{ + m_bActiveVirus = bActive; + + if ( !m_bActiveVirus ) // virus disabled? + { + m_object->SetVirusMode(FALSE); // chtites (??? - Programerus) letters also + } +} + +BOOL CBrain::RetActiveVirus() +{ + return m_bActiveVirus; +} + + +// Start editing a program. + +void CBrain::StartEditScript(int rank, char* name) +{ + CreateInterface(FALSE); // removes the control buttons + + if ( m_script[rank] == 0 ) + { + m_script[rank] = new CScript(m_iMan, m_object, &m_secondaryTask); + } + + m_studio = new CStudio(m_iMan); + m_studio->StartEditScript(m_script[rank], name, rank); +} + +// End of editing a program. + +void CBrain::StopEditScript(BOOL bCancel) +{ + if ( !bCancel ) SetActiveVirus(FALSE); + + if ( !m_studio->StopEditScript(bCancel) ) return; + + delete m_studio; + m_studio = 0; + + CreateInterface(TRUE); // puts the control buttons +} + + + +// Move the manipulator arm. + +Error CBrain::StartTaskTake() +{ + Error err; + + if ( m_primaryTask != 0 ) + { + delete m_primaryTask; // stops the current task + m_primaryTask = 0; + } + + m_primaryTask = new CTaskManager(m_iMan, m_object); + err = m_primaryTask->StartTaskTake(); + UpdateInterface(); + return err; +} + +// Move the manipulator arm. + +Error CBrain::StartTaskManip(TaskManipOrder order, TaskManipArm arm) +{ + Error err; + + if ( m_primaryTask != 0 ) + { + delete m_primaryTask; // stops the current task + m_primaryTask = 0; + } + + m_primaryTask = new CTaskManager(m_iMan, m_object); + err = m_primaryTask->StartTaskManip(order, arm); + UpdateInterface(); + return err; +} + +// Puts or removes a flag. + +Error CBrain::StartTaskFlag(TaskFlagOrder order, int rank) +{ + Error err; + + if ( m_primaryTask != 0 ) + { + delete m_primaryTask; // stops the current task + m_primaryTask = 0; + } + + m_primaryTask = new CTaskManager(m_iMan, m_object); + err = m_primaryTask->StartTaskFlag(order, rank); + UpdateInterface(); + return err; +} + +// Built a building. + +Error CBrain::StartTaskBuild(ObjectType type) +{ + Error err; + + if ( m_primaryTask != 0 ) + { + delete m_primaryTask; // stops the current task + m_primaryTask = 0; + } + + m_primaryTask = new CTaskManager(m_iMan, m_object); + err = m_primaryTask->StartTaskBuild(type); + UpdateInterface(); + return err; +} + +// Probe the ground. + +Error CBrain::StartTaskSearch() +{ + Error err; + + if ( m_primaryTask != 0 ) + { + delete m_primaryTask; // stops the current task + m_primaryTask = 0; + } + + m_primaryTask = new CTaskManager(m_iMan, m_object); + err = m_primaryTask->StartTaskSearch(); + UpdateInterface(); + return err; +} + +// Terraformed the ground. + +Error CBrain::StartTaskTerraform() +{ + Error err; + + if ( m_primaryTask != 0 ) + { + delete m_primaryTask; // stops the current task + m_primaryTask = 0; + } + + m_primaryTask = new CTaskManager(m_iMan, m_object); + err = m_primaryTask->StartTaskTerraform(); + UpdateInterface(); + return err; +} + +// Change pencil. + +Error CBrain::StartTaskPen(BOOL bDown, int color) +{ + Error err; + + m_physics->SetMotorSpeedX(0.0f); + m_physics->SetMotorSpeedY(0.0f); + m_physics->SetMotorSpeedZ(0.0f); + + if ( m_primaryTask != 0 ) + { + delete m_primaryTask; // stops the current task + m_primaryTask = 0; + } + + m_primaryTask = new CTaskManager(m_iMan, m_object); + err = m_primaryTask->StartTaskPen(bDown, color); + UpdateInterface(); + return err; +} + +// Recovers a ruin. + +Error CBrain::StartTaskRecover() +{ + Error err; + + if ( m_primaryTask != 0 ) + { + delete m_primaryTask; // stops the current task + m_primaryTask = 0; + } + + m_primaryTask = new CTaskManager(m_iMan, m_object); + err = m_primaryTask->StartTaskRecover(); + UpdateInterface(); + return err; +} + +// Deploys the shield. + +Error CBrain::StartTaskShield(TaskShieldMode mode) +{ + Error err; + + if ( m_secondaryTask != 0 ) + { + delete m_secondaryTask; // stops the current task + m_secondaryTask = 0; + } + + m_secondaryTask = new CTaskManager(m_iMan, m_object); + err = m_secondaryTask->StartTaskShield(mode, 1000.0f); + UpdateInterface(); + return err; +} + +// Shoots. + +Error CBrain::StartTaskFire(float delay) +{ + Error err; + + if ( m_primaryTask != 0 ) + { + delete m_primaryTask; // stops the current task + m_primaryTask = 0; + } + + m_primaryTask = new CTaskManager(m_iMan, m_object); + err = m_primaryTask->StartTaskFire(delay); + UpdateInterface(); + return err; +} + +// Shoots to the ant. + +Error CBrain::StartTaskFireAnt(D3DVECTOR impact) +{ + Error err; + + if ( m_primaryTask != 0 ) + { + delete m_primaryTask; // stops the current task + m_primaryTask = 0; + } + + m_primaryTask = new CTaskManager(m_iMan, m_object); + err = m_primaryTask->StartTaskFireAnt(impact); + UpdateInterface(); + return err; +} + +// Adjusts upward. + +Error CBrain::StartTaskGunGoal(float dirV, float dirH) +{ + Error err; + + if ( m_secondaryTask != 0 ) + { + delete m_secondaryTask; // stops the current task + m_secondaryTask = 0; + } + + m_secondaryTask = new CTaskManager(m_iMan, m_object); + err = m_secondaryTask->StartTaskGunGoal(dirV, dirH); + UpdateInterface(); + return err; +} + +// Reset. + +Error CBrain::StartTaskReset(D3DVECTOR goal, D3DVECTOR angle) +{ + Error err; + + if ( m_primaryTask != 0 ) + { + delete m_primaryTask; // stops the current task + m_primaryTask = 0; + } + + m_primaryTask = new CTaskManager(m_iMan, m_object); + err = m_primaryTask->StartTaskReset(goal, angle); + UpdateInterface(); + return err; +} + +// Completes the task when the time came. + +Error CBrain::EndedTask() +{ + Error err; + + if ( m_secondaryTask != 0 ) // current task? + { + err = m_secondaryTask->IsEnded(); + if ( err != ERR_CONTINUE ) // job ended? + { + delete m_secondaryTask; + m_secondaryTask = 0; + UpdateInterface(); + } + } + + if ( m_primaryTask != 0 ) // current task? + { + err = m_primaryTask->IsEnded(); + if ( err != ERR_CONTINUE ) // job ended? + { + delete m_primaryTask; + m_primaryTask = 0; + UpdateInterface(); + } + return err; + } + return ERR_STOP; +} + + + +// Shows flat areas in the field. + +void CBrain::GroundFlat() +{ + D3DVECTOR pos, speed; + FPOINT dim; + Error err; + float level; + + if ( !m_physics->RetLand() ) + { + err = ERR_FLAG_FLY; + pos = m_object->RetPosition(0); + if ( pos.y < m_water->RetLevel() ) err = ERR_FLAG_WATER; + m_displayText->DisplayError(err, m_object); + return; + } + + pos = m_object->RetPosition(0); + m_terrain->GroundFlat(pos); + m_sound->Play(SOUND_GFLAT, pos); + + level = m_terrain->RetFloorLevel(pos)+2.0f; + if ( pos.y < level ) pos.y = level; // not below the soil + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 40.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGFLAT, 1.0f); +} + + +// Not below the soil. + +void CBrain::ColorFlag(int color) +{ + m_flagColor = color; + UpdateInterface(); +} + + +// Creates all the interface when the object is selected. + +BOOL CBrain::CreateInterface(BOOL bSelect) +{ + ObjectType type; + CWindow* pw; + CButton* pb; + CColor* pc; + CSlider* ps; + CTarget* pt; + CLabel* pl; + FPOINT pos, dim, ddim; + float ox, oy, sx, sy; + char name[100]; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw != 0 ) + { + pw->Flush(); // destroys the window buttons + m_interface->DeleteControl(EVENT_WINDOW0); // destroys the window + } + m_defaultEnter = EVENT_NULL; + + if ( !bSelect ) return TRUE; + + pos.x = 0.0f; + pos.y = 0.0f; + dim.x = 540.0f/640.0f; + if ( !m_main->RetShowMap() ) dim.x = 640.0f/640.0f; + dim.y = 86.0f/480.0f; + m_interface->CreateWindows(pos, dim, 3, EVENT_WINDOW0); + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return FALSE; + + m_object->GetTooltipName(name); + pos.x = 0.0f; + pos.y = 64.0f/480.0f; + ddim.x = 540.0f/640.0f; + if ( !m_main->RetShowMap() ) ddim.x = 640.0f/640.0f; + ddim.y = 16.0f/480.0f; + pw->CreateLabel(pos, ddim, 0, EVENT_LABEL0, name); + + dim.x = 33.0f/640.0f; + dim.y = 33.0f/480.0f; + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + type = m_object->RetType(); + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEtg || + type == OBJECT_MOBILEft || + type == OBJECT_MOBILEtt || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEit || + type == OBJECT_MOBILEdr || + type == OBJECT_MOTHER || + type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_BEE || + type == OBJECT_WORM ) // vehicle? + { + ddim.x = dim.x*5.1f; + ddim.y = dim.y*2.0f; + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0.0f; + pw->CreateList(pos, ddim, -1, EVENT_OBJECT_PROGLIST, 1.10f); + UpdateScript(pw); + + pos.x = ox+sx*5.2f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, dim, 8, EVENT_OBJECT_PROGRUN); + pos.y = oy+sy*0.0f; + pw->CreateButton(pos, dim, 22, EVENT_OBJECT_PROGEDIT); + } + + if ( type == OBJECT_HUMAN || + type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEft || + type == OBJECT_BEE ) // driving? + { + pos.x = ox+sx*6.4f; + pos.y = oy+sy*0; + pb = pw->CreateButton(pos, dim, 29, EVENT_OBJECT_GASDOWN); + pb->SetImmediat(TRUE); + + pos.x = ox+sx*6.4f; + pos.y = oy+sy*1; + pb = pw->CreateButton(pos, dim, 28, EVENT_OBJECT_GASUP); + pb->SetImmediat(TRUE); + + if ( type != OBJECT_HUMAN || + m_object->RetOption() != 2 ) + { + pos.x = ox+sx*15.3f; + pos.y = oy+sy*0; + ddim.x = 14.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGauge(pos, ddim, 2, EVENT_OBJECT_GRANGE); + } + } + + if ( type == OBJECT_HUMAN || + type == OBJECT_TECH ) + { + pos.x = ox+sx*7.7f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 31, EVENT_OBJECT_HTAKE); + DefaultEnter(pw, EVENT_OBJECT_HTAKE); + } + + if ( (type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia ) && // arm? + !m_object->RetTrainer() ) + { + pos.x = ox+sx*7.7f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 32, EVENT_OBJECT_MTAKE); + DefaultEnter(pw, EVENT_OBJECT_MTAKE); + + pos.x = ox+sx*8.9f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 34, EVENT_OBJECT_MBACK); + + pos.x = ox+sx*9.9f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 35, EVENT_OBJECT_MPOWER); + + pos.x = ox+sx*10.9f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 33, EVENT_OBJECT_MFRONT); + } + + if ( type == OBJECT_MOBILEsa && // underwater? + !m_object->RetTrainer() ) + { + pos.x = ox+sx*7.7f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 32, EVENT_OBJECT_MTAKE); + DefaultEnter(pw, EVENT_OBJECT_MTAKE); + } + + if ( type == OBJECT_HUMAN ) // builder? + { + pos.x = 1.0f/640.0f; + pos.y = 4.0f/480.0f; + ddim.x = 212.0f/640.0f; + ddim.y = 64.0f/480.0f; + pw->CreateGroup(pos, ddim, 27, EVENT_NULL); + + ddim.x = dim.x*0.9f; + ddim.y = dim.y*0.9f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, ddim, 128+35, EVENT_OBJECT_BRESEARCH); + DeadInterface(pw, EVENT_OBJECT_BRESEARCH, g_build&BUILD_RESEARCH); + + pos.x = ox+sx*0.9f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, ddim, 128+32, EVENT_OBJECT_BFACTORY); + DeadInterface(pw, EVENT_OBJECT_BFACTORY, g_build&BUILD_FACTORY); + + pos.x = ox+sx*1.8f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, ddim, 128+34, EVENT_OBJECT_BCONVERT); + DeadInterface(pw, EVENT_OBJECT_BCONVERT, g_build&BUILD_CONVERT); + + pos.x = ox+sx*2.7f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, ddim, 128+36, EVENT_OBJECT_BSTATION); + DeadInterface(pw, EVENT_OBJECT_BSTATION, g_build&BUILD_STATION); + + pos.x = ox+sx*3.6f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, ddim, 128+40, EVENT_OBJECT_BRADAR); + DeadInterface(pw, EVENT_OBJECT_BRADAR, g_build&BUILD_RADAR); + + pos.x = ox+sx*4.5f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, ddim, 128+41, EVENT_OBJECT_BREPAIR); + DeadInterface(pw, EVENT_OBJECT_BREPAIR, g_build&BUILD_REPAIR); + + pos.x = ox+sx*5.4f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, ddim, 128+44, EVENT_OBJECT_BINFO); + DeadInterface(pw, EVENT_OBJECT_BINFO, g_build&BUILD_INFO); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0.1f; + pw->CreateButton(pos, ddim, 128+37, EVENT_OBJECT_BTOWER); + DeadInterface(pw, EVENT_OBJECT_BTOWER, + (g_build&BUILD_TOWER) && + (g_researchDone & RESEARCH_TOWER)); + + pos.x = ox+sx*0.9f; + pos.y = oy+sy*0.1f; + pw->CreateButton(pos, ddim, 128+39, EVENT_OBJECT_BENERGY); + DeadInterface(pw, EVENT_OBJECT_BENERGY, g_build&BUILD_ENERGY); + + pos.x = ox+sx*1.8f; + pos.y = oy+sy*0.1f; + pw->CreateButton(pos, ddim, 128+33, EVENT_OBJECT_BDERRICK); + DeadInterface(pw, EVENT_OBJECT_BDERRICK, g_build&BUILD_DERRICK); + + pos.x = ox+sx*2.7f; + pos.y = oy+sy*0.1f; + pw->CreateButton(pos, ddim, 128+42, EVENT_OBJECT_BNUCLEAR); + DeadInterface(pw, EVENT_OBJECT_BNUCLEAR, + (g_build&BUILD_NUCLEAR) && + (g_researchDone & RESEARCH_ATOMIC)); + + pos.x = ox+sx*3.6f; + pos.y = oy+sy*0.1f; + pw->CreateButton(pos, ddim, 128+38, EVENT_OBJECT_BLABO); + DeadInterface(pw, EVENT_OBJECT_BLABO, g_build&BUILD_LABO); + + pos.x = ox+sx*4.5f; + pos.y = oy+sy*0.1f; + pw->CreateButton(pos, ddim, 128+46, EVENT_OBJECT_BPARA); + DeadInterface(pw, EVENT_OBJECT_BPARA, g_build&BUILD_PARA); + + pos.x = ox+sx*5.4f; + pos.y = oy+sy*0.1f; + pw->CreateButton(pos, ddim, 128+56, EVENT_OBJECT_BXXXX); + DeadInterface(pw, EVENT_OBJECT_BXXXX, FALSE); + + if ( g_build&BUILD_GFLAT ) + { + pos.x = ox+sx*9.0f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 64+47, EVENT_OBJECT_GFLAT); + } + + if ( g_build&BUILD_FLAG ) + { + pos.x = ox+sx*10.1f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 64+54, EVENT_OBJECT_FCREATE); + + pos.x = ox+sx*11.1f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 64+55, EVENT_OBJECT_FDELETE); + + ddim.x = dim.x*0.4f; + ddim.y = dim.y*0.4f; + pos.x = ox+sx*10.1f; + pos.y = oy+sy*2.0f-ddim.y; + pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_FCOLORb); + pc->SetColor(RetColor((D3DCOLOR)0x004890ff)); + pos.x += ddim.x; + pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_FCOLORr); + pc->SetColor(RetColor((D3DCOLOR)0x00ff0000)); + pos.x += ddim.x; + pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_FCOLORg); + pc->SetColor(RetColor((D3DCOLOR)0x0000ce00)); + pos.x += ddim.x; + pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_FCOLORy); + pc->SetColor(RetColor((D3DCOLOR)0x00ffec00)); + pos.x += ddim.x; + pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_FCOLORv); + pc->SetColor(RetColor((D3DCOLOR)0x00d101fe)); + } + } + + if ( (type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis ) && // Investigator? + !m_object->RetTrainer() ) + { + pos.x = ox+sx*7.7f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 40, EVENT_OBJECT_SEARCH); + DefaultEnter(pw, EVENT_OBJECT_SEARCH); + } + + if ( type == OBJECT_MOBILErt && // Terraformer? + !m_object->RetTrainer() ) + { + pos.x = ox+sx*7.7f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 128+18, EVENT_OBJECT_TERRAFORM); + DefaultEnter(pw, EVENT_OBJECT_TERRAFORM); + + pos.x = ox+sx*10.2f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 41, EVENT_OBJECT_LIMIT); + } + + if ( type == OBJECT_MOBILErr && // recoverer? + !m_object->RetTrainer() ) + { + pos.x = ox+sx*7.7f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 128+20, EVENT_OBJECT_RECOVER); + DefaultEnter(pw, EVENT_OBJECT_RECOVER); + } + + if ( type == OBJECT_MOBILErs && // shield? + !m_object->RetTrainer() ) + { + pos.x = ox+sx*7.7f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 39, EVENT_OBJECT_BEGSHIELD); + DefaultEnter(pw, EVENT_OBJECT_BEGSHIELD); + + pos.x = ox+sx*9.0f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 47, EVENT_OBJECT_ENDSHIELD); + +//? pos.x = ox+sx*10.2f; +//? pos.y = oy+sy*0.5f; +//? pw->CreateButton(pos, dim, 41, EVENT_OBJECT_LIMIT); + + pos.x = ox+sx*10.5f; + pos.y = oy+sy*0.0f; + ddim.x = dim.x*0.5f; + ddim.y = dim.y*2.0f; + ps = pw->CreateSlider(pos, ddim, 0, EVENT_OBJECT_DIMSHIELD); + ps->SetState(STATE_VALUE); + ps->SetLimit((RADIUS_SHIELD_MIN/g_unit), (RADIUS_SHIELD_MAX/g_unit)); + ps->SetArrowStep(1.0f); + } + + if ( (type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILErc ) && // cannon? + !m_object->RetTrainer() ) + { + pos.x = ox+sx*7.7f; + pos.y = oy+sy*0.5f; + pb = pw->CreateButton(pos, dim, 42, EVENT_OBJECT_FIRE); + pb->SetImmediat(TRUE); + DefaultEnter(pw, EVENT_OBJECT_FIRE); + +//? pos.x = ox+sx*10.2f; +//? pos.y = oy+sy*0.5f; +//? pw->CreateButton(pos, dim, 41, EVENT_OBJECT_LIMIT); + } + + if ( type == OBJECT_MOBILEdr && + m_object->RetManual() ) // scribbler in manual mode? + { + pos.x = ox+sx*6.9f; + pos.y = oy+sy*0.0f; + ddim.x = dim.x*2.2f; + ddim.y = dim.y*2.0f; + pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue bottom + + pos.x = ox+sx*9.3f; + pos.y = oy+sy*0.0f; + ddim.x = dim.x*2.2f; + ddim.y = dim.y*2.0f; + pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue bottom + + pos.x = ox+sx*9.90f; + pos.y = oy+sy*0.50f; + pw->CreateButton(pos, dim, 43, EVENT_OBJECT_PEN0); + + ddim.x = dim.x*0.5f; + ddim.y = dim.y*0.5f; + pos.x = ox+sx*10.15f; + pos.y = oy+sy*1.50f; + pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN1); // black + pc->SetColor(RetColor((D3DCOLOR)0x00000000)); + pos.x = ox+sx*10.65f; + pos.y = oy+sy*1.25f; + pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN2); // yellow + pc->SetColor(RetColor((D3DCOLOR)0x00ffff00)); + pos.x = ox+sx*10.90f; + pos.y = oy+sy*0.75f; + pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN3); // orange + pc->SetColor(RetColor((D3DCOLOR)0x00ff8800)); + pos.x = ox+sx*10.65f; + pos.y = oy+sy*0.25f; + pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN4); // red + pc->SetColor(RetColor((D3DCOLOR)0x00ff0000)); + pos.x = ox+sx*10.15f; + pos.y = oy+sy*0.00f; + pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN5); // violet + pc->SetColor(RetColor((D3DCOLOR)0x00ff00ff)); + pos.x = ox+sx*9.65f; + pos.y = oy+sy*0.25f; + pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN6); // blue + pc->SetColor(RetColor((D3DCOLOR)0x000066ff)); + pos.x = ox+sx*9.40f; + pos.y = oy+sy*0.75f; + pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN7); // green + pc->SetColor(RetColor((D3DCOLOR)0x0000cc00)); + pos.x = ox+sx*9.65f; + pos.y = oy+sy*1.25f; + pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN8); // brown + pc->SetColor(RetColor((D3DCOLOR)0x00884400)); + + pos.x = ox+sx*6.9f; + pos.y = oy+sy*1.2f; + ddim.x = dim.x*2.2f; + ddim.y = dim.y*0.4f; + GetResource(RES_TEXT, RT_INTERFACE_REC, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name); + pl->SetFontSize(9.0f); + + pos.x = ox+sx*7.0f; + pos.y = oy+sy*0.3f; + pw->CreateButton(pos, dim, 44, EVENT_OBJECT_REC); + pos.x = ox+sx*8.0f; + pos.y = oy+sy*0.3f; + pw->CreateButton(pos, dim, 45, EVENT_OBJECT_STOP); + } + + if ( m_object->RetToy() ) + { + pos.x = ox+sx*12.1f; + pos.y = oy+sy*-0.1f; + ddim.x = dim.x*1.2f; + ddim.y = dim.y*2.1f; + pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue bottom + + pos.x = ox+sx*12.2f; + pos.y = oy+sy*1; + pw->CreateGroup(pos, dim, 19, EVENT_NULL); // sign SatCom + + pos.x = ox+sx*12.2f; + pos.y = oy+sy*0.0f; + pw->CreateButton(pos, dim, 128+57, EVENT_OBJECT_BHELP); + } + else + { + pos.x = ox+sx*12.3f; + pos.y = oy+sy*-0.1f; + ddim.x = dim.x*1.0f; + ddim.y = dim.y*2.1f; + pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue bottom + + pos.x = ox+sx*12.3f; + pos.y = oy+sy*1; + pw->CreateGroup(pos, dim, 19, EVENT_NULL); // sign SatCom + + pos.x = ox+sx*12.4f; + pos.y = oy+sy*0.5f; + ddim.x = dim.x*0.8f; + ddim.y = dim.y*0.5f; + pw->CreateButton(pos, ddim, 18, EVENT_OBJECT_BHELP); + pos.y = oy+sy*0.0f; + pw->CreateButton(pos, ddim, 19, EVENT_OBJECT_HELP); + } + + if ( type != OBJECT_HUMAN && + type != OBJECT_TECH && + !m_object->RetCameraLock() ) + { +//? if ( m_main->RetShowMap() ) + if ( TRUE ) + { + pos.x = ox+sx*13.4f; + pos.y = oy+sy*1; + pw->CreateButton(pos, dim, 13, EVENT_OBJECT_CAMERA); + } + else + { + ddim.x = dim.x*0.66f; + ddim.y = dim.y*0.66f; + pos.x = ox+sx*(17.0f+0.66f); + pos.y = oy+sy*0.66f; + pw->CreateButton(pos, ddim, 13, EVENT_OBJECT_CAMERA); + } + } + + if ( m_object->RetToy() && !m_object->RetManual() ) + { +#if 0 + ddim.x = dim.x*0.66f; + ddim.y = dim.y*0.66f; + pos.x = ox+sx*10.0f; + pos.y = oy+sy*0.66f; + pb = pw->CreateButton(pos, ddim, 55, EVENT_OBJECT_CAMERAleft); + pb->SetImmediat(TRUE); + pos.x = ox+sx*(10.0f+0.66f*2.0f); + pos.y = oy+sy*0.66f; + pb = pw->CreateButton(pos, ddim, 48, EVENT_OBJECT_CAMERAright); + pb->SetImmediat(TRUE); + pos.x = ox+sx*(10.0f+0.66f); + pos.y = oy+sy*(0.66f*2.0f); + pb = pw->CreateButton(pos, ddim, 49, EVENT_OBJECT_CAMERAnear); + pb->SetImmediat(TRUE); + pos.x = ox+sx*(10.0f+0.66f); + pos.y = oy+sy*0.0f; + pb = pw->CreateButton(pos, ddim, 50, EVENT_OBJECT_CAMERAaway); + pb->SetImmediat(TRUE); +#else + pos.x = ox+sx*9.0f; + pos.y = oy+sy*0; + pb = pw->CreateButton(pos, dim, 55, EVENT_OBJECT_CAMERAleft); + pb->SetImmediat(TRUE); + pos.x = ox+sx*11.0f; + pos.y = oy+sy*0; + pb = pw->CreateButton(pos, dim, 48, EVENT_OBJECT_CAMERAright); + pb->SetImmediat(TRUE); + pos.x = ox+sx*10.0f; + pos.y = oy+sy*1; + pb = pw->CreateButton(pos, dim, 49, EVENT_OBJECT_CAMERAnear); + pb->SetImmediat(TRUE); + pos.x = ox+sx*10.0f; + pos.y = oy+sy*0; + pb = pw->CreateButton(pos, dim, 50, EVENT_OBJECT_CAMERAaway); + pb->SetImmediat(TRUE); +#endif + } + + pos.x = ox+sx*13.4f; + pos.y = oy+sy*0; +#if _TEEN + pw->CreateButton(pos, dim, 9, EVENT_OBJECT_RESET); +#else + if ( m_object->RetTrainer() ) // Training? + { + pw->CreateButton(pos, dim, 9, EVENT_OBJECT_RESET); + } + else + { + pw->CreateButton(pos, dim, 10, EVENT_OBJECT_DESELECT); + } +#endif + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEft || + type == OBJECT_MOBILEtt || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEit ) // vehicle? + { + pos.x = ox+sx*14.5f; + pos.y = oy+sy*0; + ddim.x = 14.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY); + } + + if ( type == OBJECT_HUMAN || + type == OBJECT_TECH || + type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEtg || + type == OBJECT_MOBILEft || + type == OBJECT_MOBILEtt || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEit ) // vehicle? + { + pos.x = ox+sx*14.9f; + pos.y = oy+sy*0; + ddim.x = 14.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGauge(pos, ddim, 3, EVENT_OBJECT_GSHIELD); + } + +#if 0 + if ( FALSE ) + { + pos.x = 505.0f/640.0f; + pos.y = 3.0f/480.0f; + ddim.x = 33.0f/640.0f; + ddim.y = 33.0f/480.0f; + pw->CreateCompass(pos, ddim, 0, EVENT_OBJECT_COMPASS); + + pc = (CCompass*)pw->SearchControl(EVENT_OBJECT_COMPASS); + if ( pc != 0 ) + { + pc->SetState(STATE_VISIBLE, m_main->RetShowMap()); + } + } +#endif + + if ( type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILErc ) // cannon? + { + ddim.x = 64.0f/640.0f; + ddim.y = 64.0f/480.0f; + pos.x = 0.5f-ddim.x/2.0f; + pos.y = 0.5f-ddim.y/2.0f; + pw->CreateGroup(pos, ddim, 12, EVENT_OBJECT_CROSSHAIR); + + pos.x = 20.0f/640.0f; + pos.y = 100.0f/480.0f; + ddim.x = 600.0f/640.0f; + ddim.y = 340.0f/480.0f; + pt = pw->CreateTarget(pos, ddim, 0, EVENT_OBJECT_TARGET); + pt->ClearState(STATE_GLINT); + } + + ddim.x = 64.0f/640.0f; + ddim.y = 64.0f/480.0f; + pos.x = 30.0f/640.0f; + pos.y = 430.0f/480.0f-ddim.y; + pw->CreateGroup(pos, ddim, 13, EVENT_OBJECT_CORNERul); + + ddim.x = 64.0f/640.0f; + ddim.y = 64.0f/480.0f; + pos.x = 610.0f/640.0f-ddim.x; + pos.y = 430.0f/480.0f-ddim.y; + pw->CreateGroup(pos, ddim, 14, EVENT_OBJECT_CORNERur); + + ddim.x = 64.0f/640.0f; + ddim.y = 64.0f/480.0f; + pos.x = 30.0f/640.0f; + pos.y = 110.0f/480.0f; + pw->CreateGroup(pos, ddim, 15, EVENT_OBJECT_CORNERdl); + + ddim.x = 64.0f/640.0f; + ddim.y = 64.0f/480.0f; + pos.x = 610.0f/640.0f-ddim.x; + pos.y = 110.0f/480.0f; + pw->CreateGroup(pos, ddim, 16, EVENT_OBJECT_CORNERdr); + + UpdateInterface(); + m_lastUpdateTime = 0.0f; + UpdateInterface(0.0f); + + return TRUE; +} + +// Updates the state of all buttons on the interface, +// following the time that elapses ... + +void CBrain::UpdateInterface(float rTime) +{ + CWindow* pw; +#if _TEEN + CButton* pb; +#endif + CGauge* pg; + CCompass* pc; + CGroup* pgr; + CTarget* ptg; + CObject* power; + D3DVECTOR pos, hPos; + FPOINT ppos; + float energy, limit, angle, range; + int icon; + BOOL bOnBoard; + + m_lastAlarmTime += rTime; + if ( m_time < m_lastUpdateTime+0.1f ) return; + m_lastUpdateTime = m_time; + + if ( !m_object->RetSelect() ) + { + if ( m_soundChannelAlarm != -1 ) + { + m_sound->FlushEnvelope(m_soundChannelAlarm); + m_sound->AddEnvelope(m_soundChannelAlarm, 0.0f, 1.0f, 0.1f, SOPER_STOP); + m_soundChannelAlarm = -1; + } + return; + } + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); + if ( pg != 0 ) + { + power = m_object->RetPower(); + if ( power == 0 ) + { + energy = 0.0f; + } + else + { + energy = power->RetEnergy(); + limit = energy*power->RetCapacity(); + } + icon = 0; // red/green + + if ( limit < 0.2f && energy != 0.0f ) // low but not zero? + { + if ( m_lastAlarmTime >= 0.8f ) // blinks? + { + energy = 1.0f; + icon = 1; // brun + } + if ( m_lastAlarmTime >= 1.0f ) + { + m_sound->Play(SOUND_ALARM, 0.5f); // bip-bip-bip + m_lastAlarmTime = 0.0f; + } + } + pg->SetLevel(energy); + pg->SetIcon(icon); + } + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GSHIELD); + if ( pg != 0 ) + { + pg->SetLevel(m_object->RetShield()); + } + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GRANGE); + if ( pg != 0 ) + { + icon = 2; // blue/red + range = m_physics->RetReactorRange(); + + if ( range < 0.2f && range != 0.0f && !m_physics->RetLand() ) + { + if ( Mod(m_time, 0.5f) >= 0.2f ) // blinks? + { + range = 1.0f; + icon = 1; // yellow + } + if ( m_soundChannelAlarm == -1 ) + { + m_soundChannelAlarm = m_sound->Play(SOUND_ALARMt, m_object->RetPosition(0), 0.0f, 0.1f, TRUE); + m_sound->AddEnvelope(m_soundChannelAlarm, 1.0f, 1.0f, 1.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannelAlarm, 1.0f, 1.0f, 1.0f, SOPER_LOOP); + } + } + else + { + if ( m_soundChannelAlarm != -1 ) + { + m_sound->FlushEnvelope(m_soundChannelAlarm); + m_sound->AddEnvelope(m_soundChannelAlarm, 0.0f, 0.1f, 1.0f, SOPER_STOP); + m_soundChannelAlarm = -1; + } + } + + pg->SetLevel(1.0f-range); + pg->SetIcon(icon); + } + + pc = (CCompass*)pw->SearchControl(EVENT_OBJECT_COMPASS); + if ( pc != 0 ) + { + angle = -(m_object->RetAngleY(0)+PI/2.0f); + pc->SetDirection(angle); + + pc->SetState(STATE_VISIBLE, m_main->RetShowMap()); + } + +#if _TEEN + pb = (CButton*)pw->SearchControl(EVENT_OBJECT_REC); + if ( pb != 0 ) + { + if ( m_bTraceRecord && Mod(m_time, 0.4f) >= 0.2f ) + { + pb->SetState(STATE_CHECK); + } + else + { + pb->ClearState(STATE_CHECK); + } + } +#endif + + bOnBoard = m_camera->RetType() == CAMERA_ONBOARD; + + pgr = (CGroup*)pw->SearchControl(EVENT_OBJECT_CROSSHAIR); + if ( pgr != 0 ) + { + if ( bOnBoard ) + { +#if 0 + angle = m_object->RetGunGoalV(); + if ( m_object->RetType() != OBJECT_MOBILErc ) + { + angle += 10.0f*PI/360.0f; + } + ppos.x = 0.5f-(64.0f/640.0f)/2.0f; + ppos.y = 0.5f-(64.0f/480.0f)/2.0f; + ppos.y += sinf(angle)*0.6f; + pgr->SetPos(ppos); +#else + ppos.x = 0.50f-(64.0f/640.0f)/2.0f; + ppos.y = 0.50f-(64.0f/480.0f)/2.0f; + ppos.x += m_object->RetGunGoalH()/2.0f; + ppos.y += m_object->RetGunGoalV()/1.3f; + pgr->SetPos(ppos); +#endif + pgr->SetState(STATE_VISIBLE, !m_main->RetFriendAim()); + } + else + { + pgr->ClearState(STATE_VISIBLE); + } + } + + ptg = (CTarget*)pw->SearchControl(EVENT_OBJECT_TARGET); + if ( ptg != 0 ) + { + if ( bOnBoard ) + { + ptg->SetState(STATE_VISIBLE); + } + else + { + ptg->ClearState(STATE_VISIBLE); + } + } + + pgr = (CGroup*)pw->SearchControl(EVENT_OBJECT_CORNERul); + if ( pgr != 0 ) + { + pgr->SetState(STATE_VISIBLE, bOnBoard); + } + + pgr = (CGroup*)pw->SearchControl(EVENT_OBJECT_CORNERur); + if ( pgr != 0 ) + { + pgr->SetState(STATE_VISIBLE, bOnBoard); + } + + pgr = (CGroup*)pw->SearchControl(EVENT_OBJECT_CORNERdl); + if ( pgr != 0 ) + { + pgr->SetState(STATE_VISIBLE, bOnBoard); + } + + pgr = (CGroup*)pw->SearchControl(EVENT_OBJECT_CORNERdr); + if ( pgr != 0 ) + { + pgr->SetState(STATE_VISIBLE, bOnBoard); + } +} + +// Updates the status of all interface buttons. + +void CBrain::UpdateInterface() +{ + ObjectType type; + CWindow* pw; + CButton* pb; + CSlider* ps; +#if _TEEN + CColor* pc; + int color; +#endif + BOOL bEnable, bFly, bRun; + char title[100]; + + if ( !m_object->RetSelect() ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + type = m_object->RetType(); + + bEnable = ( m_secondaryTask == 0 && m_program == -1 ); + + bEnable = ( m_primaryTask == 0 && m_program == -1 ); + + EnableInterface(pw, EVENT_OBJECT_PROGEDIT, (m_primaryTask == 0 && !m_bTraceRecord)); + EnableInterface(pw, EVENT_OBJECT_PROGLIST, bEnable && !m_bTraceRecord); + EnableInterface(pw, EVENT_OBJECT_LEFT, bEnable); + EnableInterface(pw, EVENT_OBJECT_RIGHT, bEnable); + EnableInterface(pw, EVENT_OBJECT_UP, bEnable); + EnableInterface(pw, EVENT_OBJECT_DOWN, bEnable); + EnableInterface(pw, EVENT_OBJECT_HTAKE, bEnable); + EnableInterface(pw, EVENT_OBJECT_MTAKE, bEnable); + EnableInterface(pw, EVENT_OBJECT_MBACK, bEnable); + EnableInterface(pw, EVENT_OBJECT_MPOWER, bEnable); + EnableInterface(pw, EVENT_OBJECT_MFRONT, bEnable); + EnableInterface(pw, EVENT_OBJECT_GFLAT, bEnable); + EnableInterface(pw, EVENT_OBJECT_FCREATE, bEnable); + EnableInterface(pw, EVENT_OBJECT_FDELETE, bEnable); + EnableInterface(pw, EVENT_OBJECT_SEARCH, bEnable); + EnableInterface(pw, EVENT_OBJECT_TERRAFORM, bEnable); + EnableInterface(pw, EVENT_OBJECT_RECOVER, bEnable); + EnableInterface(pw, EVENT_OBJECT_FIRE, bEnable); + EnableInterface(pw, EVENT_OBJECT_RESET, bEnable); +#if _TEEN + EnableInterface(pw, EVENT_OBJECT_PEN0, bEnable); + EnableInterface(pw, EVENT_OBJECT_PEN1, bEnable); + EnableInterface(pw, EVENT_OBJECT_PEN2, bEnable); + EnableInterface(pw, EVENT_OBJECT_PEN3, bEnable); + EnableInterface(pw, EVENT_OBJECT_PEN4, bEnable); + EnableInterface(pw, EVENT_OBJECT_PEN5, bEnable); + EnableInterface(pw, EVENT_OBJECT_PEN6, bEnable); + EnableInterface(pw, EVENT_OBJECT_PEN7, bEnable); + EnableInterface(pw, EVENT_OBJECT_PEN8, bEnable); + EnableInterface(pw, EVENT_OBJECT_REC, bEnable); + EnableInterface(pw, EVENT_OBJECT_STOP, bEnable); +#endif + + if ( type == OBJECT_HUMAN ) // builder? + { + EnableInterface(pw, EVENT_OBJECT_BFACTORY, bEnable); + EnableInterface(pw, EVENT_OBJECT_BDERRICK, bEnable); + EnableInterface(pw, EVENT_OBJECT_BCONVERT, bEnable); + EnableInterface(pw, EVENT_OBJECT_BSTATION, bEnable); + EnableInterface(pw, EVENT_OBJECT_BREPAIR, bEnable); + EnableInterface(pw, EVENT_OBJECT_BTOWER, bEnable); + EnableInterface(pw, EVENT_OBJECT_BRESEARCH, bEnable); + EnableInterface(pw, EVENT_OBJECT_BRADAR, bEnable); + EnableInterface(pw, EVENT_OBJECT_BENERGY, bEnable); + EnableInterface(pw, EVENT_OBJECT_BLABO, bEnable); + EnableInterface(pw, EVENT_OBJECT_BNUCLEAR, bEnable); + EnableInterface(pw, EVENT_OBJECT_BPARA, bEnable); + EnableInterface(pw, EVENT_OBJECT_BINFO, bEnable); + EnableInterface(pw, EVENT_OBJECT_BXXXX, bEnable); + } + + pb = (CButton*)pw->SearchControl(EVENT_OBJECT_GFLAT); + if ( pb != 0 ) + { + pb->SetState(STATE_VISIBLE, m_engine->RetGroundSpot()); + } + + if ( type == OBJECT_HUMAN || // builder? + type == OBJECT_TECH ) + { + CheckInterface(pw, EVENT_OBJECT_FCOLORb, m_flagColor==0); + CheckInterface(pw, EVENT_OBJECT_FCOLORr, m_flagColor==1); + CheckInterface(pw, EVENT_OBJECT_FCOLORg, m_flagColor==2); + CheckInterface(pw, EVENT_OBJECT_FCOLORy, m_flagColor==3); + CheckInterface(pw, EVENT_OBJECT_FCOLORv, m_flagColor==4); + } + + if ( type == OBJECT_MOBILErs ) // shield? + { + if ( (m_secondaryTask == 0 || !m_secondaryTask->IsBusy()) && m_program == -1 ) + { + EnableInterface(pw, EVENT_OBJECT_BEGSHIELD, (m_secondaryTask == 0)); + EnableInterface(pw, EVENT_OBJECT_ENDSHIELD, (m_secondaryTask != 0)); + DefaultEnter (pw, EVENT_OBJECT_BEGSHIELD, (m_secondaryTask == 0)); + DefaultEnter (pw, EVENT_OBJECT_ENDSHIELD, (m_secondaryTask != 0)); + } + else + { + EnableInterface(pw, EVENT_OBJECT_BEGSHIELD, FALSE); + EnableInterface(pw, EVENT_OBJECT_ENDSHIELD, FALSE); + DefaultEnter (pw, EVENT_OBJECT_BEGSHIELD, FALSE); + DefaultEnter (pw, EVENT_OBJECT_ENDSHIELD, FALSE); + } + + ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_DIMSHIELD); + if ( ps != 0 ) + { + ps->SetVisibleValue((RADIUS_SHIELD_MIN/g_unit)+m_object->RetParam()*((RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)/g_unit)); + } + } + + bFly = bEnable; + if ( bFly && (type == OBJECT_HUMAN || type == OBJECT_TECH) ) + { + if ( m_object->RetFret() != 0 ) bFly = FALSE; // if holder -> not fly + } + EnableInterface(pw, EVENT_OBJECT_GASUP, bFly); + EnableInterface(pw, EVENT_OBJECT_GASDOWN, bFly); + if ( m_object->RetTrainer() ) // Training? + { + DeadInterface(pw, EVENT_OBJECT_GASUP, FALSE); + DeadInterface(pw, EVENT_OBJECT_GASDOWN, FALSE); + } + else + { + DeadInterface(pw, EVENT_OBJECT_GASUP, g_researchDone&RESEARCH_FLY); + DeadInterface(pw, EVENT_OBJECT_GASDOWN, g_researchDone&RESEARCH_FLY); + } + + if ( type == OBJECT_HUMAN || + type == OBJECT_TECH || + type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEtg || + type == OBJECT_MOBILEft || + type == OBJECT_MOBILEtt || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEit || + type == OBJECT_MOBILEdr || + type == OBJECT_MOTHER || + type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_BEE || + type == OBJECT_WORM ) // vehicle? + { + bRun = FALSE; + if ( m_script[m_selScript] != 0 ) + { + m_script[m_selScript]->GetTitle(title); + if ( title[0] != 0 ) + { + bRun = TRUE; + } + } + if ( !bEnable && m_program == -1 ) bRun = FALSE; + if ( m_bTraceRecord ) bRun = FALSE; + EnableInterface(pw, EVENT_OBJECT_PROGRUN, bRun); + + pb = (CButton*)pw->SearchControl(EVENT_OBJECT_PROGRUN); + if ( pb != 0 ) + { + pb->SetIcon(m_program==-1?21:8); // run/stop + } + +//? pb = (CButton*)pw->SearchControl(EVENT_OBJECT_PROGEDIT); +//? if ( pb != 0 ) +//? { +//? pb->SetIcon(m_program==-1?22:40); // edit/debug +//? } + + BlinkScript(m_program != -1); // blinks if script execution + } + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia ) // arm? + { + CheckInterface(pw, EVENT_OBJECT_MPOWER, m_manipStyle==EVENT_OBJECT_MPOWER); + CheckInterface(pw, EVENT_OBJECT_MBACK, m_manipStyle==EVENT_OBJECT_MBACK); + CheckInterface(pw, EVENT_OBJECT_MFRONT, m_manipStyle==EVENT_OBJECT_MFRONT); + } + +#if _TEEN + if ( m_object->RetTraceDown() ) + { + pb = (CButton*)pw->SearchControl(EVENT_OBJECT_PEN0); + if ( pb != 0 ) + { + pb->ClearState(STATE_CHECK); + } + + color = m_object->RetTraceColor(); + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN1); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, color==1); + } + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN2); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, color==8); + } + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN3); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, color==7); + } + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN4); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, color==4); + } + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN5); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, color==6); + } + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN6); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, color==14); + } + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN7); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, color==12); + } + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN8); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, color==10); + } + } + else + { + pb = (CButton*)pw->SearchControl(EVENT_OBJECT_PEN0); + if ( pb != 0 ) + { + pb->SetState(STATE_CHECK); + } + + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN1); + if ( pc != 0 ) + { + pc->ClearState(STATE_CHECK); + } + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN2); + if ( pc != 0 ) + { + pc->ClearState(STATE_CHECK); + } + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN3); + if ( pc != 0 ) + { + pc->ClearState(STATE_CHECK); + } + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN4); + if ( pc != 0 ) + { + pc->ClearState(STATE_CHECK); + } + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN5); + if ( pc != 0 ) + { + pc->ClearState(STATE_CHECK); + } + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN6); + if ( pc != 0 ) + { + pc->ClearState(STATE_CHECK); + } + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN7); + if ( pc != 0 ) + { + pc->ClearState(STATE_CHECK); + } + pc = (CColor*)pw->SearchControl(EVENT_OBJECT_PEN8); + if ( pc != 0 ) + { + pc->ClearState(STATE_CHECK); + } + } +#endif +} + +// Updates the list of programs. + +void CBrain::UpdateScript(CWindow *pw) +{ + CList* pl; + char name[100]; + char title[100]; + int i; + BOOL bSoluce; + + pl = (CList*)pw->SearchControl(EVENT_OBJECT_PROGLIST); + if ( pl == 0 ) return; + +#if _SCHOOL + bSoluce = m_main->RetSoluce4(); +#else + bSoluce = TRUE; +#endif + + for ( i=0 ; iGetTitle(title); + if ( !bSoluce && i == 3 ) + { + title[0] = 0; + } + if ( title[0] != 0 ) + { + sprintf(name, "%d: %s", i+1, title); + } + } + + pl->SetName(i, name); + } + + if ( !bSoluce ) + { + pl->SetEnable(3, FALSE); + } + + pl->SetSelect(m_selScript); + pl->ShowSelect(TRUE); +} + +// Returns the rank of selected script. + +int CBrain::RetSelScript() +{ + CWindow* pw; + CList* pl; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return -1; + + pl = (CList*)pw->SearchControl(EVENT_OBJECT_PROGLIST); + if ( pl == 0 ) return -1; + + return pl->RetSelect(); +} + +// Blinks the running program. + +void CBrain::BlinkScript(BOOL bEnable) +{ + CWindow* pw; + CList* pl; + + if ( !m_object->RetSelect() ) return; // robot not selected? + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pl = (CList*)pw->SearchControl(EVENT_OBJECT_PROGLIST); + if ( pl == 0 ) return; + + pl->SetBlink(bEnable); +} + +// Check the status of a button interface. + +void CBrain::CheckInterface(CWindow *pw, EventMsg event, BOOL bState) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + control->SetState(STATE_CHECK, bState); +} + +// Changes the state of a button interface. + +void CBrain::EnableInterface(CWindow *pw, EventMsg event, BOOL bState) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + control->SetState(STATE_ENABLE, bState); +} + +// Changes the state of a button on the interface. + +void CBrain::DeadInterface(CWindow *pw, EventMsg event, BOOL bState) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + control->SetState(STATE_DEAD, !bState); +} + +// Change the default input state of a button interface. + +void CBrain::DefaultEnter(CWindow *pw, EventMsg event, BOOL bState) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + if ( bState ) + { + control->SetState(STATE_DEFAULT); + m_defaultEnter = event; + } + else + { + control->ClearState(STATE_DEFAULT); + } +} + + +// Indicates whether the object is busy with a task. + +BOOL CBrain::IsBusy() +{ + return (m_primaryTask != 0); +} + +// Management of the activity of an object. + +void CBrain::SetActivity(BOOL bMode) +{ + m_bActivity = bMode; +} + +BOOL CBrain::RetActivity() +{ + return m_bActivity; +} + +// Indicates whether a program is running. + +BOOL CBrain::IsProgram() +{ + return ( m_program != -1 ); +} + +// Indicates whether a program exists. + +BOOL CBrain::ProgramExist(int rank) +{ + return ( m_script[rank] != 0 ); +} + +// Starts a program. + +void CBrain::RunProgram(int rank) +{ + if ( rank < 0 ) return; + + if ( m_script[rank] != 0 && + m_script[rank]->Run() ) + { + m_program = rank; // start new program + BlinkScript(TRUE); // blink + m_object->CreateSelectParticule(); + m_main->UpdateShortcuts(); + } +} + +// Returns the first free program. + +int CBrain::FreeProgram() +{ + int i; + + for ( i=0 ; iCompare(m_script[rank]) ) // the same already? + { + delete m_script[rank]; + m_script[rank] = 0; + return FALSE; + } + } + + return TRUE; +} + +// Load a script with a text file. + +BOOL CBrain::ReadProgram(int rank, char* filename) +{ + if ( m_script[rank] == 0 ) + { + m_script[rank] = new CScript(m_iMan, m_object, &m_secondaryTask); + } + + if ( m_script[rank]->ReadScript(filename) ) return TRUE; + + delete m_script[rank]; + m_script[rank] = 0; + + return FALSE; +} + +// Indicates whether a program is compiled correctly. + +BOOL CBrain::RetCompile(int rank) +{ + if ( m_script[rank] == 0 ) return FALSE; + return m_script[rank]->RetCompile(); +} + +// Saves a script in a text file. + +BOOL CBrain::WriteProgram(int rank, char* filename) +{ + if ( m_script[rank] == 0 ) + { + m_script[rank] = new CScript(m_iMan, m_object, &m_secondaryTask); + } + + if ( m_script[rank]->WriteScript(filename) ) return TRUE; + + delete m_script[rank]; + m_script[rank] = 0; + + return FALSE; +} + + +// Load a stack of script implementation from a file. + +BOOL CBrain::ReadStack(FILE *file) +{ + short op; + + fRead(&op, sizeof(short), 1, file); + if ( op == 1 ) // run ? + { + fRead(&op, sizeof(short), 1, file); // program rank + if ( op >= 0 && op < BRAINMAXSCRIPT ) + { + m_program = op; // program restarts + m_selScript = op; + BlinkScript(TRUE); // blink + + if ( m_script[op] == 0 ) + { + m_script[op] = new CScript(m_iMan, m_object, &m_secondaryTask); + } + if ( !m_script[op]->ReadStack(file) ) return FALSE; + } + } + + return TRUE; +} + +// ave the script implementation stack of a file. + +BOOL CBrain::WriteStack(FILE *file) +{ + short op; + + if ( m_program != -1 && // current program? + m_script[m_program]->IsRunning() ) + { + op = 1; // run + fWrite(&op, sizeof(short), 1, file); + + op = m_program; + fWrite(&op, sizeof(short), 1, file); + + return m_script[m_program]->WriteStack(file); + } + + op = 0; // stop + fWrite(&op, sizeof(short), 1, file); + return TRUE; +} + + + +// Start of registration of the design. + +void CBrain::TraceRecordStart() +{ + m_traceOper = TO_STOP; + + m_tracePos = m_object->RetPosition(0); + m_traceAngle = m_object->RetAngleY(0); + + if ( m_object->RetTraceDown() ) // pencil down? + { + m_traceColor = m_object->RetTraceColor(); + } + else // pen up? + { + m_traceColor = -1; + } + + delete m_traceRecordBuffer; + m_traceRecordBuffer = (TraceRecord*)malloc(sizeof(TraceRecord)*MAXTRACERECORD); + m_traceRecordIndex = 0; +} + +// Saving the current drawing. + +void CBrain::TraceRecordFrame() +{ + TraceOper oper = TO_STOP; + D3DVECTOR pos; + float angle, len, speed; + int color; + + speed = m_physics->RetLinMotionX(MO_REASPEED); + if ( speed > 0.0f ) oper = TO_ADVANCE; + if ( speed < 0.0f ) oper = TO_RECEDE; + + speed = m_physics->RetCirMotionY(MO_REASPEED); + if ( speed != 0.0f ) oper = TO_TURN; + + if ( m_object->RetTraceDown() ) // pencil down? + { + color = m_object->RetTraceColor(); + } + else // pen up? + { + color = -1; + } + + if ( oper != m_traceOper || + color != m_traceColor ) + { + if ( m_traceOper == TO_ADVANCE || + m_traceOper == TO_RECEDE ) + { + pos = m_object->RetPosition(0); + len = Length2d(pos, m_tracePos); + TraceRecordOper(m_traceOper, len); + } + if ( m_traceOper == TO_TURN ) + { + angle = m_object->RetAngleY(0)-m_traceAngle; + TraceRecordOper(m_traceOper, angle); + } + + if ( color != m_traceColor ) + { + TraceRecordOper(TO_PEN, (float)color); + } + + m_traceOper = oper; + m_tracePos = m_object->RetPosition(0); + m_traceAngle = m_object->RetAngleY(0); + m_traceColor = color; + } +} + +// End of the registration of the design. Program generates the CBOT. + +void CBrain::TraceRecordStop() +{ + TraceOper lastOper, curOper; + float lastParam, curParam; + int max, i; + char* buffer; + + if ( m_traceRecordBuffer == 0 ) return; + + max = 10000; + buffer = (char*)malloc(max); + *buffer = 0; + strncat(buffer, "extern void object::AutoDraw()\n{\n", max-1); + + lastOper = TO_STOP; + lastParam = 0.0f; + for ( i=0 ; iSendScript(buffer); + delete buffer; +} + +// Saves an instruction CBOT. + +BOOL CBrain::TraceRecordOper(TraceOper oper, float param) +{ + int i; + + i = m_traceRecordIndex; + if ( i >= MAXTRACERECORD ) return FALSE; + + m_traceRecordBuffer[i].oper = oper; + m_traceRecordBuffer[i].param = param; + + m_traceRecordIndex = i+1; + return TRUE; +} + +// Generates an instruction CBOT. + +BOOL CBrain::TraceRecordPut(char *buffer, int max, TraceOper oper, float param) +{ + char line[100]; + int color; + + if ( oper == TO_ADVANCE ) + { + param /= g_unit; + sprintf(line, "\tmove(%.1f);\n", param); + strncat(buffer, line, max-1); + } + + if ( oper == TO_RECEDE ) + { + param /= g_unit; + sprintf(line, "\tmove(-%.1f);\n", param); + strncat(buffer, line, max-1); + } + + if ( oper == TO_TURN ) + { + param = -param*180.0f/PI; + sprintf(line, "\tturn(%d);\n", (int)param); +//? sprintf(line, "\tturn(%.1f);\n", param); + strncat(buffer, line, max-1); + } + + if ( oper == TO_PEN ) + { + color = (int)param; + if ( color == -1 ) strncat(buffer, "\tpenup();\n", max-1); + if ( color == 1 ) strncat(buffer, "\tpendown(Black);\n", max-1); + if ( color == 8 ) strncat(buffer, "\tpendown(Yellow);\n", max-1); + if ( color == 7 ) strncat(buffer, "\tpendown(Orange);\n", max-1); + if ( color == 4 ) strncat(buffer, "\tpendown(Red);\n", max-1); + if ( color == 6 ) strncat(buffer, "\tpendown(Purple);\n", max-1); + if ( color == 14 ) strncat(buffer, "\tpendown(Blue);\n", max-1); + if ( color == 12 ) strncat(buffer, "\tpendown(Green);\n", max-1); + if ( color == 10 ) strncat(buffer, "\tpendown(Brown);\n", max-1); + } + + return TRUE; +} + diff --git a/src/object/brain.h b/src/object/brain.h new file mode 100644 index 0000000..988a3cc --- /dev/null +++ b/src/object/brain.h @@ -0,0 +1,220 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// brain.h + +#ifndef _BRAIN_H_ +#define _BRAIN_H_ + + +#include "misc.h" +#include "event.h" +#include "object.h" +#include "taskmanip.h" +#include "taskflag.h" +#include "taskshield.h" + + +class CInstanceManager; +class CD3DEngine; +class CTerrain; +class CWater; +class CCamera; +class CObject; +class CPhysics; +class CMotion; +class CTaskManager; +class CInterface; +class CWindow; +class CDisplayText; +class CScript; +class CRobotMain; +class CStudio; +class CSound; +class CParticule; + + +#define BRAINMAXSCRIPT 10 + + + +enum TraceOper +{ + TO_STOP = 0, // stop + TO_ADVANCE = 1, // advance + TO_RECEDE = 2, // back + TO_TURN = 3, // rotate + TO_PEN = 4, // color change +}; + +typedef struct +{ + TraceOper oper; + float param; +} +TraceRecord; + + + +class CBrain +{ +public: + CBrain(CInstanceManager* iMan, CObject* object); + ~CBrain(); + + void DeleteObject(BOOL bAll=FALSE); + + void SetPhysics(CPhysics* physics); + void SetMotion(CMotion* motion); + + BOOL EventProcess(const Event &event); + BOOL CreateInterface(BOOL bSelect); + + BOOL Write(char *line); + BOOL Read(char *line); + + BOOL IsBusy(); + void SetActivity(BOOL bMode); + BOOL RetActivity(); + BOOL IsProgram(); + BOOL ProgramExist(int rank); + void RunProgram(int rank); + int FreeProgram(); + int RetProgram(); + void StopProgram(); + void StopTask(); + + BOOL IntroduceVirus(); + void SetActiveVirus(BOOL bActive); + BOOL RetActiveVirus(); + + void SetScriptRun(int rank); + int RetScriptRun(); + void SetScriptName(int rank, char *name); + char* RetScriptName(int rank); + void SetSoluceName(char *name); + char* RetSoluceName(); + + BOOL ReadSoluce(char* filename); + BOOL ReadProgram(int rank, char* filename); + BOOL RetCompile(int rank); + BOOL WriteProgram(int rank, char* filename); + BOOL ReadStack(FILE *file); + BOOL WriteStack(FILE *file); + + Error StartTaskTake(); + Error StartTaskManip(TaskManipOrder order, TaskManipArm arm); + Error StartTaskFlag(TaskFlagOrder order, int rank); + Error StartTaskBuild(ObjectType type); + Error StartTaskSearch(); + Error StartTaskTerraform(); + Error StartTaskPen(BOOL bDown, int color); + Error StartTaskRecover(); + Error StartTaskShield(TaskShieldMode mode); + Error StartTaskFire(float delay); + Error StartTaskFireAnt(D3DVECTOR impact); + Error StartTaskGunGoal(float dirV, float dirH); + Error StartTaskReset(D3DVECTOR goal, D3DVECTOR angle); + + void UpdateInterface(float rTime); + void UpdateInterface(); + +protected: + BOOL EventFrame(const Event &event); + + void StartEditScript(int rank, char* name); + void StopEditScript(BOOL bCancel); + + Error EndedTask(); + + void GroundFlat(); + void ColorFlag(int color); + + void UpdateScript(CWindow *pw); + int RetSelScript(); + void BlinkScript(BOOL bEnable); + + void CheckInterface(CWindow *pw, EventMsg event, BOOL bState); + void EnableInterface(CWindow *pw, EventMsg event, BOOL bState); + void DeadInterface(CWindow *pw, EventMsg event, BOOL bState); + void DefaultEnter(CWindow *pw, EventMsg event, BOOL bState=TRUE); + + void TraceRecordStart(); + void TraceRecordFrame(); + void TraceRecordStop(); + BOOL TraceRecordOper(TraceOper oper, float param); + BOOL TraceRecordPut(char *buffer, int max, TraceOper oper, float param); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CTerrain* m_terrain; + CWater* m_water; + CCamera* m_camera; + CObject* m_object; + CPhysics* m_physics; + CMotion* m_motion; + CInterface* m_interface; + CDisplayText* m_displayText; + CRobotMain* m_main; + CStudio* m_studio; + CSound* m_sound; + CParticule* m_particule; + CTaskManager* m_primaryTask; + CTaskManager* m_secondaryTask; + + CScript* m_script[BRAINMAXSCRIPT]; + int m_selScript; // rank of the selected script + int m_program; // rank of the executed program / ​​-1 + BOOL m_bActivity; + BOOL m_bBurn; + BOOL m_bActiveVirus; + + int m_scriptRun; + char m_scriptName[BRAINMAXSCRIPT][50]; + char m_soluceName[50]; + + EventMsg m_buttonAxe; + EventMsg m_manipStyle; + EventMsg m_defaultEnter; + EventMsg m_interfaceEvent[100]; + + CObject* m_antTarget; + CObject* m_beeBullet; + float m_beeBulletSpeed; + D3DVECTOR m_startPos; + float m_time; + float m_burnTime; + float m_lastUpdateTime; + float m_lastHumanTime; + float m_lastSpiderTime; + float m_lastWormTime; + float m_lastBulletTime; + float m_lastAlarmTime; + int m_soundChannelAlarm; + int m_flagColor; + + BOOL m_bTraceRecord; + TraceOper m_traceOper; + D3DVECTOR m_tracePos; + float m_traceAngle; + int m_traceColor; + int m_traceRecordIndex; + TraceRecord* m_traceRecordBuffer; +}; + + +#endif //_BRAIN_H_ diff --git a/src/object/motion/motion.cpp b/src/object/motion/motion.cpp new file mode 100644 index 0000000..642108b --- /dev/null +++ b/src/object/motion/motion.cpp @@ -0,0 +1,257 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motion.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "light.h" +#include "particule.h" +#include "terrain.h" +#include "water.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "robotmain.h" +#include "sound.h" +#include "cmdtoken.h" +#include "motion.h" + + + + +// Object's constructor. + +CMotion::CMotion(CInstanceManager* iMan, CObject* object) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_MOTION, this, 100); + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); + m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); + m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + + m_object = object; + m_physics = 0; + m_brain = 0; + + m_actionType = -1; + m_actionTime = 0.0f; + m_progress = 0.0f; + + m_linVibration = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_cirVibration = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_inclinaison = D3DVECTOR(0.0f, 0.0f, 0.0f); +} + +// Object's destructor. + +CMotion::~CMotion() +{ + m_iMan->DeleteInstance(CLASS_MOTION, this); +} + +// Deletes the object. + +void CMotion::DeleteObject(BOOL bAll) +{ +} + + +void CMotion::SetPhysics(CPhysics* physics) +{ + m_physics = physics; +} + +void CMotion::SetBrain(CBrain* brain) +{ + m_brain = brain; +} + + +// Creates. + +BOOL CMotion::Create(D3DVECTOR pos, float angle, ObjectType type, float power) +{ + return TRUE; +} + +// Management of an event. + +BOOL CMotion::EventProcess(const Event &event) +{ + D3DVECTOR pos, dir; + float time; + + if ( m_object->RetType() != OBJECT_TOTO && + m_engine->RetPause() ) return TRUE; + + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_actionTime; + if ( m_progress > 1.0f ) m_progress = 1.0f; // (*) + + pos = m_object->RetPosition(0); + if ( pos.y < m_water->RetLevel(m_object) ) // underwater? + { + time = event.rTime*3.0f; // everything is slower + } + else + { + time = event.rTime*10.0f; + } + + dir = m_object->RetLinVibration(); + dir.x = Smooth(dir.x, m_linVibration.x, time); + dir.y = Smooth(dir.y, m_linVibration.y, time); + dir.z = Smooth(dir.z, m_linVibration.z, time); + m_object->SetLinVibration(dir); + + dir = m_object->RetCirVibration(); + dir.x = Smooth(dir.x, m_cirVibration.x, time); + dir.y = Smooth(dir.y, m_cirVibration.y, time); + dir.z = Smooth(dir.z, m_cirVibration.z, time); + m_object->SetCirVibration(dir); + + dir = m_object->RetInclinaison(); + dir.x = Smooth(dir.x, m_inclinaison.x, time); + dir.y = Smooth(dir.y, m_inclinaison.y, time); + dir.z = Smooth(dir.z, m_inclinaison.z, time); + m_object->SetInclinaison(dir); + + return TRUE; +} + +// (*) Avoids the bug of ants returned by the thumper and +// whose abdomen grown to infinity! + + +// Start an action. + +Error CMotion::SetAction(int action, float time) +{ + m_actionType = action; + m_actionTime = 1.0f/time; + m_progress = 0.0f; + return ERR_OK; +} + +// Returns the current action. + +int CMotion::RetAction() +{ + return m_actionType; +} + + +// Specifies a special parameter. + +BOOL CMotion::SetParam(int rank, float value) +{ + return FALSE; +} + +float CMotion::RetParam(int rank) +{ + return 0.0f; +} + + +// Saves all parameters of the object. + +BOOL CMotion::Write(char *line) +{ + char name[100]; + + if ( m_actionType == -1 ) return FALSE; + + sprintf(name, " mType=%d", m_actionType); + strcat(line, name); + + sprintf(name, " mTime=%.2f", m_actionTime); + strcat(line, name); + + sprintf(name, " mProgress=%.2f", m_progress); + strcat(line, name); + + return FALSE; +} + +// Restores all parameters of the object. + +BOOL CMotion::Read(char *line) +{ + m_actionType = OpInt(line, "mType", -1); + m_actionTime = OpFloat(line, "mTime", 0.0f); + m_progress = OpFloat(line, "mProgress", 0.0f); + + return FALSE; +} + + +// Gives the linear vibration. + +void CMotion::SetLinVibration(D3DVECTOR dir) +{ + m_linVibration = dir; +} + +D3DVECTOR CMotion::RetLinVibration() +{ + return m_linVibration; +} + +// Gives the circular vibration. + +void CMotion::SetCirVibration(D3DVECTOR dir) +{ + m_cirVibration = dir; +} + +D3DVECTOR CMotion::RetCirVibration() +{ + return m_cirVibration; +} + +// Gives the tilt. + +void CMotion::SetInclinaison(D3DVECTOR dir) +{ + m_inclinaison = dir; +} + +D3DVECTOR CMotion::RetInclinaison() +{ + return m_inclinaison; +} + diff --git a/src/object/motion/motion.h b/src/object/motion/motion.h new file mode 100644 index 0000000..5aa0afb --- /dev/null +++ b/src/object/motion/motion.h @@ -0,0 +1,94 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motion.h + +#ifndef _MOTION_H_ +#define _MOTION_H_ + + +#include "d3dengine.h" + + +class CInstanceManager; +class CEngine; +class CLight; +class CParticule; +class CTerrain; +class CWater; +class CCamera; +class CBrain; +class CPhysics; +class CObject; +class CRobotMain; +class CSound; + + +class CMotion +{ +public: + CMotion(CInstanceManager* iMan, CObject* object); + virtual ~CMotion(); + + void SetPhysics(CPhysics* physics); + void SetBrain(CBrain* brain); + + virtual void DeleteObject(BOOL bAll=FALSE); + virtual BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); + virtual BOOL EventProcess(const Event &event); + virtual Error SetAction(int action, float time=0.2f); + virtual int RetAction(); + + virtual BOOL SetParam(int rank, float value); + virtual float RetParam(int rank); + + virtual BOOL Write(char *line); + virtual BOOL Read(char *line); + + virtual void SetLinVibration(D3DVECTOR dir); + virtual D3DVECTOR RetLinVibration(); + virtual void SetCirVibration(D3DVECTOR dir); + virtual D3DVECTOR RetCirVibration(); + virtual void SetInclinaison(D3DVECTOR dir); + virtual D3DVECTOR RetInclinaison(); + +protected: + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CLight* m_light; + CParticule* m_particule; + CTerrain* m_terrain; + CWater* m_water; + CCamera* m_camera; + CObject* m_object; + CBrain* m_brain; + CPhysics* m_physics; + CRobotMain* m_main; + CSound* m_sound; + + int m_actionType; + float m_actionTime; + float m_progress; + + D3DVECTOR m_linVibration; // linear vibration + D3DVECTOR m_cirVibration; // circular vibration + D3DVECTOR m_inclinaison; // tilt +}; + + +#endif //_MOTION_H_ diff --git a/src/object/motion/motionant.cpp b/src/object/motion/motionant.cpp new file mode 100644 index 0000000..3790f7e --- /dev/null +++ b/src/object/motion/motionant.cpp @@ -0,0 +1,901 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionant.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "light.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "modfile.h" +#include "sound.h" +#include "motion.h" +#include "motionant.h" + + + +#define ADJUST_ANGLE FALSE // TRUE -> adjusts the angles of the members +#define START_TIME 1000.0f // beginning of the relative time + + + +// Object's constructor. + +CMotionAnt::CMotionAnt(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + CMotion::CMotion(iMan, object); + + m_armMember = START_TIME; + m_armTimeAbs = START_TIME; + m_armTimeMarch = START_TIME; + m_armTimeAction = START_TIME; + m_armTimeIndex = 0; + m_armPartIndex = 0; + m_armMemberIndex = 0; + m_armLastAction = -1; + m_bArmStop = FALSE; + m_lastParticule = 0.0f; +} + +// Object's destructor. + +CMotionAnt::~CMotionAnt() +{ +} + + +// Removes an object. + +void CMotionAnt::DeleteObject(BOOL bAll) +{ +} + + +// Creates a vehicle poses some rolling on the floor. + +BOOL CMotionAnt::Create(D3DVECTOR pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + int rank; + + if ( m_engine->RetRestCreate() < 3+18 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + + // Creates the main base. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + + pModFile->ReadModel("objects\\ant1.mod"); + pModFile->CreateEngineObject(rank); + + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // A vehicle must have necessarily a collision + //with a sphere of center (0, y, 0) (see GetCrashSphere). + m_object->CreateCrashSphere(D3DVECTOR(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f); + m_object->SetGlobalSphere(D3DVECTOR(-0.5f, 1.0f, 0.0f), 4.0f); + + // Creates the head. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\ant2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(2.0f, 0.0f, 0.0f)); + + // Creates the tail. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\ant3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, D3DVECTOR(-1.0f, 0.0f, 0.0f)); + + // Creates a right-back thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, D3DVECTOR(-0.4f, -0.1f, -0.3f)); + + // Creates a right-back leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(4, rank); + m_object->SetObjectParent(4, 3); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(4, D3DVECTOR(0.0f, 0.0f, -1.0f)); + + // Creates a right-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(5, rank); + m_object->SetObjectParent(5, 4); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(5, D3DVECTOR(0.0f, 0.0f, -2.0f)); + + // Creates two middle-right thighs. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, D3DVECTOR(0.1f, -0.1f, -0.4f)); + + // Creates two middle-right legs. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 6); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, D3DVECTOR(0.0f, 0.0f, -1.0f)); + + // Creates two middle-right foots. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 7); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, D3DVECTOR(0.0f, 0.0f, -2.0f)); + + // Creates the right front thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, D3DVECTOR(1.4f, -0.1f, -0.6f)); + + // Creates the right front leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(10, rank); + m_object->SetObjectParent(10, 9); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(10, D3DVECTOR(0.0f, 0.0f, -1.0f)); + + // Creates the right front foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(11, rank); + m_object->SetObjectParent(11, 10); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(11, D3DVECTOR(0.0f, 0.0f, -2.0f)); + + // Creates a left-back thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(12, rank); + m_object->SetObjectParent(12, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(12, D3DVECTOR(-0.4f, -0.1f, 0.3f)); + + // Creates a left-back leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(13, rank); + m_object->SetObjectParent(13, 12); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(13, D3DVECTOR(0.0f, 0.0f, 1.0f)); + + // Creates a left-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(14, rank); + m_object->SetObjectParent(14, 13); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(14, D3DVECTOR(0.0f, 0.0f, 2.0f)); + + // Creates two middle-left thighs. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(15, rank); + m_object->SetObjectParent(15, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(15, D3DVECTOR(0.1f, -0.1f, 0.4f)); + + // Creates two middle-left legs. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(16, rank); + m_object->SetObjectParent(16, 15); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(16, D3DVECTOR(0.0f, 0.0f, 1.0f)); + + // Creates two middle-left foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(17, rank); + m_object->SetObjectParent(17, 16); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(17, D3DVECTOR(0.0f, 0.0f, 2.0f)); + + // Creates the left front thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(18, rank); + m_object->SetObjectParent(18, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(18, D3DVECTOR(1.4f, -0.1f, 0.6f)); + + // Creates the left front leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(19, rank); + m_object->SetObjectParent(19, 18); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(19, D3DVECTOR(0.0f, 0.0f, 1.0f)); + + // Creates the left front foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(20, rank); + m_object->SetObjectParent(20, 19); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(20, D3DVECTOR(0.0f, 0.0f, 2.0f)); + + m_object->CreateShadowCircle(4.0f, 0.5f); + + CreatePhysics(); + m_object->SetFloorHeight(0.0f); + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); // to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return TRUE; +} + +// Creates the physics of the object. + +void CMotionAnt::CreatePhysics() +{ + Character* character; + int i; + + int member_march[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 0,45,0, 0,45,0, 0,50,0, // t0: thighs 1..3 + 30,-70,0, 20,-105,20, 25,-100,0, // t0: legs 1..3 + -70,75,0, -30,80,0, -80,80,0, // t0: feet 1..3 + // on the ground: + 0,30,0, 0,20,0, 0,15,0, // t1: thighs 1..3 + -15,-50,0, -20,-60,0, -10,-75,0, // t1: legs 1..3 + -40,50,0, -25,15,0, -50,35,0, // t1: feet 1..3 + // on the ground back: + 0,35,0, 0,30,0, 0,20,0, // t2: thighs 1..3 + -20,-15,0, -30,-55,0, -25,-70,15, // t2: legs 1..3 + -25,25,0, -20,60,0, -30,95,0, // t2: feet 1..3 + }; + + int member_stop[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 0,30,0, 0,20,0, 0,15,0, // t0: thighs 1..3 + -15,-35,0, -20,-60,0, -15,-75,0, // t0: legs 1..3 + -35,35,0, -25,40,0, -40,65,0, // t0: feet 1..3 + // on the ground: + 0,30,0, 0,20,0, 0,15,0, // t1: thighs 1..3 + -15,-35,0, -20,-60,0, -15,-75,0, // t1: legs 1..3 + -35,35,0, -25,40,0, -40,65,0, // t1: feet 1..3 + // on the ground back: + 0,30,0, 0,20,0, 0,15,0, // t2: thighs 1..3 + -15,-35,0, -20,-60,0, -15,-75,0, // t2: legs 1..3 + -35,35,0, -25,40,0, -40,65,0, // t2: feet 1..3 + }; + + int member_spec[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // prepares the fire: + 0,20,0, 0,10,0, 0,50,0, // s0: thighs 1..3 + -50,-30,0, -20,-15,0, 35,-65,0, // s0: legs 1..3 + -5,-40,0, 20,-70,0, -10,-40,0, // s0: feet 1..3 + // shot: + 0,20,0, 0,10,0, 0,50,0, // s1: thighs 1..3 + -50,-30,0, -20,-15,0, 35,-65,0, // s1: legs 1..3 + -5,-40,0, 20,-70,0, -10,-40,0, // s1: feet 1..3 + // ends the fire: + 0,30,0, 0,20,0, 0,15,0, // s2: thighs 1..3 + -15,-50,0, -20,-60,0, -10,-75,0, // s2: legs 1..3 + -40,50,0, -25,15,0, -50,35,0, // s2: feet 1..3 + // burning: + 0,30,0, 0,20,0, 0,15,0, // s3: thighs 1..3 + -15,-35,0, -20,-60,0, -15,-75,0, // s3: legs 1..3 + -35,35,0, -25,40,0, -40,65,0, // s3: feet 1..3 + // destroyed: + 0,30,0, 0,20,0, 0,15,0, // s4: thighs 1..3 + -15,-35,0, -20,-60,0, -15,-75,0, // s4: legs 1..3 + -35,35,0, -25,40,0, -40,65,0, // s4: feet 1..3 + // back1 : + 0,30,0, 0,20,0, 0,15,0, // s5: thighs 1..3 + -15,-35,0, -20,-60,0, -15,-75,0, // s5: legs 1..3 + -35,35,0, -25,40,0, -40,65,0, // s5: feet 1..3 + // back2 : + 0,45,0, 0,45,0, 0,50,0, // s6: thighs 1..3 + -35,-70,0, -20,-85,-25, -25,-100,0, // s6: legs 1..3 + -110,75,-15, -130,80,-25, -125,40,0, // s6: feet 1..3 + // back3 : + 0,30,0, 0,20,0, 0,15,0, // s7: thighs 1..3 + -15,-35,0, -20,-60,0, -15,-75,0, // s7: legs 1..3 + -35,35,0, -25,40,0, -40,65,0, // s7: feet 1..3 + }; + + m_physics->SetType(TYPE_ROLLING); + + character = m_object->RetCharacter(); + character->wheelFront = 3.0f; + character->wheelBack = 3.0f; + character->wheelLeft = 5.0f; + character->wheelRight = 5.0f; + character->height = 1.2f; + + m_physics->SetLinMotionX(MO_ADVSPEED, 12.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 12.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 15.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 15.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 5.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 5.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 10.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 1.0f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 1.0f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 20.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 20.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 40.0f); + + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MA_MARCH+i] = member_march[i]; + } + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MA_STOP+i] = member_stop[i]; + } + for ( i=0 ; i<3*3*3*8 ; i++ ) + { + m_armAngles[3*3*3*3*MA_SPEC+i] = member_spec[i]; + } +} + + +// Management of an event. + +BOOL CMotionAnt::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { +#if ADJUST_ANGLE + int i; + + if ( event.param == 'A' ) m_armTimeIndex++; + if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0; + + if ( event.param == 'Q' ) m_armPartIndex++; + if ( m_armPartIndex >= 3 ) m_armPartIndex = 0; + + if ( event.param == 'W' ) m_armMemberIndex++; + if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0; + + i = m_armMemberIndex*3; + i += m_armPartIndex*3*3; + i += m_armTimeIndex*3*3*3; +//? i += 3*3*3*3; + + if ( event.param == 'E' ) m_armAngles[i+0] += 5; + if ( event.param == 'D' ) m_armAngles[i+0] -= 5; + if ( event.param == 'R' ) m_armAngles[i+1] += 5; + if ( event.param == 'F' ) m_armAngles[i+1] -= 5; + if ( event.param == 'T' ) m_armAngles[i+2] += 5; + if ( event.param == 'G' ) m_armAngles[i+2] -= 5; + + if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop; +#endif + } + + return TRUE; +} + +// Calculates a value (radians) proportional between a and b (degrees). + +inline float Propf(float a, float b, float p) +{ + float aa, bb; + + aa = a*PI/180.0f; + bb = b*PI/180.0f; + + return aa+p*(bb-aa); +} + +// Management of an event. + +BOOL CMotionAnt::EventFrame(const Event &event) +{ + D3DVECTOR dir, pos, speed; + FPOINT dim; + float s, a, prog, time; + float tSt[9], tNd[9]; + int i, ii, st, nd, action; + BOOL bStop; + + if ( m_engine->RetPause() ) return TRUE; + if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return TRUE; + + s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f; + a = Abs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.0f); + + if ( s == 0.0f && a != 0.0f ) a *= 1.5f; + + m_armTimeAbs += event.rTime; + m_armTimeMarch += (s)*event.rTime*0.15f; + m_armMember += (s+a)*event.rTime*0.15f; + + bStop = ( a == 0.0f && s == 0.0f ); // stopped? + + action = MA_MARCH; // walking + if ( s == 0.0f && a == 0.0f ) + { + action = MA_STOP; // stop + } + + if ( bStop ) + { + prog = Mod(m_armTimeAbs, 2.0f)/10.0f; + a = Mod(m_armMember, 1.0f); + a = (prog-a)*event.rTime*2.0f; // stop position is pleasantly + m_armMember += a; + } + + if ( m_object->RetRuin() ) // destroyed? + { + m_actionType = MAS_RUIN; + } + if ( m_object->RetBurn() ) // burning? + { + if ( m_object->RetFixed() ) + { + m_actionType = MAS_BURN; + } + else + { + m_actionType = -1; + } + } + + for ( i=0 ; i<6 ; i++ ) // the six legs + { + if ( m_actionType != -1 ) // special action in progress? + { + st = 3*3*3*3*MA_SPEC + 3*3*3*m_actionType + (i%3)*3; + nd = st; + time = event.rTime*m_actionTime; + m_armTimeAction = 0.0f; + } + else + { + if ( i < 3 ) prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f); + else prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f); + if ( m_bArmStop ) + { + prog = (float)m_armTimeIndex/3.0f; + } + if ( prog < 0.33f ) // t0..t1 ? + { + prog = prog/0.33f; // 0..1 + st = 0; // index start + nd = 1; // index end + } + else if ( prog < 0.67f ) // t1..t2 ? + { + prog = (prog-0.33f)/0.33f; // 0..1 + st = 1; // index start + nd = 2; // index end + } + else // t2..t0 ? + { + prog = (prog-0.67f)/0.33f; // 0..1 + st = 2; // index start + nd = 0; // index end + } + st = 3*3*3*3*action + st*3*3*3 + (i%3)*3; + nd = 3*3*3*3*action + nd*3*3*3 + (i%3)*3; + + // More and more soft ... + time = event.rTime*(10.0f+Min(m_armTimeAction*100.0f, 200.0f)); + } + + tSt[0] = m_armAngles[st+ 0]; // x + tSt[1] = m_armAngles[st+ 1]; // y + tSt[2] = m_armAngles[st+ 2]; // z + tSt[3] = m_armAngles[st+ 9]; // x + tSt[4] = m_armAngles[st+10]; // y + tSt[5] = m_armAngles[st+11]; // z + tSt[6] = m_armAngles[st+18]; // x + tSt[7] = m_armAngles[st+19]; // y + tSt[8] = m_armAngles[st+20]; // z + + tNd[0] = m_armAngles[nd+ 0]; // x + tNd[1] = m_armAngles[nd+ 1]; // y + tNd[2] = m_armAngles[nd+ 2]; // z + tNd[3] = m_armAngles[nd+ 9]; // x + tNd[4] = m_armAngles[nd+10]; // y + tNd[5] = m_armAngles[nd+11]; // z + tNd[6] = m_armAngles[nd+18]; // x + tNd[7] = m_armAngles[nd+19]; // y + tNd[8] = m_armAngles[nd+20]; // z + + if ( m_actionType == MAS_BACK2 ) // on the back? + { + for ( ii=0 ; ii<9 ; ii++ ) + { + tSt[ii] += Rand()*50.0f; + tNd[ii] = tSt[ii]; + } +//? time = 100.0f; + time = event.rTime*10.0f; + } + + if ( i < 3 ) // right leg (1..3) ? + { + m_object->SetAngleX(3+3*i+0, Smooth(m_object->RetAngleX(3+3*i+0), Propf(tSt[0], tNd[0], prog), time)); + m_object->SetAngleY(3+3*i+0, Smooth(m_object->RetAngleY(3+3*i+0), Propf(tSt[1], tNd[1], prog), time)); + m_object->SetAngleZ(3+3*i+0, Smooth(m_object->RetAngleZ(3+3*i+0), Propf(tSt[2], tNd[2], prog), time)); + m_object->SetAngleX(3+3*i+1, Smooth(m_object->RetAngleX(3+3*i+1), Propf(tSt[3], tNd[3], prog), time)); + m_object->SetAngleY(3+3*i+1, Smooth(m_object->RetAngleY(3+3*i+1), Propf(tSt[4], tNd[4], prog), time)); + m_object->SetAngleZ(3+3*i+1, Smooth(m_object->RetAngleZ(3+3*i+1), Propf(tSt[5], tNd[5], prog), time)); + m_object->SetAngleX(3+3*i+2, Smooth(m_object->RetAngleX(3+3*i+2), Propf(tSt[6], tNd[6], prog), time)); + m_object->SetAngleY(3+3*i+2, Smooth(m_object->RetAngleY(3+3*i+2), Propf(tSt[7], tNd[7], prog), time)); + m_object->SetAngleZ(3+3*i+2, Smooth(m_object->RetAngleZ(3+3*i+2), Propf(tSt[8], tNd[8], prog), time)); + } + else // left leg (4..6) ? + { + m_object->SetAngleX(3+3*i+0, Smooth(m_object->RetAngleX(3+3*i+0), Propf(-tSt[0], -tNd[0], prog), time)); + m_object->SetAngleY(3+3*i+0, Smooth(m_object->RetAngleY(3+3*i+0), Propf(-tSt[1], -tNd[1], prog), time)); + m_object->SetAngleZ(3+3*i+0, Smooth(m_object->RetAngleZ(3+3*i+0), Propf( tSt[2], tNd[2], prog), time)); + m_object->SetAngleX(3+3*i+1, Smooth(m_object->RetAngleX(3+3*i+1), Propf(-tSt[3], -tNd[3], prog), time)); + m_object->SetAngleY(3+3*i+1, Smooth(m_object->RetAngleY(3+3*i+1), Propf(-tSt[4], -tNd[4], prog), time)); + m_object->SetAngleZ(3+3*i+1, Smooth(m_object->RetAngleZ(3+3*i+1), Propf( tSt[5], tNd[5], prog), time)); + m_object->SetAngleX(3+3*i+2, Smooth(m_object->RetAngleX(3+3*i+2), Propf(-tSt[6], -tNd[6], prog), time)); + m_object->SetAngleY(3+3*i+2, Smooth(m_object->RetAngleY(3+3*i+2), Propf(-tSt[7], -tNd[7], prog), time)); + m_object->SetAngleZ(3+3*i+2, Smooth(m_object->RetAngleZ(3+3*i+2), Propf( tSt[8], tNd[8], prog), time)); + } + } + +#if ADJUST_ANGLE + if ( m_object->RetSelect() ) + { + char s[100]; + sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex); + m_engine->SetInfoText(4, s); + } +#endif + + if ( m_actionType == MAS_PREPARE ) // prepares the shooting? + { + prog = m_progress; + + dir.x = 0.0f; + dir.y = 0.0f; + dir.z = Prop(0, -50, prog); + SetInclinaison(dir); + m_object->SetAngleZ(1, Prop(0, 65, prog)); // head + m_object->SetAngleZ(2, Prop(0, -95, prog)); // tail + } + else if ( m_actionType == MAS_FIRE ) // shooting? + { + if ( m_progress < 0.75f ) a = m_progress/0.75f; + else a = (1.0f-m_progress)/0.25f; + m_object->SetZoom(2, (a*0.5f)+1.0f); // tail + m_object->SetAngleX(2, (Rand()-0.5f)*0.3f*a); + m_object->SetAngleY(2, (Rand()-0.5f)*0.3f*a); + + dir.x = (Rand()-0.5f)*0.02f*a; + dir.y = (Rand()-0.5f)*0.05f*a; + dir.z = (Rand()-0.5f)*0.03f*a; + SetCirVibration(dir); + } + else if ( m_actionType == MAS_TERMINATE ) // ends the shooting? + { + prog = 1.0f-m_progress; + + dir.x = 0.0f; + dir.y = 0.0f; + dir.z = Prop(0, -50, prog); + SetInclinaison(dir); + m_object->SetAngleZ(1, Prop(0, 65, prog)); // head + m_object->SetAngleZ(2, Prop(0, -95, prog)); // tail + } + else if ( m_actionType == MAS_BURN ) // burning? + { + dir = D3DVECTOR(PI, 0.0f, 0.0f); + SetCirVibration(dir); + dir = D3DVECTOR(0.0f, -1.5f, 0.0f); + SetLinVibration(dir); + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + + time = event.rTime*1.0f; + m_object->SetAngleZ(1, Smooth(m_object->RetAngleZ(1), 0.0f, time)); // head + m_object->SetAngleZ(2, Smooth(m_object->RetAngleZ(2), 0.0f, time)); // tail + } + else if ( m_actionType == MAS_RUIN ) // destroyed? + { + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + SetLinVibration(dir); + SetCirVibration(dir); + SetInclinaison(dir); + } + else if ( m_actionType == MAS_BACK1 ) // starts on the back? + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) + { + m_lastParticule = m_armTimeAbs; + + pos = m_object->RetPosition(0); + speed.x = (Rand()-0.5f)*10.0f; + speed.z = (Rand()-0.5f)*10.0f; + speed.y = Rand()*5.0f; + dim.x = Rand()*3.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + + if ( m_progress < 0.5f ) + { + dir.x = 0.0f; + dir.y = powf(m_progress/0.5f, 2.0f)*12.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + else + { + dir.x = 0.0f; + dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*12.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + dir.x = m_progress*PI; + dir.y = 0.0f; + dir.z = 0.0f; + SetCirVibration(dir); + + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + + if ( m_progress >= 1.0f ) + { + SetAction(MAS_BACK2, 55.0f+Rand()*10.0f); + } + } + else if ( m_actionType == MAS_BACK2 ) // moves on the back? + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) + { + m_lastParticule = m_armTimeAbs; + + if ( rand()%10 == 0 ) + { + pos = m_object->RetPosition(0); + pos.x += (Rand()-0.5f)*5.0f; + pos.z += (Rand()-0.5f)*5.0f; + pos.y -= 1.0f; + speed.x = (Rand()-0.5f)*2.0f; + speed.z = (Rand()-0.5f)*2.0f; + speed.y = Rand()*2.0f; + dim.x = Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + } + + dir = D3DVECTOR(0.0f, -1.0f, 0.0f); + SetLinVibration(dir); + dir.x = sinf(m_armTimeAbs* 4.0f)*0.10f+ + sinf(m_armTimeAbs* 7.0f)*0.20f+ + sinf(m_armTimeAbs*10.0f)*0.40f+ + sinf(m_armTimeAbs*21.0f)*0.50f+PI; + dir.y = sinf(m_armTimeAbs* 3.0f)*0.01f+ + sinf(m_armTimeAbs* 6.0f)*0.02f+ + sinf(m_armTimeAbs*11.0f)*0.04f+ + sinf(m_armTimeAbs*20.0f)*0.02f; + dir.z = sinf(m_armTimeAbs* 5.0f)*0.01f+ + sinf(m_armTimeAbs* 8.0f)*0.02f+ + sinf(m_armTimeAbs* 9.0f)*0.04f+ + sinf(m_armTimeAbs*23.0f)*0.03f; + SetCirVibration(dir); + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + + m_object->SetAngleY(1, sinf(m_armTimeAbs*8.0f)*0.7f); // head + m_object->SetAngleY(2, cosf(m_armTimeAbs*8.0f)*0.7f); // tail + m_object->SetAngleZ(1, 0.0f); // head + m_object->SetAngleZ(2, 0.0f); // tail + + if ( m_progress >= 1.0f ) + { + SetAction(MAS_BACK3, 0.4f); + } + } + else if ( m_actionType == MAS_BACK3 ) // goes back on the legs? + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) + { + m_lastParticule = m_armTimeAbs; + + pos = m_object->RetPosition(0); + speed.x = (Rand()-0.5f)*10.0f; + speed.z = (Rand()-0.5f)*10.0f; + speed.y = Rand()*5.0f; + dim.x = Rand()*3.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + + if ( m_progress < 0.5f ) + { + dir.x = 0.0f; + dir.y = powf(m_progress/0.5f, 2.0f)*5.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + else + { + dir.x = 0.0f; + dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*5.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + dir.x = (1.0f-m_progress)*PI; + dir.y = 0.0f; + dir.z = 0.0f; + SetCirVibration(dir); + + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + + if ( m_progress >= 1.0f ) + { + SetAction(-1); + m_object->SetFixed(FALSE); // moving again + } + } + else + { + m_object->SetZoom(2, 1.0f); // tail + m_object->SetAngleX(2, 0.0f); + m_object->SetAngleY(2, 0.0f); + + if ( bStop ) + { + m_object->SetAngleZ(2, sinf(m_armTimeAbs*1.7f)*0.15f); // tail + + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + SetLinVibration(dir); + SetInclinaison(dir); + } + else + { + a = Mod(m_armTimeMarch, 1.0f); + if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1 + else a = 3.0f-4.0f*a; // 1..-1 + dir.x = sinf(a)*0.05f; + + s = Mod(m_armTimeMarch/2.0f, 1.0f); + if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1 + else s = 3.0f-4.0f*s; // 1..-1 + dir.z = sinf(s)*0.1f; + + dir.y = 0.0f; + SetInclinaison(dir); + + m_object->SetAngleZ(2, -sinf(a)*0.3f); // tail + + a = Mod(m_armMember-0.1f, 1.0f); + if ( a < 0.33f ) + { + dir.y = -(1.0f-(a/0.33f))*0.3f; + } + else if ( a < 0.67f ) + { + dir.y = 0.0f; + } + else + { + dir.y = -(a-0.67f)/0.33f*0.3f; + } + dir.x = 0.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + SetCirVibration(dir); + + m_object->SetAngleZ(1, sinf(m_armTimeAbs*1.4f)*0.20f); // head + m_object->SetAngleX(1, sinf(m_armTimeAbs*1.9f)*0.10f); // head + m_object->SetAngleY(1, sinf(m_armTimeAbs*2.1f)*0.50f); // head + } + + return TRUE; +} + + diff --git a/src/object/motion/motionant.h b/src/object/motion/motionant.h new file mode 100644 index 0000000..e8d79c6 --- /dev/null +++ b/src/object/motion/motionant.h @@ -0,0 +1,80 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionant.h + +#ifndef _MOTIONANT_H_ +#define _MOTIONANT_H_ + + +#include "motion.h" + + +class CInstanceManager; +class CEngine; +class CLight; +class CParticule; +class CTerrain; +class CCamera; +class CBrain; +class CPhysics; +class CObject; + + +#define MA_MARCH 0 +#define MA_STOP 1 +#define MA_SPEC 2 + +#define MAS_PREPARE 0 +#define MAS_FIRE 1 +#define MAS_TERMINATE 2 +#define MAS_BURN 3 +#define MAS_RUIN 4 +#define MAS_BACK1 5 +#define MAS_BACK2 6 +#define MAS_BACK3 7 + + +class CMotionAnt : public CMotion +{ +public: + CMotionAnt(CInstanceManager* iMan, CObject* object); + ~CMotionAnt(); + + void DeleteObject(BOOL bAll=FALSE); + BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); + BOOL EventProcess(const Event &event); + +protected: + void CreatePhysics(); + BOOL EventFrame(const Event &event); + +protected: + float m_armMember; + float m_armTimeAbs; + float m_armTimeMarch; + float m_armTimeAction; + short m_armAngles[3*3*3*3*3 + 3*3*3*8]; + int m_armTimeIndex; + int m_armPartIndex; + int m_armMemberIndex; + int m_armLastAction; + BOOL m_bArmStop; + float m_lastParticule; +}; + + +#endif //_MOTIONANT_H_ diff --git a/src/object/motion/motionbee.cpp b/src/object/motion/motionbee.cpp new file mode 100644 index 0000000..65ebeb7 --- /dev/null +++ b/src/object/motion/motionbee.cpp @@ -0,0 +1,663 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionbee.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "light.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "modfile.h" +#include "sound.h" +#include "motion.h" +#include "motionbee.h" + + + +#define ADJUST_ANGLE FALSE // TRUE -> adjusts the angles of the members +#define START_TIME 1000.0f // beginning of the relative time + + + +// Object's constructor. + +CMotionBee::CMotionBee(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + CMotion::CMotion(iMan, object); + + m_armMember = START_TIME; + m_armTimeAbs = START_TIME; + m_armTimeMarch = START_TIME; + m_armTimeAction = START_TIME; + m_armTimeIndex = 0; + m_armPartIndex = 0; + m_armMemberIndex = 0; + m_armLastAction = -1; + m_bArmStop = FALSE; +} + +// Object's destructor. + +CMotionBee::~CMotionBee() +{ +} + + +// Removes an object. + +void CMotionBee::DeleteObject(BOOL bAll) +{ +} + + +// Creates a vehicle traveling any lands on the ground. + +BOOL CMotionBee::Create(D3DVECTOR pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + int rank; + + if ( m_engine->RetRestCreate() < 3+18+2 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + + // Creates main base. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + + pModFile->ReadModel("objects\\bee1.mod"); + pModFile->CreateEngineObject(rank); + + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // A vehicle must have an obligatory collision + // with a sphere of center (0, y, 0) (see GetCrashSphere). + m_object->CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f); + m_object->SetGlobalSphere(D3DVECTOR(-1.0f, 1.0f, 0.0f), 5.0f); + + // Creates the head. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\bee2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(1.6f, 0.3f, 0.0f)); + + // Creates the tail. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\bee3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, D3DVECTOR(-0.8f, 0.0f, 0.0f)); + + // Creates a right-back thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, D3DVECTOR(-0.3f, -0.1f, -0.2f)); + + // Creates a right-back leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(4, rank); + m_object->SetObjectParent(4, 3); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(4, D3DVECTOR(0.0f, 0.0f, -1.0f)); + + // Creates a right-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(5, rank); + m_object->SetObjectParent(5, 4); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(5, D3DVECTOR(0.0f, 0.0f, -2.0f)); + + // Creates two middle-right thighs. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, D3DVECTOR(0.3f, -0.1f, -0.4f)); + + // Creates two middle-right legs. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 6); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, D3DVECTOR(0.0f, 0.0f, -1.0f)); + + // Creates two middle-right feet. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 7); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, D3DVECTOR(0.0f, 0.0f, -2.0f)); + + // Creates the right front thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, D3DVECTOR(1.0f, -0.1f, -0.7f)); + + // Creates the right front leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(10, rank); + m_object->SetObjectParent(10, 9); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(10, D3DVECTOR(0.0f, 0.0f, -1.0f)); + + // Creates the right front foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(11, rank); + m_object->SetObjectParent(11, 10); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(11, D3DVECTOR(0.0f, 0.0f, -2.0f)); + + // Creates a left-back thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(12, rank); + m_object->SetObjectParent(12, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(12, D3DVECTOR(-0.3f, -0.1f, 0.2f)); + m_object->SetAngleY(12, PI); + + // Creates a left-back leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(13, rank); + m_object->SetObjectParent(13, 12); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(13, D3DVECTOR(0.0f, 0.0f, -1.0f)); + + // Creates a left-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(14, rank); + m_object->SetObjectParent(14, 13); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(14, D3DVECTOR(0.0f, 0.0f, -2.0f)); + + // Creates two middle-left thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(15, rank); + m_object->SetObjectParent(15, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(15, D3DVECTOR(0.3f, -0.1f, 0.4f)); + m_object->SetAngleY(15, PI); + + // Creates two middle-left legs. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(16, rank); + m_object->SetObjectParent(16, 15); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(16, D3DVECTOR(0.0f, 0.0f, -1.0f)); + + // Creates two middle-left feet. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(17, rank); + m_object->SetObjectParent(17, 16); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(17, D3DVECTOR(0.0f, 0.0f, -2.0f)); + + // Creates front-left thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(18, rank); + m_object->SetObjectParent(18, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(18, D3DVECTOR(1.0f, -0.1f, 0.7f)); + m_object->SetAngleY(18, PI); + + // Creates front-left leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(19, rank); + m_object->SetObjectParent(19, 18); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(19, D3DVECTOR(0.0f, 0.0f, -1.0f)); + + // Creates front-left foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(20, rank); + m_object->SetObjectParent(20, 19); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(20, D3DVECTOR(0.0f, 0.0f, -2.0f)); + + // Creates the right wing. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(21, rank); + m_object->SetObjectParent(21, 0); + pModFile->ReadModel("objects\\bee7.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(21, D3DVECTOR(0.8f, 0.4f, -0.5f)); + + // Creates the left wing. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(22, rank); + m_object->SetObjectParent(22, 0); + pModFile->ReadModel("objects\\bee7.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(22, D3DVECTOR(0.8f, 0.4f, 0.5f)); + + m_object->CreateShadowCircle(6.0f, 0.5f); + + CreatePhysics(); + m_object->SetFloorHeight(0.0f); + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); // to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return TRUE; +} + +// Creates the physical object. + +void CMotionBee::CreatePhysics() +{ + Character* character; + int i; + + int member_march[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 0,45,0, 0,45,0, 0,50,0, // t0: thighs 1..3 + 30,-70,0, 20,-105,20, 25,-100,0, // t0: legs 1..3 + -70,75,0, -30,80,0, -80,80,0, // t0: feet 1..3 + // on the ground: + 0,30,0, 0,20,0, 0,15,0, // t1: thighs 1..3 + -15,-50,0, -20,-60,0, -10,-75,0, // t1: legs 1..3 + -40,50,0, -25,15,0, -50,35,0, // t1: feet 1..3 + // on the ground back: + 0,35,0, 0,30,0, 0,20,0, // t2: thighs 1..3 + -20,-15,0, -30,-55,0, -25,-70,15, // t2: legs 1..3 + -25,25,0, -20,60,0, -30,95,0, // t2: feet 1..3 + }; + + int member_spec[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // ball carrier: + 0,45,0, 0,45,0, 0,50,0, // s0: thighs 1..3 + -35,-70,0, -20,-85,-25, -25,-100,0, // s0: legs 1..3 + -110,75,-15, -130,80,-25, -125,40,0, // s0: feet 1..3 + // burning: + 0,45,0, 0,45,0, 0,50,0, // s1: thighs 1..3 + -35,-70,0, -20,-85,-25, -25,-100,0, // s1: legs 1..3 + -110,75,-15, -130,80,-25, -125,40,0, // s1: feet 1..3 + // destroyed: + 0,45,0, 0,45,0, 0,50,0, // s2: thighs 1..3 + -35,-70,0, -20,-85,-25, -25,-100,0, // s2: legs 1..3 + -110,75,-15, -130,80,-25, -125,40,0, // s2: feet 1..3 + }; + + m_physics->SetType(TYPE_FLYING); + + character = m_object->RetCharacter(); + character->wheelFront = 3.0f; + character->wheelBack = 3.0f; + character->wheelLeft = 5.0f; + character->wheelRight = 5.0f; + character->height = 2.5f; + + m_physics->SetLinMotionX(MO_ADVSPEED, 50.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 50.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 20.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f); + m_physics->SetLinMotionY(MO_RECSPEED, 60.0f); + m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionY(MO_RECACCEL, 50.0f); + m_physics->SetLinMotionY(MO_STOACCEL, 50.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 1.0f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 1.0f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 20.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 20.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 40.0f); + + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MB_MARCH+i] = member_march[i]; + } + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MB_SPEC+i] = member_spec[i]; + } +} + + +// Management of an event. + +BOOL CMotionBee::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { +#if ADJUST_ANGLE + int i; + + if ( event.param == 'A' ) m_armTimeIndex++; + if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0; + + if ( event.param == 'Q' ) m_armPartIndex++; + if ( m_armPartIndex >= 3 ) m_armPartIndex = 0; + + if ( event.param == 'W' ) m_armMemberIndex++; + if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0; + + i = m_armMemberIndex*3; + i += m_armPartIndex*3*3; + i += m_armTimeIndex*3*3*3; +//? i += 3*3*3*3; + + if ( event.param == 'E' ) m_armAngles[i+0] += 5; + if ( event.param == 'D' ) m_armAngles[i+0] -= 5; + if ( event.param == 'R' ) m_armAngles[i+1] += 5; + if ( event.param == 'F' ) m_armAngles[i+1] -= 5; + if ( event.param == 'T' ) m_armAngles[i+2] += 5; + if ( event.param == 'G' ) m_armAngles[i+2] -= 5; + + if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop; +#endif + } + + return TRUE; +} + +// Management of an event. + +BOOL CMotionBee::EventFrame(const Event &event) +{ + D3DVECTOR dir; + float s, a, prog; + int action, i, st, nd; + BOOL bStop; + + if ( m_engine->RetPause() ) return TRUE; + if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return TRUE; + + s = m_physics->RetLinMotionX(MO_MOTSPEED)*0.30f; + a = Abs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.00f); + + if ( s == 0.0f && a != 0.0f ) a *= 1.5f; + + m_armTimeAbs += event.rTime; + m_armTimeMarch += (s)*event.rTime*0.15f; + m_armMember += (s+a)*event.rTime*0.15f; + + bStop = ( a == 0.0f && s == 0.0f ); // stopped? + if ( !m_physics->RetLand() ) bStop = TRUE; + + if ( bStop ) + { + prog = Mod(m_armTimeAbs, 2.0f)/10.0f; + a = Mod(m_armMember, 1.0f); + a = (prog-a)*event.rTime*2.0f; // stop position is pleasantly + m_armMember += a; + } + + action = MB_MARCH; // flying + + m_actionType = -1; + if ( m_object->RetFret() != 0 ) m_actionType = MBS_HOLD; // carries the ball + + if ( m_object->RetRuin() ) // destroyed? + { + m_actionType = MBS_RUIN; + } + if ( m_object->RetBurn() ) // burning? + { + m_actionType = MBS_BURN; + } + + for ( i=0 ; i<6 ; i++ ) // the six legs + { + if ( m_actionType != -1 ) // special action in progress? + { + st = 3*3*3*3*MB_SPEC + 3*3*3*m_actionType + (i%3)*3; + nd = st; + } + else + { + if ( i < 3 ) prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f); + else prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f); + if ( m_bArmStop ) + { + prog = (float)m_armTimeIndex/3.0f; + } + if ( prog < 0.33f ) // t0..t1 ? + { + prog = prog/0.33f; // 0..1 + st = 0; // index start + nd = 1; // index end + } + else if ( prog < 0.67f ) // t1..t2 ? + { + prog = (prog-0.33f)/0.33f; // 0..1 + st = 1; // index start + nd = 2; // index end + } + else // t2..t0 ? + { + prog = (prog-0.67f)/0.33f; // 0..1 + st = 2; // index start + nd = 0; // index end + } + st = 3*3*3*3*action + st*3*3*3 + (i%3)*3; + nd = 3*3*3*3*action + nd*3*3*3 + (i%3)*3; + } + + if ( i < 3 ) // right leg (1..3) ? + { + m_object->SetAngleX(3+3*i+0, Prop(m_armAngles[st+ 0], m_armAngles[nd+ 0], prog)); + m_object->SetAngleY(3+3*i+0, Prop(m_armAngles[st+ 1], m_armAngles[nd+ 1], prog)); + m_object->SetAngleZ(3+3*i+0, Prop(m_armAngles[st+ 2], m_armAngles[nd+ 2], prog)); + m_object->SetAngleX(3+3*i+1, Prop(m_armAngles[st+ 9], m_armAngles[nd+ 9], prog)); + m_object->SetAngleY(3+3*i+1, Prop(m_armAngles[st+10], m_armAngles[nd+10], prog)); + m_object->SetAngleZ(3+3*i+1, Prop(m_armAngles[st+11], m_armAngles[nd+11], prog)); + m_object->SetAngleX(3+3*i+2, Prop(m_armAngles[st+18], m_armAngles[nd+18], prog)); + m_object->SetAngleY(3+3*i+2, Prop(m_armAngles[st+19], m_armAngles[nd+19], prog)); + m_object->SetAngleZ(3+3*i+2, Prop(m_armAngles[st+20], m_armAngles[nd+20], prog)); + } + else // left leg(4..6) ? + { + m_object->SetAngleX(3+3*i+0, Prop( -m_armAngles[st+ 0], -m_armAngles[nd+ 0], prog)); + m_object->SetAngleY(3+3*i+0, Prop(180-m_armAngles[st+ 1], 180-m_armAngles[nd+ 1], prog)); + m_object->SetAngleZ(3+3*i+0, Prop( -m_armAngles[st+ 2], -m_armAngles[nd+ 2], prog)); + m_object->SetAngleX(3+3*i+1, Prop( m_armAngles[st+ 9], m_armAngles[nd+ 9], prog)); + m_object->SetAngleY(3+3*i+1, Prop( -m_armAngles[st+10], -m_armAngles[nd+10], prog)); + m_object->SetAngleZ(3+3*i+1, Prop( -m_armAngles[st+11], -m_armAngles[nd+11], prog)); + m_object->SetAngleX(3+3*i+2, Prop( m_armAngles[st+18], m_armAngles[nd+18], prog)); + m_object->SetAngleY(3+3*i+2, Prop( -m_armAngles[st+19], -m_armAngles[nd+19], prog)); + m_object->SetAngleZ(3+3*i+2, Prop( -m_armAngles[st+20], -m_armAngles[nd+20], prog)); + } + } + +#if ADJUST_ANGLE + if ( m_object->RetSelect() ) + { + char s[100]; + sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex); + m_engine->SetInfoText(4, s); + } +#endif + + if ( m_physics->RetLand() ) // on the ground? + { + if ( m_object->RetRuin() ) + { + } + else if ( bStop || m_object->RetBurn() ) + { + m_object->SetAngleZ(2, sinf(m_armTimeAbs*1.7f)*0.15f+0.35f); // tail + } + else + { + a = Mod(m_armTimeMarch, 1.0f); + if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1 + else a = 3.0f-4.0f*a; // 1..-1 + dir.x = sinf(a)*0.05f; + + s = Mod(m_armTimeMarch/2.0f, 1.0f); + if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1 + else s = 3.0f-4.0f*s; // 1..-1 + dir.z = sinf(s)*0.1f; + + dir.y = 0.0f; + m_object->SetInclinaison(dir); + + m_object->SetAngleZ(2, -sinf(a)*0.3f); // tail + + a = Mod(m_armMember-0.1f, 1.0f); + if ( a < 0.33f ) + { + dir.y = -(1.0f-(a/0.33f))*0.3f; + } + else if ( a < 0.67f ) + { + dir.y = 0.0f; + } + else + { + dir.y = -(a-0.67f)/0.33f*0.3f; + } + dir.x = 0.0f; + dir.z = 0.0f; + m_object->SetLinVibration(dir); + } + } + + if ( m_physics->RetLand() ) + { + if ( bStop ) prog = 0.05f; + else prog = 0.15f; + } + else + { + prog = 1.00f; + } + +#if 0 + a = Rand()*PI/2.0f*prog; + m_object->SetAngleX(21, a); // right wing + a = -Rand()*PI/4.0f*prog; + m_object->SetAngleY(21, a); + + a = -Rand()*PI/2.0f*prog; + m_object->SetAngleX(22, a); // left wing + a = Rand()*PI/4.0f*prog; + m_object->SetAngleY(22, a); +#else + m_object->SetAngleX(21, (sinf(m_armTimeAbs*30.0f)+1.0f)*(PI/4.0f)*prog); + m_object->SetAngleY(21, -Rand()*PI/6.0f*prog); + + m_object->SetAngleX(22, -(sinf(m_armTimeAbs*30.0f)+1.0f)*(PI/4.0f)*prog); + m_object->SetAngleY(22, Rand()*PI/6.0f*prog); +#endif + + m_object->SetAngleZ(1, sinf(m_armTimeAbs*1.4f)*0.20f); // head + m_object->SetAngleX(1, sinf(m_armTimeAbs*1.9f)*0.10f); // head + m_object->SetAngleY(1, sinf(m_armTimeAbs*2.1f)*0.50f); // head + +#if 0 + h = m_terrain->RetFloorHeight(RetPosition(0)); + radius = 4.0f+h/4.0f; + color.r = 0.3f+h/80.0f; + color.g = color.r; + color.b = color.r; + color.a = color.r; + m_engine->SetObjectShadowRadius(m_objectPart[0].object, radius); + m_engine->SetObjectShadowColor(m_objectPart[0].object, color); +#endif + + return TRUE; +} + + diff --git a/src/object/motion/motionbee.h b/src/object/motion/motionbee.h new file mode 100644 index 0000000..facf650 --- /dev/null +++ b/src/object/motion/motionbee.h @@ -0,0 +1,73 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionbee.h + +#ifndef _MOTIONBEE_H_ +#define _MOTIONBEE_H_ + + +#include "motion.h" + + +class CInstanceManager; +class CEngine; +class CLight; +class CParticule; +class CTerrain; +class CCamera; +class CBrain; +class CPhysics; +class CObject; + + +#define MB_MARCH 0 +#define MB_SPEC 1 + +#define MBS_HOLD 0 +#define MBS_BURN 1 +#define MBS_RUIN 2 + + +class CMotionBee : public CMotion +{ +public: + CMotionBee(CInstanceManager* iMan, CObject* object); + ~CMotionBee(); + + void DeleteObject(BOOL bAll=FALSE); + BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); + BOOL EventProcess(const Event &event); + +protected: + void CreatePhysics(); + BOOL EventFrame(const Event &event); + +protected: + float m_armMember; + float m_armTimeAbs; + float m_armTimeMarch; + float m_armTimeAction; + short m_armAngles[3*3*3*3*2]; + int m_armTimeIndex; + int m_armPartIndex; + int m_armMemberIndex; + int m_armLastAction; + BOOL m_bArmStop; +}; + + +#endif //_MOTIONBEE_H_ diff --git a/src/object/motion/motionhuman.cpp b/src/object/motion/motionhuman.cpp new file mode 100644 index 0000000..78750fa --- /dev/null +++ b/src/object/motion/motionhuman.cpp @@ -0,0 +1,1799 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionhuman.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "light.h" +#include "particule.h" +#include "terrain.h" +#include "water.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "modfile.h" +#include "robotmain.h" +#include "sound.h" +#include "motion.h" +#include "motionhuman.h" + + + +#define ADJUST_ANGLE FALSE // TRUE -> adjusts the angles of the members +#define ADJUST_ACTION (3*3*3*3*MH_SPEC+3*3*3*MHS_SATCOM) + +#define START_TIME 1000.0f // beginning of the relative time + + + +// Object's constructor. + +CMotionHuman::CMotionHuman(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + CMotion::CMotion(iMan, object); + + m_partiReactor = -1; + m_armMember = START_TIME; + m_armTimeAbs = START_TIME; + m_armTimeAction = START_TIME; + m_armTimeSwim = START_TIME; + m_armTimeIndex = 0; + m_armPartIndex = 0; + m_armMemberIndex = 0; + m_armLastAction = -1; + m_bArmStop = FALSE; + m_lastSoundMarch = 0.0f; + m_lastSoundHhh = 0.0f; + m_time = 0.0f; + m_tired = 0.0f; + m_bDisplayPerso = FALSE; +} + +// Object's constructor. + +CMotionHuman::~CMotionHuman() +{ +} + + +// Removes an object. + +void CMotionHuman::DeleteObject(BOOL bAll) +{ + if ( m_partiReactor != -1 ) + { + m_particule->DeleteParticule(m_partiReactor); + m_partiReactor = -1; + } +} + + +// Starts an action. + +Error CMotionHuman::SetAction(int action, float time) +{ + CMotion::SetAction(action, time); + m_time = 0.0f; + return ERR_OK; +} + + +// Creates cosmonaut on the ground. + +BOOL CMotionHuman::Create(D3DVECTOR pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + char filename[100]; + int rank, option, face, glasses; + + if ( m_engine->RetRestCreate() < 16 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + option = m_object->RetOption(); + + if ( m_main->RetGamerOnlyHead() ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + face = m_main->RetGamerFace(); + sprintf(filename, "objects\\human2h%d.mod", face+1); + pModFile->ReadModel(filename); + pModFile->CreateEngineObject(rank); + + glasses = m_main->RetGamerGlasses(); + if ( glasses != 0 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + sprintf(filename, "objects\\human2g%d.mod", glasses); + pModFile->ReadModel(filename); + pModFile->CreateEngineObject(rank); + } + + CreatePhysics(type); + m_object->SetFloorHeight(0.0f); + + m_engine->LoadAllTexture(); + + delete pModFile; + return TRUE; + } + + // Creates the main base. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + + if ( option == 0 ) // head in helmet? + { + pModFile->ReadModel("objects\\human1c.mod"); + } + if ( option == 1 ) // head without helmet? + { + pModFile->ReadModel("objects\\human1h.mod"); + } + if ( option == 2 ) // without a backpack? + { + pModFile->ReadModel("objects\\human1v.mod"); + } + pModFile->CreateEngineObject(rank); + + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // A vehicle must have an obligatory collision with a sphere of center (0, y, 0) (see GetCrashSphere). + m_object->CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 2.0f, SOUND_AIE, 0.20f); + m_object->SetGlobalSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 4.0f); + + // Creates the head. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + + if ( type == OBJECT_HUMAN ) + { + if ( option == 0 ) // head in helmet? + { + face = m_main->RetGamerFace(); + sprintf(filename, "objects\\human2c%d.mod", face+1); + pModFile->ReadModel(filename); + } + if ( option == 1 || // head without helmet? + option == 2 ) // without a backpack? + { + face = m_main->RetGamerFace(); + sprintf(filename, "objects\\human2h%d.mod", face+1); + pModFile->ReadModel(filename); + } + } + if ( type == OBJECT_TECH ) + { + pModFile->ReadModel("objects\\human2t.mod"); + } + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(0.0f, 2.7f, 0.0f)); + if ( option == 1 || // head without helmet? + option == 2 ) // without a backpack? + { + m_object->SetZoom(1, D3DVECTOR(1.0f, 1.05f, 1.0f)); + } + + // Creates the glasses. + glasses = m_main->RetGamerGlasses(); + if ( glasses != 0 && type == OBJECT_HUMAN ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(15, rank); + m_object->SetObjectParent(15, 1); + sprintf(filename, "objects\\human2g%d.mod", glasses); + pModFile->ReadModel(filename); + pModFile->CreateEngineObject(rank); + } + + // Creates the right arm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\human3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, D3DVECTOR(0.0f, 2.3f, -1.2f)); + m_object->SetAngle(2, D3DVECTOR(90.0f*PI/180.0f, 90.0f*PI/180.0f, -50.0f*PI/180.0f)); + + // Creates the right forearm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 2); + pModFile->ReadModel("objects\\human4r.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, D3DVECTOR(1.3f, 0.0f, 0.0f)); + m_object->SetAngle(3, D3DVECTOR(0.0f*PI/180.0f, -20.0f*PI/180.0f, 0.0f*PI/180.0f)); + + // Creates right hand. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(4, rank); + m_object->SetObjectParent(4, 3); + pModFile->ReadModel("objects\\human5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(4, D3DVECTOR(1.2f, 0.0f, 0.0f)); + + // Creates the right thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(5, rank); + m_object->SetObjectParent(5, 0); + pModFile->ReadModel("objects\\human6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(5, D3DVECTOR(0.0f, 0.0f, -0.7f)); + m_object->SetAngle(5, D3DVECTOR(10.0f*PI/180.0f, 0.0f*PI/180.0f, 5.0f*PI/180.0f)); + + // Creates the right leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 5); + pModFile->ReadModel("objects\\human7.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, D3DVECTOR(0.0f, -1.5f, 0.0f)); + m_object->SetAngle(6, D3DVECTOR(0.0f*PI/180.0f, 0.0f*PI/180.0f, -10.0f*PI/180.0f)); + + // Creates the right foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 6); + pModFile->ReadModel("objects\\human8.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, D3DVECTOR(0.0f, -1.5f, 0.0f)); + m_object->SetAngle(7, D3DVECTOR(-10.0f*PI/180.0f, 5.0f*PI/180.0f, 5.0f*PI/180.0f)); + + // Creates the left arm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 0); + pModFile->ReadModel("objects\\human3.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, D3DVECTOR(0.0f, 2.3f, 1.2f)); + m_object->SetAngle(8, D3DVECTOR(-90.0f*PI/180.0f, -90.0f*PI/180.0f, -50.0f*PI/180.0f)); + + // Creates the left forearm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 8); + pModFile->ReadModel("objects\\human4l.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, D3DVECTOR(1.3f, 0.0f, 0.0f)); + m_object->SetAngle(9, D3DVECTOR(0.0f*PI/180.0f, 20.0f*PI/180.0f, 0.0f*PI/180.0f)); + + // Creates left hand. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(10, rank); + m_object->SetObjectParent(10, 9); + pModFile->ReadModel("objects\\human5.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(10, D3DVECTOR(1.2f, 0.0f, 0.0f)); + + // Creates the left thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(11, rank); + m_object->SetObjectParent(11, 0); + pModFile->ReadModel("objects\\human6.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(11, D3DVECTOR(0.0f, 0.0f, 0.7f)); + m_object->SetAngle(11, D3DVECTOR(-10.0f*PI/180.0f, 0.0f*PI/180.0f, 5.0f*PI/180.0f)); + + // Creates the left leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(12, rank); + m_object->SetObjectParent(12, 11); + pModFile->ReadModel("objects\\human7.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(12, D3DVECTOR(0.0f, -1.5f, 0.0f)); + m_object->SetAngle(12, D3DVECTOR(0.0f*PI/180.0f, 0.0f*PI/180.0f, -10.0f*PI/180.0f)); + + // Creates the left foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(13, rank); + m_object->SetObjectParent(13, 12); + pModFile->ReadModel("objects\\human8.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(13, D3DVECTOR(0.0f, -1.5f, 0.0f)); + m_object->SetAngle(13, D3DVECTOR(10.0f*PI/180.0f, -5.0f*PI/180.0f, 5.0f*PI/180.0f)); + + // Creates the neutron gun. + if ( option != 2 ) // with backpack? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(14, rank); + m_object->SetObjectParent(14, 0); + pModFile->ReadModel("objects\\human9.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(14, D3DVECTOR(-1.5f, 0.3f, -1.35f)); + m_object->SetAngleZ(14, PI); + } + + m_object->CreateShadowCircle(2.0f, 0.8f); + + CreatePhysics(type); + m_object->SetFloorHeight(0.0f); + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); // to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return TRUE; +} + +// Creates the physical object. + +void CMotionHuman::CreatePhysics(ObjectType type) +{ + Character* character; + int i; + + int member_march[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 90,90,-50, 10,0,55, 0,0,0, // t0: arms/thighs/- + 0,-20,0, -5,0,-110, 0,0,0, // t0: forearm/legs/- + 0,0,0, -5,0,40, 0,0,0, // t0: hands/feet/- + // on the ground: + 125,115,-45, 10,0,50, 0,0,0, // t1: arms/thighs/- + 0,-20,0, -5,0,-15, 0,0,0, // t1: forearm/legs/- + 0,0,0, -5,0,0, 0,0,0, // t1: hands/feet/- + // on the ground back: + 25,55,-40, 10,0,-15, 0,0,0, // t2: arms/thighs/- + 30,-50,40, -5,0,-55, 0,0,0, // t2: forearm/legs/- + 0,0,0, -5,0,25, 0,0,0, // t2: hands/feet/- + }; + + int member_march_take[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 15,50,-50, 10,0,55, 0,0,0, // t0: arms/thighs/- + 45,-70,10, -5,0,-110, 0,0,0, // t0: forearm/legs/- + -10,25,0, -5,0,40, 0,0,0, // t0: hands/feet/- + // on the ground: + 15,50,-55, 10,0,50, 0,0,0, // t1: arms/thighs/- + 45,-70,10, -5,0,-15, 0,0,0, // t1: forearm/legs/- + -10,25,0, -5,0,0, 0,0,0, // t1: hands/feet/- + // on the ground back: + 15,50,-45, 10,0,-15, 0,0,0, // t2: arms/thighs/- + 45,-70,10, -5,0,-55, 0,0,0, // t2: forearm/legs/- + -10,25,0, -5,0,45, 0,0,0, // t2: hands/feet/- + }; + + int member_turn[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 90,90,-50, 10,0,30, 0,0,0, // t0: arms/thighs/- + 0,-20,0, -5,0,-60, 0,0,0, // t0: forearm/legs/- + 0,0,0, -5,0,30, 0,0,0, // t0: hands/feet/- + // on the ground: + 90,110,-45, 10,0,0, 0,0,0, // t1: arms/thighs/- + 0,-20,0, -5,5,0, 0,0,0, // t1: forearm/legs/- + 0,0,0, -5,10,0, 0,0,0, // t1: hands/feet/- + // on the ground back: + 90,70,-45, 10,0,0, 0,0,0, // t2: arms/thighs/- + 0,-20,10, -5,-5,0, 0,0,0, // t2: forearm/legs/- + 0,0,0, -5,-10,0, 0,0,0, // t2: hands/feet/- + }; + + int member_stop[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, + 90,90,-50, 10,0,5, 0,0,0, // arms/thighs/- + 0,-20,0, 0,0,-10, 0,0,0, // forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // hands/feet/- + // + 90,90,-55, 10,0,5, 0,0,0, // arms/thighs/- + 0,-15,0, 0,0,-10, 0,0,0, // forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // hands/feet/- + // + 90,90,-60, 10,0,5, 0,0,0, // arms/thighs/- + 0,-10,0, 0,0,-10, 0,0,0, // forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // hands/feet/- + }; + + int member_fly[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, + -5,90,-60, 20,5,-25, 0,0,0, // arms/thighs/- + 85,-40,-25, 10,0,-30, 0,0,0, // forearm/legs/- + 40,10,25, 0,15,0, 0,0,0, // hands/feet/- + // + -15,90,-40, 20,5,-35, 0,0,0, // arms/thighs/- + 85,-40,-25, 10,0,-40, 0,0,0, // forearm/legs/- + 45,5,20, 0,15,0, 0,0,0, // hands/feet/- + // + -25,90,-50, 20,5,-20, 0,0,0, // arms/thighs/- + 85,-40,-25, 10,0,-10, 0,0,0, // forearm/legs/- + 30,15,25, 0,15,0, 0,0,0, // hands/feet/- + }; + + int member_swim[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, +#if 1 + 130,-70,200, 10,20,55, 0,0,0, // arms/thighs/- + 115,-125,0, -5,0,-110, 0,0,0, // forearm/legs/- + 0,0,0, -5,10,-5, 0,0,0, // hands/feet/- + // + 130,-95,115,55,5,5, 0,0,0, // arms/thighs/- + 75,-50,25, -5,0,-15, 0,0,0, // forearm/legs/- + 0,0,0, -5,5,-30, 0,0,0, // hands/feet/- + // + 130,-100,220,5,0,0, 0,0,0, // arms/thighs/- + 150,5,0, -5,0,-15, 0,0,0, // forearm/legs/- + 0,0,0, -5,30,-20, 0,0,0, // hands/feet/- +#endif +#if 0 + 130,-70,200,5,0,0, 0,0,0, // arms/thighs/- + 115,-125,0, -5,0,-15, 0,0,0, // forearm/legs/- + 0,0,0, -5,30,-20, 0,0,0, // hands/feet/- + // + 130,-95,115, 10,20,55, 0,0,0, // arms/thighs/- + 75,-50,25, -5,0,-110, 0,0,0, // forearm/legs/- + 0,0,0, -5,10,-5, 0,0,0, // hands/feet/- + // + 130,-100,220, 55,5,5, 0,0,0, // arms/thighs/- + 150,5,0, -5,0,-15, 0,0,0, // forearm/legs/- + 0,0,0, -5,5,-30, 0,0,0, // hands/feet/- +#endif +#if 0 + 130,-70,200, 55,5,5, 0,0,0, // arms/thighs/- + 115,-125,0, -5,0,-15, 0,0,0, // forearm/legs/- + 0,0,0, -5,5,-30, 0,0,0, // hands/feet/- + // + 130,-95,115, 5,0,0, 0,0,0, // arms/thighs/- + 75,-50,25, -5,0,-15, 0,0,0, // forearm/legs/- + 0,0,0, -5,30,-20, 0,0,0, // hands/feet/- + // + 130,-100,220, 10,20,55, 0,0,0, // arms/thighs/- + 150,5,0, -5,0,-110, 0,0,0, // forearm/legs/- + 0,0,0, -5,10,-5, 0,0,0, // hands/feet/- +#endif + }; + + int member_spec[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // shooting: + 65,5,-20, 10,0,40, 0,0,0, // s0: arms/thighs/- + -50,-30,50, 0,0,-70, 0,0,0, // s0: forearm/legs/- + 0,50,0, -10,0,35, 0,0,0, // s0: hands/feet/- + // takes weapon: + 160,135,-20,10,0,5, 0,0,0, // s1: arms/thighs/- + 10,-60,40, 0,0,-10, 0,0,0, // s1: forearm/legs/- + 0,-5,-25, -10,5,5, 0,0,0, // s1: hands/feet/- + // carries earth: + 25,40,-40, 10,0,60, 0,0,0, // s2: arms/thighs/- + 0,-45,0, 0,0,-120, 0,0,0, // s2: forearm/legs/- + 0,15,5, -10,0,70, 0,0,0, // s2: hands/feet/- + // carries in front: + 25,20,5, 10,0,55, 0,0,0, // s3: arms/thighs/- + -15,-30,10, 0,0,-110, 0,0,0, // s3: forearm/legs/- + 0,0,0, -10,0,65, 0,0,0, // s3: hands/feet/- + // carries vertically: + -30,15,-5, 10,0,15, 0,0,0, // s4: arms/thighs/- + 0,-15,15, 0,0,-30, 0,0,0, // s4: forearm/legs/- + 35,0,-15, -10,0,25, 0,0,0, // s4: hands/feet/- + // rises: + 15,50,-50, 10,0,5, 0,0,0, // s5: arms/thighs/- + 45,-70,10, 0,0,-10, 0,0,0, // s5: forearm/legs/- + -10,25,0, -10,5,5, 0,0,0, // s5: hands/feet/- + // wins: + 90,90,-30, 20,0,5, 0,0,0, // s6: arms/thighs/- + 0,-90,0, -10,0,-10, 0,0,0, // s6: forearm/legs/- + 0,25,0, -10,5,5, 0,0,0, // s6: hands/feet/- + // lose: + -70,45,35, 10,0,40, 0,0,0, // s7: arms/thighs/- + 15,-95,-5, 0,0,-70, 0,0,0, // s7: forearm/legs/- + 0,0,0, -10,0,35, 0,0,0, // s7: hands/feet/- + // shooting death (falls): + 90,90,-50, 10,0,5, 0,0,0, // s8: arms/thighs/- + 0,-20,0, 0,0,-10, 0,0,0, // s8: forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // s8: hands/feet/- + // shooting death (knees): + 110,105,-5, 10,0,25, 0,0,0, // s9: arms/thighs/- + 0,-40,20, 0,0,-120, 0,0,0, // s9: forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // s9: hands/feet/- + // shooting death (knees): + 110,120,-25, 10,0,25, 0,0,0, // s10: arms/thighs/- + 0,-40,20, 0,0,-120, 0,0,0, // s10: forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // s10: hands/feet/- + // shooting death (face down): + 110,100,-25, 25,0,10, 0,0,0, // s11: arms/thighs/- + 0,-40,20, 0,0,-25, 0,0,0, // s11: forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // s11: hands/feet/- + // shooting death (face down): + 110,100,-25, 25,0,10, 0,0,0, // s12: arms/thighs/- + 0,-40,20, 0,0,-25, 0,0,0, // s12: forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // s12: hands/feet/- + // drowned: + 110,100,-25, 25,0,10, 0,0,0, // s13: arms/thighs/- + 0,-40,20, 0,0,-25, 0,0,0, // s13: forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // s13: hands/feet/- + // puts / removes flag: + 85,45,-50, 10,0,60, 0,0,0, // s14: arms/thighs/- + -60,15,65, 0,0,-105, 0,0,0, // s14: forearm/legs/- + 0,10,0, -10,0,60, 0,0,0, // s14: hands/feet/- + // reads SatCom: + 70,30,-20, 10,0,5, 0,0,0, // s15: arms/thighs/- + 115,-65,60, 0,0,-10, 0,0,0, // s15: forearm/legs/- + 0,20,0, -10,5,5, 0,0,0, // s15: hands/feet/- + }; + + m_physics->SetType(TYPE_FLYING); + + character = m_object->RetCharacter(); + character->wheelFront = 4.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 4.0f; + character->wheelRight = 4.0f; + character->height = 3.5f; + + if ( type == OBJECT_HUMAN ) + { + m_physics->SetLinMotionX(MO_ADVSPEED, 50.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 35.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 20.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 70.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 40.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f); + m_physics->SetLinMotionY(MO_RECSPEED, 60.0f); + m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionY(MO_RECACCEL, 50.0f); + m_physics->SetLinMotionY(MO_STOACCEL, 50.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.8f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.8f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 6.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 6.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 4.0f); + } + else + { + m_physics->SetLinMotionX(MO_ADVSPEED, 40.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 15.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 8.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 8.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 8.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 50.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 50.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f); + m_physics->SetLinMotionY(MO_RECSPEED, 60.0f); + m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionY(MO_RECACCEL, 50.0f); + m_physics->SetLinMotionY(MO_STOACCEL, 50.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.6f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.6f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 4.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 4.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 3.0f); + } + + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MH_MARCH+i] = member_march[i]; + } + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MH_MARCHTAKE+i] = member_march_take[i]; + } + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MH_TURN+i] = member_turn[i]; + } + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MH_STOP+i] = member_stop[i]; + } + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MH_FLY+i] = member_fly[i]; + } + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MH_SWIM+i] = member_swim[i]; + } + for ( i=0 ; i<3*3*3*16 ; i++ ) + { + m_armAngles[3*3*3*3*MH_SPEC+i] = member_spec[i]; + } +} + + +// Management of an event. + +BOOL CMotionHuman::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { +#if ADJUST_ANGLE + int i; + + if ( event.param == 'A' ) m_armTimeIndex++; + if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0; + + if ( event.param == 'Q' ) m_armPartIndex++; + if ( m_armPartIndex >= 3 ) m_armPartIndex = 0; + + if ( event.param == 'W' ) m_armMemberIndex++; + if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0; + + i = m_armMemberIndex*3; + i += m_armPartIndex*3*3; + i += m_armTimeIndex*3*3*3; + i += ADJUST_ACTION; + + if ( event.param == 'E' ) m_armAngles[i+0] += 5; + if ( event.param == 'D' ) m_armAngles[i+0] -= 5; + if ( event.param == 'R' ) m_armAngles[i+1] += 5; + if ( event.param == 'F' ) m_armAngles[i+1] -= 5; + if ( event.param == 'T' ) m_armAngles[i+2] += 5; + if ( event.param == 'G' ) m_armAngles[i+2] -= 5; + + if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop; + + if ( event.param == 'Y' ) + { + char s[100]; + sprintf(s, "index dans table = %d %d %d\n", i, i+9, i+18); + OutputDebugString(s); + } +#endif + } + + return TRUE; +} + +// Calculates a value (radians) proportional between a and b (degrees). + +inline float Propf(float a, float b, float p) +{ + float aa, bb; + + aa = a*PI/180.0f; + bb = b*PI/180.0f; + + return aa+p*(bb-aa); +} + +// Management of an event. + +BOOL CMotionHuman::EventFrame(const Event &event) +{ + D3DMATRIX* mat; + D3DVECTOR dir, actual, pos, speed, pf; + FPOINT center, dim, p2; + float s, a, prog, rTime[2], lTime[2], time, rot, hr, hl; + float al, ar, af; + float tSt[9], tNd[9]; + float aa, bb, shield, deadFactor, level; + int i, ii, st, nd, action, legAction, armAction; + BOOL bOnBoard, bSwim, bStop; + + if ( m_engine->RetPause() ) + { + if ( m_actionType == MHS_SATCOM ) + { + m_progress += event.rTime*m_actionTime; + } + else + { + return TRUE; + } + } + + bOnBoard = FALSE; + if ( m_object->RetSelect() && + m_camera->RetType() == CAMERA_ONBOARD ) + { + bOnBoard = TRUE; + } + + if ( m_bDisplayPerso && m_main->RetGamerOnlyHead() ) + { + m_time += event.rTime; + m_object->SetLinVibration(D3DVECTOR(0.0f, -0.55f, 0.0f)); + m_object->SetCirVibration(D3DVECTOR(0.0f, m_main->RetPersoAngle(), 0.0f)); + return TRUE; + } + if ( m_bDisplayPerso ) + { + m_object->SetCirVibration(D3DVECTOR(0.0f, m_main->RetPersoAngle()+0.2f, 0.0f)); + } + + shield = m_object->RetShield(); + shield += event.rTime*(1.0f/120.0f); // regeneration in 120 seconds + if ( shield > 1.0f ) shield = 1.0f; + m_object->SetShield(shield); + + bSwim = m_physics->RetSwim(); + +#if 0 + rot = m_physics->RetCirMotionY(MO_MOTSPEED); + s = m_physics->RetLinMotionX(MO_REASPEED)*2.0f; + a = m_physics->RetLinMotionX(MO_TERSPEED); + if ( a < 0.0f ) // rises? + { + if ( s > 0.0f && s < 20.0f ) s = 20.0f; // moving slowly? +//? if ( s < 0.0f && s > -10.0f ) s = 0.0f; // falling slowly? + } + if ( a > 0.0f && !bSwim ) // falls? + { + if ( s > 0.0f && s < 10.0f ) s = 0.0f; // moving slowly? +//? if ( s < 0.0f && s > -5.0f ) s = -5.0f; // falling slowly? + } + a = Abs(rot*12.0f); + + if ( !m_physics->RetLand() && !bSwim ) // in flight? + { + s = 0.0f; + } + + if ( m_object->RetFret() != 0 ) // carries something? + { + s *= 1.3f; + } +#else + rot = m_physics->RetCirMotionY(MO_MOTSPEED); +#if 0 + s = m_physics->RetLinMotionX(MO_REASPEED); +#else + a = m_physics->RetLinMotionX(MO_REASPEED); + s = m_physics->RetLinMotionX(MO_MOTSPEED)*0.2f; + if ( Abs(a) > Abs(s) ) s = a; // the highest value +#endif + a = m_physics->RetLinMotionX(MO_TERSPEED); + if ( a < 0.0f ) // rises? + { + a += m_physics->RetLinMotionX(MO_TERSLIDE); + if ( a < 0.0f ) s -= a; + } + if ( a > 0.0f ) // falls? + { + a -= m_physics->RetLinMotionX(MO_TERSLIDE); + if ( a > 0.0f ) s -= a; + } + s *= 2.0f; + a = Abs(rot*12.0f); + + if ( !m_physics->RetLand() && !bSwim ) // in flight? + { + s = 0.0f; + } + + if ( m_object->RetFret() != 0 ) // carries something? + { + s *= 1.3f; + } +#endif + + m_time += event.rTime; + m_armTimeAbs += event.rTime; + m_armTimeAction += event.rTime; + m_armMember += s*event.rTime*0.05f; + + // Fatigue management when short. + if ( m_physics->RetLand() && s != 0.0f ) // on the ground? + { + m_tired += event.rTime*0.1f; + if ( m_tired > 1.0f ) + { + m_tired = 1.0f; + if ( m_lastSoundHhh > 3.0f ) m_lastSoundHhh = 0.5f; + } + } + else + { + m_tired -= event.rTime*0.2f; + if ( m_tired < 0.0f ) m_tired = 0.0f; + } + + if ( bSwim ) // swims? + { + s += Abs(m_physics->RetLinMotionY(MO_REASPEED)*2.0f); + a *= 2.0f; + m_armTimeSwim += Min(Max(s,a,3.0f),15.0f)*event.rTime*0.05f; + } + + bStop = ( s == 0.0f ); // stop? + prog = 0.0f; + + if ( m_physics->RetLand() ) // on the ground? + { + if ( s == 0.0f && a == 0.0f ) + { + action = MH_STOP; // stop + rTime[0] = rTime[1] = m_armTimeAbs*0.21f; + lTime[0] = lTime[1] = m_armTimeAbs*0.25f; + m_armMember = START_TIME; + } + else + { + if ( s == 0.0f ) + { + action = MH_TURN; // turn + rTime[0] = rTime[1] = m_armTimeAbs; + lTime[0] = lTime[1] = m_armTimeAbs+0.5f; + if ( rot < 0.0f ) + { + rTime[1] = 1000000.0f-rTime[1]; + } + else + { + lTime[1] = 1000000.0f-lTime[1]; + } + m_armMember = START_TIME; + } + else + { + action = MH_MARCH; // walking + if ( m_object->RetFret() != 0 ) action = MH_MARCHTAKE; // take walking + rTime[0] = rTime[1] = m_armMember; + lTime[0] = lTime[1] = m_armMember+0.5f; + } + } + if ( bSwim ) + { + rTime[0] *= 0.6f; + rTime[1] *= 0.6f; + lTime[0] = rTime[0]+0.5f; + lTime[1] = rTime[1]+0.5f; + } + } + else + { + if ( bSwim ) + { + action = MH_SWIM; // swim + rTime[0] = rTime[1] = m_armTimeSwim; + lTime[0] = lTime[1] = m_armTimeSwim; + } + else + { + action = MH_FLY; // fly + rTime[0] = rTime[1] = m_armTimeAbs*0.30f; + lTime[0] = lTime[1] = m_armTimeAbs*0.31f; + m_armMember = START_TIME; + } + } + + if ( action != m_armLastAction ) + { + m_armLastAction = action; + m_armTimeAction = 0.0f; + } + + armAction = action; + legAction = action; + + if ( m_object->RetFret() != 0 ) // carries something? + { + armAction = MH_MARCHTAKE; // take walking + } + + if ( m_physics->RetLand() ) // on the ground? + { + a = m_object->RetAngleY(0); + pos = m_object->RetPosition(0); + m_terrain->MoveOnFloor(pos); + + pf.x = pos.x+cosf(a+PI*1.5f)*0.7f; + pf.y = pos.y; + pf.z = pos.z-sinf(a+PI*1.5f)*0.7f; + m_terrain->MoveOnFloor(pf); + al = atanf((pf.y-pos.y)/0.7f); // angle for left leg + + pf = pos; + pf.x = pos.x+cosf(a+PI*0.5f)*0.7f; + pf.y = pos.y; + pf.z = pos.z-sinf(a+PI*0.5f)*0.7f; + m_terrain->MoveOnFloor(pf); + ar = atanf((pf.y-pos.y)/0.7f); // angle to right leg + + pf.x = pos.x+cosf(a+PI)*0.3f; + pf.y = pos.y; + pf.z = pos.z-sinf(a+PI)*0.3f; + m_terrain->MoveOnFloor(pf); + af = atanf((pf.y-pos.y)/0.3f); // angle for feet + } + else + { + al = 0.0f; + ar = 0.0f; + af = 0.0f; + } + + for ( i=0 ; i<4 ; i++ ) // 4 members + { + if ( m_bArmStop ) // focus? + { + st = ADJUST_ACTION + (i%2)*3; + nd = st; + time = 100.0f; + m_armTimeAction = 0.0f; + } + else if ( m_actionType != -1 ) // special action in progress? + { + st = 3*3*3*3*MH_SPEC + 3*3*3*m_actionType + (i%2)*3; + nd = st; + time = event.rTime*m_actionTime; + m_armTimeAction = 0.0f; + } + else + { + if ( i < 2 ) prog = Mod(rTime[i%2], 1.0f); + else prog = Mod(lTime[i%2], 1.0f); + if ( prog < 0.25f ) // t0..t1 ? + { + prog = prog/0.25f; // 0..1 + st = 0; // index start + nd = 1; // index end + } + else if ( prog < 0.75f ) // t1..t2 ? + { + prog = (prog-0.25f)/0.50f; // 0..1 + st = 1; // index start + nd = 2; // index end + } + else // t2..t0 ? + { + prog = (prog-0.75f)/0.25f; // 0..1 + st = 2; // index start + nd = 0; // index end + } + if ( i%2 == 0 ) // arm? + { + st = 3*3*3*3*armAction + st*3*3*3 + (i%2)*3; + nd = 3*3*3*3*armAction + nd*3*3*3 + (i%2)*3; + } + else // leg? + { + st = 3*3*3*3*legAction + st*3*3*3 + (i%2)*3; + nd = 3*3*3*3*legAction + nd*3*3*3 + (i%2)*3; + } + + // Less soft ... + time = event.rTime*(5.0f+Min(m_armTimeAction*50.0f, 100.0f)); + if ( bSwim ) time *= 0.25f; + } + + tSt[0] = m_armAngles[st+ 0]; // x + tSt[1] = m_armAngles[st+ 1]; // y + tSt[2] = m_armAngles[st+ 2]; // z + tSt[3] = m_armAngles[st+ 9]; // x + tSt[4] = m_armAngles[st+10]; // y + tSt[5] = m_armAngles[st+11]; // z + tSt[6] = m_armAngles[st+18]; // x + tSt[7] = m_armAngles[st+19]; // y + tSt[8] = m_armAngles[st+20]; // z + + tNd[0] = m_armAngles[nd+ 0]; // x + tNd[1] = m_armAngles[nd+ 1]; // y + tNd[2] = m_armAngles[nd+ 2]; // z + tNd[3] = m_armAngles[nd+ 9]; // x + tNd[4] = m_armAngles[nd+10]; // y + tNd[5] = m_armAngles[nd+11]; // z + tNd[6] = m_armAngles[nd+18]; // x + tNd[7] = m_armAngles[nd+19]; // y + tNd[8] = m_armAngles[nd+20]; // z + + aa = 0.5f; + if ( i%2 == 0 ) // arm? + { + if ( m_object->RetFret() == 0 ) // does nothing? + { + aa = 2.0f; // moves a lot + } + else + { + aa = 0.0f; // immobile + } + } + + if ( i < 2 ) // left? + { + bb = sinf(m_time*1.1f)*aa; tSt[0] += bb; tNd[0] += bb; + bb = sinf(m_time*1.0f)*aa; tSt[1] += bb; tNd[1] += bb; + bb = sinf(m_time*1.2f)*aa; tSt[2] += bb; tNd[2] += bb; + bb = sinf(m_time*2.5f)*aa; tSt[3] += bb; tNd[3] += bb; + bb = sinf(m_time*2.0f)*aa; tSt[4] += bb; tNd[4] += bb; + bb = sinf(m_time*3.8f)*aa; tSt[5] += bb; tNd[5] += bb; + bb = sinf(m_time*3.0f)*aa; tSt[6] += bb; tNd[6] += bb; + bb = sinf(m_time*2.3f)*aa; tSt[7] += bb; tNd[7] += bb; + bb = sinf(m_time*4.0f)*aa; tSt[8] += bb; tNd[8] += bb; + } + else // right? + { + bb = sinf(m_time*0.9f)*aa; tSt[0] += bb; tNd[0] += bb; + bb = sinf(m_time*1.2f)*aa; tSt[1] += bb; tNd[1] += bb; + bb = sinf(m_time*1.4f)*aa; tSt[2] += bb; tNd[2] += bb; + bb = sinf(m_time*2.9f)*aa; tSt[3] += bb; tNd[3] += bb; + bb = sinf(m_time*1.4f)*aa; tSt[4] += bb; tNd[4] += bb; + bb = sinf(m_time*3.1f)*aa; tSt[5] += bb; tNd[5] += bb; + bb = sinf(m_time*3.7f)*aa; tSt[6] += bb; tNd[6] += bb; + bb = sinf(m_time*2.0f)*aa; tSt[7] += bb; tNd[7] += bb; + bb = sinf(m_time*3.1f)*aa; tSt[8] += bb; tNd[8] += bb; + } + +#if 1 + if ( i%2 == 1 && // leg? + m_actionType == -1 ) // no special action? + { + if ( i == 1 ) // right leg? + { + ii = 5; + a = ar*0.25f; + } + else + { + ii = 11; + a = al*0.25f; + } + if ( a < -0.2f ) a = -0.2f; + if ( a > 0.2f ) a = 0.2f; + + pos = m_object->RetPosition(ii+0); + pos.y = 0.0f+a; + m_object->SetPosition(ii+0, pos); // lengthens / shortcuts thigh + + pos = m_object->RetPosition(ii+1); + pos.y = -1.5f+a; + m_object->SetPosition(ii+1, pos); // lengthens / shortcuts leg + + pos = m_object->RetPosition(ii+2); + pos.y = -1.5f+a; + m_object->SetPosition(ii+2, pos); // lengthens / shortcuts foot + + if ( i == 1 ) // right leg? + { + aa = (ar*180.0f/PI*0.5f); + } + else // left leg? + { + aa = (al*180.0f/PI*0.5f); + } + tSt[6] += aa; + tNd[6] += aa; // increases the angle X of the foot + + if ( i == 1 ) // right leg? + { + aa = (ar*180.0f/PI); + } + else // left leg? + { + aa = (al*180.0f/PI); + } + if ( aa < 0.0f ) aa = 0.0f; + if ( aa > 30.0f ) aa = 30.0f; + + tSt[2] += aa; + tNd[2] += aa; // increases the angle Z of the thigh + tSt[5] -= aa*2; + tNd[5] -= aa*2; // increases the angle Z of the leg + tSt[8] += aa; + tNd[8] += aa; // increases the angle Z of the foot + + aa = (af*180.0f/PI)*0.7f; + if ( aa < -30.0f ) aa = -30.0f; + if ( aa > 30.0f ) aa = 30.0f; + + tSt[8] -= aa; + tNd[8] -= aa; // increases the angle Z of the foot + } +#endif + + if ( m_actionType == MHS_DEADw ) // drowned? + { + if ( m_progress < 0.5f ) + { + deadFactor = m_progress/0.5f; + } + else + { + deadFactor = 1.0f-(m_progress-0.5f)/0.5f; + } + if ( deadFactor < 0.0f ) deadFactor = 0.0f; + if ( deadFactor > 1.0f ) deadFactor = 1.0f; + + for ( ii=0 ; ii<9 ; ii++ ) + { + tSt[ii] += Rand()*20.0f*deadFactor; + tNd[ii] = tSt[ii]; + } + time = 100.0f; + } + + if ( i < 2 ) // right member (0..1) ? + { + m_object->SetAngleX(2+3*i+0, Smooth(m_object->RetAngleX(2+3*i+0), Propf(tSt[0], tNd[0], prog), time)); + m_object->SetAngleY(2+3*i+0, Smooth(m_object->RetAngleY(2+3*i+0), Propf(tSt[1], tNd[1], prog), time)); + m_object->SetAngleZ(2+3*i+0, Smooth(m_object->RetAngleZ(2+3*i+0), Propf(tSt[2], tNd[2], prog), time)); + m_object->SetAngleX(2+3*i+1, Smooth(m_object->RetAngleX(2+3*i+1), Propf(tSt[3], tNd[3], prog), time)); + m_object->SetAngleY(2+3*i+1, Smooth(m_object->RetAngleY(2+3*i+1), Propf(tSt[4], tNd[4], prog), time)); + m_object->SetAngleZ(2+3*i+1, Smooth(m_object->RetAngleZ(2+3*i+1), Propf(tSt[5], tNd[5], prog), time)); + m_object->SetAngleX(2+3*i+2, Smooth(m_object->RetAngleX(2+3*i+2), Propf(tSt[6], tNd[6], prog), time)); + m_object->SetAngleY(2+3*i+2, Smooth(m_object->RetAngleY(2+3*i+2), Propf(tSt[7], tNd[7], prog), time)); + m_object->SetAngleZ(2+3*i+2, Smooth(m_object->RetAngleZ(2+3*i+2), Propf(tSt[8], tNd[8], prog), time)); + } + else // left member (2..3) ? + { + m_object->SetAngleX(2+3*i+0, Smooth(m_object->RetAngleX(2+3*i+0), Propf(-tSt[0], -tNd[0], prog), time)); + m_object->SetAngleY(2+3*i+0, Smooth(m_object->RetAngleY(2+3*i+0), Propf(-tSt[1], -tNd[1], prog), time)); + m_object->SetAngleZ(2+3*i+0, Smooth(m_object->RetAngleZ(2+3*i+0), Propf( tSt[2], tNd[2], prog), time)); + m_object->SetAngleX(2+3*i+1, Smooth(m_object->RetAngleX(2+3*i+1), Propf(-tSt[3], -tNd[3], prog), time)); + m_object->SetAngleY(2+3*i+1, Smooth(m_object->RetAngleY(2+3*i+1), Propf(-tSt[4], -tNd[4], prog), time)); + m_object->SetAngleZ(2+3*i+1, Smooth(m_object->RetAngleZ(2+3*i+1), Propf( tSt[5], tNd[5], prog), time)); + m_object->SetAngleX(2+3*i+2, Smooth(m_object->RetAngleX(2+3*i+2), Propf(-tSt[6], -tNd[6], prog), time)); + m_object->SetAngleY(2+3*i+2, Smooth(m_object->RetAngleY(2+3*i+2), Propf(-tSt[7], -tNd[7], prog), time)); + m_object->SetAngleZ(2+3*i+2, Smooth(m_object->RetAngleZ(2+3*i+2), Propf( tSt[8], tNd[8], prog), time)); + } + } + +#if ADJUST_ANGLE + if ( m_object->RetSelect() ) + { + char s[100]; + sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex); + m_engine->SetInfoText(4, s); + } +#endif + + // calculates the height lowering as a function + // of the position of the legs. + hr = 1.5f*(1.0f-cosf(m_object->RetAngleZ(5))) + + 1.5f*(1.0f-cosf(m_object->RetAngleZ(5)+m_object->RetAngleZ(6))); + a = 1.0f*sinf(m_object->RetAngleZ(5)+m_object->RetAngleZ(6)+m_object->RetAngleZ(7)); + if ( a < 0.0f ) hr += a; + + hl = 1.5f*(1.0f-cosf(m_object->RetAngleZ(11))) + + 1.5f*(1.0f-cosf(m_object->RetAngleZ(11)+m_object->RetAngleZ(12))); + a = 1.0f*sinf(m_object->RetAngleZ(11)+m_object->RetAngleZ(12)+m_object->RetAngleZ(13)); + if ( a < 0.0f ) hl += a; + + hr = Min(hr, hl); + + if ( m_actionType == MHS_FIRE ) // shooting? + { + time = event.rTime*m_actionTime; + + dir.x = (Rand()-0.5f)/8.0f; + dir.z = (Rand()-0.5f)/8.0f; + dir.y = -0.5f; // slightly lower + actual = m_object->RetLinVibration(); + dir.x = Smooth(actual.x, dir.x, time); +//? dir.y = Smooth(actual.y, dir.y, time); + dir.y = -hr; + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.x = 0.0f; + dir.y = (Rand()-0.5f)/3.0f; + dir.z = -0.1f; // slightly leaning forward + actual = m_object->RetInclinaison(); + dir.x = Smooth(actual.x, dir.x, time); + dir.y = Smooth(actual.y, dir.y, time); + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_TAKE || // carrying? + m_actionType == MHS_TAKEOTHER ) // flag? + { + time = event.rTime*m_actionTime*2.0f; + + dir.x = 0.0f; + dir.z = 0.0f; + dir.y = -1.5f; // slightly lower + actual = m_object->RetLinVibration(); + dir.x = Smooth(actual.x, dir.x, time); +//? dir.y = Smooth(actual.y, dir.y, time); + dir.y = -hr; + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.x = 0.0f; + dir.y = 0.0f; + dir.z = -0.2f; + actual = m_object->RetInclinaison(); + dir.x = Smooth(actual.x, dir.x, time); + dir.y = Smooth(actual.y, dir.y, time); + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_TAKEHIGH ) // carrying? + { + time = event.rTime*m_actionTime*2.0f; + + dir.x = 0.4f; // slightly forward + dir.z = 0.0f; + dir.y = 0.0f; + actual = m_object->RetLinVibration(); + dir.x = Smooth(actual.x, dir.x, time); +//? dir.y = Smooth(actual.y, dir.y, time); + dir.y = -hr; + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.x = 0.0f; + dir.y = 0.0f; + dir.z = -0.2f; + actual = m_object->RetInclinaison(); + dir.x = Smooth(actual.x, dir.x, time); + dir.y = Smooth(actual.y, dir.y, time); + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_FLAG ) // flag? + { + time = event.rTime*m_actionTime*2.0f; + + dir.x = 0.0f; + dir.z = 0.0f; + dir.y = -2.0f; // slightly lower + actual = m_object->RetLinVibration(); + dir.x = Smooth(actual.x, dir.x, time); +//? dir.y = Smooth(actual.y, dir.y, time); + dir.y = -hr; + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.x = 0.0f; + dir.y = 0.0f; + dir.z = -0.4f; + actual = m_object->RetInclinaison(); + dir.x = Smooth(actual.x, dir.x, time); + dir.y = Smooth(actual.y, dir.y, time); + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_DEADg ) // shooting death (falls)? + { + if ( m_physics->RetLand() ) // on the ground? + { + SetAction(MHS_DEADg1, 0.5f); // knees + } + } + else if ( m_actionType == MHS_DEADg1 ) // shooting death (knees)? + { + prog = m_progress; + if ( prog >= 1.0f ) + { + prog = 1.0f; + + for ( i=0 ; i<10 ; i++ ) + { + pos = m_object->RetPosition(0); + pos.x += (Rand()-0.5f)*4.0f; + pos.z += (Rand()-0.5f)*4.0f; + m_terrain->MoveOnFloor(pos); + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 1.2f+Rand()*1.2f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.0f); + } + m_sound->Play(SOUND_BOUMv, m_object->RetPosition(0)); + + SetAction(MHS_DEADg2, 1.0f); // expects knees + } + + time = 100.0f; + + dir.x = 0.0f; + dir.z = 0.0f; + dir.y = -1.5f*prog; + actual = m_object->RetLinVibration(); + dir.x = Smooth(actual.x, dir.x, time); + dir.y = Smooth(actual.y, dir.y, time); + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.x = 0.0f; + dir.y = 0.0f; + dir.z = -(20.0f*PI/180.0f)*prog; + actual = m_object->RetInclinaison(); + dir.x = Smooth(actual.x, dir.x, time); + dir.y = Smooth(actual.y, dir.y, time); + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_DEADg2 ) // shooting death (knees)? + { + if ( m_progress >= 1.0f ) + { + SetAction(MHS_DEADg3, 1.0f); // face down + } + + time = 100.0f; + + dir.x = 0.0f; + dir.z = 0.0f; + dir.y = -1.5f; + actual = m_object->RetLinVibration(); + dir.x = Smooth(actual.x, dir.x, time); + dir.y = Smooth(actual.y, dir.y, time); + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.x = 0.0f; + dir.y = 0.0f; + dir.z = -(20.0f*PI/180.0f); + actual = m_object->RetInclinaison(); + dir.x = Smooth(actual.x, dir.x, time); + dir.y = Smooth(actual.y, dir.y, time); + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_DEADg3 ) // shooting death (face down)? + { + prog = m_progress; + if ( prog >= 1.0f ) + { + prog = 1.0f; + + for ( i=0 ; i<20 ; i++ ) + { + pos = m_object->RetPosition(0); + pos.x += (Rand()-0.5f)*8.0f; + pos.z += (Rand()-0.5f)*8.0f; + m_terrain->MoveOnFloor(pos); + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 2.0f+Rand()*1.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.0f); + } + m_sound->Play(SOUND_BOUMv, m_object->RetPosition(0)); + + SetAction(MHS_DEADg4, 3.0f); // expects face down + } + + time = 100.0f; + prog = powf(prog, 3.0f); + + dir.y = -(1.5f+1.5f*prog); + dir.x = 0.0f; + dir.z = 0.0f; + actual = m_object->RetLinVibration(); + dir.x = Smooth(actual.x, dir.x, time); + dir.y = Smooth(actual.y, dir.y, time); + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.z = -((20.0f*PI/180.0f)+(70.0f*PI/180.0f)*prog); + dir.x = 0.0f; + dir.y = 0.0f; + actual = m_object->RetInclinaison(); + dir.x = Smooth(actual.x, dir.x, time); + dir.y = Smooth(actual.y, dir.y, time); + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_DEADg4 ) // shooting death (face down)? + { + if ( m_progress >= 1.0f ) + { + m_object->SetEnable(FALSE); + } + + time = 100.0f; + + dir.y = -(1.5f+1.5f); + dir.x = 0.0f; + dir.z = 0.0f; + actual = m_object->RetLinVibration(); + dir.x = Smooth(actual.x, dir.x, time); + dir.y = Smooth(actual.y, dir.y, time); + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.z = -((20.0f*PI/180.0f)+(70.0f*PI/180.0f)); + dir.x = 0.0f; + dir.y = 0.0f; + actual = m_object->RetInclinaison(); + dir.x = Smooth(actual.x, dir.x, time); + dir.y = Smooth(actual.y, dir.y, time); + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_DEADw ) // drowned? + { + pos = m_object->RetPosition(0); + level = m_water->RetLevel()-0.5f; + if ( pos.y < level ) + { + pos.y += 4.0f*event.rTime; // back to the surface + if ( pos.y > level ) pos.y = level; + m_object->SetPosition(0, pos); + } + if ( pos.y > level ) + { + pos.y -= 10.0f*event.rTime; // down quickly + if ( pos.y < level ) pos.y = level; + m_object->SetPosition(0, pos); + } + + prog = m_progress; + if ( prog >= 1.0f ) + { + prog = 1.0f; + if ( pos.y >= level ) m_object->SetEnable(FALSE); + } + + prog *= 2.0f; + if ( prog > 1.0f ) prog = 1.0f; + + time = 100.0f; + + dir.z = -(90.0f*PI/180.0f)*prog; + dir.x = Rand()*0.3f*deadFactor; + dir.y = Rand()*0.3f*deadFactor; + actual = m_object->RetInclinaison(); + dir.x = Smooth(actual.x, dir.x, time); + dir.y = Smooth(actual.y, dir.y, time); + dir.z = Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + + m_object->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); + } + else if ( m_actionType == MHS_LOST ) // lost? + { + time = m_time; + if ( time < 10.0f ) time *= time/10.0f; // starts slowly + + dir.x = time*2.0f; + dir.y = sinf(m_time*0.8f)*0.8f; + dir.z = sinf(m_time*0.6f)*0.5f; + m_object->SetInclinaison(dir); + SetInclinaison(dir); + +//? dir.x = -(sinf(time*0.05f+PI*1.5f)+1.0f)*100.0f; + // original code: Min(time/30.0f) (?) changed to time/30.0f + dir.x = -(powf(time/30.0f, 4.0f))*1000.0f; // from the distance + dir.y = 0.0f; + dir.z = 0.0f; + m_object->SetLinVibration(dir); + SetLinVibration(dir); + + mat = m_object->RetWorldMatrix(0); + pos = D3DVECTOR(0.5f, 3.7f, 0.0f); + pos.x += (Rand()-0.5f)*1.0f; + pos.y += (Rand()-0.5f)*1.0f; + pos.z += (Rand()-0.5f)*1.0f; + pos = Transform(*mat, pos); + speed.x = (Rand()-0.5f)*0.5f; + speed.y = (Rand()-0.5f)*0.5f; + speed.z = (Rand()-0.5f)*0.5f; + dim.x = 0.5f+Rand()*0.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTILENS1, 5.0f, 0.0f, 0.0f); + } + else if ( m_actionType == MHS_SATCOM ) // look at the SatCom? + { + SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); + SetLinVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); + SetInclinaison(D3DVECTOR(0.0f, 0.0f, 0.0f)); + } + else + { + if ( m_physics->RetLand() ) // on the ground? + { + time = event.rTime*8.0f; + if ( bSwim ) time *= 0.25f; + + if ( action == MH_MARCH ) // walking? + { + dir.x = sinf(Mod(rTime[0]+0.5f, 1.0f)*PI*2.0f)*0.10f; + dir.y = sinf(Mod(rTime[0]+0.6f, 1.0f)*PI*2.0f)*0.20f; + s = m_physics->RetLinMotionX(MO_REASPEED)*0.03f; + } + else if ( action == MH_MARCHTAKE ) // takes walking? + { + dir.x = sinf(Mod(rTime[0]+0.5f, 1.0f)*PI*2.0f)*0.10f; + dir.y = sinf(Mod(rTime[0]+0.6f, 1.0f)*PI*2.0f)*0.15f; + s = m_physics->RetLinMotionX(MO_REASPEED)*0.02f; + } + else + { + dir.x = 0.0f; + dir.y = 0.0f; + s = m_physics->RetLinMotionX(MO_REASPEED)*0.03f; + } + + if ( s < 0.0f ) s *= 0.5f; + dir.z = -s*0.7f; + + actual = m_object->RetInclinaison(); + dir.x = Smooth(actual.x, dir.x, time); + dir.y = Smooth(actual.y, dir.y, time); + dir.z = Smooth(actual.z, dir.z, time); + if ( bOnBoard ) dir *= 0.3f; + m_object->SetInclinaison(dir); + SetInclinaison(dir); + + if ( action == MH_MARCH ) // walking? + { + p2.x = 0.0f; + p2.y = sinf(Mod(rTime[0]+0.5f, 1.0f)*PI*2.0f)*0.5f; + p2 = RotatePoint(-m_object->RetAngleY(0), p2); + dir.x = p2.x; + dir.z = p2.y; + dir.y = sinf(Mod(rTime[0]*2.0f, 1.0f)*PI*2.0f)*0.3f; + } + else if ( action == MH_MARCHTAKE ) // takes walking? + { + p2.x = 0.0f; + p2.y = sinf(Mod(rTime[0]+0.5f, 1.0f)*PI*2.0f)*0.25f; + p2 = RotatePoint(-m_object->RetAngleY(0), p2); + dir.x = p2.x; + dir.z = p2.y; + dir.y = sinf(Mod(rTime[0]*2.0f, 1.0f)*PI*2.0f)*0.05f-0.3f; + } + else + { + dir.x = 0.0f; + dir.z = 0.0f; + dir.y = 0.0f; + } + + actual = m_object->RetLinVibration(); + dir.x = Smooth(actual.x, dir.x, time); + if ( action == MH_MARCHTAKE ) // takes walking? + { + dir.y = -hr; + } + else + { + s = Min(m_armTimeAction, 1.0f); + dir.y = Smooth(actual.y, dir.y, time)*s; + dir.y += -hr*(1.0f-s); + } + dir.z = Smooth(actual.z, dir.z, time); + if ( bOnBoard ) dir *= 0.3f; + m_object->SetLinVibration(dir); + + dir.x = 0.0f; + dir.z = 0.0f; + dir.y = 0.0f; + SetCirVibration(dir); + } + } + + // Management of the head. + if ( m_actionType == MHS_TAKE || // takes? + m_actionType == MHS_FLAG ) // takes? + { + m_object->SetAngleZ(1, Smooth(m_object->RetAngleZ(1), sinf(m_armTimeAbs*1.0f)*0.2f-0.6f, event.rTime*5.0f)); + m_object->SetAngleX(1, sinf(m_armTimeAbs*1.1f)*0.1f); + m_object->SetAngleY(1, Smooth(m_object->RetAngleY(1), sinf(m_armTimeAbs*1.3f)*0.2f+rot*0.3f, event.rTime*5.0f)); + } + else if ( m_actionType == MHS_TAKEOTHER || // takes? + m_actionType == MHS_TAKEHIGH ) // takes? + { + m_object->SetAngleZ(1, Smooth(m_object->RetAngleZ(1), sinf(m_armTimeAbs*1.0f)*0.2f-0.3f, event.rTime*5.0f)); + m_object->SetAngleX(1, sinf(m_armTimeAbs*1.1f)*0.1f); + m_object->SetAngleY(1, Smooth(m_object->RetAngleY(1), sinf(m_armTimeAbs*1.3f)*0.2f+rot*0.3f, event.rTime*5.0f)); + } + else if ( m_actionType == MHS_WIN ) // win + { + float factor = 0.6f+(sinf(m_armTimeAbs*0.5f)*0.40f); + m_object->SetAngleZ(1, sinf(m_armTimeAbs*5.0f)*0.20f*factor); + m_object->SetAngleX(1, sinf(m_armTimeAbs*0.6f)*0.10f); + m_object->SetAngleY(1, sinf(m_armTimeAbs*1.5f)*0.15f); + } + else if ( m_actionType == MHS_LOST ) // lost? + { + float factor = 0.6f+(sinf(m_armTimeAbs*0.5f)*0.40f); + m_object->SetAngleZ(1, sinf(m_armTimeAbs*0.6f)*0.10f); + m_object->SetAngleX(1, sinf(m_armTimeAbs*0.7f)*0.10f); + m_object->SetAngleY(1, sinf(m_armTimeAbs*3.0f)*0.30f*factor); + } + else if ( m_object->RetDead() ) // dead? + { + } + else + { + m_object->SetAngleZ(1, Smooth(m_object->RetAngleZ(1), sinf(m_armTimeAbs*1.0f)*0.2f, event.rTime*5.0f)); + m_object->SetAngleX(1, sinf(m_armTimeAbs*1.1f)*0.1f); + m_object->SetAngleY(1, Smooth(m_object->RetAngleY(1), sinf(m_armTimeAbs*1.3f)*0.2f+rot*0.3f, event.rTime*5.0f)); + } + + if ( bOnBoard ) + { + m_object->SetAngleZ(1, 0.0f); + m_object->SetAngleX(1, 0.0f); + m_object->SetAngleY(1, 0.0f); + } + + // Steps sound effects. + if ( legAction == MH_MARCH || + legAction == MH_MARCHTAKE ) + { + Sound sound[2]; + float speed, synchro, volume[2], freq[2], hard, level; + + speed = m_physics->RetLinMotionX(MO_REASPEED); + + if ( m_object->RetFret() == 0 ) + { + if ( speed > 0.0f ) synchro = 0.21f; // synchro forward + else synchro = 0.29f; // synchro backward + } + else + { + if ( speed > 0.0f ) synchro = 0.15f; // synchro forward + else synchro = 0.35f; // synchro backward + } + time = rTime[1]+synchro; + + if ( Abs(m_lastSoundMarch-time) > 0.4f && + Mod(time, 0.5f) < 0.1f ) + { + volume[0] = 0.5f; + freq[0] = 1.0f; + if ( m_object->RetFret() != 0 ) + { +//? volume[0] *= 2.0f; + freq[0] = 0.7f; + } + volume[1] = volume[0]; + freq[1] = freq[0]; + sound[0] = SOUND_CLICK; + sound[1] = SOUND_CLICK; + + pos = m_object->RetPosition(0); + + level = m_water->RetLevel(); + if ( pos.y <= level+3.0f ) // underwater? + { + sound[0] = SOUND_STEPw; + } + else + { + hard = m_terrain->RetHardness(pos); + + if ( hard >= 0.875 ) + { + sound[0] = SOUND_STEPm; // metal + } + else + { + hard /= 0.875; + sound[0] = SOUND_STEPs; // smooth + sound[1] = SOUND_STEPh; // hard + + volume[0] *= 1.0f-hard; + volume[1] *= hard; + if ( hard < 0.5f ) + { + volume[0] *= 1.0f+hard*2.0f; + volume[1] *= 1.0f+hard*2.0f; + } + else + { + volume[0] *= 3.0f-hard*2.0f; + volume[1] *= 3.0f-hard*2.0f; + } + freq[0] *= 1.0f+hard; + freq[1] *= 0.5f+hard; + } + } + + if ( sound[0] != SOUND_CLICK ) + { + m_sound->Play(sound[0], pos, volume[0], freq[0]); + } + if ( sound[1] != SOUND_CLICK ) + { + m_sound->Play(sound[1], pos, volume[1], freq[1]); + } + m_lastSoundMarch = time; + } + } + + if ( legAction == MH_SWIM ) + { + time = rTime[0]+0.5f; + + if ( Abs(m_lastSoundMarch-time) > 0.9f && + Mod(time, 1.0f) < 0.1f ) + { + m_sound->Play(SOUND_SWIM, m_object->RetPosition(0), 0.5f); + m_lastSoundMarch = time; + } + } + + m_lastSoundHhh -= event.rTime; + if ( m_lastSoundHhh <= 0.0f && + m_object->RetSelect() && + m_object->RetOption() == 0 ) // helmet? + { + m_sound->Play(SOUND_HUMAN1, m_object->RetPosition(0), (0.5f+m_tired*0.2f)); + m_lastSoundHhh = (4.0f-m_tired*2.5f)+(4.0f-m_tired*2.5f)*Rand(); + } + + return TRUE; +} + + +// Management of the display mode when customizing the personal. + +void CMotionHuman::StartDisplayPerso() +{ + m_bDisplayPerso = TRUE; +} + +void CMotionHuman::StopDisplayPerso() +{ + m_bDisplayPerso = FALSE; +} + + diff --git a/src/object/motion/motionhuman.h b/src/object/motion/motionhuman.h new file mode 100644 index 0000000..44a0c4c --- /dev/null +++ b/src/object/motion/motionhuman.h @@ -0,0 +1,102 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionhuman.h + +#ifndef _MOTIONHUMAN_H_ +#define _MOTIONHUMAN_H_ + + +#include "motion.h" +#include "misc.h" + + +class CInstanceManager; +class CEngine; +class CLight; +class CParticule; +class CTerrain; +class CCamera; +class CBrain; +class CPhysics; +class CObject; + + +#define MH_MARCH 0 +#define MH_MARCHTAKE 1 +#define MH_TURN 2 +#define MH_STOP 3 +#define MH_FLY 4 +#define MH_SWIM 5 +#define MH_SPEC 6 + +#define MHS_FIRE 0 +#define MHS_GUN 1 +#define MHS_TAKE 2 +#define MHS_TAKEOTHER 3 +#define MHS_TAKEHIGH 4 +#define MHS_UPRIGHT 5 +#define MHS_WIN 6 +#define MHS_LOST 7 +#define MHS_DEADg 8 +#define MHS_DEADg1 9 +#define MHS_DEADg2 10 +#define MHS_DEADg3 11 +#define MHS_DEADg4 12 +#define MHS_DEADw 13 +#define MHS_FLAG 14 +#define MHS_SATCOM 15 + + +class CMotionHuman : public CMotion +{ +public: + CMotionHuman(CInstanceManager* iMan, CObject* object); + ~CMotionHuman(); + + void DeleteObject(BOOL bAll=FALSE); + BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); + BOOL EventProcess(const Event &event); + Error SetAction(int action, float time=0.2f); + + void StartDisplayPerso(); + void StopDisplayPerso(); + +protected: + void CreatePhysics(ObjectType type); + BOOL EventFrame(const Event &event); + +protected: + int m_partiReactor; + float m_armMember; + float m_armTimeAbs; + float m_armTimeAction; + float m_armTimeSwim; + short m_armAngles[3*3*3*3*7 + 3*3*3*16]; + int m_armTimeIndex; + int m_armPartIndex; + int m_armMemberIndex; + int m_armLastAction; + BOOL m_bArmStop; + float m_lastSoundMarch; + float m_lastSoundHhh; + float m_time; + float m_tired; + BOOL m_bDisplayPerso; +}; + + +#endif //_MOTIONHUMAN_H_ diff --git a/src/object/motion/motionmother.cpp b/src/object/motion/motionmother.cpp new file mode 100644 index 0000000..872ef76 --- /dev/null +++ b/src/object/motion/motionmother.cpp @@ -0,0 +1,543 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionmother.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "light.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "modfile.h" +#include "sound.h" +#include "motion.h" +#include "motionmother.h" + + + +#define ADJUST_ANGLE FALSE // TRUE -> adjusts the angles of the members +#define START_TIME 1000.0f // beginning of the relative time + + + +// Object's constructor. + +CMotionMother::CMotionMother(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + CMotion::CMotion(iMan, object); + + m_armMember = START_TIME; + m_armTimeAbs = START_TIME; + m_armTimeMarch = START_TIME; + m_armTimeAction = START_TIME; + m_armTimeIndex = 0; + m_armPartIndex = 0; + m_armMemberIndex = 0; + m_armLastAction = -1; + m_specAction = -1; + m_bArmStop = FALSE; +} + +// Object's destructor. + +CMotionMother::~CMotionMother() +{ +} + + +// Removes an object. + +void CMotionMother::DeleteObject(BOOL bAll) +{ +} + + +// Creates a vehicle traveling any lands on the ground. + +BOOL CMotionMother::Create(D3DVECTOR pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + int rank; + + if ( m_engine->RetRestCreate() < 2+12+6 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + + // Creates main base. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + + pModFile->ReadModel("objects\\mother1.mod"); + pModFile->CreateEngineObject(rank); + + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // A vehicle must have a obligatory collision + //with a sphere of center (0, y, 0) (see GetCrashSphere). + m_object->CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 20.0f, SOUND_BOUM, 0.20f); + m_object->SetGlobalSphere(D3DVECTOR(-2.0f, 10.0f, 0.0f), 25.0f); + + // Creates the head. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\mother2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(16.0f, 3.0f, 0.0f)); + + // Creates a right-back leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\mother3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, D3DVECTOR(-5.0f, -1.0f, -12.0f)); + + // Creates a right-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 2); + pModFile->ReadModel("objects\\mother4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, D3DVECTOR(0.0f, 0.0f, -8.5f)); + + // Creates a middle-right leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(4, rank); + m_object->SetObjectParent(4, 0); + pModFile->ReadModel("objects\\mother3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(4, D3DVECTOR(3.5f, -1.0f, -12.0f)); + + // Creates a middle-right foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(5, rank); + m_object->SetObjectParent(5, 4); + pModFile->ReadModel("objects\\mother4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(5, D3DVECTOR(0.0f, 0.0f, -8.5f)); + + // Creates a right-front leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\mother3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, D3DVECTOR(10.0f, -1.0f, -10.0f)); + + // Creates a right-front foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 6); + pModFile->ReadModel("objects\\mother4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, D3DVECTOR(0.0f, 0.0f, -8.5f)); + + // Creates a left-back leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 0); + pModFile->ReadModel("objects\\mother3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, D3DVECTOR(-5.0f, -1.0f, 12.0f)); + m_object->SetAngleY(8, PI); + + // Creates a left-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 8); + pModFile->ReadModel("objects\\mother4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, D3DVECTOR(0.0f, 0.0f, -8.5f)); + + // Creates a middle-left leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(10, rank); + m_object->SetObjectParent(10, 0); + pModFile->ReadModel("objects\\mother3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(10, D3DVECTOR(3.5f, -1.0f, 12.0f)); + m_object->SetAngleY(10, PI); + + // Creates a middle-left foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(11, rank); + m_object->SetObjectParent(11, 10); + pModFile->ReadModel("objects\\mother4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(11, D3DVECTOR(0.0f, 0.0f, -8.5f)); + + // Creates a left-front leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(12, rank); + m_object->SetObjectParent(12, 0); + pModFile->ReadModel("objects\\mother3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(12, D3DVECTOR(10.0f, -1.0f, 10.0f)); + m_object->SetAngleY(12, PI); + + // Creates a left-front foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(13, rank); + m_object->SetObjectParent(13, 12); + pModFile->ReadModel("objects\\mother4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(13, D3DVECTOR(0.0f, 0.0f, -8.5f)); + + // Creates the right antenna. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(14, rank); + m_object->SetObjectParent(14, 1); + pModFile->ReadModel("objects\\mother5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(14, D3DVECTOR(6.0f, 1.0f, -2.5f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(15, rank); + m_object->SetObjectParent(15, 14); + pModFile->ReadModel("objects\\mother6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(15, D3DVECTOR(8.0f, 0.0f, 0.0f)); + + // Creates the left antenna. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(16, rank); + m_object->SetObjectParent(16, 1); + pModFile->ReadModel("objects\\mother5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(16, D3DVECTOR(6.0f, 1.0f, 2.5f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(17, rank); + m_object->SetObjectParent(17, 16); + pModFile->ReadModel("objects\\mother6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(17, D3DVECTOR(8.0f, 0.0f, 0.0f)); + + // Creates the right claw. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(18, rank); + m_object->SetObjectParent(18, 1); + pModFile->ReadModel("objects\\mother7.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(18, D3DVECTOR(-4.0f, -3.5f, -8.0f)); + m_object->SetZoomX(18, 1.2f); + + // Creates the left claw. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(19, rank); + m_object->SetObjectParent(19, 1); + pModFile->ReadModel("objects\\mother7.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(19, D3DVECTOR(-4.0f, -3.5f, 8.0f)); + m_object->SetZoomX(19, 1.2f); + + m_object->CreateShadowCircle(18.0f, 0.8f); + + CreatePhysics(); + m_object->SetFloorHeight(0.0f); + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); // to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return TRUE; +} + +// Creates the physics of the object. + +void CMotionMother::CreatePhysics() +{ + Character* character; + int i; + + int member[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 30,30,10, 35,-15,10, 35,-35,10, // t0: legs 1..3 + -80,-45,-35, -115,-40,-35, -90,10,-55, // t0: feet 1..3 + 0,0,0, 0,0,0, 0,0,0, // t0: unused + // on the ground: + 15,-5,10, 10,-30,10, 5,-50,10, // t1: legs 1..3 + -90,-15,-15, -110,-55,-35, -75,-75,-30, // t1: feet 1..3 + 0,0,0, 0,0,0, 0,0,0, // t1: unused + // on the ground back: + 0,40,10, 5,5,10, 0,-15,10, // t2: legs 1..3 + -45,0,-55, -65,10,-50, -125,-85,-45, // t2: feet 1..3 + 0,0,0, 0,0,0, 0,0,0, // t2: unused + }; + + m_physics->SetType(TYPE_ROLLING); + + character = m_object->RetCharacter(); + character->wheelFront = 10.0f; + character->wheelBack = 10.0f; + character->wheelLeft = 20.0f; + character->wheelRight = 20.0f; + character->height = 3.0f; + + m_physics->SetLinMotionX(MO_ADVSPEED, 8.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 8.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 10.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 10.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 30.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 20.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.1f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.1f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 10.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 20.0f); + + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[i] = member[i]; + } +} + + +// Management of an event. + +BOOL CMotionMother::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { +#if ADJUST_ANGLE + int i; + + if ( event.param == 'A' ) m_armTimeIndex++; + if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0; + + if ( event.param == 'Q' ) m_armPartIndex++; + if ( m_armPartIndex >= 3 ) m_armPartIndex = 0; + + if ( event.param == 'W' ) m_armMemberIndex++; + if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0; + + i = m_armMemberIndex*3; + i += m_armPartIndex*3*3; + i += m_armTimeIndex*3*3*3; +//? i += 3*3*3*3; + + if ( event.param == 'E' ) m_armAngles[i+0] += 5; + if ( event.param == 'D' ) m_armAngles[i+0] -= 5; + if ( event.param == 'R' ) m_armAngles[i+1] += 5; + if ( event.param == 'F' ) m_armAngles[i+1] -= 5; + if ( event.param == 'T' ) m_armAngles[i+2] += 5; + if ( event.param == 'G' ) m_armAngles[i+2] -= 5; + + if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop; +#endif + } + + return TRUE; +} + +// Management of an event. + +BOOL CMotionMother::EventFrame(const Event &event) +{ + D3DVECTOR dir; + float s, a, prog; + int i, st, nd; + BOOL bStop; + + if ( m_engine->RetPause() ) return TRUE; + if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return TRUE; + + s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f; + a = Abs(m_physics->RetCirMotionY(MO_MOTSPEED)*26.0f); + + if ( s == 0.0f && a != 0.0f ) a *= 1.5f; + + m_armTimeAbs += event.rTime; + m_armTimeMarch += (s)*event.rTime*0.05f; + m_armMember += (s+a)*event.rTime*0.05f; + + bStop = ( a == 0.0f && s == 0.0f ); // stop? + + if ( bStop ) + { + prog = Mod(m_armTimeAbs, 2.0f)/10.0f; + a = Mod(m_armMember, 1.0f); + a = (prog-a)*event.rTime*1.0f; // stop position just pleasantly + m_armMember += a; + } + + for ( i=0 ; i<6 ; i++ ) // the six legs + { + if ( i < 3 ) prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f); + else prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f); + if ( m_bArmStop ) + { + prog = (float)m_armTimeIndex/3.0f; + } + if ( prog < 0.33f ) // t0..t1 ? + { + prog = prog/0.33f; // 0..1 + st = 0; // index start + nd = 1; // index end + } + else if ( prog < 0.67f ) // t1..t2 ? + { + prog = (prog-0.33f)/0.33f; // 0..1 + st = 1; // index start + nd = 2; // index end + } + else // t2..t0 ? + { + prog = (prog-0.67f)/0.33f; // 0..1 + st = 2; // index start + nd = 0; // index end + } + st = st*27+(i%3)*3; + nd = nd*27+(i%3)*3; + if ( i < 3 ) // right leg (1..3) ? + { + m_object->SetAngleX(2+2*i+0, Prop(m_armAngles[st+ 0], m_armAngles[nd+ 0], prog)); + m_object->SetAngleY(2+2*i+0, Prop(m_armAngles[st+ 1], m_armAngles[nd+ 1], prog)); + m_object->SetAngleZ(2+2*i+0, Prop(m_armAngles[st+ 2], m_armAngles[nd+ 2], prog)); + m_object->SetAngleX(2+2*i+1, Prop(m_armAngles[st+ 9], m_armAngles[nd+ 9], prog)); + m_object->SetAngleY(2+2*i+1, Prop(m_armAngles[st+10], m_armAngles[nd+10], prog)); + m_object->SetAngleZ(2+2*i+1, Prop(m_armAngles[st+11], m_armAngles[nd+11], prog)); + } + else // left leg (4..6) ? + { + m_object->SetAngleX(2+2*i+0, Prop( m_armAngles[st+ 0], m_armAngles[nd+ 0], prog)); + m_object->SetAngleY(2+2*i+0, Prop(180-m_armAngles[st+ 1], 180-m_armAngles[nd+ 1], prog)); + m_object->SetAngleZ(2+2*i+0, Prop( -m_armAngles[st+ 2], -m_armAngles[nd+ 2], prog)); + m_object->SetAngleX(2+2*i+1, Prop( m_armAngles[st+ 9], m_armAngles[nd+ 9], prog)); + m_object->SetAngleY(2+2*i+1, Prop( -m_armAngles[st+10], -m_armAngles[nd+10], prog)); + m_object->SetAngleZ(2+2*i+1, Prop( -m_armAngles[st+11], -m_armAngles[nd+11], prog)); + } + } + +#if ADJUST_ANGLE + if ( m_object->RetSelect() ) + { + char s[100]; + sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex); + m_engine->SetInfoText(4, s); + } +#endif + + if ( !bStop && !m_object->RetRuin() ) + { + a = Mod(m_armTimeMarch, 1.0f); + if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1 + else a = 3.0f-4.0f*a; // 1..-1 + dir.x = sinf(a)*0.03f; + + s = Mod(m_armTimeMarch/2.0f, 1.0f); + if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1 + else s = 3.0f-4.0f*s; // 1..-1 + dir.z = sinf(s)*0.05f; + + dir.y = 0.0f; + m_object->SetInclinaison(dir); + + a = Mod(m_armMember-0.1f, 1.0f); + if ( a < 0.33f ) + { + dir.y = -(1.0f-(a/0.33f))*0.3f; + } + else if ( a < 0.67f ) + { + dir.y = 0.0f; + } + else + { + dir.y = -(a-0.67f)/0.33f*0.3f; + } + dir.x = 0.0f; + dir.z = 0.0f; + m_object->SetLinVibration(dir); + } + + m_object->SetAngleZ(1, sinf(m_armTimeAbs*0.5f)*0.20f); // head + m_object->SetAngleX(1, sinf(m_armTimeAbs*0.6f)*0.10f); // head + m_object->SetAngleY(1, sinf(m_armTimeAbs*0.7f)*0.20f); // head + + m_object->SetAngleZ(14, 0.50f); + m_object->SetAngleZ(16, 0.50f); + m_object->SetAngleY(14, 0.80f+sinf(m_armTimeAbs*1.1f)*0.53f); // right antenna + m_object->SetAngleY(15, 0.70f-sinf(m_armTimeAbs*1.7f)*0.43f); + m_object->SetAngleY(16, -0.80f+sinf(m_armTimeAbs*0.9f)*0.53f); // left antenna + m_object->SetAngleY(17, -0.70f-sinf(m_armTimeAbs*1.3f)*0.43f); + + m_object->SetAngleY(18, sinf(m_armTimeAbs*1.1f)*0.20f); // right claw + m_object->SetAngleZ(18, -0.20f); + m_object->SetAngleY(19, sinf(m_armTimeAbs*0.9f)*0.20f); // left claw + m_object->SetAngleZ(19, -0.20f); + + return TRUE; +} + + diff --git a/src/object/motion/motionmother.h b/src/object/motion/motionmother.h new file mode 100644 index 0000000..6e8eb32 --- /dev/null +++ b/src/object/motion/motionmother.h @@ -0,0 +1,67 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionmother.h + +#ifndef _MOTIONMOTHER_H_ +#define _MOTIONMOTHER_H_ + + +#include "motion.h" + + +class CInstanceManager; +class CEngine; +class CLight; +class CParticule; +class CTerrain; +class CCamera; +class CBrain; +class CPhysics; +class CObject; + + +class CMotionMother : public CMotion +{ +public: + CMotionMother(CInstanceManager* iMan, CObject* object); + ~CMotionMother(); + + void DeleteObject(BOOL bAll=FALSE); + BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); + BOOL EventProcess(const Event &event); + +protected: + void CreatePhysics(); + BOOL EventFrame(const Event &event); + +protected: + float m_armMember; + float m_armTimeAbs; + float m_armTimeMarch; + float m_armTimeAction; + short m_armAngles[3*3*3*3*10]; + int m_armTimeIndex; + int m_armPartIndex; + int m_armMemberIndex; + int m_armLastAction; + int m_specAction; + float m_specTime; + BOOL m_bArmStop; +}; + + +#endif //_MOTIONMOTHER_H_ diff --git a/src/object/motion/motionspider.cpp b/src/object/motion/motionspider.cpp new file mode 100644 index 0000000..99c3d06 --- /dev/null +++ b/src/object/motion/motionspider.cpp @@ -0,0 +1,789 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionspider.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "light.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "modfile.h" +#include "sound.h" +#include "motion.h" +#include "motionspider.h" + + + +#define ADJUST_ANGLE FALSE // TRUE -> adjusts the angles of the members +#define START_TIME 1000.0f // beginning of the relative time + + + +// Object's constructor. + +CMotionSpider::CMotionSpider(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + CMotion::CMotion(iMan, object); + + m_armMember = START_TIME; + m_armTimeAbs = START_TIME; + m_armTimeMarch = START_TIME; + m_armTimeAction = START_TIME; + m_armTimeIndex = 0; + m_armPartIndex = 0; + m_armMemberIndex = 0; + m_armLastAction = -1; + m_bArmStop = FALSE; + m_lastParticule = 0.0f; +} + +// Object's destructor. + +CMotionSpider::~CMotionSpider() +{ +} + + +// Removes an object. + +void CMotionSpider::DeleteObject(BOOL bAll) +{ +} + + +// Creates a vehicle traveling any lands on the ground. + +BOOL CMotionSpider::Create(D3DVECTOR pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + int rank, i, j, parent; + char name[50]; + + float table[] = + { + // x y z + 0.6f, 0.0f, 0.0f, // back leg + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + + 0.8f, 0.0f, -0.2f, // middle-back leg + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + + 1.0f, 0.0f, -0.2f, // middle-front leg + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + + 1.2f, 0.0f, 0.0f, // front leg + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + }; + + if ( m_engine->RetRestCreate() < 3+32+2 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + + // Creates the main base. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + pModFile->ReadModel("objects\\spider0.mod"); // doesn't exist + pModFile->CreateEngineObject(rank); + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // A vehicle must have a obligatory collision + // with a sphere of center (0, y, 0) (see GetCrashSphere). + m_object->CreateCrashSphere(D3DVECTOR(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f); + m_object->SetGlobalSphere(D3DVECTOR(-0.5f, 1.0f, 0.0f), 4.0f); + + // Creates the abdomen. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\spider1.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(1.0f, 0.0f, 0.0f)); + + // Creates the head. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\spider2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, D3DVECTOR(1.0f, 0.0f, 0.0f)); + + // Creates legs. + for ( i=0 ; i<4 ; i++ ) + { + for ( j=0 ; j<4 ; j++ ) + { + sprintf(name, "objects\\spider%d.mod", j+3); // 3..6 + + // Creates the right leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3+i*4+j, rank); + if ( j == 0 ) parent = 0; + else parent = 3+i*4+j-1; + m_object->SetObjectParent(3+i*4+j, parent); + pModFile->ReadModel(name); + pModFile->CreateEngineObject(rank); + pos.x = table[i*12+j*3+0]; + pos.y = table[i*12+j*3+1]; + pos.z = table[i*12+j*3+2]; + m_object->SetPosition(3+i*4+j, pos); + + // Creates the left leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(19+i*4+j, rank); + if ( j == 0 ) parent = 0; + else parent = 19+i*4+j-1; + m_object->SetObjectParent(19+i*4+j, parent); + pModFile->ReadModel(name); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + pos.x = table[i*12+j*3+0]; + pos.y = table[i*12+j*3+1]; + pos.z = -table[i*12+j*3+2]; + m_object->SetPosition(19+i*4+j, pos); + } + } + + // Creates the right mandible. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(35, rank); + m_object->SetObjectParent(35, 1); + pModFile->ReadModel("objects\\spider7.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(35, D3DVECTOR(0.0f, 0.0f, -0.3f)); + + // Creates the left mandible. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(36, rank); + m_object->SetObjectParent(36, 1); + pModFile->ReadModel("objects\\spider7.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(36, D3DVECTOR(0.0f, 0.0f, 0.3f)); + + m_object->CreateShadowCircle(4.0f, 0.5f); + + CreatePhysics(); + m_object->SetFloorHeight(0.0f); + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); // to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return TRUE; +} + +// Creates the physics of the object. + +void CMotionSpider::CreatePhysics() +{ + Character* character; + int i; + + int member_march[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4, // in the air: + 60,25,0, 60,0,0, 60,-25,0, 60,-50,0, // t0: thighs 1..4 + -35,40,0, -35,0,0, -35,0,0, -35,-40,0, // t0: legs 1..4 + -65,0,-30, -65,0,0, -65,0,0, -65,0,30, // t0: feet 1..4 + 25,0,0, 25,0,0, 25,0,0, 25,0,0, // t0: fingers 1..4 + // on the ground: + 30,15,0, 30,-10,0, 30,-35,0, 30,-60,0, // t1: thighs 1..4 + -10,40,0, -45,0,0, -45,0,0, -45,-40,0, // t1: legs 1..4 + -90,0,0, -20,0,0, -20,0,0, -20,0,0, // t1: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t1: fingers 1..4 + // on the ground back: + 35,35,0, 40,10,0, 40,-15,0, 40,-40,0, // t2: thighs 1..4 + -35,40,0, -35,0,0, -35,0,0, -25,-40,0, // t2: legs 1..4 + -50,-25,-30, -65,0,0, -65,0,0, -90,0,30, // t2: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t2: fingers 1..4 + }; + + int member_stop[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4, // in the air: + 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // t0: thighs 1..4 + -35,40,0, -45,0,0, -45,0,0, -45,-40,0, // t0: legs 1..4 + -50,-25,-30, -20,0,0, -20,0,0, -20,0,30, // t0: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t0: fingers 1..4 + // on the ground: + 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // t1: thighs 1..4 + -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // t1: legs 1..4 + -55,-25,-30, -25,0,0, -25,0,0, -25,0,0, // t1: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t1: fingers 1..4 + // on the ground back: + 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // t2: thighs 1..4 + -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // t2: legs 1..4 + -50,-25,-30, -20,0,0, -20,0,0, -20,0,30, // t2: feet 1..4 + -10,0,0, -10,0,0, -10,0,0, -10,0,0, // t2: fingers 1..4 + }; + + int member_spec[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4, // burning: + 30,25,0, 30,0,0, 30,-25,0, 30,-50,0, // s0: thighs 1..4 + -45,0,0, -45,0,0, -45,0,0, -45,0,0, // s0: legs 1..4 + -20,0,0, -20,0,0, -20,0,0, -20,0,0, // s0: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s0: fingers 1..4 + // destroyed: + 30,25,0, 30,0,0, 30,-25,0, 30,-50,0, // s1: thighs 1..4 + -45,0,0, -45,0,0, -45,0,0, -45,0,0, // s1: legs 1..4 + -20,0,0, -20,0,0, -20,0,0, -20,0,0, // s1: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s1: fingers 1..4 + // explodes: + 40,25,0, 40,0,0, 40,-25,0, 40,-50,0, // s2: thighs 1..4 + -55,0,0, -55,0,0, -55,0,0, -55,0,0, // s2: legs 1..4 + -30,0,0, -30,0,0, -30,0,0, -30,0,0, // s2: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s2: fingers 1..4 + // back1 : + 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // s3: thighs 1..4 + -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // s3: legs 1..4 + -55,-25,-30, -25,0,0, -25,0,0, -25,0,0, // s3: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s3: fingers 1..4 + // back2 : + 15,35,0, 15,0,0, 15,-25,0, 15,-50,0, // s4: thighs 1..4 + -60,40,0, -60,0,0, -60,0,0, -60,-40,0, // s4: legs 1..4 + -65,-25,-30, -65,0,0, -65,0,0, -65,0,0, // s4: feet 1..4 + -15,0,0, -15,0,0, -15,0,0, -15,0,0, // s4: fingers 1..4 + // back3 : + 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // s5: thighs 1..4 + -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // s5: legs 1..4 + -55,-25,-30, -25,0,0, -25,0,0, -25,0,0, // s5: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s5: fingers 1..4 + }; + + m_physics->SetType(TYPE_ROLLING); + + character = m_object->RetCharacter(); + character->wheelFront = 4.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 6.0f; + character->wheelRight = 6.0f; + character->height = 0.6f; + + m_physics->SetLinMotionX(MO_ADVSPEED, 12.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 12.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 15.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 15.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 5.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 5.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 10.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 1.0f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 1.0f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 20.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 20.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 40.0f); + + for ( i=0 ; i<3*4*4*3 ; i++ ) + { + m_armAngles[3*4*4*3*MS_MARCH+i] = member_march[i]; + } + for ( i=0 ; i<3*4*4*3 ; i++ ) + { + m_armAngles[3*4*4*3*MS_STOP+i] = member_stop[i]; + } + for ( i=0 ; i<3*4*4*6 ; i++ ) + { + m_armAngles[3*4*4*3*MS_SPEC+i] = member_spec[i]; + } +} + + +// Management of an event. + +BOOL CMotionSpider::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { +#if ADJUST_ANGLE + int i; + + if ( event.param == 'A' ) m_armTimeIndex++; + if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0; + + if ( event.param == 'Q' ) m_armPartIndex++; + if ( m_armPartIndex >= 4 ) m_armPartIndex = 0; + + if ( event.param == 'W' ) m_armMemberIndex++; + if ( m_armMemberIndex >= 4 ) m_armMemberIndex = 0; + + i = m_armMemberIndex*3; + i += m_armPartIndex*3*4; + i += m_armTimeIndex*3*4*4; + + if ( event.param == 'E' ) m_armAngles[i+0] += 5; + if ( event.param == 'D' ) m_armAngles[i+0] -= 5; + if ( event.param == 'R' ) m_armAngles[i+1] += 5; + if ( event.param == 'F' ) m_armAngles[i+1] -= 5; + if ( event.param == 'T' ) m_armAngles[i+2] += 5; + if ( event.param == 'G' ) m_armAngles[i+2] -= 5; + if ( event.param == 'Z' ) m_armAngles[i+3] += 5; + if ( event.param == 'H' ) m_armAngles[i+3] -= 5; + + if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop; +#endif + } + + return TRUE; +} + +// Calculates a value (radians) proportional between a and b (degrees). + +inline float Propf(float a, float b, float p) +{ + float aa, bb; + + aa = a*PI/180.0f; + bb = b*PI/180.0f; + + return aa+p*(bb-aa); +} + +// Management of an event. + +BOOL CMotionSpider::EventFrame(const Event &event) +{ + D3DVECTOR dir, pos, speed; + FPOINT dim; + float s, a, prog, time; + float tSt[12], tNd[12]; + int i, ii, st, nd, action; + BOOL bStop; + + if ( m_engine->RetPause() ) return TRUE; + if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return TRUE; + + s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f; + a = Abs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.0f); + + if ( s == 0.0f && a != 0.0f ) a *= 1.5f; + + m_armTimeAbs += event.rTime; + m_armTimeAction += event.rTime; + m_armTimeMarch += (s)*event.rTime*0.15f; + m_armMember += (s+a)*event.rTime*0.15f; + + bStop = ( a == 0.0f && s == 0.0f ); // stop? + + action = MS_MARCH; // waslking + if ( s == 0.0f && a == 0.0f ) + { + action = MS_STOP; // stop + } + + if ( bStop ) + { + prog = Mod(m_armTimeAbs, 2.0f)/10.0f; + a = Mod(m_armMember, 1.0f); + a = (prog-a)*event.rTime*2.0f; // stop position just pleasantly + m_armMember += a; + } + + if ( m_object->RetRuin() ) // destroyed? + { + m_actionType = MSS_RUIN; + } + if ( m_object->RetBurn() ) // burning? + { + if ( m_object->RetFixed() ) + { + m_actionType = MSS_BURN; + } + else + { + m_actionType = -1; + } + } + + for ( i=0 ; i<8 ; i++ ) // the 8 legs + { + if ( m_actionType != -1 ) // special action in progress? + { + st = 3*4*4*3*MS_SPEC + 3*4*4*m_actionType + (i%4)*3; + nd = st; + time = event.rTime*m_actionTime; + m_armTimeAction = 0.0f; + } + else + { +//? if ( i < 4 ) prog = Mod(m_armMember+(2.0f-(i%4))*0.25f+0.0f, 1.0f); +//? else prog = Mod(m_armMember+(2.0f-(i%4))*0.25f+0.3f, 1.0f); + if ( i < 4 ) prog = Mod(m_armMember+(2.0f-(i%4))*0.25f+0.0f, 1.0f); + else prog = Mod(m_armMember+(2.0f-(i%4))*0.25f+0.5f, 1.0f); + if ( m_bArmStop ) + { + prog = (float)m_armTimeIndex/3.0f; + action = MS_MARCH; + } + if ( prog < 0.33f ) // t0..t1 ? + { + prog = prog/0.33f; // 0..1 + st = 0; // index start + nd = 1; // index end + } + else if ( prog < 0.67f ) // t1..t2 ? + { + prog = (prog-0.33f)/0.33f; // 0..1 + st = 1; // index start + nd = 2; // index end + } + else // t2..t0 ? + { + prog = (prog-0.67f)/0.33f; // 0..1 + st = 2; // index start + nd = 0; // index end + } + st = 3*4*4*3*action + st*3*4*4 + (i%4)*3; + nd = 3*4*4*3*action + nd*3*4*4 + (i%4)*3; + + // Less and less soft ... +//? time = event.rTime*(2.0f+Min(m_armTimeAction*20.0f, 40.0f)); + time = event.rTime*10.0f; + } + + tSt[ 0] = m_armAngles[st+ 0]; // x + tSt[ 1] = m_armAngles[st+ 1]; // y + tSt[ 2] = m_armAngles[st+ 2]; // z + tSt[ 3] = m_armAngles[st+12]; // x + tSt[ 4] = m_armAngles[st+13]; // y + tSt[ 5] = m_armAngles[st+14]; // z + tSt[ 6] = m_armAngles[st+24]; // x + tSt[ 7] = m_armAngles[st+25]; // y + tSt[ 8] = m_armAngles[st+26]; // z + tSt[ 9] = m_armAngles[st+36]; // x + tSt[10] = m_armAngles[st+37]; // y + tSt[11] = m_armAngles[st+38]; // z + + tNd[ 0] = m_armAngles[nd+ 0]; // x + tNd[ 1] = m_armAngles[nd+ 1]; // y + tNd[ 2] = m_armAngles[nd+ 2]; // z + tNd[ 3] = m_armAngles[nd+12]; // x + tNd[ 4] = m_armAngles[nd+13]; // y + tNd[ 5] = m_armAngles[nd+14]; // z + tNd[ 6] = m_armAngles[nd+24]; // x + tNd[ 7] = m_armAngles[nd+25]; // y + tNd[ 8] = m_armAngles[nd+26]; // z + tNd[ 9] = m_armAngles[nd+36]; // z + tNd[10] = m_armAngles[nd+37]; // z + tNd[11] = m_armAngles[nd+38]; // z + + if ( m_actionType == MSS_BACK2 ) // on the back? + { + for ( ii=0 ; ii<12 ; ii++ ) + { + tSt[ii] += Rand()*20.0f; + tNd[ii] = tSt[ii]; + } +//? time = 100.0f; + time = event.rTime*10.0f; + } + + if ( i < 4 ) // right leg (1..4) ? + { + m_object->SetAngleX(3+4*i+0, Smooth(m_object->RetAngleX(3+4*i+0), Propf(tSt[ 0], tNd[ 0], prog), time)); + m_object->SetAngleY(3+4*i+0, Smooth(m_object->RetAngleY(3+4*i+0), Propf(tSt[ 1], tNd[ 1], prog), time)); + m_object->SetAngleZ(3+4*i+0, Smooth(m_object->RetAngleZ(3+4*i+0), Propf(tSt[ 2], tNd[ 2], prog), time)); + m_object->SetAngleX(3+4*i+1, Smooth(m_object->RetAngleX(3+4*i+1), Propf(tSt[ 3], tNd[ 3], prog), time)); + m_object->SetAngleY(3+4*i+1, Smooth(m_object->RetAngleY(3+4*i+1), Propf(tSt[ 4], tNd[ 4], prog), time)); + m_object->SetAngleZ(3+4*i+1, Smooth(m_object->RetAngleZ(3+4*i+1), Propf(tSt[ 5], tNd[ 5], prog), time)); + m_object->SetAngleX(3+4*i+2, Smooth(m_object->RetAngleX(3+4*i+2), Propf(tSt[ 6], tNd[ 6], prog), time)); + m_object->SetAngleY(3+4*i+2, Smooth(m_object->RetAngleY(3+4*i+2), Propf(tSt[ 7], tNd[ 7], prog), time)); + m_object->SetAngleZ(3+4*i+2, Smooth(m_object->RetAngleZ(3+4*i+2), Propf(tSt[ 8], tNd[ 8], prog), time)); + m_object->SetAngleX(3+4*i+3, Smooth(m_object->RetAngleX(3+4*i+3), Propf(tSt[ 9], tNd[ 9], prog), time)); + m_object->SetAngleY(3+4*i+3, Smooth(m_object->RetAngleY(3+4*i+3), Propf(tSt[10], tNd[10], prog), time)); + m_object->SetAngleZ(3+4*i+3, Smooth(m_object->RetAngleZ(3+4*i+3), Propf(tSt[11], tNd[11], prog), time)); + } + else // left leg (5..8) ? + { + m_object->SetAngleX(3+4*i+0, Smooth(m_object->RetAngleX(3+4*i+0), Propf(-tSt[ 0], -tNd[ 0], prog), time)); + m_object->SetAngleY(3+4*i+0, Smooth(m_object->RetAngleY(3+4*i+0), Propf(-tSt[ 1], -tNd[ 1], prog), time)); + m_object->SetAngleZ(3+4*i+0, Smooth(m_object->RetAngleZ(3+4*i+0), Propf( tSt[ 2], tNd[ 2], prog), time)); + m_object->SetAngleX(3+4*i+1, Smooth(m_object->RetAngleX(3+4*i+1), Propf(-tSt[ 3], -tNd[ 3], prog), time)); + m_object->SetAngleY(3+4*i+1, Smooth(m_object->RetAngleY(3+4*i+1), Propf(-tSt[ 4], -tNd[ 4], prog), time)); + m_object->SetAngleZ(3+4*i+1, Smooth(m_object->RetAngleZ(3+4*i+1), Propf( tSt[ 5], tNd[ 5], prog), time)); + m_object->SetAngleX(3+4*i+2, Smooth(m_object->RetAngleX(3+4*i+2), Propf(-tSt[ 6], -tNd[ 6], prog), time)); + m_object->SetAngleY(3+4*i+2, Smooth(m_object->RetAngleY(3+4*i+2), Propf(-tSt[ 7], -tNd[ 7], prog), time)); + m_object->SetAngleZ(3+4*i+2, Smooth(m_object->RetAngleZ(3+4*i+2), Propf( tSt[ 8], tNd[ 8], prog), time)); + m_object->SetAngleX(3+4*i+3, Smooth(m_object->RetAngleX(3+4*i+3), Propf(-tSt[ 9], -tNd[ 9], prog), time)); + m_object->SetAngleY(3+4*i+3, Smooth(m_object->RetAngleY(3+4*i+3), Propf(-tSt[10], -tNd[10], prog), time)); + m_object->SetAngleZ(3+4*i+3, Smooth(m_object->RetAngleZ(3+4*i+3), Propf( tSt[11], tNd[11], prog), time)); + } + } + +#if ADJUST_ANGLE + if ( m_object->RetSelect() ) + { + char s[100]; + sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex); + m_engine->SetInfoText(4, s); + } +#endif + + if ( m_actionType == MSS_BURN ) // burning? + { + dir = D3DVECTOR(PI, 0.0f, 0.0f); + SetCirVibration(dir); + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + SetLinVibration(dir); + SetInclinaison(dir); + + time = event.rTime*1.0f; + m_object->SetAngleZ(1, Smooth(m_object->RetAngleZ(1), 0.0f, time)); // head + } + else if ( m_actionType == MSS_RUIN ) // destroyed? + { + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + SetLinVibration(dir); + SetCirVibration(dir); + SetInclinaison(dir); + } + else if ( m_actionType == MSS_EXPLO ) // exploded? + { + m_object->SetZoomY(1, 1.0f+m_progress); + m_object->SetZoomZ(1, 1.0f+m_progress); + m_object->SetZoomX(1, 1.0f+m_progress/2.0f); + + dir.x = (Rand()-0.5f)*0.1f*m_progress; + dir.y = (Rand()-0.5f)*0.1f*m_progress; + dir.z = (Rand()-0.5f)*0.1f*m_progress; + m_object->SetCirVibration(dir); + } + else if ( m_actionType == MSS_BACK1 ) // turns on the back? + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) + { + m_lastParticule = m_armTimeAbs; + + pos = m_object->RetPosition(0); + speed.x = (Rand()-0.5f)*10.0f; + speed.z = (Rand()-0.5f)*10.0f; + speed.y = Rand()*5.0f; + dim.x = Rand()*3.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + + if ( m_progress < 0.5f ) + { + dir.x = 0.0f; + dir.y = powf(m_progress/0.5f, 2.0f)*12.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + else + { + dir.x = 0.0f; + dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*12.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + dir.x = m_progress*PI; + dir.y = 0.0f; + dir.z = 0.0f; + SetCirVibration(dir); + + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + + if ( m_progress >= 1.0f ) + { + SetAction(MSS_BACK2, 55.0f+Rand()*10.0f); + } + } + else if ( m_actionType == MSS_BACK2 ) // moves on the back? + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) + { + m_lastParticule = m_armTimeAbs; + + if ( rand()%10 == 0 ) + { + pos = m_object->RetPosition(0); + pos.x += (Rand()-0.5f)*8.0f; + pos.z += (Rand()-0.5f)*8.0f; + pos.y -= 1.0f; + speed.x = (Rand()-0.5f)*2.0f; + speed.z = (Rand()-0.5f)*2.0f; + speed.y = Rand()*2.0f; + dim.x = Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + } + + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + SetLinVibration(dir); + dir.x = sinf(m_armTimeAbs* 3.0f)*0.20f+ + sinf(m_armTimeAbs* 6.0f)*0.20f+ + sinf(m_armTimeAbs*10.0f)*0.20f+ + sinf(m_armTimeAbs*17.0f)*0.30f+PI; + dir.y = sinf(m_armTimeAbs* 4.0f)*0.02f+ + sinf(m_armTimeAbs* 5.0f)*0.02f+ + sinf(m_armTimeAbs*11.0f)*0.02f+ + sinf(m_armTimeAbs*18.0f)*0.03f; + dir.z = sinf(m_armTimeAbs* 2.0f)*0.02f+ + sinf(m_armTimeAbs* 7.0f)*0.02f+ + sinf(m_armTimeAbs*13.0f)*0.02f+ + sinf(m_armTimeAbs*15.0f)*0.03f; + SetCirVibration(dir); + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + + m_object->SetAngleY(1, sinf(m_armTimeAbs*5.0f)*0.05f); // tail + m_object->SetAngleY(2, cosf(m_armTimeAbs*5.0f)*0.20f); // head + m_object->SetAngleZ(1, 0.4f); // tail + m_object->SetAngleZ(2, 0.0f); // head + + if ( m_progress >= 1.0f ) + { + SetAction(MSS_BACK3, 0.4f); + } + } + else if ( m_actionType == MSS_BACK3 ) // recovers on the legs? + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) + { + m_lastParticule = m_armTimeAbs; + + pos = m_object->RetPosition(0); + speed.x = (Rand()-0.5f)*10.0f; + speed.z = (Rand()-0.5f)*10.0f; + speed.y = Rand()*5.0f; + dim.x = Rand()*3.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + + if ( m_progress < 0.5f ) + { + dir.x = 0.0f; + dir.y = powf(m_progress/0.5f, 2.0f)*5.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + else + { + dir.x = 0.0f; + dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*5.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + dir.x = (1.0f-m_progress)*PI; + dir.y = 0.0f; + dir.z = 0.0f; + SetCirVibration(dir); + + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + + if ( m_progress >= 1.0f ) + { + SetAction(-1); + m_object->SetFixed(FALSE); // moving again + } + } + else + { + if ( bStop ) + { + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + } + else + { + a = Mod(m_armMember, 1.0f); + if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1 + else a = 3.0f-4.0f*a; // 1..-1 + dir.x = sinf(a)*0.05f; + + s = Mod(m_armMember/2.0f, 1.0f); + if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1 + else s = 3.0f-4.0f*s; // 1..-1 + dir.z = sinf(s)*0.1f; + + dir.y = 0.0f; + SetInclinaison(dir); + } + + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + SetLinVibration(dir); + SetCirVibration(dir); + + m_object->SetAngleZ(1, sinf(m_armTimeAbs*1.7f)*0.02f); // tail + m_object->SetAngleX(1, sinf(m_armTimeAbs*1.3f)*0.05f); + m_object->SetAngleY(1, sinf(m_armTimeAbs*2.4f)*0.10f); + m_object->SetZoom(1, 1.0f+sinf(m_armTimeAbs*3.3f)*0.05f); + + m_object->SetAngleZ(2, sinf(m_armTimeAbs*1.4f)*0.20f); // head + m_object->SetAngleX(2, sinf(m_armTimeAbs*1.9f)*0.10f); + m_object->SetAngleY(2, sinf(m_armTimeAbs*2.1f)*0.10f); + + m_object->SetAngleY(35, sinf(m_armTimeAbs*3.1f)*0.20f); // mandible + m_object->SetAngleY(36, -sinf(m_armTimeAbs*3.1f)*0.20f); // mandible + } + + return TRUE; +} + + diff --git a/src/object/motion/motionspider.h b/src/object/motion/motionspider.h new file mode 100644 index 0000000..294daf3 --- /dev/null +++ b/src/object/motion/motionspider.h @@ -0,0 +1,78 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionspider.h + +#ifndef _MOTIONSPIDER_H_ +#define _MOTIONSPIDER_H_ + + +#include "motion.h" + + +class CInstanceManager; +class CEngine; +class CLight; +class CParticule; +class CTerrain; +class CCamera; +class CBrain; +class CPhysics; +class CObject; + + +#define MS_MARCH 0 +#define MS_STOP 1 +#define MS_SPEC 2 + +#define MSS_BURN 0 +#define MSS_RUIN 1 +#define MSS_EXPLO 2 +#define MSS_BACK1 3 +#define MSS_BACK2 4 +#define MSS_BACK3 5 + + +class CMotionSpider : public CMotion +{ +public: + CMotionSpider(CInstanceManager* iMan, CObject* object); + ~CMotionSpider(); + + void DeleteObject(BOOL bAll=FALSE); + BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); + BOOL EventProcess(const Event &event); + +protected: + void CreatePhysics(); + BOOL EventFrame(const Event &event); + +protected: + float m_armMember; + float m_armTimeAbs; + float m_armTimeMarch; + float m_armTimeAction; + short m_armAngles[3*4*4*3*3 + 3*4*4*6]; + int m_armTimeIndex; + int m_armPartIndex; + int m_armMemberIndex; + int m_armLastAction; + BOOL m_bArmStop; + float m_lastParticule; +}; + + +#endif //_MOTIONSPIDER_H_ diff --git a/src/object/motion/motiontoto.cpp b/src/object/motion/motiontoto.cpp new file mode 100644 index 0000000..afd5779 --- /dev/null +++ b/src/object/motion/motiontoto.cpp @@ -0,0 +1,886 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motiontoto.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "light.h" +#include "particule.h" +#include "terrain.h" +#include "water.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "modfile.h" +#include "robotmain.h" +#include "sound.h" +#include "motion.h" +#include "motiontoto.h" + + + +#define START_TIME 1000.0f // beginning of the relative time + + + +// Object's constructor. + +CMotionToto::CMotionToto(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + CMotion::CMotion(iMan, object); + + m_time = 0.0f; + m_bDisplayInfo = FALSE; + m_bQuickPos = FALSE; + m_bStartAction = FALSE; + m_speedAction = 20.0f; + m_soundChannel = -1; + m_clownRadius = 0.0f; + m_clownDelay = 0.0f; + m_clownTime = 0.0f; + m_blinkTime = 0.0f; + m_blinkProgress = -1.0f; + m_lastMotorParticule = 0.0f; + m_type = OBJECT_NULL; + m_mousePos = FPOINT(0.0f, 0.0f); +} + +// Object's destructor. + +CMotionToto::~CMotionToto() +{ +} + + +// Removes an object. + +void CMotionToto::DeleteObject(BOOL bAll) +{ + if ( m_soundChannel != -1 ) + { + m_sound->Stop(m_soundChannel); + m_soundChannel = -1; + } +} + + +// Creates a vehicle traveling any lands on the ground. + +BOOL CMotionToto::Create(D3DVECTOR pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + int rank; + + if ( m_engine->RetRestCreate() < 10 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + + // Creates the head. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + pModFile->ReadModel("objects\\toto1.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // Creates mouth. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\toto2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(1.00f, 0.17f, 0.00f)); + + // Creates the left eye. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\toto3.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, D3DVECTOR(0.85f, 1.04f, 0.25f)); + m_object->SetAngleY(2, -20.0f*PI/180.0f); + + // Creates the right eye. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 0); + pModFile->ReadModel("objects\\toto3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, D3DVECTOR(0.85f, 1.04f, -0.25f)); + m_object->SetAngleY(3, 20.0f*PI/180.0f); + + // Creates left antenna. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(4, rank); + m_object->SetObjectParent(4, 0); + pModFile->ReadModel("objects\\toto4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(4, D3DVECTOR(0.0f, 1.9f, 0.3f)); + m_object->SetAngleX(4, 30.0f*PI/180.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(5, rank); + m_object->SetObjectParent(5, 4); + pModFile->ReadModel("objects\\toto4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(5, D3DVECTOR(0.0f, 0.67f, 0.0f)); + m_object->SetAngleX(5, 30.0f*PI/180.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 5); + pModFile->ReadModel("objects\\toto5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, D3DVECTOR(0.0f, 0.70f, 0.0f)); + m_object->SetAngleX(6, 30.0f*PI/180.0f); + + // Creates right antenna. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\toto4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, D3DVECTOR(0.0f, 1.9f, -0.3f)); + m_object->SetAngleX(7, -30.0f*PI/180.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 7); + pModFile->ReadModel("objects\\toto4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, D3DVECTOR(0.0f, 0.67f, 0.0f)); + m_object->SetAngleX(8, -30.0f*PI/180.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 8); + pModFile->ReadModel("objects\\toto5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, D3DVECTOR(0.0f, 0.70f, 0.0f)); + m_object->SetAngleX(9, -30.0f*PI/180.0f); + + m_object->SetZoom(0, 0.5f); // is little + m_object->SetFloorHeight(0.0f); + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); // to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return TRUE; +} + + +// Beginning of the display of informations, with foo in the left margin. + +void CMotionToto::StartDisplayInfo() +{ +return; +//? + m_bDisplayInfo = TRUE; + + m_actionType = -1; + m_actionTime = 0.0f; + m_progress = 0.0f; + + m_object->SetAngleY(0, 0.0f); + m_mousePos = FPOINT(0.5f, 0.5f); +} + +// End of the display of informations. + +void CMotionToto::StopDisplayInfo() +{ + m_bDisplayInfo = FALSE; + m_bQuickPos = TRUE; +} + +// Gives the position of the mouse. + +void CMotionToto::SetMousePos(FPOINT pos) +{ + m_mousePos = pos; +} + + +// Management of an event. + +BOOL CMotionToto::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + return TRUE; +} + +// Management of an event. + +BOOL CMotionToto::EventFrame(const Event &event) +{ + D3DMATRIX* mat; + D3DVECTOR eye, lookat, dir, perp, nPos, aPos, pos, speed; + D3DVECTOR vibLin, vibCir, dirSpeed, aAntenna; + FPOINT dim; + POINT wDim; + ParticuleType type; + float progress, focus, distance, shift, verti, level, zoom; + float aAngle, nAngle, mAngle, angle, linSpeed, cirSpeed; + int sheet, i, r; + BOOL bHidden; + + if ( m_engine->RetPause() && + !m_main->RetInfoLock() ) return TRUE; + + if ( m_bDisplayInfo ) // "looks" mouse? + { + bHidden = FALSE; + } + else + { + bHidden = FALSE; + + if ( m_main->RetMovieLock() ) // current movie? + { + bHidden = TRUE; + } + if ( !m_engine->RetTotoMode() ) + { + if ( !m_main->RetEditLock() ) // current edition? + { + bHidden = TRUE; + } + } + } + + if ( bHidden ) + { + nPos = m_object->RetPosition(0); + m_terrain->MoveOnFloor(nPos, TRUE); + nPos.y -= 100.0f; // hidden under the ground! + m_object->SetPosition(0, nPos); + return TRUE; + } + + m_time += event.rTime; + m_blinkTime -= event.rTime; + + progress = 0.0f; + if ( m_actionType != -1 ) // current action? + { + if ( m_progress < 0.15f ) + { + progress = m_progress/0.15f; + } + else if ( m_progress < 0.85f ) + { + progress = 1.0f; + } + else + { + progress = (1.0f-m_progress)/0.15f; + } + } + + if ( m_progress >= 1.0f ) + { + m_actionType = -1; // action ended + m_actionTime = 0.0f; + m_progress = 0.0f; + + m_clownTime = 0.0f; + m_clownDelay = 0.0f; + } + + focus = m_engine->RetFocus(); + eye = m_engine->RetEyePt(); + lookat = m_engine->RetLookatPt(); + + vibLin = D3DVECTOR(0.0f, 0.0f, 0.0f); + vibCir = D3DVECTOR(0.0f, 0.0f, 0.0f); + aAntenna = D3DVECTOR(0.0f, 0.0f, 0.0f); + aAntenna.x += 30.0f*PI/180.0f; + + // Calculates the new position. + if ( m_bDisplayInfo ) + { + wDim = m_engine->RetDim(); + nPos.x = -4.0f*((float)wDim.x/(float)wDim.y)/(640.0f/480.0f); + nPos.y = -0.5f; + nPos.z = 7.0f; // in the left margin + + linSpeed = 0.0f; + } + else + { +#if 0 + distance = 30.0f-progress*24.5f; // remoteness + shift = 18.0f-progress*15.4f; // shift is left + verti = 10.0f-progress* 9.6f; // shift at the top +#else + distance = 30.0f-progress*18.0f; // remoteness + shift = 18.0f-progress*11.0f; // shift is left + verti = 10.0f-progress* 8.0f; // shift at the top +#endif + + if ( m_actionType == -1 && + (m_type == OBJECT_HUMAN || + m_type == OBJECT_TECH || + m_type == OBJECT_MOBILEwa || + m_type == OBJECT_MOBILEta || + m_type == OBJECT_MOBILEfa || + m_type == OBJECT_MOBILEia || + m_type == OBJECT_MOBILEwc || + m_type == OBJECT_MOBILEtc || + m_type == OBJECT_MOBILEfc || + m_type == OBJECT_MOBILEic || + m_type == OBJECT_MOBILEwi || + m_type == OBJECT_MOBILEti || + m_type == OBJECT_MOBILEfi || + m_type == OBJECT_MOBILEii || + m_type == OBJECT_MOBILEws || + m_type == OBJECT_MOBILEts || + m_type == OBJECT_MOBILEfs || + m_type == OBJECT_MOBILEis || + m_type == OBJECT_MOBILErt || + m_type == OBJECT_MOBILErc || + m_type == OBJECT_MOBILErr || + m_type == OBJECT_MOBILErs || + m_type == OBJECT_MOBILEsa || + m_type == OBJECT_MOBILEwt || + m_type == OBJECT_MOBILEtt || + m_type == OBJECT_MOBILEft || + m_type == OBJECT_MOBILEit || + m_type == OBJECT_MOBILEdr ) ) // vehicle? + { + m_clownTime += event.rTime; + if ( m_clownTime >= m_clownDelay ) + { + if ( rand()%10 < 2 ) + { + m_clownRadius = 2.0f+Rand()*10.0f; +//? m_clownDelay = m_clownRadius/(2.0f+Rand()*2.0f); + m_clownDelay = 1.5f+Rand()*1.0f; + } + else + { + m_clownRadius = 0.0f; + m_clownDelay = 2.0f+Rand()*2.0f; + } + pos = m_object->RetPosition(0); + if ( pos.y < m_water->RetLevel() ) // underwater? + { + m_clownRadius /= 1.5f; + m_clownDelay *= 2.0f; + } + m_clownTime = 0.0f; + } + else + { + distance -= m_clownRadius*sinf(m_clownTime*PI*2.0f/m_clownDelay); + shift -= m_clownRadius-m_clownRadius*cosf(m_clownTime*PI*2.0f/m_clownDelay); + } + + verti += (18.0f-shift)*0.2f; + } + + distance /= focus; +//? shift *= focus; + verti /= focus; + + dir = Normalize(lookat-eye); + nPos = eye + dir*distance; + + perp.x = -dir.z; + perp.y = dir.y; + perp.z = dir.x; + nPos = nPos + perp*shift; + + nPos.y += verti; + + if ( m_bQuickPos ) // immediately in place? + { + m_bQuickPos = FALSE; + linSpeed = 0.0f; + } + else + { + aPos = m_object->RetPosition(0); + if ( m_actionType == -1 ) + { + level = 4.0f; + } + else + { + if ( m_bStartAction ) + { + m_bStartAction = FALSE; + m_speedAction = Length(nPos, aPos)/15.0f; + if ( m_speedAction < 20.0f ) m_speedAction = 20.0f; + } + level = m_speedAction; + } + if ( level > 1.0f/event.rTime ) level = 1.0f/event.rTime; + nPos = aPos + (nPos-aPos)*event.rTime*level; // progression aPos -> nPos + + linSpeed = Length2d(nPos, aPos)/event.rTime; + dirSpeed = (nPos-aPos)/event.rTime; + nPos.y -= linSpeed*0.015f*(1.0f-progress); // at ground level if moving fast + } + } + + // Calculate the new angle. + nAngle = NormAngle(RotateAngle(eye.x-lookat.x, lookat.z-eye.z)-0.9f); + if ( linSpeed == 0.0f || m_actionType != -1 ) + { + mAngle = nAngle; + } + else + { + mAngle = NormAngle(RotateAngle(dirSpeed.x, -dirSpeed.z)); + } + level = Min(linSpeed*0.1f, 1.0f); + nAngle = nAngle*(1.0f-level) + mAngle*level; + aAngle = NormAngle(m_object->RetAngleY(0)); + + if ( nAngle < aAngle ) + { + if ( nAngle+PI*2.0f-aAngle < aAngle-nAngle ) nAngle += PI*2.0f; + } + else + { + if ( aAngle+PI*2.0f-nAngle < nAngle-aAngle ) aAngle += PI*2.0f; + } + nAngle = aAngle + (nAngle-aAngle)*event.rTime*4.0f; + + // Leans quotes if running. + cirSpeed = (aAngle-nAngle)/event.rTime; + angle = cirSpeed*0.3f*(1.0f-progress); + if ( angle > 0.7f ) angle = 0.7f; + if ( angle < -0.7f ) angle = -0.7f; + vibCir.x += angle*1.5f; + aAntenna.x += Abs(angle)*0.8f; // deviates + + // Leans forward so quickly advance. + angle = linSpeed*0.10f*(1.0f-progress); + if ( angle > 1.0f ) angle = 1.0f; + vibCir.z -= angle/2.0f; // leans forward + aAntenna.z -= angle; // leans forward + + // Calculates the residual motion. +#if 1 + vibLin.y += (sinf(m_time*2.00f)*0.5f+ + sinf(m_time*2.11f)*0.2f)*(1.0f-progress); + + vibCir.z += sinf(m_time*PI* 2.01f)*(PI/ 75.0f)+ + sinf(m_time*PI* 2.51f)*(PI/100.0f)+ + sinf(m_time*PI*19.01f)*(PI/200.0f); + + vibCir.x += sinf(m_time*PI* 2.03f)*(PI/ 75.0f)+ + sinf(m_time*PI* 2.52f)*(PI/100.0f)+ + sinf(m_time*PI*19.53f)*(PI/200.0f); + + vibCir.y += (sinf(m_time*PI* 1.07f)*(PI/ 10.0f)+ + sinf(m_time*PI* 1.19f)*(PI/ 17.0f)+ + sinf(m_time*PI* 1.57f)*(PI/ 31.0f))*(1.0f-progress); +#endif + + // Calculates the animations in action. + if ( m_actionType == MT_ERROR ) // no-no? + { + vibCir.y += progress*sinf(m_progress*PI*11.0f)*1.0f; + vibCir.z -= progress*0.5f; // leans forward + + aAntenna.x -= progress*0.4f; // narrows + aAntenna.z += progress*1.0f; // leaning back + } + + if ( m_actionType == MT_WARNING ) // warning? + { + vibCir.x += progress*sinf(m_progress*PI*17.0f)*0.5f; + + aAntenna.x += progress*sinf(m_progress*PI*17.0f)*0.5f; // deviates + aAntenna.z += progress*cosf(m_progress*PI*17.0f)*0.5f; // turns + } + + if ( m_actionType == MT_INFO ) // yes-yes? + { + vibCir.z += progress*sinf(m_progress*PI*19.0f)*0.7f; + + aAntenna.x -= progress*0.2f; // narrows + aAntenna.z -= progress*cosf(m_progress*PI*19.0f)*0.9f; // turns + } + + if ( m_actionType == MT_MESSAGE ) // message? + { + vibCir.x += progress*sinf(m_progress*PI*15.0f)*0.3f; + vibCir.z += progress*cosf(m_progress*PI*15.0f)*0.3f; + + aAntenna.x -= progress*0.4f; // narrows + aAntenna.z -= progress*cosf(m_progress*PI*19.0f)*0.8f; + } + + // Initialize the object. + if ( m_bDisplayInfo ) // "looks" mouse? + { + if ( m_mousePos.x < 0.15f ) + { + progress = 1.0f-m_mousePos.x/0.15f; + vibCir.y += progress*PI/2.0f; + } + else + { + progress = (m_mousePos.x-0.15f)/0.85f; + vibCir.y -= progress*PI/3.0f; + } + + angle = RotateAngle(m_mousePos.x-0.1f, m_mousePos.y-0.5f-vibLin.y*0.2f); + if ( angle < PI ) + { + if ( angle > PI*0.5f ) angle = PI-angle; + if ( angle > PI*0.3f ) angle = PI*0.3f; + vibCir.z += angle; + } + else + { + angle = PI*2.0f-angle; + if ( angle > PI*0.5f ) angle = PI-angle; + if ( angle > PI*0.3f ) angle = PI*0.3f; + vibCir.z -= angle; + } + } + else + { + nPos.y += vibLin.y; + level = m_terrain->RetFloorLevel(nPos); + if ( nPos.y < level+2.0f ) + { + nPos.y = level+2.0f; // just above the ground + } + nPos.y -= vibLin.y; + } + m_object->SetPosition(0, nPos); + m_object->SetAngleY(0, nAngle); + + SetLinVibration(vibLin); + SetCirVibration(vibCir); + + // Calculates the residual movement of the antennas. + pos = aAntenna*0.40f; + pos.x += sinf(m_time*PI*2.07f)*(PI/50.0f)+ + sinf(m_time*PI*2.59f)*(PI/70.0f)+ + sinf(m_time*PI*2.67f)*(PI/90.0f); + + pos.y += sinf(m_time*PI*2.22f)*(PI/50.0f)+ + sinf(m_time*PI*2.36f)*(PI/70.0f)+ + sinf(m_time*PI*3.01f)*(PI/90.0f); + + pos.z += sinf(m_time*PI*2.11f)*(PI/50.0f)+ + sinf(m_time*PI*2.83f)*(PI/70.0f)+ + sinf(m_time*PI*3.09f)*(PI/90.0f); + + m_object->SetAngle(4, pos); // left antenna + m_object->SetAngle(5, pos); // left antenna + m_object->SetAngle(6, pos); // left antenna + + pos = aAntenna*0.40f; + pos.x = -pos.x; + pos.x += sinf(m_time*PI*2.33f)*(PI/50.0f)+ + sinf(m_time*PI*2.19f)*(PI/70.0f)+ + sinf(m_time*PI*2.07f)*(PI/90.0f); + + pos.y += sinf(m_time*PI*2.44f)*(PI/50.0f)+ + sinf(m_time*PI*2.77f)*(PI/70.0f)+ + sinf(m_time*PI*3.22f)*(PI/90.0f); + + pos.z += sinf(m_time*PI*2.05f)*(PI/50.0f)+ + sinf(m_time*PI*2.38f)*(PI/70.0f)+ + sinf(m_time*PI*2.79f)*(PI/90.0f); + + m_object->SetAngle(7, pos); // right antenna + m_object->SetAngle(8, pos); // right antenna + m_object->SetAngle(9, pos); // right antenna + + // Movement of the mouth. + if ( m_actionType == MT_ERROR ) // no-no? + { + m_object->SetAngleX(1, 0.0f); + m_object->SetAngleZ(1, 0.2f+sinf(m_time*10.0f)*0.2f); + m_object->SetZoomY(1, 2.0f+sinf(m_time*10.0f)); + m_object->SetZoomZ(1, 1.0f); + } + else if ( m_actionType == MT_WARNING ) // warning? + { + m_object->SetAngleX(1, 15.0f*PI/180.0f); + m_object->SetAngleZ(1, 0.0f); + m_object->SetZoomY(1, 1.0f); + m_object->SetZoomZ(1, 1.0f); + } + else if ( m_actionType == MT_INFO ) // yes-yes? + { + m_object->SetAngleX(1, 0.0f); + m_object->SetAngleZ(1, 0.0f); + m_object->SetZoomY(1, 1.0f); + m_object->SetZoomZ(1, 0.7f+sinf(m_time*10.0f)*0.3f); + } + else if ( m_actionType == MT_MESSAGE ) // message? + { + m_object->SetAngleX(1, 0.0f); + m_object->SetAngleZ(1, 0.0f); + m_object->SetZoomY(1, 1.0f); + m_object->SetZoomZ(1, 0.8f+sinf(m_time*7.0f)*0.2f); + } + else + { + m_object->SetAngleX(1, 0.0f); + m_object->SetAngleZ(1, 0.0f); + m_object->SetZoomY(1, 1.0f); + m_object->SetZoomZ(1, 1.0f); + } + + // Eye blinking management. + if ( m_blinkTime <= 0.0f && m_blinkProgress == -1.0f ) + { + m_blinkProgress = 0.0f; + } + + if ( m_blinkProgress >= 0.0f ) + { + m_blinkProgress += event.rTime*3.2f; + + if ( m_blinkProgress < 1.0f ) + { + if ( m_blinkProgress < 0.5f ) zoom = m_blinkProgress/0.5f; + else zoom = 2.0f-m_blinkProgress/0.5f; + m_object->SetZoomY(2, 1.0f-zoom*0.9f); + m_object->SetZoomY(3, 1.0f-zoom*0.9f); + } + else + { + m_blinkProgress = -1.0f; + m_blinkTime = 0.1f+Rand()*4.0f; + m_object->SetZoomY(2, 1.0f); + m_object->SetZoomY(3, 1.0f); + } + } + + if ( m_actionType == MT_ERROR ) // no-no? + { + m_object->SetAngleX(2, -30.0f*PI/180.0f); + m_object->SetAngleX(3, 30.0f*PI/180.0f); + } + else if ( m_actionType == MT_WARNING ) // warning? + { + m_object->SetAngleX(2, -15.0f*PI/180.0f); + m_object->SetAngleX(3, 15.0f*PI/180.0f); + } + else if ( m_actionType == MT_INFO ) // yes-yes? + { + m_object->SetAngleX(2, 40.0f*PI/180.0f); + m_object->SetAngleX(3, -40.0f*PI/180.0f); + } + else if ( m_actionType == MT_MESSAGE ) // message? + { + m_object->SetAngleX(2, 20.0f*PI/180.0f); + m_object->SetAngleX(3, -20.0f*PI/180.0f); + } + else + { + m_object->SetAngleX(2, 0.0f); + m_object->SetAngleX(3, 0.0f); + } + + mat = m_object->RetWorldMatrix(0); // must be done every time! + + // Generates particles. + if ( m_time-m_lastMotorParticule >= m_engine->ParticuleAdapt(0.05f) ) + { + m_lastMotorParticule = m_time; + + if ( m_bDisplayInfo ) sheet = SH_FRONT; + else sheet = SH_WORLD; + + pos = m_object->RetPosition(0); + if ( !m_bDisplayInfo && + pos.y < m_water->RetLevel() ) // underwater? + { + float t = Mod(m_time, 3.5f); + if ( t >= 2.2f || ( t >= 1.2f && t <= 1.4f ) ) // breathe? + { + pos = D3DVECTOR(1.0f, 0.2f, 0.0f); + pos.z += (Rand()-0.5f)*0.5f; + + speed = pos; + speed.y += 5.0f+Rand()*5.0f; + speed.x += Rand()*2.0f; + speed.z += (Rand()-0.5f)*2.0f; + + pos = Transform(*mat, pos); + speed = Transform(*mat, speed)-pos; + + dim.x = 0.12f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBUBBLE, 3.0f, 0.0f, 0.0f); + } + } + else // out of water? + { + pos = D3DVECTOR(0.0f, -0.5f, 0.0f); + pos.z += (Rand()-0.5f)*0.5f; + + speed = pos; + speed.y -= (1.5f+Rand()*1.5f) + vibLin.y; + speed.x += (Rand()-0.5f)*2.0f; + speed.z += (Rand()-0.5f)*2.0f; + +// mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, pos); + speed = Transform(*mat, speed)-pos; + + dim.x = (Rand()*0.4f+0.4f)*(1.0f+Min(linSpeed*0.1f, 5.0f)); + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTITOTO, 1.0f+Rand()*1.0f, 0.0f, 1.0f, sheet); + } + + if ( m_actionType != -1 && // current action? + m_progress <= 0.85f ) + { + pos.x = (Rand()-0.5f)*1.0f; + pos.y = (Rand()-0.5f)*1.0f+3.5f; + pos.z = (Rand()-0.5f)*1.0f; + pos = Transform(*mat, pos); + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = (Rand()*0.3f+0.3f); + dim.y = dim.x; + if ( m_actionType == MT_ERROR ) type = PARTIERROR; + if ( m_actionType == MT_WARNING ) type = PARTIWARNING; + if ( m_actionType == MT_INFO ) type = PARTIINFO; + if ( m_actionType == MT_MESSAGE ) type = PARTIWARNING; + m_particule->CreateParticule(pos, speed, dim, type, 0.5f+Rand()*0.5f, 0.0f, 1.0f, sheet); + + pos.x = 0.50f+(Rand()-0.5f)*0.80f; + pos.y = 0.86f+(Rand()-0.5f)*0.08f; + pos.z = 0.00f; + dim.x = (Rand()*0.04f+0.04f); + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, type, 0.5f+Rand()*0.5f, 0.0f, 1.0f, SH_INTERFACE); + } + +//? if ( m_bDisplayInfo && m_main->RetGlint() ) + if ( FALSE ) + { + pos.x = (Rand()-0.5f)*1.4f; + pos.y = (Rand()-0.5f)*1.4f+3.5f; + pos.z = (Rand()-0.5f)*1.4f; + pos = Transform(*mat, pos); + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = (Rand()*0.5f+0.5f); + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIERROR, 0.5f+Rand()*0.5f, 0.0f, 1.0f, sheet); + + for ( i=0 ; i<10 ; i++ ) + { + pos.x = 0.60f+(Rand()-0.5f)*0.76f; + pos.y = 0.47f+(Rand()-0.5f)*0.90f; + pos.z = 0.00f; + r = rand()%4; + if ( r == 0 ) pos.x = 0.21f; // the left edge + else if ( r == 1 ) pos.x = 0.98f; // the right edge + else if ( r == 2 ) pos.y = 0.02f; // on the lower edge + else pos.y = 0.92f; // on the upper edge + dim.x = (Rand()*0.02f+0.02f); + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, PARTIERROR, 0.5f+Rand()*0.5f, 0.0f, 1.0f, SH_INTERFACE); + } + } + } + + // Move the sound. + if ( m_soundChannel != -1 ) + { + if ( !m_sound->Position(m_soundChannel, m_object->RetPosition(0)) ) + { + m_soundChannel = -1; + } + } + + return TRUE; +} + + +// Starts an action. + +Error CMotionToto::SetAction(int action, float time) +{ + Sound sound; + + CMotion::SetAction(action, time); + + m_bStartAction = TRUE; + + sound = SOUND_CLICK; + if ( action == MT_ERROR ) sound = SOUND_ERROR; + if ( action == MT_WARNING ) sound = SOUND_WARNING; + if ( action == MT_INFO ) sound = SOUND_INFO; + if ( action == MT_MESSAGE ) sound = SOUND_MESSAGE; + + if ( sound != SOUND_CLICK ) + { + m_soundChannel = m_sound->Play(sound, m_object->RetPosition(0)); + } + + return ERR_OK; +} + +// Specifies the type of the object is attached to toto. + +void CMotionToto::SetLinkType(ObjectType type) +{ + m_type = type; +} + + diff --git a/src/object/motion/motiontoto.h b/src/object/motion/motiontoto.h new file mode 100644 index 0000000..22955bb --- /dev/null +++ b/src/object/motion/motiontoto.h @@ -0,0 +1,81 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motiontoto.h + +#ifndef _MOTIONTOTO_H_ +#define _MOTIONTOTO_H_ + + +#include "struct.h" +#include "object.h" +#include "motion.h" + + +class CInstanceManager; +class CEngine; +class CLight; +class CParticule; +class CTerrain; +class CCamera; +class CBrain; +class CPhysics; + + +#define MT_ERROR 0 +#define MT_WARNING 1 +#define MT_INFO 2 +#define MT_MESSAGE 3 + + +class CMotionToto : public CMotion +{ +public: + CMotionToto(CInstanceManager* iMan, CObject* object); + ~CMotionToto(); + + void DeleteObject(BOOL bAll=FALSE); + BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); + BOOL EventProcess(const Event &event); + Error SetAction(int action, float time=0.2f); + void SetLinkType(ObjectType type); + + void StartDisplayInfo(); + void StopDisplayInfo(); + void SetMousePos(FPOINT pos); + +protected: + BOOL EventFrame(const Event &event); + +protected: + float m_time; + float m_lastMotorParticule; + BOOL m_bDisplayInfo; + BOOL m_bQuickPos; + BOOL m_bStartAction; + float m_speedAction; + float m_clownRadius; + float m_clownDelay; + float m_clownTime; + float m_blinkTime; + float m_blinkProgress; + int m_soundChannel; + ObjectType m_type; + FPOINT m_mousePos; +}; + + +#endif //_MOTIONTOTO_H_ diff --git a/src/object/motion/motionvehicle.cpp b/src/object/motion/motionvehicle.cpp new file mode 100644 index 0000000..73dae74 --- /dev/null +++ b/src/object/motion/motionvehicle.cpp @@ -0,0 +1,2091 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionvehicle.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "light.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "modfile.h" +#include "sound.h" +#include "motion.h" +#include "motionvehicle.h" + + + +#define ARM_NEUTRAL_ANGLE1 110.0f*PI/180.0f +#define ARM_NEUTRAL_ANGLE2 -130.0f*PI/180.0f +#define ARM_NEUTRAL_ANGLE3 -50.0f*PI/180.0f + + + +// Object's constructor. + +CMotionVehicle::CMotionVehicle(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + int i; + + CMotion::CMotion(iMan, object); + + for ( i=0 ; i<4 ; i++ ) + { + m_wheelTurn[i] = 0.0f; + } + for ( i=0 ; i<3 ; i++ ) + { + m_flyPaw[i] = 0.0f; + } + m_posTrackLeft = 0.0f; + m_posTrackRight = 0.0f; + m_partiReactor = -1; + m_armTimeAbs = 1000.0f; + m_armMember = 1000.0f; + m_canonTime = 0.0f; + m_lastTimeCanon = 0.0f; + m_wheelLastPos = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_wheelLastAngle = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_posKey = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_bFlyFix = FALSE; + + m_bTraceDown = FALSE; + m_traceColor = 1; // black + m_traceWidth = 0.5f; +} + +// Object's destructor. + +CMotionVehicle::~CMotionVehicle() +{ +} + + +// Removes an object. + +void CMotionVehicle::DeleteObject(BOOL bAll) +{ + if ( m_partiReactor != -1 ) + { + m_particule->DeleteParticule(m_partiReactor); + m_partiReactor = -1; + } +} + + +// Creates a vehicle traveling any lands on the ground. + +BOOL CMotionVehicle::Create(D3DVECTOR pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + CObject* pPower; + int rank, i, j, parent; + D3DCOLORVALUE color; + char name[50]; + + if ( m_engine->RetRestCreate() < 1+5+18+1 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + + // Creates the main base. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEfs ) + { + pModFile->ReadModel("objects\\lem1f.mod"); + } + if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts ) + { + pModFile->ReadModel("objects\\lem1t.mod"); + } + if ( type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEws ) + { + if ( m_object->RetTrainer() ) + { + pModFile->ReadModel("objects\\lem1wt.mod"); + } + else + { + pModFile->ReadModel("objects\\lem1w.mod"); + } + } + if ( type == OBJECT_MOBILEia || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEis ) + { + pModFile->ReadModel("objects\\lem1i.mod"); + } + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) + { + pModFile->ReadModel("objects\\roller1.mod"); + } + if ( type == OBJECT_MOBILEsa ) + { + pModFile->ReadModel("objects\\subm1.mod"); + } + if ( type == OBJECT_MOBILEtg ) + { + pModFile->ReadModel("objects\\target.mod"); + } + if ( type == OBJECT_MOBILEwt ) + { + pModFile->ReadModel("objects\\trainerw.mod"); + } + if ( type == OBJECT_MOBILEft ) + { + pModFile->ReadModel("objects\\trainerf.mod"); + } + if ( type == OBJECT_MOBILEtt ) + { + pModFile->ReadModel("objects\\trainert.mod"); + } + if ( type == OBJECT_MOBILEit ) + { + pModFile->ReadModel("objects\\traineri.mod"); + } + if ( type == OBJECT_MOBILEdr ) + { + pModFile->ReadModel("objects\\drawer1.mod"); + } + if ( type == OBJECT_APOLLO2 ) + { + pModFile->ReadModel("objects\\apolloj1.mod"); + } + pModFile->CreateEngineObject(rank); + + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // A vehicle must have a obligatory collision + // with a sphere of center (0, y, 0) (see GetCrashSphere). + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) + { + m_object->CreateCrashSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 6.5f, SOUND_BOUMm, 0.45f); + m_object->SetGlobalSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 7.0f); + } + else if ( type == OBJECT_MOBILEsa ) + { + m_object->CreateCrashSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f); + m_object->SetGlobalSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 6.0f); + } + else if ( type == OBJECT_MOBILEdr ) + { + m_object->CreateCrashSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + m_object->SetGlobalSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 7.0f); + } + else if ( type == OBJECT_APOLLO2 ) + { + m_object->CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 8.0f, SOUND_BOUMm, 0.45f); + } + else + { + m_object->CreateCrashSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f); + m_object->SetGlobalSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 6.0f); + } + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia ) + { + // Creates the arm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\lem2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(0.0f, 5.3f, 0.0f)); + m_object->SetAngleZ(1, ARM_NEUTRAL_ANGLE1); + + // Creates the forearm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 1); + pModFile->ReadModel("objects\\lem3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, D3DVECTOR(5.0f, 0.0f, 0.0f)); + m_object->SetAngleZ(2, ARM_NEUTRAL_ANGLE2); + + // Creates the hand. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 2); + pModFile->ReadModel("objects\\lem4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, D3DVECTOR(3.5f, 0.0f, 0.0f)); + m_object->SetAngleZ(3, ARM_NEUTRAL_ANGLE3); + m_object->SetAngleX(3, PI/2.0f); + + // Creates the close clamp. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(4, rank); + m_object->SetObjectParent(4, 3); + pModFile->ReadModel("objects\\lem5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(4, D3DVECTOR(1.5f, 0.0f, 0.0f)); + m_object->SetAngleZ(4, -PI*0.10f); + + // Creates the remote clamp. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(5, rank); + m_object->SetObjectParent(5, 3); + pModFile->ReadModel("objects\\lem6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(5, D3DVECTOR(1.5f, 0.0f, 0.0f)); + m_object->SetAngleZ(5, PI*0.10f); + } + + if ( type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis ) + { + // Creates the arm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\lem2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(0.0f, 5.3f, 0.0f)); + m_object->SetAngleZ(1, 110.0f*PI/180.0f); + + // Creates the forearm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 1); + pModFile->ReadModel("objects\\lem3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, D3DVECTOR(5.0f, 0.0f, 0.0f)); + m_object->SetAngleZ(2, -110.0f*PI/180.0f); + + // Creates the sensor. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 2); + pModFile->ReadModel("objects\\lem4s.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, D3DVECTOR(3.5f, 0.0f, 0.0f)); + m_object->SetAngleZ(3, -65.0f*PI/180.0f); + } + + if ( type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic ) + { + // Creates the cannon. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\canon.mod"); + pModFile->CreateEngineObject(rank); +//? m_object->SetPosition(1, D3DVECTOR(0.0f, 5.3f, 0.0f)); + m_object->SetPosition(1, D3DVECTOR(0.0f, 5.3f, 0.0f)); + m_object->SetAngleZ(1, 0.0f); + } + + if ( type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii ) + { + // Creates the insect cannon. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\canoni1.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(0.0f, 5.3f, 0.0f)); + m_object->SetAngleZ(1, 0.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 1); + pModFile->ReadModel("objects\\canoni2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, D3DVECTOR(0.0f, 2.5f, 0.0f)); + m_object->SetAngleZ(2, 0.0f); + } + + if ( type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEwt ) + { + // Creates the right-back wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, D3DVECTOR(-3.0f, 1.0f, -3.0f)); + + // Creates the left-back wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, D3DVECTOR(-3.0f, 1.0f, 3.0f)); + m_object->SetAngleY(7, PI); + + // Creates the right-front wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, D3DVECTOR(2.0f, 1.0f, -3.0f)); + + // Creates the left-front wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, D3DVECTOR(2.0f, 1.0f, 3.0f)); + m_object->SetAngleY(9, PI); + } + + if ( type == OBJECT_MOBILEtg ) + { + // Creates the right-back wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, D3DVECTOR(-2.0f, 1.0f, -3.0f)); + + // Creates the left-back wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, D3DVECTOR(-2.0f, 1.0f, 3.0f)); + m_object->SetAngleY(7, PI); + + // Creates the right-front wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, D3DVECTOR(3.0f, 1.0f, -3.0f)); + + // Creates the left-front wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, D3DVECTOR(3.0f, 1.0f, 3.0f)); + m_object->SetAngleY(9, PI); + } + + if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts ) // caterpillars? + { + // Creates the right caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\lem2t.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, D3DVECTOR(0.0f, 2.0f, -3.0f)); + + // Creates the left caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\lem3t.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, D3DVECTOR(0.0f, 2.0f, 3.0f)); + } + + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) // large caterpillars? + { + // Creates the right caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\roller2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, D3DVECTOR(0.0f, 2.0f, -3.0f)); + + // Creates the left caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\roller3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, D3DVECTOR(0.0f, 2.0f, 3.0f)); + } + + if ( type == OBJECT_MOBILEsa ) // underwater caterpillars? + { + // Creates the right caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\subm4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, D3DVECTOR(0.0f, 1.0f, -3.0f)); + + // Creates the left caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\subm5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, D3DVECTOR(0.0f, 1.0f, 3.0f)); + } + + if ( type == OBJECT_MOBILEdr ) // caterpillars? + { + // Creates the right caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\drawer2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, D3DVECTOR(0.0f, 1.0f, -3.0f)); + + // Creates the left caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\drawer3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, D3DVECTOR(0.0f, 1.0f, 3.0f)); + } + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEft ) // flying? + { + // Creates the front foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\lem2f.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, D3DVECTOR(1.7f, 3.0f, 0.0f)); + + // Creates the right-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\lem2f.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, D3DVECTOR(-1.8f, 3.0f, -1.5f)); + m_object->SetAngleY(7, 120.0f*PI/180.0f); + + // Creates the left-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 0); + pModFile->ReadModel("objects\\lem2f.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, D3DVECTOR(-1.8f, 3.0f, 1.5f)); + m_object->SetAngleY(8, -120.0f*PI/180.0f); + } + + if ( type == OBJECT_MOBILEia || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILEii ) // insect legs? + { + float table[] = + { + // x y z + -1.5f, 1.2f, -0.7f, // back leg + 0.0f, 0.0f, -1.0f, + 0.0f, 0.0f, -2.0f, + + 0.0f, 1.2f, -0.9f, // middle leg + 0.0f, 0.0f, -1.0f, + 0.0f, 0.0f, -2.0f, + + 1.5f, 1.2f, -0.7f, // front leg + 0.0f, 0.0f, -1.0f, + 0.0f, 0.0f, -2.0f, + }; + + for ( i=0 ; i<3 ; i++ ) + { + for ( j=0 ; j<3 ; j++ ) + { + sprintf(name, "objects\\ant%d.mod", j+4); // 4..6 + + // Creates the right leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6+i*3+j, rank); + if ( j == 0 ) parent = 0; + else parent = 6+i*3+j-1; + m_object->SetObjectParent(6+i*3+j, parent); + pModFile->ReadModel(name); + pModFile->CreateEngineObject(rank); + pos.x = table[i*9+j*3+0]; + pos.y = table[i*9+j*3+1]; + pos.z = table[i*9+j*3+2]; + m_object->SetPosition(6+i*3+j, pos); + + // Creates the left leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(15+i*3+j, rank); + if ( j == 0 ) parent = 0; + else parent = 15+i*3+j-1; + m_object->SetObjectParent(15+i*3+j, parent); + pModFile->ReadModel(name); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + pos.x = table[i*9+j*3+0]; + pos.y = table[i*9+j*3+1]; + pos.z = -table[i*9+j*3+2]; + m_object->SetPosition(15+i*3+j, pos); + } + } + } + + if ( type == OBJECT_MOBILErt ) + { + // Creates the holder. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\roller2t.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(0.0f, 0.0f, 0.0f)); + m_object->SetAngleZ(1, 0.0f); + + // Creates the pestle. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\roller3t.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, D3DVECTOR(9.0f, 4.0f, 0.0f)); + m_object->SetAngleZ(2, 0.0f); + } + + if ( type == OBJECT_MOBILErc ) + { + // Creates the holder. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\roller2c.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(3.0f, 4.6f, 0.0f)); + m_object->SetAngleZ(1, PI/8.0f); + + // Creates the cannon. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\roller3p.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, D3DVECTOR(7.0f, 6.5f, 0.0f)); + m_object->SetAngleZ(2, 0.0f); + } + + if ( type == OBJECT_MOBILErr ) + { + // Creates the holder. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\recover1.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(2.0f, 5.0f, 0.0f)); + + // Creates the right arm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 1); + pModFile->ReadModel("objects\\recover2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, D3DVECTOR(0.1f, 0.0f, -5.0f)); + m_object->SetAngleZ(2, 126.0f*PI/180.0f); + + // Creates the right forearm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 2); + pModFile->ReadModel("objects\\recover3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, D3DVECTOR(5.0f, 0.0f, -0.5f)); + m_object->SetAngleZ(3, -144.0f*PI/180.0f); + + // Creates the left arm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(4, rank); + m_object->SetObjectParent(4, 1); + pModFile->ReadModel("objects\\recover2.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(4, D3DVECTOR(0.1f, 0.0f, 5.0f)); + m_object->SetAngleZ(4, 126.0f*PI/180.0f); + + // Creates the left forearm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(5, rank); + m_object->SetObjectParent(5, 4); + pModFile->ReadModel("objects\\recover3.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(5, D3DVECTOR(5.0f, 0.0f, 0.5f)); + m_object->SetAngleZ(5, -144.0f*PI/180.0f); + } + + if ( type == OBJECT_MOBILErs ) + { + // Creates the holder. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\roller2s.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(0.0f, 0.0f, 0.0f)); + m_object->SetAngleZ(1, 0.0f); + + // Creates the intermediate piston. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 1); + pModFile->ReadModel("objects\\roller3s.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, D3DVECTOR(7.0f, 4.5f, 0.0f)); + m_object->SetAngleZ(2, 0.0f); + + // Creates the piston with the sphere. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 2); + pModFile->ReadModel("objects\\roller4s.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, D3DVECTOR(0.0f, 1.0f, 0.0f)); + m_object->SetAngleZ(3, 0.0f); + } + + if ( type == OBJECT_MOBILEsa ) + { + // Creates the holder. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\subm2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(4.2f, 3.0f, 0.0f)); + + // Creates the right tong. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 1); + pModFile->ReadModel("objects\\subm3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, D3DVECTOR(0.5f, 0.0f, -1.5f)); + + // Creates the left tong. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 1); + pModFile->ReadModel("objects\\subm3.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, D3DVECTOR(0.5f, 0.0f, 1.5f)); + } + + if ( type == OBJECT_MOBILEdr ) + { + // Creates the carousel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\drawer4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(-3.0f, 3.0f, 0.0f)); + + // Creates the key. + if ( m_object->RetToy() ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\drawer5.mod"); + pModFile->CreateEngineObject(rank); + m_posKey = D3DVECTOR(3.0f, 5.7f, 0.0f); + m_object->SetPosition(2, m_posKey); + m_object->SetAngleY(2, 90.0f*PI/180.0f); + } + + // Creates pencils. + for ( i=0 ; i<8 ; i++ ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(10+i, rank); + m_object->SetObjectParent(10+i, 1); + sprintf(name, "objects\\drawer%d.mod", 10+i); + pModFile->ReadModel(name); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(10+i, D3DVECTOR(0.0f, 0.0f, 0.0f)); + m_object->SetAngleY(10+i, 45.0f*PI/180.0f*i); + } + } + + if ( type == OBJECT_MOBILEwt ) + { + // Creates the key. + if ( m_object->RetToy() ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\drawer5.mod"); + pModFile->CreateEngineObject(rank); + m_posKey = D3DVECTOR(0.2f, 4.1f, 0.0f); + m_object->SetPosition(2, m_posKey); + m_object->SetAngleY(2, 90.0f*PI/180.0f); + } + } + + if ( type == OBJECT_APOLLO2 ) + { + // Creates the accessories. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\apolloj2.mod"); // antenna + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(5.5f, 8.8f, 2.0f)); + m_object->SetAngleY(1, -120.0f*PI/180.0f); + m_object->SetAngleZ(1, 45.0f*PI/180.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\apolloj3.mod"); // camera + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, D3DVECTOR(5.5f, 2.8f, -2.0f)); + m_object->SetAngleY(2, 30.0f*PI/180.0f); + + // Creates the wheels. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\apolloj4.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, D3DVECTOR(-5.75f, 1.65f, -5.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\apolloj4.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, D3DVECTOR(-5.75f, 1.65f, 5.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 0); + pModFile->ReadModel("objects\\apolloj4.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, D3DVECTOR(5.75f, 1.65f, -5.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 0); + pModFile->ReadModel("objects\\apolloj4.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, D3DVECTOR(5.75f, 1.65f, 5.00f)); + + // Creates mud guards. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(10, rank); + m_object->SetObjectParent(10, 0); + pModFile->ReadModel("objects\\apolloj6.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(10, D3DVECTOR(-5.75f, 1.65f, -5.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(11, rank); + m_object->SetObjectParent(11, 0); + pModFile->ReadModel("objects\\apolloj6.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(11, D3DVECTOR(-5.75f, 1.65f, 5.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(12, rank); + m_object->SetObjectParent(12, 0); + pModFile->ReadModel("objects\\apolloj5.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(12, D3DVECTOR(5.75f, 1.65f, -5.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(13, rank); + m_object->SetObjectParent(13, 0); + pModFile->ReadModel("objects\\apolloj5.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(13, D3DVECTOR(5.75f, 1.65f, 5.00f)); + } + +#if 1 + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) + { + m_object->CreateShadowCircle(6.0f, 1.0f); + } + else if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEsa ) + { + m_object->CreateShadowCircle(5.0f, 1.0f); + } + else if ( type == OBJECT_MOBILEdr ) + { + m_object->CreateShadowCircle(4.5f, 1.0f); + } + else if ( type == OBJECT_APOLLO2 ) + { + m_object->CreateShadowCircle(7.0f, 0.8f); + } + else + { + m_object->CreateShadowCircle(4.0f, 1.0f); + } +#else + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) + { + m_object->CreateShadowCircle(6.0f, 1.0f, D3DSHADOWTANK); + } + else if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts ) + { + m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWTANK); + } + else if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEfs ) + { + m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWFLY); + } + else if ( type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEws ) + { + m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWWHEEL); + } + else if ( type == OBJECT_APOLLO2 ) + { + m_object->CreateShadowCircle(6.0f, 0.8f); + } + else + { + m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWNORM); + } +#endif + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEft ) // flying? + { +//? color.r = 0.5f-1.0f; +//? color.g = 0.2f-1.0f; +//? color.b = 0.0f-1.0f; // orange +//? color.r = 0.8f; +//? color.g = 0.6f; +//? color.b = 0.0f; // yellow-orange + color.r = 0.0f; + color.g = 0.4f; + color.b = 0.8f; // blue + color.a = 0.0f; + m_object->CreateShadowLight(50.0f, color); + } + + CreatePhysics(type); + m_object->SetFloorHeight(0.0f); + + if ( power > 0.0f && + type != OBJECT_MOBILEdr && + type != OBJECT_APOLLO2 ) + { + color.r = 1.0f; + color.g = 1.0f; + color.b = 0.0f; // yellow + color.a = 0.0f; + m_object->CreateEffectLight(20.0f, color); + + // Creates the battery. + pPower = new CObject(m_iMan); + pPower->SetType(power<=1.0f?OBJECT_POWER:OBJECT_ATOMIC); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + pPower->SetObjectRank(0, rank); + + if ( power <= 1.0f ) pModFile->ReadModel("objects\\power.mod"); + else pModFile->ReadModel("objects\\atomic.mod"); + pModFile->CreateEngineObject(rank); + + pPower->SetPosition(0, m_object->RetCharacter()->posPower); + pPower->CreateCrashSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + pPower->SetGlobalSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 1.5f); + + pPower->SetTruck(m_object); + m_object->SetPower(pPower); + + if ( power <= 1.0f ) pPower->SetEnergy(power); + else pPower->SetEnergy(power/100.0f); + } + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); //to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return TRUE; +} + +// Creates the physics of the object. + +void CMotionVehicle::CreatePhysics(ObjectType type) +{ + Character* character; + + character = m_object->RetCharacter(); + + if ( type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEwt ) // wheels? + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 3.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 4.0f; + character->wheelRight = 4.0f; + character->posPower = D3DVECTOR(-3.2f, 3.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 20.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 10.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 40.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 50.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 30.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 20.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.8f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.8f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 8.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 8.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 12.0f); + } + + if ( type == OBJECT_MOBILEtg ) + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 4.0f; + character->wheelBack = 3.0f; + character->wheelLeft = 4.0f; + character->wheelRight = 4.0f; + character->posPower = D3DVECTOR(-3.2f, 3.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 20.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 10.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 40.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 50.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 20.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 20.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.8f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.8f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 10.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 15.0f); + } + + if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts ) // caterpillars? + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 4.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 4.8f; + character->wheelRight = 4.8f; + character->posPower = D3DVECTOR(-3.2f, 3.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 8.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 15.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 8.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 20.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 10.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 6.0f); + } + + if ( type == OBJECT_MOBILEia || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEis ) // legs? + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 4.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 5.0f; + character->wheelRight = 5.0f; + character->posPower = D3DVECTOR(-3.2f, 3.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 8.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 40.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 10.0f); +//? m_physics->SetLinMotionX(MO_TERFORCE, 15.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 10.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 15.0f); + } + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEft ) // flying? + { + m_physics->SetType(TYPE_FLYING); + + character->wheelFront = 5.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 4.5f; + character->wheelRight = 4.5f; + character->posPower = D3DVECTOR(-3.2f, 3.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 50.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 50.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 20.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 50.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 50.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f); + m_physics->SetLinMotionY(MO_RECSPEED, 60.0f); + m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionY(MO_RECACCEL, 50.0f); + m_physics->SetLinMotionY(MO_STOACCEL, 50.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.4f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.4f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 2.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 2.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 2.0f); + } + + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) // large caterpillars? + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 5.0f; + character->wheelBack = 5.0f; + character->wheelLeft = 6.0f; + character->wheelRight = 6.0f; + character->posPower = D3DVECTOR(-5.8f, 4.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 10.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 5.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 10.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 5.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 20.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.3f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.3f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 2.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 2.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 4.0f); + } + + if ( type == OBJECT_MOBILEsa ) + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 4.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 4.0f; + character->wheelRight = 4.0f; + character->posPower = D3DVECTOR(-5.0f, 3.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 10.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 10.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 20.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 5.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 5.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 10.0f); + } + + if ( type == OBJECT_MOBILEdr ) + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 4.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 4.0f; + character->wheelRight = 4.0f; + character->posPower = D3DVECTOR(-5.0f, 3.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 10.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 10.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 20.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 5.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 5.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 10.0f); + } + + if ( type == OBJECT_APOLLO2 ) // jeep? + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 6.0f; + character->wheelBack = 6.0f; + character->wheelLeft = 5.0f; + character->wheelRight = 5.0f; + + m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 10.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 2.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 2.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 30.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 20.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.4f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.4f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 2.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 2.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 4.0f); + } +} + + +// Management of an event. + +BOOL CMotionVehicle::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { + } + + return TRUE; +} + +// Management of an event. + +BOOL CMotionVehicle::EventFrame(const Event &event) +{ + D3DMATRIX* mat; + Character* character; + D3DVECTOR pos, angle, floor; + ObjectType type; + float s, a, speedBL, speedBR, speedFL, speedFR, h, a1, a2; + float back, front, dist, radius, limit[2]; + + if ( m_engine->RetPause() ) return TRUE; + if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return TRUE; + + type = m_object->RetType(); + + if ( type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEtg || + type == OBJECT_APOLLO2 ) // wheels? + { + s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.0f; + a = m_physics->RetCirMotionY(MO_MOTSPEED)*3.0f; + + if ( type == OBJECT_APOLLO2 ) s *= 0.5f; + + speedBR = -s+a; + speedBL = s+a; + speedFR = -s+a; + speedFL = s+a; + + m_object->SetAngleZ(6, m_object->RetAngleZ(6)+event.rTime*speedBR); // turning the wheels + m_object->SetAngleZ(7, m_object->RetAngleZ(7)+event.rTime*speedBL); + m_object->SetAngleZ(8, m_object->RetAngleZ(8)+event.rTime*speedFR); + m_object->SetAngleZ(9, m_object->RetAngleZ(9)+event.rTime*speedFL); + + if ( s > 0.0f ) + { + m_wheelTurn[0] = -a*0.05f; + m_wheelTurn[1] = -a*0.05f+PI; + m_wheelTurn[2] = a*0.05f; + m_wheelTurn[3] = a*0.05f+PI; + } + else if ( s < 0.0f ) + { + m_wheelTurn[0] = a*0.05f; + m_wheelTurn[1] = a*0.05f+PI; + m_wheelTurn[2] = -a*0.05f; + m_wheelTurn[3] = -a*0.05f+PI; + } + else + { + m_wheelTurn[0] = Abs(a)*0.05f; + m_wheelTurn[1] = -Abs(a)*0.05f+PI; + m_wheelTurn[2] = -Abs(a)*0.05f; + m_wheelTurn[3] = Abs(a)*0.05f+PI; + } + m_object->SetAngleY(6, m_object->RetAngleY(6)+(m_wheelTurn[0]-m_object->RetAngleY(6))*event.rTime*8.0f); + m_object->SetAngleY(7, m_object->RetAngleY(7)+(m_wheelTurn[1]-m_object->RetAngleY(7))*event.rTime*8.0f); + m_object->SetAngleY(8, m_object->RetAngleY(8)+(m_wheelTurn[2]-m_object->RetAngleY(8))*event.rTime*8.0f); + m_object->SetAngleY(9, m_object->RetAngleY(9)+(m_wheelTurn[3]-m_object->RetAngleY(9))*event.rTime*8.0f); + + if ( type == OBJECT_APOLLO2 ) + { + m_object->SetAngleY(10, m_object->RetAngleY(6)+(m_wheelTurn[0]-m_object->RetAngleY(6))*event.rTime*8.0f); + m_object->SetAngleY(11, m_object->RetAngleY(7)+(m_wheelTurn[1]-m_object->RetAngleY(7))*event.rTime*8.0f+PI); + m_object->SetAngleY(12, m_object->RetAngleY(8)+(m_wheelTurn[2]-m_object->RetAngleY(8))*event.rTime*8.0f); + m_object->SetAngleY(13, m_object->RetAngleY(9)+(m_wheelTurn[3]-m_object->RetAngleY(9))*event.rTime*8.0f+PI); + } + + pos = m_object->RetPosition(0); + angle = m_object->RetAngle(0); + if ( pos.x != m_wheelLastPos.x || + pos.y != m_wheelLastPos.y || + pos.z != m_wheelLastPos.z || + angle.x != m_wheelLastAngle.x || + angle.y != m_wheelLastAngle.y || + angle.z != m_wheelLastAngle.z ) + { + m_wheelLastPos = pos; + m_wheelLastAngle = angle; + + if ( type == OBJECT_MOBILEtg ) + { + back = -2.0f; // back wheels position + front = 3.0f; // front wheels position + dist = 3.0f; // distancing wheels Z + radius = 1.0f; + } + else if ( type == OBJECT_APOLLO2 ) + { + back = -5.75f; // back wheels position + front = 5.75f; // front wheels position + dist = 5.00f; // distancing wheels Z + radius = 1.65f; + } + else + { + back = -3.0f; // back wheels position + front = 2.0f; // front wheels position + dist = 3.0f; // distancing wheels Z + radius = 1.0f; + } + + if ( Length(pos, m_engine->RetEyePt()) < 50.0f ) // suspension? + { + character = m_object->RetCharacter(); + mat = m_object->RetWorldMatrix(0); + + pos.x = -character->wheelBack; // right back wheel + pos.z = -character->wheelRight; + pos.y = 0.0f; + pos = Transform(*mat, pos); + h = m_terrain->RetFloorHeight(pos); + if ( h > 0.5f ) h = 0.5f; + if ( h < -0.5f ) h = -0.5f; + pos.x = back; + pos.y = radius-h; + pos.z = -dist; + m_object->SetPosition(6, pos); + if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(10, pos); + + pos.x = -character->wheelBack; // left back wheel + pos.z = character->wheelLeft; + pos.y = 0.0f; + pos = Transform(*mat, pos); + h = m_terrain->RetFloorHeight(pos); + if ( h > 0.5f ) h = 0.5f; + if ( h < -0.5f ) h = -0.5f; + pos.x = back; + pos.y = radius-h; + pos.z = dist; + m_object->SetPosition(7, pos); + if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(11, pos); + + pos.x = character->wheelFront; // right front wheel + pos.z = -character->wheelRight; + pos.y = 0.0f; + pos = Transform(*mat, pos); + h = m_terrain->RetFloorHeight(pos); + if ( h > 0.5f ) h = 0.5f; + if ( h < -0.5f ) h = -0.5f; + pos.x = front; + pos.y = radius-h; + pos.z = -dist; + m_object->SetPosition(8, pos); + if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(12, pos); + + pos.x = character->wheelFront; // left front wheel + pos.z = character->wheelLeft; + pos.y = 0.0f; + pos = Transform(*mat, pos); + h = m_terrain->RetFloorHeight(pos); + if ( h > 0.5f ) h = 0.5f; + if ( h < -0.5f ) h = -0.5f; + pos.x = front; + pos.y = radius-h; + pos.z = dist; + m_object->SetPosition(9, pos); + if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(13, pos); + } + else + { + m_object->SetPosition(6, D3DVECTOR(back, radius, -dist)); + m_object->SetPosition(7, D3DVECTOR(back, radius, dist)); + m_object->SetPosition(8, D3DVECTOR(front, radius, -dist)); + m_object->SetPosition(9, D3DVECTOR(front, radius, dist)); + + if ( type == OBJECT_APOLLO2 ) + { + m_object->SetPosition(10, D3DVECTOR(back, radius, -dist)); + m_object->SetPosition(11, D3DVECTOR(back, radius, dist)); + m_object->SetPosition(12, D3DVECTOR(front, radius, -dist)); + m_object->SetPosition(13, D3DVECTOR(front, radius, dist)); + } + } + } + } + + if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEdr ) // caterpillars? + { + s = m_physics->RetLinMotionX(MO_MOTSPEED)*0.7f; + a = m_physics->RetCirMotionY(MO_MOTSPEED)*2.5f; + + m_posTrackLeft += event.rTime*(s+a); + m_posTrackRight += event.rTime*(s-a); + + UpdateTrackMapping(m_posTrackLeft, m_posTrackRight, type); + + pos = m_object->RetPosition(0); + angle = m_object->RetAngle(0); + if ( pos.x != m_wheelLastPos.x || + pos.y != m_wheelLastPos.y || + pos.z != m_wheelLastPos.z || + angle.x != m_wheelLastAngle.x || + angle.y != m_wheelLastAngle.y || + angle.z != m_wheelLastAngle.z ) + { + m_wheelLastPos = pos; + m_wheelLastAngle = angle; + + if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts ) + { + limit[0] = 8.0f*PI/180.0f; + limit[1] = -12.0f*PI/180.0f; + } + else if ( type == OBJECT_MOBILEsa ) + { + limit[0] = 15.0f*PI/180.0f; + limit[1] = -15.0f*PI/180.0f; + } + else if ( type == OBJECT_MOBILEdr ) + { + limit[0] = 10.0f*PI/180.0f; + limit[1] = -10.0f*PI/180.0f; + } + else + { + limit[0] = 15.0f*PI/180.0f; + limit[1] = -10.0f*PI/180.0f; + } + + if ( Length(pos, m_engine->RetEyePt()) < 50.0f ) // suspension? + { + character = m_object->RetCharacter(); + mat = m_object->RetWorldMatrix(0); + + pos.x = character->wheelFront; // right front wheel + pos.z = -character->wheelRight; + pos.y = 0.0f; + pos = Transform(*mat, pos); + a1 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelFront); + + pos.x = -character->wheelBack; // right back wheel + pos.z = -character->wheelRight; + pos.y = 0.0f; + pos = Transform(*mat, pos); + a2 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelBack); + + a = (a2-a1)/2.0f; + if ( a > limit[0] ) a = limit[0]; + if ( a < limit[1] ) a = limit[1]; + m_object->SetAngleZ(6, a); + + pos.x = character->wheelFront; // left front wheel + pos.z = character->wheelLeft; + pos.y = 0.0f; + pos = Transform(*mat, pos); + a1 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelFront); + + pos.x = -character->wheelBack; // left back wheel + pos.z = character->wheelLeft; + pos.y = 0.0f; + pos = Transform(*mat, pos); + a2 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelBack); + + a = (a2-a1)/2.0f; + if ( a > limit[0] ) a = limit[0]; + if ( a < limit[1] ) a = limit[1]; + m_object->SetAngleZ(7, a); + } + else + { + m_object->SetAngleZ(6, 0.0f); + m_object->SetAngleZ(7, 0.0f); + } + } + } + + if ( type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEdr ) // toy is key? + { + pos = m_posKey; + if ( m_object->RetSelect() && + m_camera->RetType() == CAMERA_ONBOARD ) + { + pos.y += 10.0f; // out of sight! + } + m_object->SetPosition(2, pos); + + s = -Abs(m_physics->RetLinMotionX(MO_MOTSPEED)*0.1f); + s += -Abs(m_physics->RetCirMotionY(MO_MOTSPEED)*1.5f); + m_object->SetAngleY(2, m_object->RetAngleY(2)+event.rTime*s); // turns the key + } + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEft ) // flying? + { + EventFrameFly(event); + } + + if ( type == OBJECT_MOBILEia || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEis ) // legs? + { + EventFrameInsect(event); + } + + if ( type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEii ) // insect cannon? + { + EventFrameCanoni(event); + } + + return TRUE; +} + +// Managing an event for a flying robot. + +BOOL CMotionVehicle::EventFrameFly(const Event &event) +{ + D3DMATRIX* mat; + D3DVECTOR pos, angle, paw[3]; + float hope[3], actual, final, h, a; + int i; + + pos = m_object->RetPosition(0); + angle = m_object->RetAngle(0); + if ( m_bFlyFix && + pos.x == m_wheelLastPos.x && + pos.y == m_wheelLastPos.y && + pos.z == m_wheelLastPos.z && + angle.x == m_wheelLastAngle.x && + angle.y == m_wheelLastAngle.y && + angle.z == m_wheelLastAngle.z ) return TRUE; + + m_wheelLastPos = pos; + m_wheelLastAngle = angle; + + if ( m_physics->RetLand() ) // on the ground? + { + mat = m_object->RetWorldMatrix(0); + paw[0] = Transform(*mat, D3DVECTOR( 4.2f, 0.0f, 0.0f)); // front + paw[1] = Transform(*mat, D3DVECTOR(-3.0f, 0.0f, -3.7f)); // right back + paw[2] = Transform(*mat, D3DVECTOR(-3.0f, 0.0f, 3.7f)); // left back + + for ( i=0 ; i<3 ; i++ ) + { + h = m_terrain->RetFloorHeight(paw[i]); + a = -atanf(h*0.5f); + if ( a > PI*0.2f ) a = PI*0.2f; + if ( a < -PI*0.2f ) a = -PI*0.2f; + hope[i] = a; + } + } + else // in flight? + { + hope[0] = 0.0f; // front + hope[1] = 0.0f; // right back + hope[2] = 0.0f; // left back + } + + m_bFlyFix = TRUE; + for ( i=0 ; i<3 ; i++ ) + { + actual = m_object->RetAngleZ(6+i); + final = Smooth(actual, hope[i], event.rTime*5.0f); + if ( final != actual ) + { + m_bFlyFix = FALSE; // it is moving + m_object->SetAngleZ(6+i, final); + } + } + + return TRUE; +} + +// Event management for insect legs. + +BOOL CMotionVehicle::EventFrameInsect(const Event &event) +{ + D3DVECTOR dir; + float s, a, prog, time; + int i, st, nd, action; + BOOL bStop, bOnBoard; + + static int table[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 60,25,0, 60,0,0, 60,-25,0, // t0: thighs 1..4 + -35,0,0, -35,0,0, -35,0,0, // t0: legs 1..4 + -65,0,0, -65,0,0, -65,0,0, // t0: feet 1..4 + // on the ground: + 30,10,0, 30,-15,0, 30,-40,0, // t1: thighs 1..4 + -45,0,0, -45,0,0, -45,0,0, // t1: legs 1..4 + -20,0,0, -20,0,0, -20,0,0, // t1: feet 1..4 + // on the ground back: + 35,40,0, 40,15,0, 40,-10,0, // t2: thighs 1..4 + -35,0,0, -35,0,0, -35,0,0, // t2: legs 1..4 + -50,0,0, -65,0,0, -65,0,0, // t2: feet 1..4 + // stop: + 35,35,0, 40,10,0, 40,-15,0, // s0: thighs 1..4 + -35,0,0, -35,0,0, -35,0,0, // s0: legs 1..4 + -50,0,0, -65,0,0, -65,0,0, // s0: feet 1..4 + }; + + bOnBoard = FALSE; + if ( m_object->RetSelect() && + m_camera->RetType() == CAMERA_ONBOARD ) + { + bOnBoard = TRUE; + } + + s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f; + a = Abs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.0f); + + if ( s == 0.0f && a != 0.0f ) a *= 1.5f; + + m_armTimeAbs += event.rTime; + m_armMember += (s+a)*event.rTime*0.15f; + + bStop = ( a == 0.0f && s == 0.0f ); // stop? + + action = 0; // walking + if ( s == 0.0f && a == 0.0f ) + { + action = 3; // stop + } + + if ( bStop ) + { + prog = Mod(m_armTimeAbs, 2.0f)/10.0f; + a = Mod(m_armMember, 1.0f); + a = (prog-a)*event.rTime*2.0f; // stop position is pleasantly + m_armMember += a; + } + + if ( m_object->RetRuin() ) // burn or explode? + { + action = 3; + } + + for ( i=0 ; i<6 ; i++ ) // the six legs + { + if ( action != 0 ) // special action in progress? + { + st = 3*3*3*action + (i%3)*3; + nd = st; + time = event.rTime*5.0f; + } + else + { + if ( i < 3 ) prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f); + else prog = Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f); + if ( prog < 0.33f ) // t0..t1 ? + { + prog = prog/0.33f; // 0..1 + st = 0; // index start + nd = 1; // index end + } + else if ( prog < 0.67f ) // t1..t2 ? + { + prog = (prog-0.33f)/0.33f; // 0..1 + st = 1; // index start + nd = 2; // index end + } + else // t2..t0 ? + { + prog = (prog-0.67f)/0.33f; // 0..1 + st = 2; // index start + nd = 0; // index end + } + st = 3*3*3*action + st*3*3*3 + (i%3)*3; + nd = 3*3*3*action + nd*3*3*3 + (i%3)*3; + + // Less and less soft ... + time = event.rTime*20.0f; + } + + if ( i < 3 ) // right leg (1..3) ? + { + m_object->SetAngleX(6+3*i+0, Smooth(m_object->RetAngleX(6+3*i+0), Prop(table[st+ 0], table[nd+ 0], prog), time)); + m_object->SetAngleY(6+3*i+0, Smooth(m_object->RetAngleY(6+3*i+0), Prop(table[st+ 1], table[nd+ 1], prog), time)); + m_object->SetAngleZ(6+3*i+0, Smooth(m_object->RetAngleZ(6+3*i+0), Prop(table[st+ 2], table[nd+ 2], prog), time)); + m_object->SetAngleX(6+3*i+1, Smooth(m_object->RetAngleX(6+3*i+1), Prop(table[st+ 9], table[nd+ 9], prog), time)); + m_object->SetAngleY(6+3*i+1, Smooth(m_object->RetAngleY(6+3*i+1), Prop(table[st+10], table[nd+10], prog), time)); + m_object->SetAngleZ(6+3*i+1, Smooth(m_object->RetAngleZ(6+3*i+1), Prop(table[st+11], table[nd+11], prog), time)); + m_object->SetAngleX(6+3*i+2, Smooth(m_object->RetAngleX(6+3*i+2), Prop(table[st+18], table[nd+18], prog), time)); + m_object->SetAngleY(6+3*i+2, Smooth(m_object->RetAngleY(6+3*i+2), Prop(table[st+19], table[nd+19], prog), time)); + m_object->SetAngleZ(6+3*i+2, Smooth(m_object->RetAngleZ(6+3*i+2), Prop(table[st+20], table[nd+20], prog), time)); + } + else // left leg (4..6) ? + { + m_object->SetAngleX(6+3*i+0, Smooth(m_object->RetAngleX(6+3*i+0), Prop(-table[st+ 0], -table[nd+ 0], prog), time)); + m_object->SetAngleY(6+3*i+0, Smooth(m_object->RetAngleY(6+3*i+0), Prop(-table[st+ 1], -table[nd+ 1], prog), time)); + m_object->SetAngleZ(6+3*i+0, Smooth(m_object->RetAngleZ(6+3*i+0), Prop( table[st+ 2], table[nd+ 2], prog), time)); + m_object->SetAngleX(6+3*i+1, Smooth(m_object->RetAngleX(6+3*i+1), Prop(-table[st+ 9], -table[nd+ 9], prog), time)); + m_object->SetAngleY(6+3*i+1, Smooth(m_object->RetAngleY(6+3*i+1), Prop(-table[st+10], -table[nd+10], prog), time)); + m_object->SetAngleZ(6+3*i+1, Smooth(m_object->RetAngleZ(6+3*i+1), Prop( table[st+11], table[nd+11], prog), time)); + m_object->SetAngleX(6+3*i+2, Smooth(m_object->RetAngleX(6+3*i+2), Prop(-table[st+18], -table[nd+18], prog), time)); + m_object->SetAngleY(6+3*i+2, Smooth(m_object->RetAngleY(6+3*i+2), Prop(-table[st+19], -table[nd+19], prog), time)); + m_object->SetAngleZ(6+3*i+2, Smooth(m_object->RetAngleZ(6+3*i+2), Prop( table[st+20], table[nd+20], prog), time)); + } + } + + if ( bStop ) + { + } + else + { + a = Mod(m_armMember, 1.0f); + if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1 + else a = 3.0f-4.0f*a; // 1..-1 + dir.x = sinf(a)*0.05f; + + s = Mod(m_armMember/2.0f, 1.0f); + if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1 + else s = 3.0f-4.0f*s; // 1..-1 + dir.z = sinf(s)*0.1f; + + dir.y = 0.0f; + + if ( bOnBoard ) dir *= 0.6f; + SetInclinaison(dir); + } + + return TRUE; +} + +// Event management for a insect cannon. + +BOOL CMotionVehicle::EventFrameCanoni(const Event &event) +{ + CObject* power; + D3DVECTOR pos, speed; + FPOINT dim; + float zoom, angle, energy, factor; + BOOL bOnBoard = FALSE; + + m_canonTime += event.rTime; + + if ( m_object->RetSelect() && + m_camera->RetType() == CAMERA_ONBOARD ) + { + bOnBoard = TRUE; + } + + power = m_object->RetPower(); + if ( power == 0 ) + { + energy = 0.0f; + } + else + { + energy = power->RetEnergy(); + } + if ( energy == 0.0f ) return TRUE; + + factor = 0.5f+energy*0.5f; + if ( bOnBoard ) factor *= 0.8f; + + zoom = 1.3f+ + sinf(m_canonTime*PI*0.31f)*0.10f+ + sinf(m_canonTime*PI*0.52f)*0.08f+ + sinf(m_canonTime*PI*1.53f)*0.05f; + zoom *= factor; + m_object->SetZoomY(2, zoom); + + zoom = 1.0f+ + sinf(m_canonTime*PI*0.27f)*0.07f+ + sinf(m_canonTime*PI*0.62f)*0.06f+ + sinf(m_canonTime*PI*1.73f)*0.03f; + zoom *= factor; + m_object->SetZoomZ(2, zoom); + + angle = sinf(m_canonTime*1.0f)*0.10f+ + sinf(m_canonTime*1.3f)*0.15f+ + sinf(m_canonTime*2.7f)*0.05f; + m_object->SetAngleX(2, angle); + +#if 0 + m_lastTimeCanon -= event.rTime; + if ( m_lastTimeCanon <= 0.0f ) + { + m_lastTimeCanon = m_engine->ParticuleAdapt(0.5f+Rand()*0.5f); + + pos = m_object->RetPosition(0); + pos.y += 8.0f; + speed.y = 7.0f+Rand()*3.0f; + speed.x = (Rand()-0.5f)*2.0f; + speed.z = 2.0f+Rand()*2.0f; + if ( Rand() < 0.5f ) speed.z = -speed.z; + mat = m_object->RetRotateMatrix(0); + speed = Transform(*mat, speed); + dim.x = Rand()*0.1f+0.1f; + if ( bOnBoard ) dim.x *= 0.4f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIORGANIC2, 2.0f, 10.0f); + } +#endif + + return TRUE; +} + + +// Updates the mapping of the texture of the caterpillars. + +void CMotionVehicle::UpdateTrackMapping(float left, float right, ObjectType type) +{ + D3DMATERIAL7 mat; + float limit[4]; + int rRank, lRank, i; + + ZeroMemory( &mat, sizeof(D3DMATERIAL7) ); + mat.diffuse.r = 1.0f; + mat.diffuse.g = 1.0f; + mat.diffuse.b = 1.0f; // white + mat.ambient.r = 0.5f; + mat.ambient.g = 0.5f; + mat.ambient.b = 0.5f; + + rRank = m_object->RetObjectRank(6); + lRank = m_object->RetObjectRank(7); + + + if ( type == OBJECT_MOBILEdr ) + { + limit[0] = 0.0f; + limit[1] = 1000000.0f; + limit[2] = limit[1]; + limit[3] = m_engine->RetLimitLOD(1); + + m_engine->TrackTextureMapping(rRank, mat, D3DSTATEPART1, "drawer.tga", "", + limit[0], limit[1], D3DMAPPINGX, + right, 1.0f, 8.0f, 192.0f, 256.0f); + + m_engine->TrackTextureMapping(lRank, mat, D3DSTATEPART2, "drawer.tga", "", + limit[0], limit[1], D3DMAPPINGX, + left, 1.0f, 8.0f, 192.0f, 256.0f); + } + else + { + limit[0] = 0.0f; + limit[1] = m_engine->RetLimitLOD(0); + limit[2] = limit[1]; + limit[3] = m_engine->RetLimitLOD(1); + + for ( i=0 ; i<2 ; i++ ) + { + m_engine->TrackTextureMapping(rRank, mat, D3DSTATEPART1, "lemt.tga", "", + limit[i*2+0], limit[i*2+1], D3DMAPPINGX, + right, 1.0f, 8.0f, 192.0f, 256.0f); + + m_engine->TrackTextureMapping(lRank, mat, D3DSTATEPART2, "lemt.tga", "", + limit[i*2+0], limit[i*2+1], D3DMAPPINGX, + left, 1.0f, 8.0f, 192.0f, 256.0f); + } + } + +} + + + +// State management of the pencil drawing robot. + +BOOL CMotionVehicle::RetTraceDown() +{ + return m_bTraceDown; +} + +void CMotionVehicle::SetTraceDown(BOOL bDown) +{ + m_bTraceDown = bDown; +} + +int CMotionVehicle::RetTraceColor() +{ + return m_traceColor; +} + +void CMotionVehicle::SetTraceColor(int color) +{ + m_traceColor = color; +} + +float CMotionVehicle::RetTraceWidth() +{ + return m_traceWidth; +} + +void CMotionVehicle::SetTraceWidth(float width) +{ + m_traceWidth = width; +} + + diff --git a/src/object/motion/motionvehicle.h b/src/object/motion/motionvehicle.h new file mode 100644 index 0000000..1b351c4 --- /dev/null +++ b/src/object/motion/motionvehicle.h @@ -0,0 +1,82 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionvehicle.h + +#ifndef _MOTIONVEHICLE_H_ +#define _MOTIONVEHICLE_H_ + + +#include "motion.h" + + +class CInstanceManager; +class CEngine; +class CLight; +class CParticule; +class CTerrain; +class CCamera; +class CBrain; +class CPhysics; +class CObject; + + +class CMotionVehicle : public CMotion +{ +public: + CMotionVehicle(CInstanceManager* iMan, CObject* object); + ~CMotionVehicle(); + + void DeleteObject(BOOL bAll=FALSE); + BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); + BOOL EventProcess(const Event &event); + + BOOL RetTraceDown(); + void SetTraceDown(BOOL bDown); + int RetTraceColor(); + void SetTraceColor(int color); + float RetTraceWidth(); + void SetTraceWidth(float width); + +protected: + void CreatePhysics(ObjectType type); + BOOL EventFrame(const Event &event); + BOOL EventFrameFly(const Event &event); + BOOL EventFrameInsect(const Event &event); + BOOL EventFrameCanoni(const Event &event); + void UpdateTrackMapping(float left, float right, ObjectType type); + +protected: + float m_wheelTurn[4]; + float m_flyPaw[3]; + float m_posTrackLeft; + float m_posTrackRight; + int m_partiReactor; + float m_armTimeAbs; + float m_armMember; + float m_canonTime; + float m_lastTimeCanon; + D3DVECTOR m_wheelLastPos; + D3DVECTOR m_wheelLastAngle; + D3DVECTOR m_posKey; + BOOL m_bFlyFix; + BOOL m_bTraceDown; + int m_traceColor; + float m_traceWidth; +}; + + +#endif //_MOTIONVEHICLE_H_ diff --git a/src/object/motion/motionworm.cpp b/src/object/motion/motionworm.cpp new file mode 100644 index 0000000..eb32b44 --- /dev/null +++ b/src/object/motion/motionworm.cpp @@ -0,0 +1,380 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionworm.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "light.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "modfile.h" +#include "sound.h" +#include "motion.h" +#include "motionworm.h" + + + +#define START_TIME 1000.0f // beginning of the relative time +#define TIME_UPDOWN 2.0f // time for up / down +#define DOWN_ALTITUDE 3.0f // underground distance +#define WORM_PART 7 // number of parts of a worm + + + +// Object's constructor. + +CMotionWorm::CMotionWorm(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + CMotion::CMotion(iMan, object); + + m_timeUp = 18.0f; + m_timeDown = 18.0f; + m_armMember = START_TIME; + m_armTimeAbs = START_TIME; + m_armTimeMarch = START_TIME; + m_armTimeAction = START_TIME; + m_armTimeIndex = 0; + m_armPartIndex = 0; + m_armMemberIndex = 0; + m_armLinSpeed = 0.0f; + m_armCirSpeed = 0.0f; + m_armLastAction = -1; + m_specAction = -1; + m_lastParticule = 0.0f; + m_bArmStop = FALSE; +} + +// Object's destructor. + +CMotionWorm::~CMotionWorm() +{ +} + + +// Removes an object. + +void CMotionWorm::DeleteObject(BOOL bAll) +{ +} + + +// Creates a vehicle traveling any lands on the ground. + +BOOL CMotionWorm::Create(D3DVECTOR pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + int rank, i; + float px; + + if ( m_engine->RetRestCreate() < 2+WORM_PART+1 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + + // Creates the main base. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + pModFile->ReadModel("objects\\worm0.mod"); // there is no purpose! + pModFile->CreateEngineObject(rank); + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // A vehicle must have a obligatory collision with a sphere of center (0, y, 0) (see GetCrashSphere). + m_object->CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f); + m_object->SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 5.0f); + + px = 1.0f+WORM_PART/2; + + // Creates the head. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\worm1.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, D3DVECTOR(px, 0.0f, 0.0f)); + px -= 1.0f; + + // Creates the body. + for ( i=0 ; iCreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2+i, rank); + m_object->SetObjectParent(2+i, 0); + pModFile->ReadModel("objects\\worm2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2+i, D3DVECTOR(px, 0.0f, 0.0f)); + px -= 1.0f; + } + + // Creates the tail. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2+WORM_PART, rank); + m_object->SetObjectParent(2+WORM_PART, 0); + pModFile->ReadModel("objects\\worm3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2+WORM_PART, D3DVECTOR(px, 0.0f, 0.0f)); + + m_object->CreateShadowCircle(0.0f, 1.0f, D3DSHADOWWORM); + + CreatePhysics(); + m_object->SetFloorHeight(0.0f); + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); // to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return TRUE; +} + +// Creates the physics of the object. + +void CMotionWorm::CreatePhysics() +{ + Character* character; + + m_physics->SetType(TYPE_ROLLING); + + character = m_object->RetCharacter(); + character->wheelFront = 10.0f; + character->wheelBack = 10.0f; + character->wheelLeft = 2.0f; + character->wheelRight = 2.0f; + character->height = -0.2f; + + m_physics->SetLinMotionX(MO_ADVSPEED, 3.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 3.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 10.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 10.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 5.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 5.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.2f*PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.2f*PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 10.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 20.0f); +} + + + +// Specifies a special parameter. + +BOOL CMotionWorm::SetParam(int rank, float value) +{ + if ( rank == 0 ) + { + m_timeDown = value; + return TRUE; + } + + if ( rank == 1 ) + { + m_timeUp = value; + return TRUE; + } + + return FALSE; +} + +float CMotionWorm::RetParam(int rank) +{ + if ( rank == 0 ) return m_timeDown; + if ( rank == 1 ) return m_timeUp; + return 0.0f; +} + + + +// Management of an event. + +BOOL CMotionWorm::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { + } + + return TRUE; +} + +// Management of an event. + +BOOL CMotionWorm::EventFrame(const Event &event) +{ + D3DMATRIX* mat; + D3DVECTOR pos, p, angle, speed; + FPOINT center, pp, dim; + float height[WORM_PART+2]; + float floor, a, s, px, curve, phase, h, zoom, radius; + int i, under; + + if ( m_engine->RetPause() ) return TRUE; + + s = m_physics->RetLinMotionX(MO_MOTSPEED)/m_physics->RetLinMotionX(MO_ADVSPEED); + a = m_physics->RetCirMotionY(MO_MOTSPEED)/m_physics->RetCirMotionY(MO_ADVSPEED); + + if ( s == 0.0f && a != 0.0f ) s = a; + + m_armLinSpeed += (s-m_armLinSpeed)*event.rTime*3.0f; + m_armCirSpeed += (a-m_armCirSpeed)*event.rTime*1.5f; + + m_armTimeAbs += event.rTime; + m_armTimeMarch += event.rTime*m_armLinSpeed; + + under = 0; // no piece under the ground + for ( i=0 ; iRetBurn() ) // is burning? + { + h = 0.0f; // remains on earth + } + h += 0.3f; + height[i] = h; + } + m_object->SetVisible(under!=WORM_PART+2); + + if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return TRUE; + + pos = m_object->RetPosition(0); + floor = m_terrain->RetFloorLevel(pos, TRUE); + + mat = m_object->RetWorldMatrix(0); + + px = 1.0f+WORM_PART/2; + for ( i=0 ; iSetObjectShadowRadius(m_object->RetObjectRank(0), radius); + + pos.x = px+ sinf(m_armTimeMarch*4.0f+0.5f*i)*0.6f; + pos.y = height[i]+sinf(m_armTimeMarch*4.0f+0.5f*i)*0.2f*m_armLinSpeed; + pos.y += sinf(m_armTimeAbs *1.3f+0.2f*i)*0.1f; + pos.z = sinf(m_armTimeAbs *2.0f+0.7f*i)*0.2f; + + curve = ((float)i-(WORM_PART+2)/2)*m_armCirSpeed*0.1f; + center.x = 0.0f; + center.y = 0.0f; + pp.x = pos.x; + pp.y = pos.z; + pp = RotatePoint(center, curve, pp); + pos.x = pp.x; + pos.z = pp.y; + + p = Transform(*mat, pos); + pos.y += m_terrain->RetFloorLevel(p, TRUE)-floor; + m_object->SetPosition(i+1, pos); + + zoom = Mod(m_armTimeAbs*0.5f+100.0f-i*0.1f, 2.0f); + if ( zoom > 1.0f ) zoom = 2.0f-zoom; + zoom *= 1.6f; + if ( zoom < 1.0f ) zoom = 1.0f; + m_object->SetZoomY(i+1, 0.2f+zoom*0.8f); + m_object->SetZoomZ(i+1, zoom); + + if ( height[i] >= -1.0f && height[i] < -0.2f && + m_lastParticule+m_engine->ParticuleAdapt(0.2f) <= m_armTimeMarch ) + { + m_lastParticule = m_armTimeMarch; + + pos = p; + pos.y += -height[i]; + pos.x += (Rand()-0.5f)*4.0f; + pos.z += (Rand()-0.5f)*4.0f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = Rand()*2.0f+1.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + + px -= 1.0f; + } + + for ( i=0 ; iRetPosition(i+2); + pos -= m_object->RetPosition(i+1); + + angle.z = -RotateAngle(Length(pos.x, pos.z), pos.y); + angle.y = PI-RotateAngle(pos.x, pos.z); + angle.x = 0.0f; + m_object->SetAngle(i+1, angle); + + if ( i == WORM_PART ) + { + m_object->SetAngle(i+2, angle); + } + } + + return TRUE; +} + + diff --git a/src/object/motion/motionworm.h b/src/object/motion/motionworm.h new file mode 100644 index 0000000..cabb2ba --- /dev/null +++ b/src/object/motion/motionworm.h @@ -0,0 +1,75 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionworm.h + +#ifndef _MOTIONWORM_H_ +#define _MOTIONWORM_H_ + + +#include "motion.h" + + +class CInstanceManager; +class CEngine; +class CLight; +class CParticule; +class CTerrain; +class CCamera; +class CBrain; +class CPhysics; +class CObject; + + +class CMotionWorm : public CMotion +{ +public: + CMotionWorm(CInstanceManager* iMan, CObject* object); + ~CMotionWorm(); + + void DeleteObject(BOOL bAll=FALSE); + BOOL Create(D3DVECTOR pos, float angle, ObjectType type, float power); + BOOL EventProcess(const Event &event); + + BOOL SetParam(int rank, float value); + float RetParam(int rank); + +protected: + void CreatePhysics(); + BOOL EventFrame(const Event &event); + +protected: + float m_timeUp; + float m_timeDown; + float m_armMember; + float m_armTimeAbs; + float m_armTimeMarch; + float m_armTimeAction; + short m_armAngles[3*3*3*3*10]; + int m_armTimeIndex; + int m_armPartIndex; + int m_armMemberIndex; + int m_armLastAction; + float m_armLinSpeed; + float m_armCirSpeed; + int m_specAction; + float m_specTime; + BOOL m_bArmStop; + float m_lastParticule; +}; + + +#endif //_MOTIONWORM_H_ diff --git a/src/object/object.cpp b/src/object/object.cpp new file mode 100644 index 0000000..0757e46 --- /dev/null +++ b/src/object/object.cpp @@ -0,0 +1,7607 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// object.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "CBot/CBotDll.h" +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "d3dutil.h" +#include "global.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "restext.h" +#include "math3d.h" +#include "mainmovie.h" +#include "robotmain.h" +#include "light.h" +#include "terrain.h" +#include "water.h" +#include "blitz.h" +#include "camera.h" +#include "particule.h" +#include "physics.h" +#include "brain.h" +#include "motion.h" +#include "motionhuman.h" +#include "motiontoto.h" +#include "motionvehicle.h" +#include "motionmother.h" +#include "motionant.h" +#include "motionspider.h" +#include "motionbee.h" +#include "motionworm.h" +#include "modfile.h" +#include "auto.h" +#include "autobase.h" +#include "autoportico.h" +#include "autoderrick.h" +#include "autofactory.h" +#include "autorepair.h" +#include "autodestroyer.h" +#include "autostation.h" +#include "autoenergy.h" +#include "autoconvert.h" +#include "autotower.h" +#include "autoresearch.h" +#include "autolabo.h" +#include "autonuclear.h" +#include "autoradar.h" +#include "autoegg.h" +#include "autonest.h" +#include "autoroot.h" +#include "autoflag.h" +#include "autoinfo.h" +#include "autojostle.h" +#include "autopara.h" +#include "autosafe.h" +#include "autohuston.h" +#include "automush.h" +#include "autokid.h" +#include "task.h" +#include "pyro.h" +#include "displaytext.h" +#include "cmdtoken.h" +#include "cbottoken.h" +#include "sound.h" +#include "object.h" + + + +#define ADJUST_ONBOARD FALSE // TRUE -> adjusts the camera ONBOARD +#define ADJUST_ARM FALSE // TRUE -> adjusts the manipulator arm +#define VIRUS_DELAY 60.0f // duration of virus infection +#define LOSS_SHIELD 0.24f // loss of the shield by shot +#define LOSS_SHIELD_H 0.10f // loss of the shield for humans +#define LOSS_SHIELD_M 0.02f // loss of the shield for the laying + +#if ADJUST_ONBOARD +static float debug_x = 0.0f; +static float debug_y = 0.0f; +static float debug_z = 0.0f; +#endif + +#if ADJUST_ARM +static float debug_arm1 = 0.0f; +static float debug_arm2 = 0.0f; +static float debug_arm3 = 0.0f; +#endif + + + + +// Updates the class Object. + +void uObject(CBotVar* botThis, void* user) +{ + CObject* object = (CObject*)user; + CObject* power; + CObject* fret; + CPhysics* physics; + CBotVar *pVar, *pSub; + ObjectType type; + D3DVECTOR pos; + float value; + int iValue; + + if ( object == 0 ) return; + + physics = object->RetPhysics(); + + // Updates the object's type. + pVar = botThis->GivItemList(); // "category" + type = object->RetType(); + pVar->SetValInt(type, object->RetName()); + + // Updates the position of the object. + pVar = pVar->GivNext(); // "position" + if ( object->RetTruck() == 0 ) + { + pos = object->RetPosition(0); + pos.y -= object->RetWaterLevel(); // relative to sea level! + pSub = pVar->GivItemList(); // "x" + pSub->SetValFloat(pos.x/g_unit); + pSub = pSub->GivNext(); // "y" + pSub->SetValFloat(pos.z/g_unit); + pSub = pSub->GivNext(); // "z" + pSub->SetValFloat(pos.y/g_unit); + } + else // object transported? + { + pSub = pVar->GivItemList(); // "x" + pSub->SetInit(IS_NAN); + pSub = pSub->GivNext(); // "y" + pSub->SetInit(IS_NAN); + pSub = pSub->GivNext(); // "z" + pSub->SetInit(IS_NAN); + } + + // Updates the angle. + pos = object->RetAngle(0); + pos += object->RetInclinaison(); + pVar = pVar->GivNext(); // "orientation" + pVar->SetValFloat(360.0f-Mod(pos.y*180.0f/PI, 360.0f)); + pVar = pVar->GivNext(); // "pitch" + pVar->SetValFloat(pos.z*180.0f/PI); + pVar = pVar->GivNext(); // "roll" + pVar->SetValFloat(pos.x*180.0f/PI); + + // Updates the energy level of the object. + pVar = pVar->GivNext(); // "energyLevel" + value = object->RetEnergy(); + pVar->SetValFloat(value); + + // Updates the shield level of the object. + pVar = pVar->GivNext(); // "shieldLevel" + value = object->RetShield(); + pVar->SetValFloat(value); + + // Updates the temperature of the reactor. + pVar = pVar->GivNext(); // "temperature" + if ( physics == 0 ) value = 0.0f; + else value = 1.0f-physics->RetReactorRange(); + pVar->SetValFloat(value); + + // Updates the height above the ground. + pVar = pVar->GivNext(); // "altitude" + if ( physics == 0 ) value = 0.0f; + else value = physics->RetFloorHeight(); + pVar->SetValFloat(value/g_unit); + + // Updates the lifetime of the object. + pVar = pVar->GivNext(); // "lifeTime" + value = object->RetAbsTime(); + pVar->SetValFloat(value); + + // Updates the material of the object. + pVar = pVar->GivNext(); // "material" + iValue = object->RetMaterial(); + pVar->SetValInt(iValue); + + // Updates the type of battery. + pVar = pVar->GivNext(); // "energyCell" + power = object->RetPower(); + if ( power == 0 ) pVar->SetPointer(0); + else pVar->SetPointer(power->RetBotVar()); + + // Updates the transported object's type. + pVar = pVar->GivNext(); // "load" + fret = object->RetFret(); + if ( fret == 0 ) pVar->SetPointer(0); + else pVar->SetPointer(fret->RetBotVar()); +} + + + + +// Object's constructor. + +CObject::CObject(CInstanceManager* iMan) +{ + int i; + + m_iMan = iMan; + m_iMan->AddInstance(CLASS_OBJECT, this, 500); + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); + m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); + m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + m_physics = 0; + m_brain = 0; + m_motion = 0; + m_auto = 0; + m_runScript = 0; + + m_type = OBJECT_FIX; + m_id = ++g_id; + m_option = 0; + m_name[0] = 0; + m_partiReactor = -1; + m_shadowLight = -1; + m_effectLight = -1; + m_linVibration = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_cirVibration = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_inclinaison = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_lastParticule = 0.0f; + + m_power = 0; + m_fret = 0; + m_truck = 0; + m_truckLink = 0; + m_energy = 1.0f; + m_capacity = 1.0f; + m_shield = 1.0f; + m_range = 0.0f; + m_transparency = 0.0f; + m_lastEnergy = 999.9f; + m_bHilite = FALSE; + m_bSelect = FALSE; + m_bSelectable = TRUE; + m_bCheckToken = TRUE; + m_bVisible = TRUE; + m_bEnable = TRUE; + m_bGadget = FALSE; + m_bProxyActivate = FALSE; + m_bTrainer = FALSE; + m_bToy = FALSE; + m_bManual = FALSE; + m_bFixed = FALSE; + m_bClip = TRUE; + m_bShowLimit = FALSE; + m_showLimitRadius = 0.0f; + m_aTime = 0.0f; + m_shotTime = 0.0f; + m_bVirusMode = FALSE; + m_virusTime = 0.0f; + m_lastVirusParticule = 0.0f; + m_totalDesectList = 0; + m_bLock = FALSE; + m_bExplo = FALSE; + m_bCargo = FALSE; + m_bBurn = FALSE; + m_bDead = FALSE; + m_bFlat = FALSE; + m_gunGoalV = 0.0f; + m_gunGoalH = 0.0f; + m_shieldRadius = 0.0f; + m_defRank = -1; + m_magnifyDamage = 1.0f; + m_proxyDistance = 60.0f; + m_param = 0.0f; + + ZeroMemory(&m_character, sizeof(Character)); + m_character.wheelFront = 1.0f; + m_character.wheelBack = 1.0f; + m_character.wheelLeft = 1.0f; + m_character.wheelRight = 1.0f; + + m_resetCap = RESET_NONE; + m_bResetBusy = FALSE; + m_resetPosition = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_resetAngle = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_resetRun = -1; + + m_cameraType = CAMERA_BACK; + m_cameraDist = 50.0f; + m_bCameraLock = FALSE; + + m_infoTotal = 0; + m_infoReturn = NAN; + m_bInfoUpdate = FALSE; + + for ( i=0 ; iAddUpdateFunc(uObject); + } + + m_botVar = CBotVar::Create("", CBotTypResult(CBotTypClass, "object")); + m_botVar->SetUserPtr(this); + m_botVar->SetIdent(m_id); +} + +// Object's destructor. + +CObject::~CObject() +{ + if ( m_botVar != 0 ) + { + m_botVar->SetUserPtr(OBJECTDELETED); + delete m_botVar; + } + + delete m_physics; + delete m_brain; + delete m_motion; + delete m_auto; + + m_iMan->DeleteInstance(CLASS_OBJECT, this); +} + + +// Removes an object. +// If bAll = TRUE, it does not help, +// because all objects in the scene are quickly destroyed! + +void CObject::DeleteObject(BOOL bAll) +{ + CObject* pObj; + CPyro* pPyro; + int i; + + if ( m_botVar != 0 ) + { + m_botVar->SetUserPtr(OBJECTDELETED); + } + + if ( m_camera->RetObject() == this ) + { + m_camera->SetObject(0); + } + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + pObj->DeleteDeselList(this); + } + + if ( !bAll ) + { +#if 0 + type = m_camera->RetType(); + if ( (type == CAMERA_BACK || + type == CAMERA_FIX || + type == CAMERA_EXPLO || + type == CAMERA_ONBOARD) && + m_camera->RetObject() == this ) + { + pObj = m_main->SearchNearest(RetPosition(0), this); + if ( pObj == 0 ) + { + m_camera->SetObject(0); + m_camera->SetType(CAMERA_FREE); + } + else + { + m_camera->SetObject(pObj); + m_camera->SetType(CAMERA_BACK); + } + } +#endif + for ( i=0 ; i<1000000 ; i++ ) + { + pPyro = (CPyro*)m_iMan->SearchInstance(CLASS_PYRO, i); + if ( pPyro == 0 ) break; + + pPyro->CutObjectLink(this); // the object no longer exists + } + + if ( m_bSelect ) + { + SetSelect(FALSE); + } + + if ( m_type == OBJECT_BASE || + m_type == OBJECT_FACTORY || + m_type == OBJECT_REPAIR || + m_type == OBJECT_DESTROYER|| + m_type == OBJECT_DERRICK || + m_type == OBJECT_STATION || + m_type == OBJECT_CONVERT || + m_type == OBJECT_TOWER || + m_type == OBJECT_RESEARCH || + m_type == OBJECT_RADAR || + m_type == OBJECT_INFO || + m_type == OBJECT_ENERGY || + m_type == OBJECT_LABO || + m_type == OBJECT_NUCLEAR || + m_type == OBJECT_PARA || + m_type == OBJECT_SAFE || + m_type == OBJECT_HUSTON || + m_type == OBJECT_START || + m_type == OBJECT_END ) // building? + { + m_terrain->DeleteBuildingLevel(RetPosition(0)); // flattens the field + } + } + + m_type = OBJECT_NULL; // invalid object until complete destruction + + if ( m_partiReactor != -1 ) + { + m_particule->DeleteParticule(m_partiReactor); + m_partiReactor = -1; + } + + if ( m_shadowLight != -1 ) + { + m_light->DeleteLight(m_shadowLight); + m_shadowLight = -1; + } + + if ( m_effectLight != -1 ) + { + m_light->DeleteLight(m_effectLight); + m_effectLight = -1; + } + + if ( m_physics != 0 ) + { + m_physics->DeleteObject(bAll); + } + + if ( m_brain != 0 ) + { + m_brain->DeleteObject(bAll); + } + + if ( m_motion != 0 ) + { + m_motion->DeleteObject(bAll); + } + + if ( m_auto != 0 ) + { + m_auto->DeleteObject(bAll); + } + + for ( i=0 ; iDeleteObject(m_objectPart[i].object); + + if ( m_objectPart[i].masterParti != -1 ) + { + m_particule->DeleteParticule(m_objectPart[i].masterParti); + m_objectPart[i].masterParti = -1; + } + } + } + + if ( m_bShowLimit ) + { + m_main->FlushShowLimit(0); + m_bShowLimit = FALSE; + } + + if ( !bAll ) m_main->CreateShortcuts(); +} + +// Simplifies a object (he was the brain, among others). + +void CObject::Simplify() +{ + if ( m_brain != 0 ) + { + m_brain->StopProgram(); + } + m_main->SaveOneScript(this); + + if ( m_physics != 0 ) + { + m_physics->DeleteObject(); + delete m_physics; + m_physics = 0; + } + + if ( m_brain != 0 ) + { + m_brain->DeleteObject(); + delete m_brain; + m_brain = 0; + } + + if ( m_motion != 0 ) + { + m_motion->DeleteObject(); + delete m_motion; + m_motion = 0; + } + + if ( m_auto != 0 ) + { + m_auto->DeleteObject(); + delete m_auto; + m_auto = 0; + } + + m_main->CreateShortcuts(); +} + + +// Detonates an object, when struck by a shot. +// If FALSE is returned, the object is still screwed. +// If TRUE is returned, the object is destroyed. + +BOOL CObject::ExploObject(ExploType type, float force, float decay) +{ + PyroType pyroType; + CPyro* pyro; + float loss, shield; + + if ( type == EXPLO_BURN ) + { + if ( m_type == OBJECT_MOBILEtg || + m_type == OBJECT_TEEN28 || // cylinder? + m_type == OBJECT_METAL || + m_type == OBJECT_POWER || + m_type == OBJECT_ATOMIC || + m_type == OBJECT_TNT || + m_type == OBJECT_SCRAP1 || + m_type == OBJECT_SCRAP2 || + m_type == OBJECT_SCRAP3 || + m_type == OBJECT_SCRAP4 || + m_type == OBJECT_SCRAP5 || + m_type == OBJECT_BULLET || + m_type == OBJECT_EGG ) // object that isn't burning? + { + type = EXPLO_BOUM; + force = 1.0f; + decay = 1.0f; + } + } + + if ( EXPLO_BOUM ) + { + if ( m_shotTime < 0.5f ) return FALSE; + m_shotTime = 0.0f; + } + + if ( m_type == OBJECT_HUMAN && m_bDead ) return FALSE; + + // Calculate the power lost by the explosion. + if ( force == 0.0f ) + { + if ( m_type == OBJECT_HUMAN ) + { + loss = LOSS_SHIELD_H; + } + else if ( m_type == OBJECT_MOTHER ) + { + loss = LOSS_SHIELD_M; + } + else + { + loss = LOSS_SHIELD; + } + } + else + { + loss = force; + } + loss *= m_magnifyDamage; + loss *= decay; + + // Decreases the power of the shield. + shield = RetShield(); + shield -= loss; + if ( shield < 0.0f ) shield = 0.0f; + SetShield(shield); + + if ( shield > 0.0f ) // not dead yet? + { + if ( type == EXPLO_WATER ) + { + if ( m_type == OBJECT_HUMAN ) + { + pyroType = PT_SHOTH; + } + else + { + pyroType = PT_SHOTW; + } + } + else + { + if ( m_type == OBJECT_HUMAN ) + { + pyroType = PT_SHOTH; + } + else if ( m_type == OBJECT_MOTHER ) + { + pyroType = PT_SHOTM; + } + else + { + pyroType = PT_SHOTT; + } + } + } + else // completely dead? + { + if ( type == EXPLO_BURN ) // burning? + { + if ( m_type == OBJECT_MOTHER || + m_type == OBJECT_ANT || + m_type == OBJECT_SPIDER || + m_type == OBJECT_BEE || + m_type == OBJECT_WORM || + m_type == OBJECT_BULLET ) + { + pyroType = PT_BURNO; + SetBurn(TRUE); + } + else if ( m_type == OBJECT_HUMAN ) + { + pyroType = PT_DEADG; + } + else + { + pyroType = PT_BURNT; + SetBurn(TRUE); + } + SetVirusMode(FALSE); + } + else if ( type == EXPLO_WATER ) + { + if ( m_type == OBJECT_HUMAN ) + { + pyroType = PT_DEADW; + } + else + { + pyroType = PT_FRAGW; + } + } + else // explosion? + { + if ( m_type == OBJECT_ANT || + m_type == OBJECT_SPIDER || + m_type == OBJECT_BEE || + m_type == OBJECT_WORM ) + { + pyroType = PT_EXPLOO; + } + else if ( m_type == OBJECT_MOTHER || + m_type == OBJECT_NEST || + m_type == OBJECT_BULLET ) + { + pyroType = PT_FRAGO; + } + else if ( m_type == OBJECT_HUMAN ) + { + pyroType = PT_DEADG; + } + else if ( m_type == OBJECT_BASE || + m_type == OBJECT_DERRICK || + m_type == OBJECT_FACTORY || + m_type == OBJECT_STATION || + m_type == OBJECT_CONVERT || + m_type == OBJECT_REPAIR || + m_type == OBJECT_DESTROYER|| + m_type == OBJECT_TOWER || + m_type == OBJECT_NEST || + m_type == OBJECT_RESEARCH || + m_type == OBJECT_RADAR || + m_type == OBJECT_INFO || + m_type == OBJECT_ENERGY || + m_type == OBJECT_LABO || + m_type == OBJECT_NUCLEAR || + m_type == OBJECT_PARA || + m_type == OBJECT_SAFE || + m_type == OBJECT_HUSTON || + m_type == OBJECT_START || + m_type == OBJECT_END ) // building? + { + pyroType = PT_FRAGT; + } + else if ( m_type == OBJECT_MOBILEtg || + m_type == OBJECT_TEEN28 || // cylinder? + m_type == OBJECT_TEEN31 ) // basket? + { + pyroType = PT_FRAGT; + } + else + { + pyroType = PT_EXPLOT; + } + } + + loss = 1.0f; + } + + pyro = new CPyro(m_iMan); + pyro->Create(pyroType, this, loss); + + if ( shield == 0.0f ) // dead? + { + if ( m_brain != 0 ) + { + m_brain->StopProgram(); + } + m_main->SaveOneScript(this); + } + + if ( shield > 0.0f ) return FALSE; // not dead yet + + if ( RetSelect() ) + { + SetSelect(FALSE); // deselects the object + m_camera->SetType(CAMERA_EXPLO); + m_main->DeselectAll(); + } + DeleteDeselList(this); + + if ( m_botVar != 0 ) + { + if ( m_type == OBJECT_STONE || + m_type == OBJECT_URANIUM || + m_type == OBJECT_METAL || + m_type == OBJECT_POWER || + m_type == OBJECT_ATOMIC || + m_type == OBJECT_BULLET || + m_type == OBJECT_BBOX || + m_type == OBJECT_TNT || + m_type == OBJECT_SCRAP1 || + m_type == OBJECT_SCRAP2 || + m_type == OBJECT_SCRAP3 || + m_type == OBJECT_SCRAP4 || + m_type == OBJECT_SCRAP5 ) // (*) + { + m_botVar->SetUserPtr(OBJECTDELETED); + } + } + + return TRUE; +} + +// (*) If a robot or cosmonaut dies, the subject must continue to exist, +// so that programs of the ants continue to operate as usual. + + +// Initializes a new part. + +void CObject::InitPart(int part) +{ + m_objectPart[part].bUsed = TRUE; + m_objectPart[part].object = -1; + m_objectPart[part].parentPart = -1; + + m_objectPart[part].position = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_objectPart[part].angle.y = 0.0f; + m_objectPart[part].angle.x = 0.0f; + m_objectPart[part].angle.z = 0.0f; + m_objectPart[part].zoom = D3DVECTOR(1.0f, 1.0f, 1.0f); + + m_objectPart[part].bTranslate = TRUE; + m_objectPart[part].bRotate = TRUE; + m_objectPart[part].bZoom = FALSE; + + D3DUtil_SetIdentityMatrix(m_objectPart[part].matTranslate); + D3DUtil_SetIdentityMatrix(m_objectPart[part].matRotate); + D3DUtil_SetIdentityMatrix(m_objectPart[part].matTransform); + D3DUtil_SetIdentityMatrix(m_objectPart[part].matWorld); + + m_objectPart[part].masterParti = -1; +} + +// Creates a new part, and returns its number. +// Returns -1 on error. + +int CObject::CreatePart() +{ + int i; + + for ( i=0 ; iDeleteParticule(m_objectPart[part].masterParti); + m_objectPart[part].masterParti = -1; + } + + m_objectPart[part].bUsed = FALSE; + m_engine->DeleteObject(m_objectPart[part].object); + UpdateTotalPart(); +} + +void CObject::UpdateTotalPart() +{ + int i; + + m_totalPart = 0; + for ( i=0 ; iSetIdent(m_id); + } +} + +int CObject::RetID() +{ + return m_id; +} + + +// Saves all the parameters of the object. + +BOOL CObject::Write(char *line) +{ + D3DVECTOR pos; + Info info; + char name[100]; + float value; + int i; + + sprintf(name, " camera=%s", GetCamera(RetCameraType())); + strcat(line, name); + + if ( RetCameraLock() != 0 ) + { + sprintf(name, " cameraLock=%d", RetCameraLock()); + strcat(line, name); + } + + if ( RetEnergy() != 0.0f ) + { + sprintf(name, " energy=%.2f", RetEnergy()); + strcat(line, name); + } + + if ( RetCapacity() != 1.0f ) + { + sprintf(name, " capacity=%.2f", RetCapacity()); + strcat(line, name); + } + + if ( RetShield() != 1.0f ) + { + sprintf(name, " shield=%.2f", RetShield()); + strcat(line, name); + } + + if ( RetRange() != 1.0f ) + { + sprintf(name, " range=%.2f", RetRange()); + strcat(line, name); + } + + if ( RetSelectable() != 1 ) + { + sprintf(name, " selectable=%d", RetSelectable()); + strcat(line, name); + } + + if ( RetEnable() != 1 ) + { + sprintf(name, " enable=%d", RetEnable()); + strcat(line, name); + } + + if ( RetFixed() != 0 ) + { + sprintf(name, " fixed=%d", RetFixed()); + strcat(line, name); + } + + if ( RetClip() != 1 ) + { + sprintf(name, " clip=%d", RetClip()); + strcat(line, name); + } + + if ( RetLock() != 0 ) + { + sprintf(name, " lock=%d", RetLock()); + strcat(line, name); + } + + if ( RetProxyActivate() != 0 ) + { + sprintf(name, " proxyActivate=%d", RetProxyActivate()); + strcat(line, name); + + sprintf(name, " proxyDistance=%.2f", RetProxyDistance()/g_unit); + strcat(line, name); + } + + if ( RetMagnifyDamage() != 1.0f ) + { + sprintf(name, " magnifyDamage=%.2f", RetMagnifyDamage()); + strcat(line, name); + } + + if ( RetGunGoalV() != 0.0f ) + { + sprintf(name, " aimV=%.2f", RetGunGoalV()); + strcat(line, name); + } + if ( RetGunGoalH() != 0.0f ) + { + sprintf(name, " aimH=%.2f", RetGunGoalH()); + strcat(line, name); + } + + if ( RetParam() != 0.0f ) + { + sprintf(name, " param=%.2f", RetParam()); + strcat(line, name); + } + + if ( RetResetCap() != 0 ) + { + sprintf(name, " resetCap=%d", RetResetCap()); + strcat(line, name); + + pos = RetResetPosition()/g_unit; + sprintf(name, " resetPos=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); + strcat(line, name); + + pos = RetResetAngle()/(PI/180.0f); + sprintf(name, " resetAngle=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); + strcat(line, name); + + sprintf(name, " resetRun=%d", RetResetRun()); + strcat(line, name); + } + + if ( m_bVirusMode != 0 ) + { + sprintf(name, " virusMode=%d", m_bVirusMode); + strcat(line, name); + } + + if ( m_virusTime != 0.0f ) + { + sprintf(name, " virusTime=%.2f", m_virusTime); + strcat(line, name); + } + + // Puts information in terminal (OBJECT_INFO). + for ( i=0 ; iWrite(line); + } + + if ( m_brain != 0 ) + { + m_brain->Write(line); + } + + if ( m_physics != 0 ) + { + m_physics->Write(line); + } + + if ( m_auto != 0 ) + { + m_auto->Write(line); + } + + return TRUE; +} + +// Returns all parameters of the object. + +BOOL CObject::Read(char *line) +{ + D3DVECTOR pos, dir; + Info info; + CameraType cType; + char op[20]; + char text[100]; + char* p; + float value; + int i; + + cType = OpCamera(line, "camera"); + if ( cType != CAMERA_NULL ) + { + SetCameraType(cType); + } + + SetCameraLock(OpInt(line, "cameraLock", 0)); + SetEnergy(OpFloat(line, "energy", 0.0f)); + SetCapacity(OpFloat(line, "capacity", 1.0f)); + SetShield(OpFloat(line, "shield", 1.0f)); + SetRange(OpFloat(line, "range", 1.0f)); + SetSelectable(OpInt(line, "selectable", 1)); + SetEnable(OpInt(line, "enable", 1)); + SetFixed(OpInt(line, "fixed", 0)); + SetClip(OpInt(line, "clip", 1)); + SetLock(OpInt(line, "lock", 0)); + SetProxyActivate(OpInt(line, "proxyActivate", 0)); + SetProxyDistance(OpFloat(line, "proxyDistance", 15.0f)*g_unit); + SetRange(OpFloat(line, "range", 30.0f)); + SetMagnifyDamage(OpFloat(line, "magnifyDamage", 1.0f)); + SetGunGoalV(OpFloat(line, "aimV", 0.0f)); + SetGunGoalH(OpFloat(line, "aimH", 0.0f)); + SetParam(OpFloat(line, "param", 0.0f)); + SetResetCap((ResetCap)OpInt(line, "resetCap", 0)); + SetResetPosition(OpDir(line, "resetPos")*g_unit); + SetResetAngle(OpDir(line, "resetAngle")*(PI/180.0f)); + SetResetRun(OpInt(line, "resetRun", 0)); + m_bBurn = OpInt(line, "burnMode", 0); + m_bVirusMode = OpInt(line, "virusMode", 0); + m_virusTime = OpFloat(line, "virusTime", 0.0f); + + // Puts information in terminal (OBJECT_INFO). + for ( i=0 ; iReadModel("objects\\convert1.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetFloorHeight(0.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(1, rank); + SetObjectParent(1, 0); + pModFile->ReadModel("objects\\convert2.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(1, D3DVECTOR(0.0f, 14.0f, 0.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(2, rank); + SetObjectParent(2, 0); + pModFile->ReadModel("objects\\convert3.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(2, D3DVECTOR(0.0f, 11.5f, 0.0f)); + SetAngleX(2, -PI*0.35f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(3, rank); + SetObjectParent(3, 0); + pModFile->ReadModel("objects\\convert3.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(3, D3DVECTOR(0.0f, 11.5f, 0.0f)); + SetAngleY(3, PI); + SetAngleX(3, -PI*0.35f); + + m_terrain->AddBuildingLevel(pos, 7.0f, 9.0f, 1.0f, 0.5f); + + CreateCrashSphere(D3DVECTOR(-10.0f, 2.0f, 4.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-10.0f, 2.0f, -4.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-10.0f, 9.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 14.0f, 0.0f), 1.5f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(-3.0f, 8.0f, 0.0f), 14.0f); + } + + if ( m_type == OBJECT_TOWER ) + { + pModFile->ReadModel("objects\\tower.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetFloorHeight(0.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(1, rank); + SetObjectParent(1, 0); + pModFile->ReadModel("objects\\roller2c.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(1, D3DVECTOR(0.0f, 20.0f, 0.0f)); + SetAngleZ(1, PI/2.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(2, rank); + SetObjectParent(2, 1); + pModFile->ReadModel("objects\\roller3c.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(2, D3DVECTOR(4.5f, 0.0f, 0.0f)); + SetAngleZ(2, 0.0f); + + CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 6.5f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(0.0f, 8.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(0.0f, 15.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(0.0f, 24.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 7.0f); + + m_character.posPower = D3DVECTOR(5.0f, 3.0f, 0.0f); + + CreateShadowCircle(6.0f, 1.0f); + m_showLimitRadius = BLITZPARA; + } + + if ( m_type == OBJECT_NUCLEAR ) + { + pModFile->ReadModel("objects\\nuclear1.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetFloorHeight(0.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(1, rank); + SetObjectParent(1, 0); + pModFile->ReadModel("objects\\nuclear2.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(1, D3DVECTOR(20.0f, 10.0f, 0.0f)); + SetAngleZ(1, 135.0f*PI/180.0f); + + CreateCrashSphere(D3DVECTOR( 0.0f, 0.0f, 0.0f), 19.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 24.0f, 0.0f), 15.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(22.0f, 1.0f, 0.0f), 1.5f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 17.0f, 0.0f), 26.0f); + + m_character.posPower = D3DVECTOR(22.0f, 3.0f, 0.0f); + + CreateShadowCircle(21.0f, 1.0f); + } + + if ( m_type == OBJECT_PARA ) + { + pModFile->ReadModel("objects\\para.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetFloorHeight(0.0f); + + m_terrain->AddBuildingLevel(pos, 16.0f, 18.0f, 1.0f, 0.5f); + + CreateCrashSphere(D3DVECTOR( 13.0f, 3.0f, 13.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 11.0f, 15.0f, 11.0f), 2.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-13.0f, 3.0f, 13.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-11.0f, 15.0f, -11.0f), 2.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 13.0f, 3.0f, -13.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 11.0f, 15.0f, -11.0f), 2.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-13.0f, 3.0f, -13.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-11.0f, 15.0f, -11.0f), 2.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 26.0f, 0.0f), 9.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 54.0f, 0.0f), 14.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 20.0f); + + CreateShadowCircle(21.0f, 1.0f); + m_showLimitRadius = BLITZPARA; + } + + if ( m_type == OBJECT_SAFE ) + { + pModFile->ReadModel("objects\\safe1.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetFloorHeight(0.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(1, rank); + SetObjectParent(1, 0); + pModFile->ReadModel("objects\\safe2.mod"); + pModFile->CreateEngineObject(rank); + SetZoom(1, 1.05f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(2, rank); + SetObjectParent(2, 0); + pModFile->ReadModel("objects\\safe3.mod"); + pModFile->CreateEngineObject(rank); + SetZoom(2, 1.05f); + + m_terrain->AddBuildingLevel(pos, 18.0f, 20.0f, 1.0f, 0.5f); + + CreateCrashSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 13.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 13.0f); + + CreateShadowCircle(23.0f, 1.0f); + } + + if ( m_type == OBJECT_HUSTON ) + { + pModFile->ReadModel("objects\\huston1.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetFloorHeight(0.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(1, rank); + SetObjectParent(1, 0); + pModFile->ReadModel("objects\\huston2.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(1, D3DVECTOR(0.0f, 39.0f, 30.0f)); + SetAngleY(1, -PI/2.0f); + SetZoom(1, 3.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(2, rank); + SetObjectParent(2, 1); + pModFile->ReadModel("objects\\huston3.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(2, D3DVECTOR(0.0f, 4.5f, 1.9f)); + + CreateCrashSphere(D3DVECTOR( 15.0f, 6.0f, -53.0f), 16.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-15.0f, 6.0f, -53.0f), 16.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 15.0f, 6.0f, -26.0f), 16.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-15.0f, 6.0f, -26.0f), 16.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 15.0f, 6.0f, 0.0f), 16.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-15.0f, 6.0f, 0.0f), 16.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 15.0f, 6.0f, 26.0f), 16.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-15.0f, 6.0f, 26.0f), 16.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 15.0f, 6.0f, 53.0f), 16.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-15.0f, 6.0f, 53.0f), 16.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 27.0f, 30.0f), 12.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 45.0f, 30.0f), 14.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 26.0f, 4.0f, -61.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-26.0f, 4.0f, -61.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 26.0f, 4.0f, 61.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-26.0f, 4.0f, 61.0f), 5.0f, SOUND_BOUMm, 0.45f); + } + + if ( m_type == OBJECT_TARGET1 ) + { + pModFile->ReadModel("objects\\target1.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, 1.5f); + SetFloorHeight(0.0f); + + CreateCrashSphere(D3DVECTOR( 0.0f, 50.0f+14.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( -7.0f, 50.0f+12.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 7.0f, 50.0f+12.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-12.0f, 50.0f+ 7.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 12.0f, 50.0f+ 7.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-14.0f, 50.0f+ 0.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 14.0f, 50.0f+ 0.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-12.0f, 50.0f- 7.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 12.0f, 50.0f- 7.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( -7.0f, 50.0f-12.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 7.0f, 50.0f-12.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 50.0f-14.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + + CreateCrashSphere(D3DVECTOR(0.0f, 30.0f, 0.0f), 2.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(0.0f, 24.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(0.0f, 16.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 8.0f, SOUND_BOUMm, 0.45f); + + CreateShadowCircle(15.0f, 1.0f); + } + + if ( m_type == OBJECT_TARGET2 ) + { + pModFile->ReadModel("objects\\target2.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetFloorHeight(0.0f); + + height += 50.0f*1.5f; + } + + if ( m_type == OBJECT_NEST ) + { + pModFile->ReadModel("objects\\nest.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetFloorHeight(0.0f); + + m_terrain->AddBuildingLevel(pos, 3.0f, 5.0f, 1.0f, 0.5f); + + CreateShadowCircle(4.0f, 1.0f); + } + + if ( m_type == OBJECT_START ) + { + pModFile->ReadModel("objects\\start.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetFloorHeight(0.0f); + + m_terrain->AddBuildingLevel(pos, 7.0f, 9.0f, 1.0f, 0.5f); + } + + if ( m_type == OBJECT_END ) + { + pModFile->ReadModel("objects\\end.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetFloorHeight(0.0f); + + m_terrain->AddBuildingLevel(pos, 7.0f, 9.0f, 1.0f, 0.5f); + } + +#if 0 + if ( power > 0.0f ) // creates a battery? + { + CObject* pPower; + + pPower = new CObject(m_iMan); + pPower->SetType(power<=1.0f?OBJECT_POWER:OBJECT_ATOMIC); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + pPower->SetObjectRank(0, rank); + + if ( power <= 1.0f ) pModFile->ReadModel("objects\\power.mod"); + else pModFile->ReadModel("objects\\atomic.mod"); + pModFile->CreateEngineObject(rank); + + pPower->SetPosition(0, RetCharacter()->posPower); + pPower->CreateCrashSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + pPower->SetGlobalSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 1.5f); + + pPower->SetTruck(this); + SetPower(pPower); + + if ( power <= 1.0f ) pPower->SetEnergy(power); + else pPower->SetEnergy(power/100.0f); + } +#endif + + pos = RetPosition(0); + pos.y += height; + SetPosition(0, pos); // to display the shadows immediately + + CreateOtherObject(type); + m_engine->LoadAllTexture(); + + delete pModFile; + return TRUE; +} + +// Creates a small resource set on the ground. + +BOOL CObject::CreateResource(D3DVECTOR pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + char name[50]; + int rank; + float radius, height; + + if ( type != OBJECT_SHOW ) + { + if ( m_engine->RetRestCreate() < 1 ) return FALSE; + } + + pModFile = new CModFile(m_iMan); + + SetType(type); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object + SetObjectRank(0, rank); + SetEnergy(power); + + name[0] = 0; + if ( type == OBJECT_STONE ) strcpy(name, "objects\\stone.mod"); + if ( type == OBJECT_URANIUM ) strcpy(name, "objects\\uranium.mod"); + if ( type == OBJECT_METAL ) strcpy(name, "objects\\metal.mod"); + if ( type == OBJECT_POWER ) strcpy(name, "objects\\power.mod"); + if ( type == OBJECT_ATOMIC ) strcpy(name, "objects\\atomic.mod"); + if ( type == OBJECT_BULLET ) strcpy(name, "objects\\bullet.mod"); + if ( type == OBJECT_BBOX ) strcpy(name, "objects\\bbox.mod"); + if ( type == OBJECT_KEYa ) strcpy(name, "objects\\keya.mod"); + if ( type == OBJECT_KEYb ) strcpy(name, "objects\\keyb.mod"); + if ( type == OBJECT_KEYc ) strcpy(name, "objects\\keyc.mod"); + if ( type == OBJECT_KEYd ) strcpy(name, "objects\\keyd.mod"); + if ( type == OBJECT_TNT ) strcpy(name, "objects\\tnt.mod"); + if ( type == OBJECT_SCRAP1 ) strcpy(name, "objects\\scrap1.mod"); + if ( type == OBJECT_SCRAP2 ) strcpy(name, "objects\\scrap2.mod"); + if ( type == OBJECT_SCRAP3 ) strcpy(name, "objects\\scrap3.mod"); + if ( type == OBJECT_SCRAP4 ) strcpy(name, "objects\\scrap4.mod"); + if ( type == OBJECT_SCRAP5 ) strcpy(name, "objects\\scrap5.mod"); + if ( type == OBJECT_BOMB ) strcpy(name, "objects\\bomb.mod"); + if ( type == OBJECT_WAYPOINT ) strcpy(name, "objects\\waypoint.mod"); + if ( type == OBJECT_SHOW ) strcpy(name, "objects\\show.mod"); + if ( type == OBJECT_WINFIRE ) strcpy(name, "objects\\winfire.mod"); + if ( type == OBJECT_BAG ) strcpy(name, "objects\\bag.mod"); + if ( type == OBJECT_MARKSTONE ) strcpy(name, "objects\\cross1.mod"); + if ( type == OBJECT_MARKURANIUM ) strcpy(name, "objects\\cross3.mod"); + if ( type == OBJECT_MARKPOWER ) strcpy(name, "objects\\cross2.mod"); + if ( type == OBJECT_MARKKEYa ) strcpy(name, "objects\\crossa.mod"); + if ( type == OBJECT_MARKKEYb ) strcpy(name, "objects\\crossb.mod"); + if ( type == OBJECT_MARKKEYc ) strcpy(name, "objects\\crossc.mod"); + if ( type == OBJECT_MARKKEYd ) strcpy(name, "objects\\crossd.mod"); + if ( type == OBJECT_EGG ) strcpy(name, "objects\\egg.mod"); + + pModFile->ReadModel(name); + pModFile->CreateEngineObject(rank); + + SetPosition(0, pos); + SetAngleY(0, angle); + + if ( type == OBJECT_SHOW ) // remains in the air? + { + delete pModFile; + return TRUE; + } + + radius = 1.5f; + height = 0.0f; + + if ( type == OBJECT_MARKSTONE || + type == OBJECT_MARKURANIUM || + type == OBJECT_MARKKEYa || + type == OBJECT_MARKKEYb || + type == OBJECT_MARKKEYc || + type == OBJECT_MARKKEYd || + type == OBJECT_MARKPOWER || + type == OBJECT_WAYPOINT ) + { + } + else if ( type == OBJECT_EGG ) + { + CreateCrashSphere(D3DVECTOR(-1.0f, 2.8f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 10.0f); + radius = 3.0f; + } + else if ( type == OBJECT_BOMB ) + { + CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 3.0f); + radius = 3.0f; + } + else if ( type == OBJECT_BAG ) + { + CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f); + SetZoom(0, 1.5f); + radius = 5.0f; + height = -1.4f; + } + else + { + CreateCrashSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 1.5f); + } + CreateShadowCircle(radius, 1.0f); + + SetFloorHeight(0.0f); + CreateOtherObject(type); + m_engine->LoadAllTexture(); + FloorAdjust(); + + pos = RetPosition(0); + pos.y += height; + SetPosition(0, pos); // to display the shadows immediately + + delete pModFile; + return TRUE; +} + +// Creates a flag placed on the ground. + +BOOL CObject::CreateFlag(D3DVECTOR pos, float angle, ObjectType type) +{ + CModFile* pModFile; + char name[50]; + int rank, i; + + if ( m_engine->RetRestCreate() < 1+4 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + SetType(type); + + name[0] = 0; + if ( type == OBJECT_FLAGb ) strcpy(name, "objects\\flag1b.mod"); + if ( type == OBJECT_FLAGr ) strcpy(name, "objects\\flag1r.mod"); + if ( type == OBJECT_FLAGg ) strcpy(name, "objects\\flag1g.mod"); + if ( type == OBJECT_FLAGy ) strcpy(name, "objects\\flag1y.mod"); + if ( type == OBJECT_FLAGv ) strcpy(name, "objects\\flag1v.mod"); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object + SetObjectRank(0, rank); + pModFile->ReadModel(name); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + name[0] = 0; + if ( type == OBJECT_FLAGb ) strcpy(name, "objects\\flag2b.mod"); + if ( type == OBJECT_FLAGr ) strcpy(name, "objects\\flag2r.mod"); + if ( type == OBJECT_FLAGg ) strcpy(name, "objects\\flag2g.mod"); + if ( type == OBJECT_FLAGy ) strcpy(name, "objects\\flag2y.mod"); + if ( type == OBJECT_FLAGv ) strcpy(name, "objects\\flag2v.mod"); + + for ( i=0 ; i<4 ; i++ ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(1+i, rank); + SetObjectParent(1+i, i); + pModFile->ReadModel(name); + pModFile->CreateEngineObject(rank); + if ( i == 0 ) SetPosition(1+i, D3DVECTOR(0.15f, 5.0f, 0.0f)); + else SetPosition(1+i, D3DVECTOR(0.79f, 0.0f, 0.0f)); + } + + SetJotlerSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 1.0f); + CreateShadowCircle(2.0f, 0.3f); + + SetFloorHeight(0.0f); + CreateOtherObject(type); + m_engine->LoadAllTexture(); + FloorAdjust(); + + pos = RetPosition(0); + SetPosition(0, pos); // to display the shadows immediately + + delete pModFile; + return TRUE; +} + +// Creates a barrier placed on the ground. + +BOOL CObject::CreateBarrier(D3DVECTOR pos, float angle, float height, + ObjectType type) +{ + CModFile* pModFile; + int rank; + + if ( m_engine->RetRestCreate() < 1 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + SetType(type); + + if ( type == OBJECT_BARRIER0 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\barrier0.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR( 3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + + CreateShadowCircle(6.0f, 0.5f, D3DSHADOWWORM); + } + + if ( type == OBJECT_BARRIER1 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\barrier1.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR( 8.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-8.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + + CreateShadowCircle(12.0f, 0.5f, D3DSHADOWWORM); + } + + if ( type == OBJECT_BARRIER2 ) // cardboard? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\barrier2.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR( 8.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-8.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + + CreateShadowCircle(12.0f, 0.8f, D3DSHADOWWORM); + } + + if ( type == OBJECT_BARRIER3 ) // match + straw? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\barrier3.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR( 8.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-8.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); + + CreateShadowCircle(10.0f, 0.5f, D3DSHADOWWORM); + } + + pos = RetPosition(0); + SetPosition(0, pos); // to display the shadows immediately + + SetFloorHeight(0.0f); + CreateOtherObject(type); + FloorAdjust(); + + pos = RetPosition(0); + pos.y += height; + SetPosition(0, pos); + + delete pModFile; + return TRUE; +} + +// Creates a plant placed on the ground. + +BOOL CObject::CreatePlant(D3DVECTOR pos, float angle, float height, + ObjectType type) +{ + CModFile* pModFile; + int rank; + + if ( m_engine->RetRestCreate() < 1 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + SetType(type); + + if ( type == OBJECT_PLANT0 || + type == OBJECT_PLANT1 || + type == OBJECT_PLANT2 || + type == OBJECT_PLANT3 || + type == OBJECT_PLANT4 ) // standard? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + if ( type == OBJECT_PLANT0 ) pModFile->ReadModel("objects\\plant0.mod"); + if ( type == OBJECT_PLANT1 ) pModFile->ReadModel("objects\\plant1.mod"); + if ( type == OBJECT_PLANT2 ) pModFile->ReadModel("objects\\plant2.mod"); + if ( type == OBJECT_PLANT3 ) pModFile->ReadModel("objects\\plant3.mod"); + if ( type == OBJECT_PLANT4 ) pModFile->ReadModel("objects\\plant4.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + height -= 2.0f; + + CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f); + SetGlobalSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 6.0f); + SetJotlerSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 8.0f); + + CreateShadowCircle(8.0f, 0.5f); + } + + if ( type == OBJECT_PLANT5 || + type == OBJECT_PLANT6 || + type == OBJECT_PLANT7 ) // clover? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + if ( type == OBJECT_PLANT5 ) pModFile->ReadModel("objects\\plant5.mod"); + if ( type == OBJECT_PLANT6 ) pModFile->ReadModel("objects\\plant6.mod"); + if ( type == OBJECT_PLANT7 ) pModFile->ReadModel("objects\\plant7.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + +//? CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 3.0f, SOUND_BOUM, 0.10f); + SetJotlerSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f); + + CreateShadowCircle(5.0f, 0.3f); + } + + if ( type == OBJECT_PLANT8 || + type == OBJECT_PLANT9 ) // squash? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + if ( type == OBJECT_PLANT8 ) pModFile->ReadModel("objects\\plant8.mod"); + if ( type == OBJECT_PLANT9 ) pModFile->ReadModel("objects\\plant9.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f); + CreateCrashSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f); + + CreateShadowCircle(10.0f, 0.5f); + } + + if ( type == OBJECT_PLANT10 || + type == OBJECT_PLANT11 || + type == OBJECT_PLANT12 || + type == OBJECT_PLANT13 || + type == OBJECT_PLANT14 ) // succulent? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + if ( type == OBJECT_PLANT10 ) pModFile->ReadModel("objects\\plant10.mod"); + if ( type == OBJECT_PLANT11 ) pModFile->ReadModel("objects\\plant11.mod"); + if ( type == OBJECT_PLANT12 ) pModFile->ReadModel("objects\\plant12.mod"); + if ( type == OBJECT_PLANT13 ) pModFile->ReadModel("objects\\plant13.mod"); + if ( type == OBJECT_PLANT14 ) pModFile->ReadModel("objects\\plant14.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR(0.0f, 12.0f, 0.0f), 5.0f, SOUND_BOUM, 0.10f); + SetGlobalSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 6.0f); + SetJotlerSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 8.0f); + + CreateShadowCircle(8.0f, 0.3f); + } + + if ( type == OBJECT_PLANT15 || + type == OBJECT_PLANT16 || + type == OBJECT_PLANT17 || + type == OBJECT_PLANT18 || + type == OBJECT_PLANT19 ) // fern? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + if ( type == OBJECT_PLANT15 ) pModFile->ReadModel("objects\\plant15.mod"); + if ( type == OBJECT_PLANT16 ) pModFile->ReadModel("objects\\plant16.mod"); + if ( type == OBJECT_PLANT17 ) pModFile->ReadModel("objects\\plant17.mod"); + if ( type == OBJECT_PLANT18 ) pModFile->ReadModel("objects\\plant18.mod"); + if ( type == OBJECT_PLANT19 ) pModFile->ReadModel("objects\\plant19.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + if ( type != OBJECT_PLANT19 ) + { + CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f); + SetGlobalSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 6.0f); + } + SetJotlerSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 8.0f); + + CreateShadowCircle(8.0f, 0.5f); + } + + if ( type == OBJECT_TREE0 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\tree0.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR( 0.0f, 3.0f, 2.0f), 3.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR(-1.0f, 10.0f, 1.0f), 2.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR( 0.0f, 17.0f, 0.0f), 2.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR( 1.0f, 27.0f, 0.0f), 2.0f, SOUND_BOUMs, 0.20f); + + CreateShadowCircle(8.0f, 0.5f); + } + + if ( type == OBJECT_TREE1 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\tree1.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR( 0.0f, 3.0f, 2.0f), 3.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR(-2.0f, 11.0f, 1.0f), 2.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR(-2.0f, 19.0f, 2.0f), 2.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR( 2.0f, 26.0f, 0.0f), 2.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR( 2.0f, 34.0f,-2.0f), 2.0f, SOUND_BOUMs, 0.20f); + + CreateShadowCircle(8.0f, 0.5f); + } + + if ( type == OBJECT_TREE2 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\tree2.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR( 0.0f, 3.0f, 1.0f), 3.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR(-2.0f, 10.0f, 1.0f), 2.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR(-2.0f, 19.0f, 2.0f), 2.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR( 2.0f, 25.0f, 0.0f), 2.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR( 3.0f, 32.0f,-2.0f), 2.0f, SOUND_BOUMs, 0.20f); + + CreateShadowCircle(8.0f, 0.5f); + } + + if ( type == OBJECT_TREE3 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\tree3.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR(-2.0f, 3.0f, 2.0f), 3.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR(-3.0f, 9.0f, 1.0f), 2.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR( 0.0f, 18.0f, 0.0f), 2.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR( 0.0f, 27.0f, 7.0f), 2.0f, SOUND_BOUMs, 0.20f); + + CreateShadowCircle(8.0f, 0.5f); + } + + if ( type == OBJECT_TREE4 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\tree4.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 10.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR(0.0f, 21.0f, 0.0f), 8.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR(0.0f, 32.0f, 0.0f), 7.0f, SOUND_BOUMs, 0.20f); + + CreateShadowCircle(8.0f, 0.5f); + } + + if ( type == OBJECT_TREE5 ) // giant tree (for the world "teen") + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\tree5.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR( 0.0f, 5.0f,-10.0f), 25.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR(-65.0f, 5.0f, 65.0f), 20.0f, SOUND_BOUMs, 0.20f); + CreateCrashSphere(D3DVECTOR( 38.0f, 5.0f, 21.0f), 18.0f, SOUND_BOUMs, 0.20f); + + CreateShadowCircle(50.0f, 0.5f); + } + + pos = RetPosition(0); + SetPosition(0, pos); // to display the shadows immediately + + SetFloorHeight(0.0f); + CreateOtherObject(type); + + pos = RetPosition(0); + pos.y += height; + SetPosition(0, pos); + + delete pModFile; + return TRUE; +} + +// Creates a mushroom placed on the ground. + +BOOL CObject::CreateMushroom(D3DVECTOR pos, float angle, float height, + ObjectType type) +{ + CModFile* pModFile; + int rank; + + if ( m_engine->RetRestCreate() < 1 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + SetType(type); + + if ( type == OBJECT_MUSHROOM1 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\mush1.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 3.0f, SOUND_BOUM, 0.10f); + SetGlobalSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 5.5f); + SetJotlerSphere(D3DVECTOR(0.0f, 3.0f, 0.0f), 5.5f); + + CreateShadowCircle(6.0f, 0.5f); + } + + if ( type == OBJECT_MUSHROOM2 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\mush2.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 3.0f, SOUND_BOUM, 0.10f); + SetGlobalSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 5.5f); + SetJotlerSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 5.5f); + + CreateShadowCircle(5.0f, 0.5f); + } + + pos = RetPosition(0); + SetPosition(0, pos); // to display the shadows immediately + + SetFloorHeight(0.0f); + CreateOtherObject(type); + + pos = RetPosition(0); + pos.y += height; + SetPosition(0, pos); + + delete pModFile; + return TRUE; +} + +// Creates a toy placed on the ground. + +BOOL CObject::CreateTeen(D3DVECTOR pos, float angle, float zoom, float height, + ObjectType type) +{ + CModFile* pModFile; + D3DMATRIX* mat; + D3DCOLORVALUE color; + int rank; + float fShadow; + BOOL bFloorAdjust = TRUE; + + if ( m_engine->RetRestCreate() < 1 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + SetType(type); + + fShadow = Norm(1.0f-height/10.0f); + + if ( type == OBJECT_TEEN0 ) // orange pencil lg=10 + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen0.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR( 5.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 2.5f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-2.5f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-5.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + + CreateShadowCircle(5.0f, 0.8f*fShadow, D3DSHADOWWORM); + } + + if ( type == OBJECT_TEEN1 ) // blue pencil lg=14 + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen1.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR( 6.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 4.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 2.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-2.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-4.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-6.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + + CreateShadowCircle(6.0f, 0.8f*fShadow, D3DSHADOWWORM); + } + + if ( type == OBJECT_TEEN2 ) // red pencil lg=16 + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen2.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR( 7.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 4.7f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 2.3f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-2.3f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-4.7f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-7.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + + CreateShadowCircle(6.0f, 0.8f*fShadow, D3DSHADOWWORM); + } + + if ( type == OBJECT_TEEN3 ) // jar with pencils + { + rank = m_engine->CreateObject(); +//? m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, TYPEMETAL); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen3.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 4.0f); + CreateShadowCircle(6.0f, 0.5f*fShadow); + } + + if ( type == OBJECT_TEEN4 ) // scissors + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen4.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-9.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-6.0f, 1.0f, 0.0f), 1.1f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-3.0f, 1.0f, 0.0f), 1.2f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 1.0f, 0.0f), 1.3f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 5.1f, 1.0f,-1.3f), 2.6f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 8.0f, 1.0f, 2.2f), 2.3f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 9.4f, 1.0f,-2.0f), 2.0f, SOUND_BOUMm, 0.45f); + + CreateShadowCircle(10.0f, 0.5f*fShadow, D3DSHADOWWORM); + } + + if ( type == OBJECT_TEEN5 ) // CD + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen5.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + SetFloorHeight(0.0f); + bFloorAdjust = FALSE; + + m_terrain->AddBuildingLevel(pos, 5.9f, 6.1f, 0.2f, 0.5f); + CreateShadowCircle(8.0f, 0.2f*fShadow); + } + + if ( type == OBJECT_TEEN6 ) // book 1 + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen6.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); + + CreateShadowCircle(20.0f, 0.2f*fShadow); + } + + if ( type == OBJECT_TEEN7 ) // book 2 + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen7.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); + + CreateShadowCircle(20.0f, 0.2f*fShadow); + } + + if ( type == OBJECT_TEEN8 ) // a stack of books 1 + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen8.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); + + SetGlobalSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 12.0f); + CreateShadowCircle(20.0f, 0.2f*fShadow); + } + + if ( type == OBJECT_TEEN9 ) // a stack of books 2 + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen9.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 7.5f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-5.0f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 4.5f, 3.0f,-7.5f), 5.0f, SOUND_BOUMm, 0.45f); + + SetGlobalSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 12.0f); + CreateShadowCircle(20.0f, 0.2f*fShadow); + } + + if ( type == OBJECT_TEEN10 ) // bookcase + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen10.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-26.0f, 3.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-15.0f, 3.0f,-4.0f), 6.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-15.0f, 3.0f, 5.0f), 6.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( -4.0f, 3.0f,-4.0f), 6.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( -4.0f, 3.0f, 5.0f), 6.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 6.0f, 3.0f,-4.0f), 6.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 6.0f, 3.0f, 4.0f), 6.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 14.0f, 3.0f,-3.0f), 6.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 14.0f, 3.0f, 2.0f), 6.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 24.0f, 3.0f, 5.0f), 6.0f, SOUND_BOUMm, 0.45f); + + SetGlobalSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 20.0f); + CreateShadowCircle(40.0f, 0.2f*fShadow); + } + + if ( type == OBJECT_TEEN11 ) // lamp + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen11.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetFloorHeight(0.0f); + SetZoom(0, zoom); + + mat = RetWorldMatrix(0); + pos = Transform(*mat, D3DVECTOR(-56.0f, 22.0f, 0.0f)); + m_particule->CreateParticule(pos, D3DVECTOR(0.0f, 0.0f, 0.0f), FPOINT(20.0f, 20.0f), PARTISELY, 1.0f, 0.0f, 0.0f); + + pos = Transform(*mat, D3DVECTOR(-65.0f, 40.0f, 0.0f)); + color.r = 4.0f; + color.g = 2.0f; + color.b = 0.0f; // yellow-orange + color.a = 0.0f; + m_main->CreateSpot(pos, color); + } + + if ( type == OBJECT_TEEN12 ) // coke + { + rank = m_engine->CreateObject(); +//? m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, TYPEMETAL); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen12.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 9.0f, 0.0f), 5.0f); + CreateShadowCircle(4.5f, 1.0f*fShadow); + } + + if ( type == OBJECT_TEEN13 ) // cardboard farm + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen13.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); + + SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 15.0f); + CreateShadowCircle(20.0f, 1.0f*fShadow); + } + + if ( type == OBJECT_TEEN14 ) // open box + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen14.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); + + SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 15.0f); + CreateShadowCircle(20.0f, 1.0f*fShadow); + } + + if ( type == OBJECT_TEEN15 ) // stack of cartons + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen15.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f,-7.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 10.0f, 4.0f, 7.0f), 5.0f, SOUND_BOUMm, 0.45f); + + SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 15.0f); + CreateShadowCircle(20.0f, 1.0f*fShadow); + } + + if ( type == OBJECT_TEEN16 ) // watering can + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen16.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-8.0f, 4.0f, 0.0f), 12.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 8.0f, 4.0f, 0.0f), 12.0f, SOUND_BOUMm, 0.45f); + + SetGlobalSphere(D3DVECTOR(0.0f, 13.0f, 0.0f), 20.0f); + CreateShadowCircle(18.0f, 1.0f*fShadow); + } + + if ( type == OBJECT_TEEN17 ) // wheel | + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen17.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR( 0.0f, 31.0f, 0.0f), 31.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 31.0f, 0.0f), 31.0f); + CreateShadowCircle(24.0f, 0.5f*fShadow); + } + + if ( type == OBJECT_TEEN18 ) // wheel / + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen18.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR( 0.0f, 31.0f, 0.0f), 31.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 31.0f, 0.0f), 31.0f); + CreateShadowCircle(24.0f, 0.5f*fShadow); + } + + if ( type == OBJECT_TEEN19 ) // wheel = + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen19.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR( 0.0f, 10.0f, 0.0f), 32.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 32.0f); + CreateShadowCircle(33.0f, 1.0f*fShadow); + } + + if ( type == OBJECT_TEEN20 ) // wall with shelf + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen20.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-175.0f, 0.0f, -5.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-175.0f, 0.0f, -35.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( -55.0f, 0.0f, -5.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( -55.0f, 0.0f, -35.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( -37.0f, 0.0f, -5.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( -37.0f, 0.0f, -35.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 83.0f, 0.0f, -5.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 83.0f, 0.0f, -35.0f), 4.0f, SOUND_BOUMm, 0.45f); + } + + if ( type == OBJECT_TEEN21 ) // wall with window + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen21.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + } + + if ( type == OBJECT_TEEN22 ) // wall with door and shelf + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen22.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-135.0f, 0.0f, -5.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-135.0f, 0.0f, -35.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( -15.0f, 0.0f, -5.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( -15.0f, 0.0f, -35.0f), 4.0f, SOUND_BOUMm, 0.45f); + } + + if ( type == OBJECT_TEEN23 ) // skateboard on wheels + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen23.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + if ( m_option == 1 ) // passage under the prohibited skateboard? + { + CreateCrashSphere(D3DVECTOR(-10.0f, 2.0f, 0.0f), 11.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 10.0f, 2.0f, 0.0f), 11.0f, SOUND_BOUMm, 0.45f); + } + + CreateCrashSphere(D3DVECTOR(-23.0f, 2.0f, 7.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-23.0f, 2.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-23.0f, 2.0f,-7.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 23.0f, 2.0f, 7.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 23.0f, 2.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 23.0f, 2.0f,-7.0f), 3.0f, SOUND_BOUMm, 0.45f); + + CreateShadowCircle(35.0f, 0.8f*fShadow, D3DSHADOWWORM); + } + + if ( type == OBJECT_TEEN24 ) // skate / + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen24.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-12.0f, 0.0f, -3.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-12.0f, 0.0f, 3.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateShadowCircle(20.0f, 0.2f*fShadow); + } + + if ( type == OBJECT_TEEN25 ) // skate / + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen25.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-12.0f, 0.0f, -3.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-12.0f, 0.0f, 3.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateShadowCircle(20.0f, 0.2f*fShadow); + } + + if ( type == OBJECT_TEEN26 ) // ceiling lamp + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen26.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + SetFloorHeight(0.0f); + + mat = RetWorldMatrix(0); + pos = Transform(*mat, D3DVECTOR(0.0f, 50.0f, 0.0f)); + m_particule->CreateParticule(pos, D3DVECTOR(0.0f, 0.0f, 0.0f), FPOINT(100.0f, 100.0f), PARTISELY, 1.0f, 0.0f, 0.0f); + + pos = Transform(*mat, D3DVECTOR(0.0f, 50.0f, 0.0f)); + color.r = 4.0f; + color.g = 2.0f; + color.b = 0.0f; // yellow-orange + color.a = 0.0f; + m_main->CreateSpot(pos, color); + } + + if ( type == OBJECT_TEEN27 ) // large plant? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen27.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f); + CreateShadowCircle(40.0f, 0.5f); + } + + if ( type == OBJECT_TEEN28 ) // bottle? + { + rank = m_engine->CreateObject(); +//? m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, TYPEMETAL); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen28.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 5.0f, SOUND_BOUM, 0.10f); + CreateShadowCircle(7.0f, 0.6f*fShadow); + } + + if ( type == OBJECT_TEEN29 ) // bridge? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen29.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + bFloorAdjust = FALSE; + } + + if ( type == OBJECT_TEEN30 ) // jump? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen30.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 15.0f, SOUND_BOUM, 0.10f); + SetGlobalSphere(D3DVECTOR(0.0f, 15.0f, 0.0f), 17.0f); + CreateShadowCircle(20.0f, 1.0f*fShadow); + } + + if ( type == OBJECT_TEEN31 ) // basket? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen31.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-10.0f, 2.0f, 0.0f), 5.0f, SOUND_BOUM, 0.10f); + CreateCrashSphere(D3DVECTOR( 0.0f, 2.0f, 0.0f), 6.0f, SOUND_BOUM, 0.10f); + CreateCrashSphere(D3DVECTOR( 9.0f, 4.0f, 1.0f), 6.0f, SOUND_BOUM, 0.10f); + + SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 10.0f); + CreateShadowCircle(16.0f, 0.6f*fShadow); + } + + if ( type == OBJECT_TEEN32 ) // chair? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen32.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR( 17.5f, 1.0f, 17.5f), 3.5f, SOUND_BOUM, 0.10f); + CreateCrashSphere(D3DVECTOR( 17.5f, 1.0f, -17.5f), 3.5f, SOUND_BOUM, 0.10f); + CreateCrashSphere(D3DVECTOR(-17.5f, 1.0f, 17.5f), 3.5f, SOUND_BOUM, 0.10f); + CreateCrashSphere(D3DVECTOR(-17.5f, 1.0f, -17.5f), 3.5f, SOUND_BOUM, 0.10f); + SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 26.0f); + CreateShadowCircle(35.0f, 0.3f*fShadow); + } + + if ( type == OBJECT_TEEN33 ) // panel? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen33.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f); + CreateShadowCircle(10.0f, 0.3f*fShadow); + } + + if ( type == OBJECT_TEEN34 ) // stone? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen34.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f); + CreateShadowCircle(3.0f, 1.0f*fShadow); + } + + if ( type == OBJECT_TEEN35 ) // pipe? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen35.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(-40.0f, 5.0f, 0.0f), 10.0f, SOUND_BOUM, 0.10f); + CreateCrashSphere(D3DVECTOR(-20.0f, 5.0f, 0.0f), 10.0f, SOUND_BOUM, 0.10f); + CreateCrashSphere(D3DVECTOR( 0.0f, 5.0f, 0.0f), 10.0f, SOUND_BOUM, 0.10f); + CreateCrashSphere(D3DVECTOR( 20.0f, 5.0f, 0.0f), 10.0f, SOUND_BOUM, 0.10f); + CreateCrashSphere(D3DVECTOR( 40.0f, 5.0f, 0.0f), 10.0f, SOUND_BOUM, 0.10f); + CreateShadowCircle(40.0f, 0.8f*fShadow, D3DSHADOWWORM); + } + + if ( type == OBJECT_TEEN36 ) // trunk? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen36.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + bFloorAdjust = FALSE; + } + + if ( type == OBJECT_TEEN37 ) // boat? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen37.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + bFloorAdjust = FALSE; + } + + if ( type == OBJECT_TEEN38 ) // fan? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen38a.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(1, rank); + SetObjectParent(1, 0); + pModFile->ReadModel("objects\\teen38b.mod"); // engine + pModFile->CreateEngineObject(rank); + SetPosition(1, D3DVECTOR(0.0f, 30.0f, 0.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(2, rank); + SetObjectParent(2, 1); + pModFile->ReadModel("objects\\teen38c.mod"); // propeller + pModFile->CreateEngineObject(rank); + SetPosition(2, D3DVECTOR(0.0f, 0.0f, 0.0f)); + + CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 10.0f, SOUND_BOUM, 0.10f); + SetGlobalSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 10.0f); + CreateShadowCircle(15.0f, 0.5f*fShadow); + } + + if ( type == OBJECT_TEEN39 ) // potted plant? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen39.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 8.5f, SOUND_BOUM, 0.10f); + SetGlobalSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 8.5f); + CreateShadowCircle(10.0f, 1.0f*fShadow); + } + + if ( type == OBJECT_TEEN40 ) // balloon? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen40.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 11.0f, SOUND_BOUM, 0.10f); + SetGlobalSphere(D3DVECTOR(0.0f, 14.0f, 0.0f), 15.0f); + CreateShadowCircle(15.0f, 0.7f*fShadow); + } + + if ( type == OBJECT_TEEN41 ) // fence? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen41.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + } + + if ( type == OBJECT_TEEN42 ) // clover? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen42.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 2.0f, SOUND_BOUM, 0.10f); + CreateShadowCircle(15.0f, 0.4f*fShadow); + } + + if ( type == OBJECT_TEEN43 ) // clover? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen43.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 2.0f, SOUND_BOUM, 0.10f); + CreateShadowCircle(15.0f, 0.4f*fShadow); + } + + if ( type == OBJECT_TEEN44 ) // car? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\teen44.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, zoom); + + CreateCrashSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 55.0f, SOUND_BOUM, 0.10f); + SetGlobalSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 55.0f); + CreateShadowCircle(55.0f, 1.0f*fShadow); + } + + pos = RetPosition(0); + SetPosition(0, pos); // to display the shadows immediately + + if ( bFloorAdjust ) + { + SetFloorHeight(0.0f); + FloorAdjust(); + } + + CreateOtherObject(type); + + pos = RetPosition(0); + pos.y += height; + SetPosition(0, pos); + + delete pModFile; + return TRUE; +} + +// Creates a crystal placed on the ground. + +BOOL CObject::CreateQuartz(D3DVECTOR pos, float angle, float height, + ObjectType type) +{ + CModFile* pModFile; + float radius; + int rank; + + if ( m_engine->RetRestCreate() < 1 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + SetType(type); + + if ( type == OBJECT_QUARTZ0 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEQUARTZ); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\quartz0.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 3.5f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 3.5f); + + CreateShadowCircle(4.0f, 0.5f); + } + if ( type == OBJECT_QUARTZ1 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEQUARTZ); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\quartz1.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 5.0f); + + CreateShadowCircle(5.0f, 0.5f); + } + if ( type == OBJECT_QUARTZ2 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEQUARTZ); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\quartz2.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 6.0f); + + CreateShadowCircle(6.0f, 0.5f); + } + if ( type == OBJECT_QUARTZ3 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEQUARTZ); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\quartz3.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + + CreateCrashSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 10.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 10.0f); + + CreateShadowCircle(10.0f, 0.5f); + } + + pos = RetPosition(0); + SetPosition(0, pos); // to display the shadows immediately + + SetFloorHeight(0.0f); + CreateOtherObject(type); + + pos = RetPosition(0); + pos.y += height; + SetPosition(0, pos); + + if ( type == OBJECT_QUARTZ0 ) + { + pos.y += 4.0f; + radius = 2.0f; + } + if ( type == OBJECT_QUARTZ1 ) + { + pos.y += 6.0f; + radius = 4.0f; + } + if ( type == OBJECT_QUARTZ2 ) + { + pos.y += 10.0f; + radius = 5.0f; + } + if ( type == OBJECT_QUARTZ3 ) + { + pos.y += 16.0f; + radius = 8.0f; + } + m_particule->CreateParticule(pos, pos, FPOINT(2.0f, 2.0f), PARTIQUARTZ, 0.7f+Rand()*0.7f, radius, 0.0f); + m_particule->CreateParticule(pos, pos, FPOINT(2.0f, 2.0f), PARTIQUARTZ, 0.7f+Rand()*0.7f, radius, 0.0f); + + delete pModFile; + return TRUE; +} + +// Creates a root placed on the ground. + +BOOL CObject::CreateRoot(D3DVECTOR pos, float angle, float height, + ObjectType type) +{ + CModFile* pModFile; + int rank; + + if ( m_engine->RetRestCreate() < 1 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + SetType(type); + + if ( type == OBJECT_ROOT0 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\root0.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, 2.0f); + + CreateCrashSphere(D3DVECTOR(-5.0f, 1.0f, 0.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 4.0f, 1.0f, 2.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 4.0f, 1.0f, -3.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 2.0f, 5.0f, -1.0f), 1.5f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR(-4.0f, 5.0f, -1.0f), 1.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR(-2.0f, 8.0f, -0.5f), 1.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 0.0f, 10.0f, -0.5f), 1.0f, SOUND_BOUMv, 0.15f); +//? SetGlobalSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 11.0f); + + CreateShadowCircle(16.0f, 0.5f); + } + if ( type == OBJECT_ROOT1 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\root1.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, 2.0f); + + CreateCrashSphere(D3DVECTOR(-4.0f, 1.0f, 1.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 0.0f, 1.0f, 2.0f), 1.5f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 3.0f, 1.0f, -2.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR(-2.0f, 5.0f, 1.0f), 1.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 2.0f, 5.0f, 0.0f), 1.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 0.0f, 8.0f, 1.0f), 1.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 0.0f, 12.0f, 1.0f), 1.0f, SOUND_BOUMv, 0.15f); +//? SetGlobalSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 12.0f); + + CreateShadowCircle(16.0f, 0.5f); + } + if ( type == OBJECT_ROOT2 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\root2.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, 2.0f); + + CreateCrashSphere(D3DVECTOR(-3.0f, 1.0f, 0.5f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 3.0f, 1.0f, -1.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR(-1.0f, 4.5f, 0.0f), 1.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 3.0f, 7.0f, 1.0f), 1.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 0.0f, 7.0f, -1.0f), 1.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 4.0f, 11.0f, 1.0f), 1.0f, SOUND_BOUMv, 0.15f); +//? SetGlobalSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 10.0f); + + CreateShadowCircle(16.0f, 0.5f); + } + if ( type == OBJECT_ROOT3 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\root3.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, 2.0f); + + CreateCrashSphere(D3DVECTOR(-4.0f, 1.0f, 1.0f), 3.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 4.0f, 1.0f, -3.0f), 3.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 6.0f, 1.0f, 4.0f), 3.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR(-2.5f, 7.0f, 2.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 4.0f, 7.0f, 2.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 3.0f, 6.0f, -1.0f), 1.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 0.0f, 12.0f, 0.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 1.0f, 16.0f, 0.0f), 1.0f, SOUND_BOUMv, 0.15f); +//? SetGlobalSphere(D3DVECTOR(0.0f, 10.0f, 0.0f), 14.0f); + + CreateShadowCircle(22.0f, 0.5f); + } + if ( type == OBJECT_ROOT4 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\root4.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, 2.0f); + + CreateCrashSphere(D3DVECTOR( -7.0f, 2.0f, 3.0f), 4.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 5.0f, 2.0f, -6.0f), 4.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 6.0f, 2.0f, 6.0f), 3.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR(-11.0f, 1.0f, -2.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 1.0f, 1.0f, -7.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( -4.0f, 10.0f, 3.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 1.0f, 11.0f, 7.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 3.0f, 11.0f, -3.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( -3.0f, 17.0f, 1.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( -3.0f, 23.0f, -1.0f), 2.0f, SOUND_BOUMv, 0.15f); +//? SetGlobalSphere(D3DVECTOR(0.0f, 12.0f, 0.0f), 20.0f); + + CreateShadowCircle(30.0f, 0.5f); + } + if ( type == OBJECT_ROOT5 ) // gravity root ? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\root4.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, 2.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(1, rank); + SetObjectParent(1, 0); + pModFile->ReadModel("objects\\root5.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(1, D3DVECTOR(-5.0f, 28.0f, -4.0f)); + SetAngleX(1, -30.0f*PI/180.0f); + SetAngleZ(1, 20.0f*PI/180.0f); + + CreateCrashSphere(D3DVECTOR( -7.0f, 2.0f, 3.0f), 4.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 5.0f, 2.0f, -6.0f), 4.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 6.0f, 2.0f, 6.0f), 3.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR(-11.0f, 1.0f, -2.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 1.0f, 1.0f, -7.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( -4.0f, 10.0f, 3.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 1.0f, 11.0f, 7.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( 3.0f, 11.0f, -3.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( -3.0f, 17.0f, 1.0f), 2.0f, SOUND_BOUMv, 0.15f); + CreateCrashSphere(D3DVECTOR( -3.0f, 23.0f, -1.0f), 2.0f, SOUND_BOUMv, 0.15f); +//? SetGlobalSphere(D3DVECTOR(0.0f, 12.0f, 0.0f), 20.0f); + + CreateShadowCircle(30.0f, 0.5f); + } + + pos = RetPosition(0); + SetPosition(0, pos); // to display the shadows immediately + + SetFloorHeight(0.0f); + CreateOtherObject(type); + + pos = RetPosition(0); + pos.y += height; + SetPosition(0, pos); + + delete pModFile; + return TRUE; +} + +// Creates a small home. + +BOOL CObject::CreateHome(D3DVECTOR pos, float angle, float height, + ObjectType type) +{ + CModFile* pModFile; + int rank; + + if ( m_engine->RetRestCreate() < 1 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + SetType(type); + + if ( type == OBJECT_HOME1 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\home1.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, 1.3f); + + CreateCrashSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 10.0f, SOUND_BOUMs, 0.25f); +//? SetGlobalSphere(D3DVECTOR(0.0f, 6.0f, 0.0f), 11.0f); + CreateShadowCircle(16.0f, 0.5f); + } + + pos = RetPosition(0); + SetPosition(0, pos); // to display the shadows immediately + + SetFloorHeight(0.0f); + CreateOtherObject(type); + + pos = RetPosition(0); + pos.y += height; + SetPosition(0, pos); + + delete pModFile; + return TRUE; +} + +// Creates ruin placed on the ground. + +BOOL CObject::CreateRuin(D3DVECTOR pos, float angle, float height, + ObjectType type) +{ + CModFile* pModFile; + char name[50]; + int rank; + + if ( m_engine->RetRestCreate() < 1+4 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + SetType(type); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object + SetObjectRank(0, rank); + + name[0] = 0; + if ( type == OBJECT_RUINmobilew1 ) strcpy(name, "objects\\ruin1.mod"); + if ( type == OBJECT_RUINmobilew2 ) strcpy(name, "objects\\ruin1.mod"); + if ( type == OBJECT_RUINmobilet1 ) strcpy(name, "objects\\ruin2.mod"); + if ( type == OBJECT_RUINmobilet2 ) strcpy(name, "objects\\ruin2.mod"); + if ( type == OBJECT_RUINmobiler1 ) strcpy(name, "objects\\ruin3.mod"); + if ( type == OBJECT_RUINmobiler2 ) strcpy(name, "objects\\ruin3.mod"); + if ( type == OBJECT_RUINfactory ) strcpy(name, "objects\\ruin4.mod"); + if ( type == OBJECT_RUINdoor ) strcpy(name, "objects\\ruin5.mod"); + if ( type == OBJECT_RUINsupport ) strcpy(name, "objects\\ruin6.mod"); + if ( type == OBJECT_RUINradar ) strcpy(name, "objects\\ruin7.mod"); + if ( type == OBJECT_RUINconvert ) strcpy(name, "objects\\ruin8.mod"); + if ( type == OBJECT_RUINbase ) strcpy(name, "objects\\ruin9.mod"); + if ( type == OBJECT_RUINhead ) strcpy(name, "objects\\ruin10.mod"); + + pModFile->ReadModel(name); + pModFile->CreateEngineObject(rank); + + SetPosition(0, pos); + SetAngleY(0, angle); + + if ( type == OBJECT_RUINmobilew1 ) // vehicle had wheels? + { + // Creates the right-back wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(6, rank); + SetObjectParent(6, 0); + + pModFile->ReadModel("objects\\ruin1w.mod"); + pModFile->CreateEngineObject(rank); + + SetPosition(6, D3DVECTOR(-3.0f, 1.8f, -4.0f)); + SetAngleX(6, -PI/2.0f); + + // Creates the left-back wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(7, rank); + SetObjectParent(7, 0); + + pModFile->ReadModel("objects\\ruin1w.mod"); + pModFile->CreateEngineObject(rank); + + SetPosition(7, D3DVECTOR(-3.0f, 1.0f, 3.0f)); + SetAngleY(7, PI-0.3f); + SetAngleX(7, -0.3f); + + // Creates the right-front wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(8, rank); + SetObjectParent(8, 0); + + pModFile->ReadModel("objects\\ruin1w.mod"); + pModFile->CreateEngineObject(rank); + + SetPosition(8, D3DVECTOR(2.0f, 1.6f, -3.0f)); + SetAngleY(8, 0.3f); + + // Creates the left-front wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(9, rank); + SetObjectParent(9, 0); + + pModFile->ReadModel("objects\\ruin1w.mod"); + pModFile->CreateEngineObject(rank); + + SetPosition(9, D3DVECTOR(2.0f, 1.0f, 3.0f)); + SetAngleY(9, PI-0.2f); + SetAngleX(9, 0.2f); + + CreateCrashSphere(D3DVECTOR(0.0f, 2.8f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); +//? SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 10.0f); + + CreateShadowCircle(4.0f, 1.0f); + } + + if ( type == OBJECT_RUINmobilew2 ) // vehicle has wheels? + { + // Creates the left-back wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(7, rank); + SetObjectParent(7, 0); + + pModFile->ReadModel("objects\\ruin1w.mod"); + pModFile->CreateEngineObject(rank); + + SetPosition(7, D3DVECTOR(-3.0f, 1.0f, 3.0f)); + SetAngleY(7, PI+0.3f); + SetAngleX(7, 0.4f); + + // Creates the left-front wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(9, rank); + SetObjectParent(9, 0); + + pModFile->ReadModel("objects\\ruin1w.mod"); + pModFile->CreateEngineObject(rank); + + SetPosition(9, D3DVECTOR(2.0f, 1.0f, 3.0f)); + SetAngleY(9, PI+0.3f); + SetAngleX(9, -0.3f); + + CreateCrashSphere(D3DVECTOR(0.0f, 2.8f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); +//? SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 10.0f); + + CreateShadowCircle(4.0f, 1.0f); + } + + if ( type == OBJECT_RUINmobilet1 ) // vehicle have caterpillars? + { + // Creates the cannon. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(1, rank); + SetObjectParent(1, 0); + + pModFile->ReadModel("objects\\ruin2c.mod"); + pModFile->CreateEngineObject(rank); + + SetPosition(1, D3DVECTOR(3.0f, 5.0f, -2.5f)); + SetAngleX(1, -PI*0.85f); + SetAngleY(1, -0.4f); + SetAngleZ(1, -0.1f); + + CreateCrashSphere(D3DVECTOR(1.0f, 2.8f, -1.0f), 5.0f, SOUND_BOUMm, 0.45f); +//? SetGlobalSphere(D3DVECTOR(1.0f, 5.0f, -1.0f), 10.0f); + + CreateShadowCircle(5.0f, 1.0f); + } + + if ( type == OBJECT_RUINmobilet2 ) // vehicle have caterpillars? + { + CreateCrashSphere(D3DVECTOR(0.0f, 2.8f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); +//? SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 10.0f); + + CreateShadowCircle(5.0f, 1.0f); + } + + if ( type == OBJECT_RUINmobiler1 ) // vehicle skating? + { + CreateCrashSphere(D3DVECTOR(1.0f, 2.8f, -1.0f), 5.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(1.0f, 5.0f, -1.0f), 10.0f); + + CreateShadowCircle(5.0f, 1.0f); + } + + if ( type == OBJECT_RUINmobiler2 ) // vehicle skating? + { + CreateCrashSphere(D3DVECTOR(0.0f, 1.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 5.0f, 0.0f), 10.0f); + + CreateShadowCircle(6.0f, 1.0f); + } + + if ( type == OBJECT_RUINfactory ) // factory ? + { + CreateCrashSphere(D3DVECTOR( 9.0f, 1.0f, -11.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 2.0f, -11.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, -10.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-12.0f, 11.0f, -4.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-10.0f, 4.0f, -2.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-11.0f, 8.0f, 3.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-11.0f, 2.0f, 4.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-11.0f, 2.0f, 10.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( -4.0f, 0.0f, 10.0f), 3.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 18.0f); + + CreateShadowCircle(20.0f, 0.7f); + } + + if ( type == OBJECT_RUINdoor ) // converter holder? + { + CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); +//? SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 6.0f); + + CreateShadowCircle(6.0f, 1.0f); + } + + if ( type == OBJECT_RUINsupport ) // radar holder? + { + CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); +//? SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 4.0f); + + CreateShadowCircle(3.0f, 1.0f); + } + + if ( type == OBJECT_RUINradar ) // radar base? + { + CreateCrashSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); +//? SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 6.0f); + + CreateShadowCircle(6.0f, 1.0f); + } + + if ( type == OBJECT_RUINconvert ) // converter? + { + m_terrain->AddBuildingLevel(pos, 7.0f, 9.0f, 1.0f, 0.5f); + + CreateCrashSphere(D3DVECTOR(-10.0f, 0.0f, 4.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-10.0f, 0.0f, -4.0f), 5.0f, SOUND_BOUMm, 0.45f); +//? SetGlobalSphere(D3DVECTOR(-3.0f, 0.0f, 0.0f), 14.0f); + } + + if ( type == OBJECT_RUINbase ) // base? + { + CreateCrashSphere(D3DVECTOR( 0.0f, 15.0f, 0.0f),28.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 17.0f, 6.0f, 42.0f), 6.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 17.0f, 17.0f, 42.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-17.0f, 6.0f, 42.0f), 6.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-17.0f, 17.0f, 42.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-42.0f, 6.0f, 17.0f), 6.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-42.0f, 17.0f, 17.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-42.0f, 6.0f, -17.0f), 6.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-42.0f, 17.0f, -17.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-17.0f, 6.0f, -42.0f), 6.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-17.0f, 10.0f, -42.0f), 4.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 15.0f, 13.0f, -34.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 31.0f, 15.0f, -13.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 21.0f, 8.0f, -39.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 26.0f, 8.0f, -33.0f), 5.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 48.0f); + + CreateShadowCircle(40.0f, 1.0f); + } + + if ( type == OBJECT_RUINhead ) // base cap? + { + CreateCrashSphere(D3DVECTOR( 0.0f, 13.0f, 0.0f),20.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, -8.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f,-16.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f,-22.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-21.0f, 7.0f, 9.0f), 8.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( -9.0f, 7.0f, 21.0f), 8.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 21.0f, 7.0f, 9.0f), 8.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 9.0f, 7.0f, 21.0f), 8.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-21.0f, 7.0f, -9.0f), 8.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( -9.0f, 7.0f, -21.0f), 8.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 21.0f, 7.0f, -9.0f), 8.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 9.0f, 7.0f, -21.0f), 8.0f, SOUND_BOUMm, 0.45f); + SetGlobalSphere(D3DVECTOR(0.0f, 0.0f, 0.0f), 35.0f); + + CreateShadowCircle(30.0f, 1.0f); + } + + pos = RetPosition(0); + SetPosition(0, pos); //to display the shadows immediately + + SetFloorHeight(0.0f); + CreateOtherObject(type); + + if ( type != OBJECT_RUINfactory && + type != OBJECT_RUINconvert && + type != OBJECT_RUINbase ) + { + FloorAdjust(); + } + + pos = RetPosition(0); + pos.y += height; + SetPosition(0, pos); //to display the shadows immediately + + if ( type == OBJECT_RUINmobilew1 ) + { + pos = RetPosition(0); + pos.y -= 0.5f; + SetPosition(0, pos); + + angle = RetAngleX(0)-0.1f; + SetAngleX(0, angle); + } + + if ( type == OBJECT_RUINmobilew2 ) + { + pos = RetPosition(0); + pos.y -= 1.5f; + SetPosition(0, pos); + + angle = RetAngleX(0)-0.9f; + SetAngleX(0, angle); + + angle = RetAngleZ(0)-0.1f; + SetAngleZ(0, angle); + } + + if ( type == OBJECT_RUINmobilet1 ) + { + pos = RetPosition(0); + pos.y -= 0.9f; + SetPosition(0, pos); + + angle = RetAngleX(0)-0.3f; + SetAngleX(0, angle); + } + + if ( type == OBJECT_RUINmobilet2 ) + { + pos = RetPosition(0); + pos.y -= 1.5f; + SetPosition(0, pos); + + angle = RetAngleX(0)-0.3f; + SetAngleX(0, angle); + + angle = RetAngleZ(0)+0.8f; + SetAngleZ(0, angle); + } + + if ( type == OBJECT_RUINmobiler1 ) + { + pos = RetPosition(0); + pos.y += 4.0f; + SetPosition(0, pos); + + angle = RetAngleX(0)-PI*0.6f; + SetAngleX(0, angle); + + angle = RetAngleZ(0)-0.2f; + SetAngleZ(0, angle); + } + + if ( type == OBJECT_RUINmobiler2 ) + { + pos = RetPosition(0); + pos.y += 2.0f; + SetPosition(0, pos); + + angle = RetAngleX(0)-0.1f; + SetAngleX(0, angle); + + angle = RetAngleZ(0)-0.3f; + SetAngleZ(0, angle); + } + + if ( type == OBJECT_RUINdoor ) + { + pos = RetPosition(0); + pos.y -= 0.5f; + SetPosition(0, pos); + + angle = RetAngleZ(0)-0.1f; + SetAngleZ(0, angle); + } + + if ( type == OBJECT_RUINsupport ) + { + pos = RetPosition(0); + pos.y += 0.5f; + SetPosition(0, pos); + +//? angle = RetAngleY(0)+0.1f; +//? SetAngleY(0, angle); + + angle = RetAngleX(0)+0.1f; + SetAngleX(0, angle); + + angle = RetAngleZ(0)+0.1f; + SetAngleZ(0, angle); + } + + if ( type == OBJECT_RUINradar ) + { + pos = RetPosition(0); + pos.y -= 0.5f; + SetPosition(0, pos); + + angle = RetAngleX(0)+0.15f; + SetAngleX(0, angle); + + angle = RetAngleZ(0)+0.1f; + SetAngleZ(0, angle); + } + + if ( type == OBJECT_RUINconvert ) + { + pos = RetPosition(0); + pos.y -= 1.0f; + SetPosition(0, pos); + } + + if ( type == OBJECT_RUINbase ) + { + pos = RetPosition(0); + pos.y -= 1.0f; + SetPosition(0, pos); + + angle = RetAngleX(0)+0.15f; + SetAngleX(0, angle); + } + + if ( type == OBJECT_RUINhead ) + { + pos = RetPosition(0); + pos.y += 8.0f; + SetPosition(0, pos); + + angle = RetAngleX(0)+PI*0.4f; + SetAngleX(0, angle); + } + + delete pModFile; + return TRUE; +} + +// Creates a gadget apollo. + +BOOL CObject::CreateApollo(D3DVECTOR pos, float angle, ObjectType type) +{ + CModFile* pModFile; + int rank, i; + + if ( m_engine->RetRestCreate() < 6 ) return FALSE; + + pModFile = new CModFile(m_iMan); + + SetType(type); + + if ( type == OBJECT_APOLLO1 ) // LEM ? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\apollol1.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetZoom(0, 1.2f); + SetFloorHeight(0.0f); + + for ( i=0 ; i<4 ; i++ ) // creates feet + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(i+1, rank); + SetObjectParent(i+1, 0); + pModFile->ReadModel("objects\\apollol2.mod"); + pModFile->CreateEngineObject(rank); + SetAngleY(i+1, PI/2.0f*i); + } + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(5, rank); + SetObjectParent(5, 0); + pModFile->ReadModel("objects\\apollol3.mod"); // ladder + pModFile->CreateEngineObject(rank); + +//? m_terrain->AddBuildingLevel(pos, 10.0f, 13.0f, 12.0f, 0.0f); + + CreateCrashSphere(D3DVECTOR( 0.0f, 4.0f, 0.0f), 9.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 11.0f, 5.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-11.0f, 5.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 5.0f, -11.0f), 3.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 0.0f, 5.0f, 11.0f), 3.0f, SOUND_BOUMm, 0.45f); + + SetGlobalSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 9.0f); + + CreateShadowCircle(16.0f, 0.5f); + } + + if ( type == OBJECT_APOLLO2 ) // jeep + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); //it is a stationary object + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\apolloj1.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetFloorHeight(0.0f); + + // Wheels. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(1, rank); + SetObjectParent(1, 0); + pModFile->ReadModel("objects\\apolloj4.mod"); // wheel + pModFile->CreateEngineObject(rank); + SetPosition(1, D3DVECTOR(-5.75f, 1.65f, -5.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(2, rank); + SetObjectParent(2, 0); + pModFile->ReadModel("objects\\apolloj4.mod"); // wheel + pModFile->CreateEngineObject(rank); + SetPosition(2, D3DVECTOR(-5.75f, 1.65f, 5.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(3, rank); + SetObjectParent(3, 0); + pModFile->ReadModel("objects\\apolloj4.mod"); // wheel + pModFile->CreateEngineObject(rank); + SetPosition(3, D3DVECTOR(5.75f, 1.65f, -5.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(4, rank); + SetObjectParent(4, 0); + pModFile->ReadModel("objects\\apolloj4.mod"); // wheel + pModFile->CreateEngineObject(rank); + SetPosition(4, D3DVECTOR(5.75f, 1.65f, 5.0f)); + + // Accessories: + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(5, rank); + SetObjectParent(5, 0); + pModFile->ReadModel("objects\\apolloj2.mod"); // antenna + pModFile->CreateEngineObject(rank); + SetPosition(5, D3DVECTOR(5.5f, 8.8f, 2.0f)); + SetAngleY(5, -120.0f*PI/180.0f); + SetAngleZ(5, 45.0f*PI/180.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(6, rank); + SetObjectParent(6, 0); + pModFile->ReadModel("objects\\apolloj3.mod"); // camera + pModFile->CreateEngineObject(rank); + SetPosition(6, D3DVECTOR(5.5f, 2.8f, -2.0f)); + SetAngleY(6, 30.0f*PI/180.0f); + + CreateCrashSphere(D3DVECTOR( 3.0f, 2.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR(-3.0f, 2.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + CreateCrashSphere(D3DVECTOR( 7.0f, 9.0f, 2.0f), 2.0f, SOUND_BOUMm, 0.20f); + + CreateShadowCircle(7.0f, 0.8f); + + FloorAdjust(); + } + + if ( type == OBJECT_APOLLO3 ) // flag? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\apollof.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetFloorHeight(0.0f); + + SetJotlerSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 1.0f); + CreateShadowCircle(2.0f, 0.3f); + } + + if ( type == OBJECT_APOLLO4 ) // module? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\apollom.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetFloorHeight(0.0f); + + CreateCrashSphere(D3DVECTOR(0.0f, 2.0f, 0.0f), 2.0f, SOUND_BOUMm, 0.45f); + CreateShadowCircle(5.0f, 0.8f); + + FloorAdjust(); + } + + if ( type == OBJECT_APOLLO5 ) // antenna? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object + SetObjectRank(0, rank); + pModFile->ReadModel("objects\\apolloa.mod"); + pModFile->CreateEngineObject(rank); + SetPosition(0, pos); + SetAngleY(0, angle); + SetFloorHeight(0.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + SetObjectRank(1, rank); + SetObjectParent(1, 0); + pModFile->ReadModel("objects\\apolloj2.mod"); // antenna + pModFile->CreateEngineObject(rank); + SetPosition(1, D3DVECTOR(0.0f, 5.0f, 0.0f)); + SetAngleY(1, -120.0f*PI/180.0f); + SetAngleZ(1, 45.0f*PI/180.0f); + + CreateCrashSphere(D3DVECTOR(0.0f, 4.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.35f); + CreateShadowCircle(3.0f, 0.7f); + } + + CreateOtherObject(type); + + pos = RetPosition(0); + SetPosition(0, pos); // to display the shadows immediately + + delete pModFile; + return TRUE; +} + +// Creates all sub-objects for managing the object. + +void CObject::CreateOtherObject(ObjectType type) +{ + if ( type == OBJECT_BASE ) + { + m_auto = new CAutoBase(m_iMan, this); + } + if ( type == OBJECT_PORTICO ) + { + m_auto = new CAutoPortico(m_iMan, this); + } + if ( type == OBJECT_DERRICK ) + { + m_auto = new CAutoDerrick(m_iMan, this); + } + if ( type == OBJECT_FACTORY ) + { + m_auto = new CAutoFactory(m_iMan, this); + } + if ( type == OBJECT_REPAIR ) + { + m_auto = new CAutoRepair(m_iMan, this); + } + if ( type == OBJECT_DESTROYER ) + { + m_auto = new CAutoDestroyer(m_iMan, this); + } + if ( type == OBJECT_STATION ) + { + m_auto = new CAutoStation(m_iMan, this); + } + if ( type == OBJECT_CONVERT ) + { + m_auto = new CAutoConvert(m_iMan, this); + } + if ( type == OBJECT_TOWER ) + { + m_auto = new CAutoTower(m_iMan, this); + } + if ( type == OBJECT_RESEARCH ) + { + m_auto = new CAutoResearch(m_iMan, this); + } + if ( type == OBJECT_RADAR ) + { + m_auto = new CAutoRadar(m_iMan, this); + } + if ( type == OBJECT_INFO ) + { + m_auto = new CAutoInfo(m_iMan, this); + } + if ( type == OBJECT_ENERGY ) + { + m_auto = new CAutoEnergy(m_iMan, this); + } + if ( type == OBJECT_LABO ) + { + m_auto = new CAutoLabo(m_iMan, this); + } + if ( type == OBJECT_NUCLEAR ) + { + m_auto = new CAutoNuclear(m_iMan, this); + } + if ( type == OBJECT_PARA ) + { + m_auto = new CAutoPara(m_iMan, this); + } + if ( type == OBJECT_SAFE ) + { + m_auto = new CAutoSafe(m_iMan, this); + } + if ( type == OBJECT_HUSTON ) + { + m_auto = new CAutoHuston(m_iMan, this); + } + if ( type == OBJECT_EGG ) + { + m_auto = new CAutoEgg(m_iMan, this); + } + if ( type == OBJECT_NEST ) + { + m_auto = new CAutoNest(m_iMan, this); + } + if ( type == OBJECT_ROOT5 ) + { + m_auto = new CAutoRoot(m_iMan, this); + } + if ( type == OBJECT_MUSHROOM2 ) + { + m_auto = new CAutoMush(m_iMan, this); + } + if ( type == OBJECT_FLAGb || + type == OBJECT_FLAGr || + type == OBJECT_FLAGg || + type == OBJECT_FLAGy || + type == OBJECT_FLAGv ) + { + m_auto = new CAutoFlag(m_iMan, this); + } + if ( type == OBJECT_TEEN36 || // trunk? + type == OBJECT_TEEN37 || // boat? + type == OBJECT_TEEN38 ) // fan? + { + m_auto = new CAutoKid(m_iMan, this); + } +} + + +// Reads a program. + +BOOL CObject::ReadProgram(int rank, char* filename) +{ + if ( m_brain != 0 ) + { + return m_brain->ReadProgram(rank, filename); + } + return FALSE; +} + +// Writes a program. + +BOOL CObject::WriteProgram(int rank, char* filename) +{ + if ( m_brain != 0 ) + { + return m_brain->WriteProgram(rank, filename); + } + return FALSE; +} + +// Starts a program. + +BOOL CObject::RunProgram(int rank) +{ + if ( m_brain != 0 ) + { + m_brain->RunProgram(rank); + return TRUE; + } + if ( m_auto != 0 ) + { + m_auto->Start(rank); + return TRUE; + } + return FALSE; +} + + + + +// Calculates the matrix for transforming the object. +// Returns TRUE if the matrix has changed. +// The rotations occur in the order Y, Z and X. + +BOOL CObject::UpdateTransformObject(int part, BOOL bForceUpdate) +{ + D3DVECTOR position, angle, eye; + BOOL bModif = FALSE; + int parent; + + if ( m_truck != 0 ) // transported by truck? + { + m_objectPart[part].bTranslate = TRUE; + m_objectPart[part].bRotate = TRUE; + } + + if ( !bForceUpdate && + !m_objectPart[part].bTranslate && + !m_objectPart[part].bRotate ) return FALSE; + + position = m_objectPart[part].position; + angle = m_objectPart[part].angle; + + if ( part == 0 ) // main part? + { + position += m_linVibration; + angle += m_cirVibration+m_inclinaison; + } + + if ( m_objectPart[part].bTranslate || + m_objectPart[part].bRotate ) + { + if ( m_objectPart[part].bTranslate ) + { + D3DUtil_SetIdentityMatrix(m_objectPart[part].matTranslate); + m_objectPart[part].matTranslate._41 = position.x; + m_objectPart[part].matTranslate._42 = position.y; + m_objectPart[part].matTranslate._43 = position.z; + } + + if ( m_objectPart[part].bRotate ) + { + MatRotateZXY(m_objectPart[part].matRotate, angle); + } + + if ( m_objectPart[part].bZoom ) + { + D3DMATRIX mz; + D3DUtil_SetIdentityMatrix(mz); + mz._11 = m_objectPart[part].zoom.x; + mz._22 = m_objectPart[part].zoom.y; + mz._33 = m_objectPart[part].zoom.z; + m_objectPart[part].matTransform = mz * + m_objectPart[part].matRotate * + m_objectPart[part].matTranslate; + } + else + { + m_objectPart[part].matTransform = m_objectPart[part].matRotate * + m_objectPart[part].matTranslate; + } + bModif = TRUE; + } + + if ( bForceUpdate || + m_objectPart[part].bTranslate || + m_objectPart[part].bRotate ) + { + parent = m_objectPart[part].parentPart; + + if ( part == 0 && m_truck != 0 ) // transported by a truck? + { + D3DMATRIX* matWorldTruck; + matWorldTruck = m_truck->RetWorldMatrix(m_truckLink); + m_objectPart[part].matWorld = m_objectPart[part].matTransform * + *matWorldTruck; + } + else + { + if ( parent == -1 ) // no parent? + { + m_objectPart[part].matWorld = m_objectPart[part].matTransform; + } + else + { + m_objectPart[part].matWorld = m_objectPart[part].matTransform * + m_objectPart[parent].matWorld; + } + } + bModif = TRUE; + } + + if ( bModif ) + { + m_engine->SetObjectTransform(m_objectPart[part].object, + m_objectPart[part].matWorld); + } + + m_objectPart[part].bTranslate = FALSE; + m_objectPart[part].bRotate = FALSE; + + return bModif; +} + +// Updates all matrices to transform the object father and all his sons. +// Assume a maximum of 4 degrees of freedom. +// Appropriate, for example, to a body, an arm, forearm, hand and fingers. + +BOOL CObject::UpdateTransformObject() +{ + BOOL bUpdate1, bUpdate2, bUpdate3, bUpdate4; + int level1, level2, level3, level4, rank; + int parent1, parent2, parent3, parent4; + + if ( m_bFlat ) + { + for ( level1=0 ; level1RetLimitLOD(0); + limit[2] = limit[1]; + limit[3] = m_engine->RetLimitLOD(1); + limit[4] = limit[3]; + limit[5] = 1000000.0f; + + for ( j=0 ; j<3 ; j++ ) + { + m_engine->ChangeTextureMapping(m_objectPart[0].object, + mat, D3DSTATEPART3, "lemt.tga", "", + limit[j*2+0], limit[j*2+1], D3DMAPPING1Y, + au, bu, 1.0f, 0.0f); + } +} + + +// Manual action. + +BOOL CObject::EventProcess(const Event &event) +{ + if ( event.event == EVENT_KEYDOWN ) + { +#if ADJUST_ONBOARD + if ( m_bSelect ) + { + if ( event.param == 'E' ) debug_x += 0.1f; + if ( event.param == 'D' ) debug_x -= 0.1f; + if ( event.param == 'R' ) debug_y += 0.1f; + if ( event.param == 'F' ) debug_y -= 0.1f; + if ( event.param == 'T' ) debug_z += 0.1f; + if ( event.param == 'G' ) debug_z -= 0.1f; + } +#endif +#if ADJUST_ARM + if ( m_bSelect ) + { + if ( event.param == 'X' ) debug_arm1 += 5.0f*PI/180.0f; + if ( event.param == 'C' ) debug_arm1 -= 5.0f*PI/180.0f; + if ( event.param == 'V' ) debug_arm2 += 5.0f*PI/180.0f; + if ( event.param == 'B' ) debug_arm2 -= 5.0f*PI/180.0f; + if ( event.param == 'N' ) debug_arm3 += 5.0f*PI/180.0f; + if ( event.param == 'M' ) debug_arm3 -= 5.0f*PI/180.0f; + if ( event.param == 'X' || + event.param == 'C' || + event.param == 'V' || + event.param == 'B' || + event.param == 'N' || + event.param == 'M' ) + { + SetAngleZ(1, debug_arm1); + SetAngleZ(2, debug_arm2); + SetAngleZ(3, debug_arm3); + char s[100]; + sprintf(s, "a=%.2f b=%.2f c=%.2f", debug_arm1*180.0f/PI, debug_arm2*180.0f/PI, debug_arm3*180.0f/PI); + m_engine->SetInfoText(5, s); + } + } +#endif + } + + if ( m_physics != 0 ) + { + if ( !m_physics->EventProcess(event) ) // object destroyed? + { + if ( RetSelect() && + m_type != OBJECT_ANT && + m_type != OBJECT_SPIDER && + m_type != OBJECT_BEE ) + { + if ( !m_bDead ) m_camera->SetType(CAMERA_EXPLO); + m_main->DeselectAll(); + } + return FALSE; + } + } + + if ( m_auto != 0 ) + { + m_auto->EventProcess(event); + + if ( event.event == EVENT_FRAME && + m_auto->IsEnded() != ERR_CONTINUE ) + { + m_auto->DeleteObject(); + delete m_auto; + m_auto = 0; + } + } + + if ( m_motion != 0 ) + { + m_motion->EventProcess(event); + } + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + return TRUE; +} + + +// Animates the object. + +BOOL CObject::EventFrame(const Event &event) +{ + if ( m_type == OBJECT_HUMAN && m_main->RetMainMovie() == MM_SATCOMopen ) + { + UpdateTransformObject(); + return TRUE; + } + + if ( m_type != OBJECT_SHOW && m_engine->RetPause() ) return TRUE; + + m_aTime += event.rTime; + m_shotTime += event.rTime; + + VirusFrame(event.rTime); + PartiFrame(event.rTime); + + UpdateMapping(); + UpdateTransformObject(); + UpdateSelectParticule(); + + if ( m_bProxyActivate ) // active if it is near? + { + CPyro* pyro; + D3DVECTOR eye; + float dist; + + eye = m_engine->RetLookatPt(); + dist = Length(eye, RetPosition(0)); + if ( dist < m_proxyDistance ) + { + m_bProxyActivate = FALSE; + m_main->CreateShortcuts(); + m_sound->Play(SOUND_FINDING); + pyro = new CPyro(m_iMan); + pyro->Create(PT_FINDING, this, 0.0f); + m_displayText->DisplayError(INFO_FINDING, this); + } + } + + return TRUE; +} + +// Updates the mapping of the object. + +void CObject::UpdateMapping() +{ + if ( m_type == OBJECT_POWER || + m_type == OBJECT_ATOMIC || + m_type == OBJECT_STATION || + m_type == OBJECT_ENERGY ) + { + UpdateEnergyMapping(); + } +} + + +// Management of viruses. + +void CObject::VirusFrame(float rTime) +{ + ParticuleType type; + D3DVECTOR pos, speed; + FPOINT dim; + int r; + + if ( !m_bVirusMode ) return; // healthy object? + + m_virusTime += rTime; + if ( m_virusTime >= VIRUS_DELAY ) + { + m_bVirusMode = FALSE; // the virus is no longer active + } + + if ( m_lastVirusParticule+m_engine->ParticuleAdapt(0.2f) <= m_aTime ) + { + m_lastVirusParticule = m_aTime; + + r = rand()%10; + if ( r == 0 ) type = PARTIVIRUS1; + if ( r == 1 ) type = PARTIVIRUS2; + if ( r == 2 ) type = PARTIVIRUS3; + if ( r == 3 ) type = PARTIVIRUS4; + if ( r == 4 ) type = PARTIVIRUS5; + if ( r == 5 ) type = PARTIVIRUS6; + if ( r == 6 ) type = PARTIVIRUS7; + if ( r == 7 ) type = PARTIVIRUS8; + if ( r == 8 ) type = PARTIVIRUS9; + if ( r == 9 ) type = PARTIVIRUS10; + + pos = RetPosition(0); + pos.x += (Rand()-0.5f)*10.0f; + pos.z += (Rand()-0.5f)*10.0f; + speed.x = (Rand()-0.5f)*2.0f; + speed.z = (Rand()-0.5f)*2.0f; + speed.y = Rand()*4.0f+4.0f; + dim.x = Rand()*0.3f+0.3f; + dim.y = dim.x; + + m_particule->CreateParticule(pos, speed, dim, type, 3.0f); + } +} + +// Management particles mistresses. + +void CObject::PartiFrame(float rTime) +{ + D3DVECTOR pos, angle, factor; + int i, channel; + + for ( i=0 ; iGetPosition(channel, pos) ) + { + m_objectPart[i].masterParti = -1; // particle no longer exists! + continue; + } + + SetPosition(i, pos); + + // Each song spins differently. + switch( i%5 ) + { + case 0: factor = D3DVECTOR( 0.5f, 0.3f, 0.6f); break; + case 1: factor = D3DVECTOR(-0.3f, 0.4f,-0.2f); break; + case 2: factor = D3DVECTOR( 0.4f,-0.6f,-0.3f); break; + case 3: factor = D3DVECTOR(-0.6f,-0.2f, 0.0f); break; + case 4: factor = D3DVECTOR( 0.4f, 0.1f,-0.7f); break; + } + + angle = RetAngle(i); + angle += rTime*PI*factor; + SetAngle(i, angle); + } +} + + +// Changes the perspective to view if it was like in the vehicle, +// or behind the vehicle. + +void CObject::SetViewFromHere(D3DVECTOR &eye, float &dirH, float &dirV, + D3DVECTOR &lookat, D3DVECTOR &upVec, + CameraType type) +{ + float speed; + int part; + + UpdateTransformObject(); + + part = 0; + if ( m_type == OBJECT_HUMAN || + m_type == OBJECT_TECH ) + { + eye.x = -0.2f; + eye.y = 3.3f; + eye.z = 0.0f; +//? eye.x = 1.0f; +//? eye.y = 3.3f; +//? eye.z = 0.0f; + } + else if ( m_type == OBJECT_MOBILErt || + m_type == OBJECT_MOBILErr || + m_type == OBJECT_MOBILErs ) + { + eye.x = -1.1f; // on the cap + eye.y = 7.9f; + eye.z = 0.0f; + } + else if ( m_type == OBJECT_MOBILEwc || + m_type == OBJECT_MOBILEtc || + m_type == OBJECT_MOBILEfc || + m_type == OBJECT_MOBILEic ) // fireball? + { +//? eye.x = -0.9f; // on the cannon +//? eye.y = 3.0f; +//? eye.z = 0.0f; +//? part = 1; + eye.x = -0.9f; // on the cannon + eye.y = 8.3f; + eye.z = 0.0f; + } + else if ( m_type == OBJECT_MOBILEwi || + m_type == OBJECT_MOBILEti || + m_type == OBJECT_MOBILEfi || + m_type == OBJECT_MOBILEii ) // orgaball ? + { +//? eye.x = -3.5f; // on the cannon +//? eye.y = 5.1f; +//? eye.z = 0.0f; +//? part = 1; + eye.x = -2.5f; // on the cannon + eye.y = 10.4f; + eye.z = 0.0f; + } + else if ( m_type == OBJECT_MOBILErc ) + { +//? eye.x = 2.0f; // in the cannon +//? eye.y = 0.0f; +//? eye.z = 0.0f; +//? part = 2; + eye.x = 4.0f; // on the cannon + eye.y = 11.0f; + eye.z = 0.0f; + } + else if ( m_type == OBJECT_MOBILEsa ) + { + eye.x = 3.0f; + eye.y = 4.5f; + eye.z = 0.0f; + } + else if ( m_type == OBJECT_MOBILEdr ) + { + eye.x = 1.0f; + eye.y = 6.5f; + eye.z = 0.0f; + } + else if ( m_type == OBJECT_APOLLO2 ) + { + eye.x = -3.0f; + eye.y = 6.0f; + eye.z = -2.0f; + } + else + { + eye.x = 0.7f; // between the brackets + eye.y = 4.8f; + eye.z = 0.0f; + } +#if ADJUST_ONBOARD + eye.x += debug_x; + eye.y += debug_y; + eye.z += debug_z; + char s[100]; + sprintf(s, "x=%.2f y=%.2f z=%.2f", eye.x, eye.y, eye.z); + m_engine->SetInfoText(4, s); +#endif + + if ( type == CAMERA_BACK ) + { + eye.x -= 20.0f; + eye.y += 1.0f; + } + + lookat.x = eye.x+1.0f; + lookat.y = eye.y+0.0f; + lookat.z = eye.z+0.0f; + + eye = Transform(m_objectPart[part].matWorld, eye); + lookat = Transform(m_objectPart[part].matWorld, lookat); + + // Camera tilts when turning. + upVec = D3DVECTOR(0.0f, 1.0f, 0.0f); + if ( m_physics != 0 ) + { + if ( m_physics->RetLand() ) // on ground? + { + speed = m_physics->RetLinMotionX(MO_REASPEED); + lookat.y -= speed*0.002f; + + speed = m_physics->RetCirMotionY(MO_REASPEED); + upVec.z -= speed*0.04f; + } + else // in flight? + { + speed = m_physics->RetLinMotionX(MO_REASPEED); + lookat.y += speed*0.002f; + + speed = m_physics->RetCirMotionY(MO_REASPEED); + upVec.z += speed*0.08f; + } + } + upVec = Transform(m_objectPart[0].matRotate, upVec); + + dirH = -(m_objectPart[part].angle.y+PI/2.0f); + dirV = 0.0f; + +} + + +// Management of features. + +void CObject::SetCharacter(Character* character) +{ + CopyMemory(&m_character, character, sizeof(Character)); +} + +void CObject::GetCharacter(Character* character) +{ + CopyMemory(character, &m_character, sizeof(Character)); +} + +Character* CObject::RetCharacter() +{ + return &m_character; +} + + +// Returns the absolute time. + +float CObject::RetAbsTime() +{ + return m_aTime; +} + + +// Management of energy contained in a battery. +// Single subject possesses the battery energy, but not the vehicle that carries the battery! + +void CObject::SetEnergy(float level) +{ + if ( level < 0.0f ) level = 0.0f; + if ( level > 1.0f ) level = 1.0f; + m_energy = level; +} + +float CObject::RetEnergy() +{ + if ( m_type != OBJECT_POWER && + m_type != OBJECT_ATOMIC && + m_type != OBJECT_STATION && + m_type != OBJECT_ENERGY ) return 0.0f; + return m_energy; +} + + +// Management of the capacity of a battery. +// Single subject possesses a battery capacity, +// but not the vehicle that carries the battery! + +void CObject::SetCapacity(float capacity) +{ + m_capacity = capacity; +} + +float CObject::RetCapacity() +{ + return m_capacity; +} + + +// Management of the shield. + +void CObject::SetShield(float level) +{ + m_shield = level; +} + +float CObject::RetShield() +{ + if ( m_type == OBJECT_FRET || + m_type == OBJECT_STONE || + m_type == OBJECT_URANIUM || + m_type == OBJECT_BULLET || + m_type == OBJECT_METAL || + m_type == OBJECT_BBOX || + m_type == OBJECT_KEYa || + m_type == OBJECT_KEYb || + m_type == OBJECT_KEYc || + m_type == OBJECT_KEYd || + m_type == OBJECT_TNT || + m_type == OBJECT_TEEN31 || // basket? + m_type == OBJECT_SCRAP1 || + m_type == OBJECT_SCRAP2 || + m_type == OBJECT_SCRAP3 || + m_type == OBJECT_SCRAP4 || + m_type == OBJECT_SCRAP5 || + m_type == OBJECT_BOMB || + m_type == OBJECT_WAYPOINT || + m_type == OBJECT_FLAGb || + m_type == OBJECT_FLAGr || + m_type == OBJECT_FLAGg || + m_type == OBJECT_FLAGy || + m_type == OBJECT_FLAGv || + m_type == OBJECT_POWER || + m_type == OBJECT_ATOMIC || + m_type == OBJECT_ANT || + m_type == OBJECT_SPIDER || + m_type == OBJECT_BEE || + m_type == OBJECT_WORM ) return 0.0f; + return m_shield; +} + + +// Management of flight range (zero = infinity). + +void CObject::SetRange(float delay) +{ + m_range = delay; +} + +float CObject::RetRange() +{ + return m_range; +} + + +// Management of transparency of the object. + +void CObject::SetTransparency(float value) +{ + int i; + + m_transparency = value; + + for ( i=0 ; iSetObjectTransparency(m_objectPart[i].object, value); + } + } +} + +float CObject::RetTransparency() +{ + return m_transparency; +} + + +// Management of the object matter. + +ObjectMaterial CObject::RetMaterial() +{ + if ( m_type == OBJECT_HUMAN ) + { + return OM_HUMAN; + } + + if ( m_type == OBJECT_SCRAP4 || + m_type == OBJECT_SCRAP5 ) + { + return OM_HUMAN; + } + + return OM_METAL; +} + + +// Indicates whether the gadget is a nonessential. + +void CObject::SetGadget(BOOL bMode) +{ + m_bGadget = bMode; +} + +BOOL CObject::RetGadget() +{ + return m_bGadget; +} + + +// Indicates whether an object is stationary (ant on the back). + +void CObject::SetFixed(BOOL bFixed) +{ + m_bFixed = bFixed; +} + +BOOL CObject::RetFixed() +{ + return m_bFixed; +} + + +// Indicates whether an object is subjected to clipping (obstacles). + +void CObject::SetClip(BOOL bClip) +{ + m_bClip = bClip; +} + +BOOL CObject::RetClip() +{ + return m_bClip; +} + + + +// Pushes an object. + +BOOL CObject::JostleObject(float force) +{ + CAutoJostle* pa; + + if ( m_type == OBJECT_FLAGb || + m_type == OBJECT_FLAGr || + m_type == OBJECT_FLAGg || + m_type == OBJECT_FLAGy || + m_type == OBJECT_FLAGv ) // flag? + { + if ( m_auto == 0 ) return FALSE; + + m_auto->Start(1); + } + else + { + if ( m_auto != 0 ) return FALSE; + + m_auto = new CAutoJostle(m_iMan, this); + pa = (CAutoJostle*)m_auto; + pa->Start(0, force); + } + + return TRUE; +} + + +// Beginning of the effect when the instruction "detect" is used. + +void CObject::StartDetectEffect(CObject *target, BOOL bFound) +{ + D3DMATRIX* mat; + D3DVECTOR pos, goal; + FPOINT dim; + + mat = RetWorldMatrix(0); + pos = Transform(*mat, D3DVECTOR(2.0f, 3.0f, 0.0f)); + + if ( target == 0 ) + { + goal = Transform(*mat, D3DVECTOR(50.0f, 3.0f, 0.0f)); + } + else + { + goal = target->RetPosition(0); + goal.y += 3.0f; + goal = SegmentDist(pos, goal, Length(pos, goal)-3.0f); + } + + dim.x = 3.0f; + dim.y = dim.x; + m_particule->CreateRay(pos, goal, PARTIRAY2, dim, 0.2f); + + if ( target != 0 ) + { + goal = target->RetPosition(0); + goal.y += 3.0f; + goal = SegmentDist(pos, goal, Length(pos, goal)-1.0f); + dim.x = 6.0f; + dim.y = dim.x; + m_particule->CreateParticule(goal, D3DVECTOR(0.0f, 0.0f, 0.0f), dim, + bFound?PARTIGLINT:PARTIGLINTr, 0.5f); + } + + m_sound->Play(bFound?SOUND_BUILD:SOUND_RECOVER); +} + + +// Management of time from which a virus is active. + +void CObject::SetVirusMode(BOOL bEnable) +{ + m_bVirusMode = bEnable; + m_virusTime = 0.0f; + + if ( m_bVirusMode && m_brain != 0 ) + { + if ( !m_brain->IntroduceVirus() ) // tries to infect + { + m_bVirusMode = FALSE; // program was not contaminated! + } + } +} + +BOOL CObject::RetVirusMode() +{ + return m_bVirusMode; +} + +float CObject::RetVirusTime() +{ + return m_virusTime; +} + + +// Management mode of the camera. + +void CObject::SetCameraType(CameraType type) +{ + m_cameraType = type; +} + +CameraType CObject::RetCameraType() +{ + return m_cameraType; +} + +void CObject::SetCameraDist(float dist) +{ + m_cameraDist = dist; +} + +float CObject::RetCameraDist() +{ + return m_cameraDist; +} + +void CObject::SetCameraLock(BOOL bLock) +{ + m_bCameraLock = bLock; +} + +BOOL CObject::RetCameraLock() +{ + return m_bCameraLock; +} + + + +// Management of the demonstration of the object. + +void CObject::SetHilite(BOOL bMode) +{ + int list[OBJECTMAXPART+1]; + int i, j; + + m_bHilite = bMode; + + if ( m_bHilite ) + { + j = 0; + for ( i=0 ; iSetHiliteRank(list); // gives the list of selected parts + } +} + +BOOL CObject::RetHilite() +{ + return m_bHilite; +} + + +// Indicates whether the object is selected or not. + +void CObject::SetSelect(BOOL bMode, BOOL bDisplayError) +{ + Error err; + + m_bSelect = bMode; + + if ( m_physics != 0 ) + { + m_physics->CreateInterface(m_bSelect); + } + + if ( m_auto != 0 ) + { + m_auto->CreateInterface(m_bSelect); + } + + CreateSelectParticule(); // creates / removes particles + + if ( !m_bSelect ) + { + SetGunGoalH(0.0f); // puts the cannon right + return; // selects if not finished + } + + err = ERR_OK; + if ( m_physics != 0 ) + { + err = m_physics->RetError(); + } + if ( m_auto != 0 ) + { + err = m_auto->RetError(); + } + if ( err != ERR_OK && bDisplayError ) + { + m_displayText->DisplayError(err, this); + } +} + +// Indicates whether the object is selected or not. + +BOOL CObject::RetSelect(BOOL bReal) +{ + if ( !bReal && m_main->RetFixScene() ) return FALSE; + return m_bSelect; +} + + +// Indicates whether the object is selectable or not. + +void CObject::SetSelectable(BOOL bMode) +{ + m_bSelectable = bMode; +} + +// Indicates whether the object is selecionnable or not. + +BOOL CObject::RetSelectable() +{ + return m_bSelectable; +} + + +// Management of the activities of an object. + +void CObject::SetActivity(BOOL bMode) +{ + if ( m_brain != 0 ) + { + m_brain->SetActivity(bMode); + } +} + +BOOL CObject::RetActivity() +{ + if ( m_brain != 0 ) + { + return m_brain->RetActivity(); + } + return FALSE; +} + + +// Indicates if necessary to check the tokens of the object. + +void CObject::SetCheckToken(BOOL bMode) +{ + m_bCheckToken = bMode; +} + +// Indicates if necessary to check the tokens of the object. + +BOOL CObject::RetCheckToken() +{ + return m_bCheckToken; +} + + +// Management of the visibility of an object. +// The object is not hidden or visually disabled, but ignores detections! +// For example: underground worm. + +void CObject::SetVisible(BOOL bVisible) +{ + m_bVisible = bVisible; +} + +BOOL CObject::RetVisible() +{ + return m_bVisible; +} + + +// Management mode of operation of an object. +// An inactive object is an object destroyed, nonexistent. +// This mode is used for objects "resetables" +// during training to simulate destruction. + +void CObject::SetEnable(BOOL bEnable) +{ + m_bEnable = bEnable; +} + +BOOL CObject::RetEnable() +{ + return m_bEnable; +} + + +// Management mode or an object is only active when you're close. + +void CObject::SetProxyActivate(BOOL bActivate) +{ + m_bProxyActivate = bActivate; +} + +BOOL CObject::RetProxyActivate() +{ + return m_bProxyActivate; +} + +void CObject::SetProxyDistance(float distance) +{ + m_proxyDistance = distance; +} + +float CObject::RetProxyDistance() +{ + return m_proxyDistance; +} + + +// Management of the method of increasing damage. + +void CObject::SetMagnifyDamage(float factor) +{ + m_magnifyDamage = factor; +} + +float CObject::RetMagnifyDamage() +{ + return m_magnifyDamage; +} + + +// Management of free parameter. + +void CObject::SetParam(float value) +{ + m_param = value; +} + +float CObject::RetParam() +{ + return m_param; +} + + +// Management of the mode "blocked" of an object. +// For example, a cube of titanium is blocked while it is used to make something, +//or a vehicle is blocked as its construction is not finished. + +void CObject::SetLock(BOOL bLock) +{ + m_bLock = bLock; +} + +BOOL CObject::RetLock() +{ + return m_bLock; +} + +// Management of the mode "current explosion" of an object. +// An object in this mode is not saving. + +void CObject::SetExplo(BOOL bExplo) +{ + m_bExplo = bExplo; +} + +BOOL CObject::RetExplo() +{ + return m_bExplo; +} + + +// Mode management "cargo ship" during movies. + +void CObject::SetCargo(BOOL bCargo) +{ + m_bCargo = bCargo; +} + +BOOL CObject::RetCargo() +{ + return m_bCargo; +} + + +// Management of the HS mode of an object. + +void CObject::SetBurn(BOOL bBurn) +{ + m_bBurn = bBurn; + +//? if ( m_botVar != 0 ) +//? { +//? if ( m_bBurn ) m_botVar->SetUserPtr(OBJECTDELETED); +//? else m_botVar->SetUserPtr(this); +//? } +} + +BOOL CObject::RetBurn() +{ + return m_bBurn; +} + +void CObject::SetDead(BOOL bDead) +{ + m_bDead = bDead; + + if ( bDead && m_brain != 0 ) + { + m_brain->StopProgram(); // stops the current task + } + +//? if ( m_botVar != 0 ) +//? { +//? if ( m_bDead ) m_botVar->SetUserPtr(OBJECTDELETED); +//? else m_botVar->SetUserPtr(this); +//? } +} + +BOOL CObject::RetDead() +{ + return m_bDead; +} + +BOOL CObject::RetRuin() +{ + return m_bBurn|m_bFlat; +} + +BOOL CObject::RetActif() +{ + return !m_bLock && !m_bBurn && !m_bFlat && m_bVisible && m_bEnable; +} + + +// Management of the point of aim. + +void CObject::SetGunGoalV(float gunGoal) +{ + if ( m_type == OBJECT_MOBILEfc || + m_type == OBJECT_MOBILEtc || + m_type == OBJECT_MOBILEwc || + m_type == OBJECT_MOBILEic ) // fireball? + { + if ( gunGoal > 10.0f*PI/180.0f ) gunGoal = 10.0f*PI/180.0f; + if ( gunGoal < -20.0f*PI/180.0f ) gunGoal = -20.0f*PI/180.0f; + SetAngleZ(1, gunGoal); + } + else if ( m_type == OBJECT_MOBILEfi || + m_type == OBJECT_MOBILEti || + m_type == OBJECT_MOBILEwi || + m_type == OBJECT_MOBILEii ) // orgaball? + { + if ( gunGoal > 20.0f*PI/180.0f ) gunGoal = 20.0f*PI/180.0f; + if ( gunGoal < -20.0f*PI/180.0f ) gunGoal = -20.0f*PI/180.0f; + SetAngleZ(1, gunGoal); + } + else if ( m_type == OBJECT_MOBILErc ) // phazer? + { + if ( gunGoal > 45.0f*PI/180.0f ) gunGoal = 45.0f*PI/180.0f; + if ( gunGoal < -20.0f*PI/180.0f ) gunGoal = -20.0f*PI/180.0f; + SetAngleZ(2, gunGoal); + } + else + { + gunGoal = 0.0f; + } + + m_gunGoalV = gunGoal; +} + +void CObject::SetGunGoalH(float gunGoal) +{ + if ( m_type == OBJECT_MOBILEfc || + m_type == OBJECT_MOBILEtc || + m_type == OBJECT_MOBILEwc || + m_type == OBJECT_MOBILEic ) // fireball? + { + if ( gunGoal > 40.0f*PI/180.0f ) gunGoal = 40.0f*PI/180.0f; + if ( gunGoal < -40.0f*PI/180.0f ) gunGoal = -40.0f*PI/180.0f; + SetAngleY(1, gunGoal); + } + else if ( m_type == OBJECT_MOBILEfi || + m_type == OBJECT_MOBILEti || + m_type == OBJECT_MOBILEwi || + m_type == OBJECT_MOBILEii ) // orgaball? + { + if ( gunGoal > 40.0f*PI/180.0f ) gunGoal = 40.0f*PI/180.0f; + if ( gunGoal < -40.0f*PI/180.0f ) gunGoal = -40.0f*PI/180.0f; + SetAngleY(1, gunGoal); + } + else if ( m_type == OBJECT_MOBILErc ) // phazer? + { + if ( gunGoal > 40.0f*PI/180.0f ) gunGoal = 40.0f*PI/180.0f; + if ( gunGoal < -40.0f*PI/180.0f ) gunGoal = -40.0f*PI/180.0f; + SetAngleY(2, gunGoal); + } + else + { + gunGoal = 0.0f; + } + + m_gunGoalH = gunGoal; +} + +float CObject::RetGunGoalV() +{ + return m_gunGoalV; +} + +float CObject::RetGunGoalH() +{ + return m_gunGoalH; +} + + + +// Shows the limits of the object. + +BOOL CObject::StartShowLimit() +{ + if ( m_showLimitRadius == 0.0f ) return FALSE; + + m_main->SetShowLimit(0, PARTILIMIT1, this, RetPosition(0), m_showLimitRadius); + m_bShowLimit = TRUE; + return TRUE; +} + +void CObject::StopShowLimit() +{ + m_bShowLimit = FALSE; +} + + + +// Indicates whether a program is under execution. + +BOOL CObject::IsProgram() +{ + if ( m_brain == 0 ) return FALSE; + return m_brain->IsProgram(); +} + + +// Creates or removes particles associated to the object. + +void CObject::CreateSelectParticule() +{ + D3DVECTOR pos, speed; + FPOINT dim; + int i; + + // Removes particles preceding. + for ( i=0 ; i<4 ; i++ ) + { + if ( m_partiSel[i] != -1 ) + { + m_particule->DeleteParticule(m_partiSel[i]); + m_partiSel[i] = -1; + } + } + + if ( m_bSelect || IsProgram() ) + { + // Creates particles lens for the headlights. + if ( m_type == OBJECT_MOBILEfa || + m_type == OBJECT_MOBILEta || + m_type == OBJECT_MOBILEwa || + m_type == OBJECT_MOBILEia || + m_type == OBJECT_MOBILEfc || + m_type == OBJECT_MOBILEtc || + m_type == OBJECT_MOBILEwc || + m_type == OBJECT_MOBILEic || + m_type == OBJECT_MOBILEfi || + m_type == OBJECT_MOBILEti || + m_type == OBJECT_MOBILEwi || + m_type == OBJECT_MOBILEii || + m_type == OBJECT_MOBILEfs || + m_type == OBJECT_MOBILEts || + m_type == OBJECT_MOBILEws || + m_type == OBJECT_MOBILEis || + m_type == OBJECT_MOBILErt || + m_type == OBJECT_MOBILErc || + m_type == OBJECT_MOBILErr || + m_type == OBJECT_MOBILErs || + m_type == OBJECT_MOBILEsa || + m_type == OBJECT_MOBILEtg || + m_type == OBJECT_MOBILEft || + m_type == OBJECT_MOBILEtt || + m_type == OBJECT_MOBILEwt || + m_type == OBJECT_MOBILEit || + m_type == OBJECT_MOBILEdr ) // vehicle? + { + pos = D3DVECTOR(0.0f, 0.0f, 0.0f); + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 0.0f; + dim.y = 0.0f; + m_partiSel[0] = m_particule->CreateParticule(pos, speed, dim, PARTISELY, 1.0f, 0.0f, 0.0f); + m_partiSel[1] = m_particule->CreateParticule(pos, speed, dim, PARTISELY, 1.0f, 0.0f, 0.0f); + m_partiSel[2] = m_particule->CreateParticule(pos, speed, dim, PARTISELR, 1.0f, 0.0f, 0.0f); + m_partiSel[3] = m_particule->CreateParticule(pos, speed, dim, PARTISELR, 1.0f, 0.0f, 0.0f); + UpdateSelectParticule(); + } + } +} + +// Updates the particles associated to the object. + +void CObject::UpdateSelectParticule() +{ + D3DVECTOR pos[4]; + FPOINT dim[4]; + float zoom[4]; + float angle; + int i; + + if ( !m_bSelect && !IsProgram() ) return; + + dim[0].x = 1.0f; + dim[1].x = 1.0f; + dim[2].x = 1.2f; + dim[3].x = 1.2f; + + // Lens front yellow. + if ( m_type == OBJECT_MOBILErt || + m_type == OBJECT_MOBILErc || + m_type == OBJECT_MOBILErr || + m_type == OBJECT_MOBILErs ) // large caterpillars? + { + pos[0] = D3DVECTOR(4.2f, 2.8f, 1.5f); + pos[1] = D3DVECTOR(4.2f, 2.8f, -1.5f); + dim[0].x = 1.5f; + dim[1].x = 1.5f; + } + else if ( m_type == OBJECT_MOBILEwt || + m_type == OBJECT_MOBILEtt || + m_type == OBJECT_MOBILEft || + m_type == OBJECT_MOBILEit ) // trainer ? + { + pos[0] = D3DVECTOR(4.2f, 2.5f, 1.2f); + pos[1] = D3DVECTOR(4.2f, 2.5f, -1.2f); + dim[0].x = 1.5f; + dim[1].x = 1.5f; + } + else if ( m_type == OBJECT_MOBILEsa ) // submarine? + { + pos[0] = D3DVECTOR(3.6f, 4.0f, 2.0f); + pos[1] = D3DVECTOR(3.6f, 4.0f, -2.0f); + } + else if ( m_type == OBJECT_MOBILEtg ) // target? + { + pos[0] = D3DVECTOR(3.4f, 6.5f, 2.0f); + pos[1] = D3DVECTOR(3.4f, 6.5f, -2.0f); + } + else if ( m_type == OBJECT_MOBILEdr ) // designer? + { + pos[0] = D3DVECTOR(4.9f, 3.5f, 2.5f); + pos[1] = D3DVECTOR(4.9f, 3.5f, -2.5f); + } + else + { + pos[0] = D3DVECTOR(4.2f, 2.5f, 1.5f); + pos[1] = D3DVECTOR(4.2f, 2.5f, -1.5f); + } + + // Red back lens + if ( m_type == OBJECT_MOBILEfa || + m_type == OBJECT_MOBILEfc || + m_type == OBJECT_MOBILEfi || + m_type == OBJECT_MOBILEfs || + m_type == OBJECT_MOBILEft ) // flying? + { + pos[2] = D3DVECTOR(-4.0f, 3.1f, 4.5f); + pos[3] = D3DVECTOR(-4.0f, 3.1f, -4.5f); + dim[2].x = 0.6f; + dim[3].x = 0.6f; + } + if ( m_type == OBJECT_MOBILEwa || + m_type == OBJECT_MOBILEwc || + m_type == OBJECT_MOBILEwi || + m_type == OBJECT_MOBILEws ) // wheels? + { + pos[2] = D3DVECTOR(-4.5f, 2.7f, 2.8f); + pos[3] = D3DVECTOR(-4.5f, 2.7f, -2.8f); + } + if ( m_type == OBJECT_MOBILEwt ) // wheels? + { + pos[2] = D3DVECTOR(-4.0f, 2.5f, 2.2f); + pos[3] = D3DVECTOR(-4.0f, 2.5f, -2.2f); + } + if ( m_type == OBJECT_MOBILEia || + m_type == OBJECT_MOBILEic || + m_type == OBJECT_MOBILEii || + m_type == OBJECT_MOBILEis || + m_type == OBJECT_MOBILEit ) // legs? + { + pos[2] = D3DVECTOR(-4.5f, 2.7f, 2.8f); + pos[3] = D3DVECTOR(-4.5f, 2.7f, -2.8f); + } + if ( m_type == OBJECT_MOBILEta || + m_type == OBJECT_MOBILEtc || + m_type == OBJECT_MOBILEti || + m_type == OBJECT_MOBILEts || + m_type == OBJECT_MOBILEtt ) // caterpillars? + { + pos[2] = D3DVECTOR(-3.6f, 4.2f, 3.0f); + pos[3] = D3DVECTOR(-3.6f, 4.2f, -3.0f); + } + if ( m_type == OBJECT_MOBILErt || + m_type == OBJECT_MOBILErc || + m_type == OBJECT_MOBILErr || + m_type == OBJECT_MOBILErs ) // large caterpillars? + { + pos[2] = D3DVECTOR(-5.0f, 5.2f, 2.5f); + pos[3] = D3DVECTOR(-5.0f, 5.2f, -2.5f); + } + if ( m_type == OBJECT_MOBILEsa ) // submarine? + { + pos[2] = D3DVECTOR(-3.6f, 4.0f, 2.0f); + pos[3] = D3DVECTOR(-3.6f, 4.0f, -2.0f); + } + if ( m_type == OBJECT_MOBILEtg ) // target? + { + pos[2] = D3DVECTOR(-2.4f, 6.5f, 2.0f); + pos[3] = D3DVECTOR(-2.4f, 6.5f, -2.0f); + } + if ( m_type == OBJECT_MOBILEdr ) // designer? + { + pos[2] = D3DVECTOR(-5.3f, 2.7f, 1.8f); + pos[3] = D3DVECTOR(-5.3f, 2.7f, -1.8f); + } + + angle = RetAngleY(0)/PI; + + zoom[0] = 1.0f; + zoom[1] = 1.0f; + zoom[2] = 1.0f; + zoom[3] = 1.0f; + + if ( IsProgram() && // current program? + Mod(m_aTime, 0.7f) < 0.3f ) + { + zoom[0] = 0.0f; // blinks + zoom[1] = 0.0f; + zoom[2] = 0.0f; + zoom[3] = 0.0f; + } + + // Updates lens. + for ( i=0 ; i<4 ; i++ ) + { + pos[i] = Transform(m_objectPart[0].matWorld, pos[i]); + dim[i].y = dim[i].x; + m_particule->SetParam(m_partiSel[i], pos[i], dim[i], zoom[i], angle, 1.0f); + } +} + + +// Gives the pointer to the current script execution. + +void CObject::SetRunScript(CScript* script) +{ + m_runScript = script; +} + +CScript* CObject::RetRunScript() +{ + return m_runScript; +} + +// Returns the variables of "this" for CBOT. + +CBotVar* CObject::RetBotVar() +{ + return m_botVar; +} + +// Returns the physics associated to the object. + +CPhysics* CObject::RetPhysics() +{ + return m_physics; +} + +// Returns the brain associated to the object. + +CBrain* CObject::RetBrain() +{ + return m_brain; +} + +// Returns the movement associated to the object. + +CMotion* CObject::RetMotion() +{ + return m_motion; +} + +// Returns the controller associated to the object. + +CAuto* CObject::RetAuto() +{ + return m_auto; +} + +void CObject::SetAuto(CAuto* automat) +{ + m_auto = automat; +} + + + +// Management of the position in the file definition. + +void CObject::SetDefRank(int rank) +{ + m_defRank = rank; +} + +int CObject::RetDefRank() +{ + return m_defRank; +} + + +// Gives the object name for the tooltip. + +BOOL CObject::GetTooltipName(char* name) +{ + GetResource(RES_OBJECT, m_type, name); + return ( name[0] != 0 ); +} + + +// Adds the object previously selected in the list. + +void CObject::AddDeselList(CObject* pObj) +{ + int i; + + if ( m_totalDesectList >= OBJECTMAXDESELLIST ) + { + for ( i=0 ; iRetTraceDown(); +} + +void CObject::SetTraceDown(BOOL bDown) +{ + CMotionVehicle* mv; + if ( m_motion == 0 ) return; + mv = (CMotionVehicle*)m_motion; + mv->SetTraceDown(bDown); +} + +int CObject::RetTraceColor() +{ + CMotionVehicle* mv; + if ( m_motion == 0 ) return 0; + mv = (CMotionVehicle*)m_motion; + return mv->RetTraceColor(); +} + +void CObject::SetTraceColor(int color) +{ + CMotionVehicle* mv; + if ( m_motion == 0 ) return; + mv = (CMotionVehicle*)m_motion; + mv->SetTraceColor(color); +} + +float CObject::RetTraceWidth() +{ + CMotionVehicle* mv; + if ( m_motion == 0 ) return 0.0f; + mv = (CMotionVehicle*)m_motion; + return mv->RetTraceWidth(); +} + +void CObject::SetTraceWidth(float width) +{ + CMotionVehicle* mv; + if ( m_motion == 0 ) return; + mv = (CMotionVehicle*)m_motion; + mv->SetTraceWidth(width); +} + + diff --git a/src/object/object.h b/src/object/object.h new file mode 100644 index 0000000..af7a3e4 --- /dev/null +++ b/src/object/object.h @@ -0,0 +1,781 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// object.h + +#ifndef _OBJECT_H_ +#define _OBJECT_H_ + + +#include "d3dengine.h" +#include "camera.h" +#include "sound.h" + + +class CInstanceManager; +class CLight; +class CTerrain; +class CWater; +class CParticule; +class CPhysics; +class CBrain; +class CMotion; +class CAuto; +class CDisplayText; +class CRobotMain; +class CBotVar; +class CScript; + + + +// The father of all parts must always be the part number zero! + +#define OBJECTMAXPART 40 +#define MAXCRASHSPHERE 40 +#define OBJECTMAXDESELLIST 10 +#define OBJECTMAXINFO 10 +#define OBJECTMAXCMDLINE 20 + +enum ObjectType +{ + OBJECT_NULL = 0, // object destroyed + OBJECT_FIX = 1, // stationary scenery + OBJECT_PORTICO = 2, // gantry + OBJECT_BASE = 3, // great main base + OBJECT_DERRICK = 4, // derrick set + OBJECT_FACTORY = 5, // factory set + OBJECT_STATION = 6, // recharging station + OBJECT_CONVERT = 7, // converter station + OBJECT_REPAIR = 8, // reparation + OBJECT_TOWER = 9, // defense tower + OBJECT_NEST = 10, // nest + OBJECT_RESEARCH = 11, // research center + OBJECT_RADAR = 12, // radar + OBJECT_ENERGY = 13, // energy factory + OBJECT_LABO = 14, // analytical laboratory for insect + OBJECT_NUCLEAR = 15, // nuclear power plant + OBJECT_START = 16, // starting + OBJECT_END = 17, // finish + OBJECT_INFO = 18, // information terminal + OBJECT_PARA = 19, // lightning conductor + OBJECT_TARGET1 = 20, // gate target + OBJECT_TARGET2 = 21, // center target + OBJECT_SAFE = 22, // safe + OBJECT_HUSTON = 23, // control centre + OBJECT_DESTROYER = 24, // destroyer + OBJECT_FRET = 30, // transportable + OBJECT_STONE = 31, // stone + OBJECT_URANIUM = 32, // uranium + OBJECT_METAL = 33, // metal + OBJECT_POWER = 34, // normal battery + OBJECT_ATOMIC = 35, // atomic battery + OBJECT_BULLET = 36, // bullet + OBJECT_BBOX = 37, // black-box + OBJECT_TNT = 38, // box of TNT + OBJECT_SCRAP1 = 40, // metal waste + OBJECT_SCRAP2 = 41, // metal waste + OBJECT_SCRAP3 = 42, // metal waste + OBJECT_SCRAP4 = 43, // plastic waste + OBJECT_SCRAP5 = 44, // plastic waste + OBJECT_MARKPOWER = 50, // mark underground energy source + OBJECT_MARKSTONE = 51, // mark underground ore + OBJECT_MARKURANIUM = 52, // mark underground uranium + OBJECT_MARKKEYa = 53, // mark underground key + OBJECT_MARKKEYb = 54, // mark underground key + OBJECT_MARKKEYc = 55, // mark underground key + OBJECT_MARKKEYd = 56, // mark underground key + OBJECT_BOMB = 60, // bomb + OBJECT_WINFIRE = 61, // fireworks + OBJECT_SHOW = 62, // shows a place + OBJECT_BAG = 63, // survival bag + OBJECT_PLANT0 = 70, // plant 0 + OBJECT_PLANT1 = 71, // plant 1 + OBJECT_PLANT2 = 72, // plant 2 + OBJECT_PLANT3 = 73, // plant 3 + OBJECT_PLANT4 = 74, // plant 4 + OBJECT_PLANT5 = 75, // plant 5 + OBJECT_PLANT6 = 76, // plant 6 + OBJECT_PLANT7 = 77, // plant 7 + OBJECT_PLANT8 = 78, // plant 8 + OBJECT_PLANT9 = 79, // plant 9 + OBJECT_PLANT10 = 80, // plant 10 + OBJECT_PLANT11 = 81, // plant 11 + OBJECT_PLANT12 = 82, // plant 12 + OBJECT_PLANT13 = 83, // plant 13 + OBJECT_PLANT14 = 84, // plant 14 + OBJECT_PLANT15 = 85, // plant 15 + OBJECT_PLANT16 = 86, // plant 16 + OBJECT_PLANT17 = 87, // plant 17 + OBJECT_PLANT18 = 88, // plant 18 + OBJECT_PLANT19 = 89, // plant 19 + OBJECT_TREE0 = 90, // tree 0 + OBJECT_TREE1 = 91, // tree 1 + OBJECT_TREE2 = 92, // tree 2 + OBJECT_TREE3 = 93, // tree 3 + OBJECT_TREE4 = 94, // tree 4 + OBJECT_TREE5 = 95, // tree 5 + OBJECT_TREE6 = 96, // tree 6 + OBJECT_TREE7 = 97, // tree 7 + OBJECT_TREE8 = 98, // tree 8 + OBJECT_TREE9 = 99, // tree 9 + OBJECT_MOBILEwt = 100, // wheel-trainer + OBJECT_MOBILEtt = 101, // track-trainer + OBJECT_MOBILEft = 102, // fly-trainer + OBJECT_MOBILEit = 103, // insect-trainer + OBJECT_MOBILEwa = 110, // wheel-arm + OBJECT_MOBILEta = 111, // track-arm + OBJECT_MOBILEfa = 112, // fly-arm + OBJECT_MOBILEia = 113, // insect-arm + OBJECT_MOBILEwc = 120, // wheel-cannon + OBJECT_MOBILEtc = 121, // track-cannon + OBJECT_MOBILEfc = 122, // fly-cannon + OBJECT_MOBILEic = 123, // insect-cannon + OBJECT_MOBILEwi = 130, // wheel-insect-cannon + OBJECT_MOBILEti = 131, // track-insect-cannon + OBJECT_MOBILEfi = 132, // fly-insect-cannon + OBJECT_MOBILEii = 133, // insect-insect-cannon + OBJECT_MOBILEws = 140, // wheel-search + OBJECT_MOBILEts = 141, // track-search + OBJECT_MOBILEfs = 142, // fly-search + OBJECT_MOBILEis = 143, // insect-search + OBJECT_MOBILErt = 200, // roller-terraform + OBJECT_MOBILErc = 201, // roller-canon + OBJECT_MOBILErr = 202, // roller-recover + OBJECT_MOBILErs = 203, // roller-shield + OBJECT_MOBILEsa = 210, // submarine + OBJECT_MOBILEtg = 211, // training target + OBJECT_MOBILEdr = 212, // robot drawing + OBJECT_WAYPOINT = 250, // waypoint + OBJECT_FLAGb = 260, // blue flag + OBJECT_FLAGr = 261, // red flag + OBJECT_FLAGg = 262, // green flag + OBJECT_FLAGy = 263, // yellow flag + OBJECT_FLAGv = 264, // violet flag + OBJECT_KEYa = 270, // key a + OBJECT_KEYb = 271, // key b + OBJECT_KEYc = 272, // key c + OBJECT_KEYd = 273, // key d + OBJECT_HUMAN = 300, // human + OBJECT_TOTO = 301, // toto + OBJECT_TECH = 302, // technician + OBJECT_BARRIER0 = 400, // barrier + OBJECT_BARRIER1 = 401, // barrier + OBJECT_BARRIER2 = 402, // barrier + OBJECT_BARRIER3 = 403, // barrier + OBJECT_BARRIER4 = 404, // barrier + OBJECT_MOTHER = 500, // insect queen + OBJECT_EGG = 501, // egg + OBJECT_ANT = 502, // ant + OBJECT_SPIDER = 503, // spider + OBJECT_BEE = 504, // bee + OBJECT_WORM = 505, // worm + OBJECT_RUINmobilew1 = 600, // ruin 1 + OBJECT_RUINmobilew2 = 601, // ruin 1 + OBJECT_RUINmobilet1 = 602, // ruin 2 + OBJECT_RUINmobilet2 = 603, // ruin 2 + OBJECT_RUINmobiler1 = 604, // ruin 3 + OBJECT_RUINmobiler2 = 605, // ruin 3 + OBJECT_RUINfactory = 606, // ruin 4 + OBJECT_RUINdoor = 607, // ruin 5 + OBJECT_RUINsupport = 608, // ruin 6 + OBJECT_RUINradar = 609, // ruin 7 + OBJECT_RUINconvert = 610, // ruin 8 + OBJECT_RUINbase = 611, // ruin 9 + OBJECT_RUINhead = 612, // ruin 10 + OBJECT_TEEN0 = 620, // toy + OBJECT_TEEN1 = 621, // toy + OBJECT_TEEN2 = 622, // toy + OBJECT_TEEN3 = 623, // toy + OBJECT_TEEN4 = 624, // toy + OBJECT_TEEN5 = 625, // toy + OBJECT_TEEN6 = 626, // toy + OBJECT_TEEN7 = 627, // toy + OBJECT_TEEN8 = 628, // toy + OBJECT_TEEN9 = 629, // toy + OBJECT_TEEN10 = 630, // toy + OBJECT_TEEN11 = 631, // toy + OBJECT_TEEN12 = 632, // toy + OBJECT_TEEN13 = 633, // toy + OBJECT_TEEN14 = 634, // toy + OBJECT_TEEN15 = 635, // toy + OBJECT_TEEN16 = 636, // toy + OBJECT_TEEN17 = 637, // toy + OBJECT_TEEN18 = 638, // toy + OBJECT_TEEN19 = 639, // toy + OBJECT_TEEN20 = 640, // toy + OBJECT_TEEN21 = 641, // toy + OBJECT_TEEN22 = 642, // toy + OBJECT_TEEN23 = 643, // toy + OBJECT_TEEN24 = 644, // toy + OBJECT_TEEN25 = 645, // toy + OBJECT_TEEN26 = 646, // toy + OBJECT_TEEN27 = 647, // toy + OBJECT_TEEN28 = 648, // toy + OBJECT_TEEN29 = 649, // toy + OBJECT_TEEN30 = 650, // toy + OBJECT_TEEN31 = 651, // toy + OBJECT_TEEN32 = 652, // toy + OBJECT_TEEN33 = 653, // toy + OBJECT_TEEN34 = 654, // toy + OBJECT_TEEN35 = 655, // toy + OBJECT_TEEN36 = 656, // toy + OBJECT_TEEN37 = 657, // toy + OBJECT_TEEN38 = 658, // toy + OBJECT_TEEN39 = 659, // toy + OBJECT_TEEN40 = 660, // toy + OBJECT_TEEN41 = 661, // toy + OBJECT_TEEN42 = 662, // toy + OBJECT_TEEN43 = 663, // toy + OBJECT_TEEN44 = 664, // toy + OBJECT_TEEN45 = 665, // toy + OBJECT_TEEN46 = 666, // toy + OBJECT_TEEN47 = 667, // toy + OBJECT_TEEN48 = 668, // toy + OBJECT_TEEN49 = 669, // toy + OBJECT_QUARTZ0 = 700, // crystal 0 + OBJECT_QUARTZ1 = 701, // crystal 1 + OBJECT_QUARTZ2 = 702, // crystal 2 + OBJECT_QUARTZ3 = 703, // crystal 3 + OBJECT_QUARTZ4 = 704, // crystal 4 + OBJECT_QUARTZ5 = 705, // crystal 5 + OBJECT_QUARTZ6 = 706, // crystal 6 + OBJECT_QUARTZ7 = 707, // crystal 7 + OBJECT_QUARTZ8 = 708, // crystal 8 + OBJECT_QUARTZ9 = 709, // crystal 9 + OBJECT_ROOT0 = 710, // root 0 + OBJECT_ROOT1 = 711, // root 1 + OBJECT_ROOT2 = 712, // root 2 + OBJECT_ROOT3 = 713, // root 3 + OBJECT_ROOT4 = 714, // root 4 + OBJECT_ROOT5 = 715, // root 5 + OBJECT_ROOT6 = 716, // root 6 + OBJECT_ROOT7 = 717, // root 7 + OBJECT_ROOT8 = 718, // root 8 + OBJECT_ROOT9 = 719, // root 9 + OBJECT_SEAWEED0 = 720, // seaweed 0 + OBJECT_SEAWEED1 = 721, // seaweed 1 + OBJECT_SEAWEED2 = 722, // seaweed 2 + OBJECT_SEAWEED3 = 723, // seaweed 3 + OBJECT_SEAWEED4 = 724, // seaweed 4 + OBJECT_SEAWEED5 = 725, // seaweed 5 + OBJECT_SEAWEED6 = 726, // seaweed 6 + OBJECT_SEAWEED7 = 727, // seaweed 7 + OBJECT_SEAWEED8 = 728, // seaweed 8 + OBJECT_SEAWEED9 = 729, // seaweed 9 + OBJECT_MUSHROOM0 = 730, // mushroom 0 + OBJECT_MUSHROOM1 = 731, // mushroom 1 + OBJECT_MUSHROOM2 = 732, // mushroom 2 + OBJECT_MUSHROOM3 = 733, // mushroom 3 + OBJECT_MUSHROOM4 = 734, // mushroom 4 + OBJECT_MUSHROOM5 = 735, // mushroom 5 + OBJECT_MUSHROOM6 = 736, // mushroom 6 + OBJECT_MUSHROOM7 = 737, // mushroom 7 + OBJECT_MUSHROOM8 = 738, // mushroom 8 + OBJECT_MUSHROOM9 = 739, // mushroom 9 + OBJECT_APOLLO1 = 900, // apollo lem + OBJECT_APOLLO2 = 901, // apollo jeep + OBJECT_APOLLO3 = 902, // apollo flag + OBJECT_APOLLO4 = 903, // apollo module + OBJECT_APOLLO5 = 904, // apollo antenna + OBJECT_HOME1 = 910, // home 1 + OBJECT_MAX = 1000, +}; + +enum ObjectMaterial +{ + OM_METAL = 0, // metal + OM_PLASTIC = 1, // plastic + OM_HUMAN = 2, // cosmonaut + OM_ANIMAL = 3, // insect + OM_VEGETAL = 4, // plant + OM_MINERAL = 5, // stone +}; + +typedef struct +{ + char bUsed; + int object; // number of the object in CD3DEngine + int parentPart; // number of father part + int masterParti; // master canal of the particle + D3DVECTOR position; + D3DVECTOR angle; + D3DVECTOR zoom; + char bTranslate; + char bRotate; + char bZoom; + D3DMATRIX matTranslate; + D3DMATRIX matRotate; + D3DMATRIX matTransform; + D3DMATRIX matWorld; +} +ObjectPart; + +typedef struct +{ + float wheelFront; // position X of the front wheels + float wheelBack; // position X of the back wheels + float wheelLeft; // position Z of the left wheels + float wheelRight; // position Z of the right wheels + float height; // normal height on top of ground + D3DVECTOR posPower; // position of the battery +} +Character; + +typedef struct +{ + char name[20]; // name of the information + float value; // value of the information +} +Info; + +enum ExploType +{ + EXPLO_BOUM = 1, + EXPLO_BURN = 2, + EXPLO_WATER = 3, +}; + +enum ResetCap +{ + RESET_NONE = 0, + RESET_MOVE = 1, + RESET_DELETE = 2, +}; + +enum RadarFilter +{ + FILTER_NONE = 0, + FILTER_ONLYLANDING = 1, + FILTER_ONLYFLYING = 2, +}; + + + + +class CObject +{ +public: + CObject(CInstanceManager* iMan); + ~CObject(); + + void DeleteObject(BOOL bAll=FALSE); + void Simplify(); + BOOL ExploObject(ExploType type, float force, float decay=1.0f); + + BOOL EventProcess(const Event &event); + void UpdateMapping(); + + int CreatePart(); + void DeletePart(int part); + void SetObjectRank(int part, int objRank); + int RetObjectRank(int part); + void SetObjectParent(int part, int parent); + void SetType(ObjectType type); + ObjectType RetType(); + char* RetName(); + void SetOption(int option); + int RetOption(); + + void SetID(int id); + int RetID(); + + BOOL Write(char *line); + BOOL Read(char *line); + + void SetDrawWorld(BOOL bDraw); + void SetDrawFront(BOOL bDraw); + + BOOL CreateVehicle(D3DVECTOR pos, float angle, ObjectType type, float power, BOOL bTrainer, BOOL bToy); + BOOL CreateInsect(D3DVECTOR pos, float angle, ObjectType type); + BOOL CreateBuilding(D3DVECTOR pos, float angle, float height, ObjectType type, float power=1.0f); + BOOL CreateResource(D3DVECTOR pos, float angle, ObjectType type, float power=1.0f); + BOOL CreateFlag(D3DVECTOR pos, float angle, ObjectType type); + BOOL CreateBarrier(D3DVECTOR pos, float angle, float height, ObjectType type); + BOOL CreatePlant(D3DVECTOR pos, float angle, float height, ObjectType type); + BOOL CreateMushroom(D3DVECTOR pos, float angle, float height, ObjectType type); + BOOL CreateTeen(D3DVECTOR pos, float angle, float zoom, float height, ObjectType type); + BOOL CreateQuartz(D3DVECTOR pos, float angle, float height, ObjectType type); + BOOL CreateRoot(D3DVECTOR pos, float angle, float height, ObjectType type); + BOOL CreateHome(D3DVECTOR pos, float angle, float height, ObjectType type); + BOOL CreateRuin(D3DVECTOR pos, float angle, float height, ObjectType type); + BOOL CreateApollo(D3DVECTOR pos, float angle, ObjectType type); + + BOOL ReadProgram(int rank, char* filename); + BOOL WriteProgram(int rank, char* filename); + BOOL RunProgram(int rank); + + int RetShadowLight(); + int RetEffectLight(); + + void FlushCrashShere(); + int CreateCrashSphere(D3DVECTOR pos, float radius, Sound sound, float hardness=0.45f); + int RetCrashSphereTotal(); + BOOL GetCrashSphere(int rank, D3DVECTOR &pos, float &radius); + float RetCrashSphereHardness(int rank); + Sound RetCrashSphereSound(int rank); + void DeleteCrashSphere(int rank); + void SetGlobalSphere(D3DVECTOR pos, float radius); + void GetGlobalSphere(D3DVECTOR &pos, float &radius); + void SetJotlerSphere(D3DVECTOR pos, float radius); + void GetJotlerSphere(D3DVECTOR &pos, float &radius); + void SetShieldRadius(float radius); + float RetShieldRadius(); + + void SetFloorHeight(float height); + void FloorAdjust(); + + void SetLinVibration(D3DVECTOR dir); + D3DVECTOR RetLinVibration(); + void SetCirVibration(D3DVECTOR dir); + D3DVECTOR RetCirVibration(); + void SetInclinaison(D3DVECTOR dir); + D3DVECTOR RetInclinaison(); + + void SetPosition(int part, const D3DVECTOR &pos); + D3DVECTOR RetPosition(int part); + void SetAngle(int part, const D3DVECTOR &angle); + D3DVECTOR RetAngle(int part); + void SetAngleY(int part, float angle); + void SetAngleX(int part, float angle); + void SetAngleZ(int part, float angle); + float RetAngleY(int part); + float RetAngleX(int part); + float RetAngleZ(int part); + void SetZoom(int part, float zoom); + void SetZoom(int part, D3DVECTOR zoom); + D3DVECTOR RetZoom(int part); + void SetZoomX(int part, float zoom); + float RetZoomX(int part); + void SetZoomY(int part, float zoom); + float RetZoomY(int part); + void SetZoomZ(int part, float zoom); + float RetZoomZ(int part); + + float RetWaterLevel(); + + void SetTrainer(BOOL bEnable); + BOOL RetTrainer(); + + void SetToy(BOOL bEnable); + BOOL RetToy(); + + void SetManual(BOOL bManual); + BOOL RetManual(); + + void SetResetCap(ResetCap cap); + ResetCap RetResetCap(); + void SetResetBusy(BOOL bBusy); + BOOL RetResetBusy(); + void SetResetPosition(const D3DVECTOR &pos); + D3DVECTOR RetResetPosition(); + void SetResetAngle(const D3DVECTOR &angle); + D3DVECTOR RetResetAngle(); + void SetResetRun(int run); + int RetResetRun(); + + void SetMasterParticule(int part, int parti); + int RetMasterParticule(int part); + + void SetPower(CObject* power); + CObject* RetPower(); + void SetFret(CObject* fret); + CObject* RetFret(); + void SetTruck(CObject* truck); + CObject* RetTruck(); + void SetTruckPart(int part); + int RetTruckPart(); + + void InfoFlush(); + void DeleteInfo(int rank); + void SetInfo(int rank, Info info); + Info RetInfo(int rank); + int RetInfoTotal(); + void SetInfoReturn(float value); + float RetInfoReturn(); + void SetInfoUpdate(BOOL bUpdate); + BOOL RetInfoUpdate(); + + BOOL SetCmdLine(int rank, float value); + float RetCmdLine(int rank); + + D3DMATRIX* RetRotateMatrix(int part); + D3DMATRIX* RetTranslateMatrix(int part); + D3DMATRIX* RetTransformMatrix(int part); + D3DMATRIX* RetWorldMatrix(int part); + + void SetViewFromHere(D3DVECTOR &eye, float &dirH, float &dirV, D3DVECTOR &lookat, D3DVECTOR &upVec, CameraType type); + + void SetCharacter(Character* character); + void GetCharacter(Character* character); + Character* RetCharacter(); + + float RetAbsTime(); + + void SetEnergy(float level); + float RetEnergy(); + + void SetCapacity(float capacity); + float RetCapacity(); + + void SetShield(float level); + float RetShield(); + + void SetRange(float delay); + float RetRange(); + + void SetTransparency(float value); + float RetTransparency(); + + ObjectMaterial RetMaterial(); + + void SetGadget(BOOL bMode); + BOOL RetGadget(); + + void SetFixed(BOOL bFixed); + BOOL RetFixed(); + + void SetClip(BOOL bClip); + BOOL RetClip(); + + BOOL JostleObject(float force); + + void StartDetectEffect(CObject *target, BOOL bFound); + + void SetVirusMode(BOOL bEnable); + BOOL RetVirusMode(); + float RetVirusTime(); + + void SetCameraType(CameraType type); + CameraType RetCameraType(); + void SetCameraDist(float dist); + float RetCameraDist(); + void SetCameraLock(BOOL bLock); + BOOL RetCameraLock(); + + void SetHilite(BOOL bMode); + BOOL RetHilite(); + + void SetSelect(BOOL bMode, BOOL bDisplayError=TRUE); + BOOL RetSelect(BOOL bReal=FALSE); + + void SetSelectable(BOOL bMode); + BOOL RetSelectable(); + + void SetActivity(BOOL bMode); + BOOL RetActivity(); + + void SetVisible(BOOL bVisible); + BOOL RetVisible(); + + void SetEnable(BOOL bEnable); + BOOL RetEnable(); + + void SetCheckToken(BOOL bMode); + BOOL RetCheckToken(); + + void SetProxyActivate(BOOL bActivate); + BOOL RetProxyActivate(); + void SetProxyDistance(float distance); + float RetProxyDistance(); + + void SetMagnifyDamage(float factor); + float RetMagnifyDamage(); + + void SetParam(float value); + float RetParam(); + + void SetExplo(BOOL bExplo); + BOOL RetExplo(); + void SetLock(BOOL bLock); + BOOL RetLock(); + void SetCargo(BOOL bCargo); + BOOL RetCargo(); + void SetBurn(BOOL bBurn); + BOOL RetBurn(); + void SetDead(BOOL bDead); + BOOL RetDead(); + BOOL RetRuin(); + BOOL RetActif(); + + void SetGunGoalV(float gunGoal); + void SetGunGoalH(float gunGoal); + float RetGunGoalV(); + float RetGunGoalH(); + + BOOL StartShowLimit(); + void StopShowLimit(); + + BOOL IsProgram(); + void CreateSelectParticule(); + + void SetRunScript(CScript* script); + CScript* RetRunScript(); + CBotVar* RetBotVar(); + CPhysics* RetPhysics(); + CBrain* RetBrain(); + CMotion* RetMotion(); + CAuto* RetAuto(); + void SetAuto(CAuto* automat); + + void SetDefRank(int rank); + int RetDefRank(); + + BOOL GetTooltipName(char* name); + + void AddDeselList(CObject* pObj); + CObject* SubDeselList(); + void DeleteDeselList(CObject* pObj); + + BOOL CreateShadowCircle(float radius, float intensity, D3DShadowType type=D3DSHADOWNORM); + BOOL CreateShadowLight(float height, D3DCOLORVALUE color); + BOOL CreateEffectLight(float height, D3DCOLORVALUE color); + + void FlatParent(); + + BOOL RetTraceDown(); + void SetTraceDown(BOOL bDown); + int RetTraceColor(); + void SetTraceColor(int color); + float RetTraceWidth(); + void SetTraceWidth(float width); + +protected: + BOOL EventFrame(const Event &event); + void VirusFrame(float rTime); + void PartiFrame(float rTime); + void CreateOtherObject(ObjectType type); + void InitPart(int part); + void UpdateTotalPart(); + int SearchDescendant(int parent, int n); + void UpdateEnergyMapping(); + BOOL UpdateTransformObject(int part, BOOL bForceUpdate); + BOOL UpdateTransformObject(); + void UpdateSelectParticule(); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CLight* m_light; + CTerrain* m_terrain; + CWater* m_water; + CCamera* m_camera; + CParticule* m_particule; + CPhysics* m_physics; + CBrain* m_brain; + CMotion* m_motion; + CAuto* m_auto; + CDisplayText* m_displayText; + CRobotMain* m_main; + CSound* m_sound; + CBotVar* m_botVar; + CScript* m_runScript; + + ObjectType m_type; // OBJECT_* + int m_id; // unique identifier + char m_name[50]; // name of the object + Character m_character; // characteristic + int m_option; // option + int m_partiReactor; // number of the particle of the reactor + int m_shadowLight; // number of light from the shadows + float m_shadowHeight; // height of light from the shadows + int m_effectLight; // number of light effects + float m_effectHeight; // height of light effects + D3DVECTOR m_linVibration; // linear vibration + D3DVECTOR m_cirVibration; // circular vibration + D3DVECTOR m_inclinaison; // tilt + CObject* m_power; // battery used by the vehicle + CObject* m_fret; // object transported + CObject* m_truck; // object with the latter + int m_truckLink; // part + float m_energy; // energy contained (if battery) + float m_lastEnergy; + float m_capacity; // capacity (if battery) + float m_shield; // shield + float m_range; // flight range + float m_transparency; // transparency (0..1) + int m_material; // matter(0..n) + float m_aTime; + float m_shotTime; // time since last shot + BOOL m_bVirusMode; // virus activated/triggered + float m_virusTime; // lifetime of the virus + float m_lastVirusParticule; + float m_lastParticule; + BOOL m_bHilite; + BOOL m_bSelect; // object selected + BOOL m_bSelectable; // selectable object + BOOL m_bCheckToken; // object with audited tokens + BOOL m_bVisible; // object active but undetectable + BOOL m_bEnable; // dead object + BOOL m_bProxyActivate; // active object so close + BOOL m_bGadget; // object nonessential + BOOL m_bLock; + BOOL m_bExplo; + BOOL m_bCargo; + BOOL m_bBurn; + BOOL m_bDead; + BOOL m_bFlat; + BOOL m_bTrainer; // drive vehicle (without remote) + BOOL m_bToy; // toy key + BOOL m_bManual; // manual control (Scribbler) + BOOL m_bFixed; + BOOL m_bClip; + BOOL m_bShowLimit; + float m_showLimitRadius; + float m_gunGoalV; + float m_gunGoalH; + CameraType m_cameraType; + float m_cameraDist; + BOOL m_bCameraLock; + int m_defRank; + float m_magnifyDamage; + float m_proxyDistance; + float m_param; + + int m_crashSphereUsed; // number of spheres used + D3DVECTOR m_crashSpherePos[MAXCRASHSPHERE]; + float m_crashSphereRadius[MAXCRASHSPHERE]; + float m_crashSphereHardness[MAXCRASHSPHERE]; + Sound m_crashSphereSound[MAXCRASHSPHERE]; + D3DVECTOR m_globalSpherePos; + float m_globalSphereRadius; + D3DVECTOR m_jotlerSpherePos; + float m_jotlerSphereRadius; + float m_shieldRadius; + + int m_totalPart; + ObjectPart m_objectPart[OBJECTMAXPART]; + + int m_totalDesectList; + CObject* m_objectDeselectList[OBJECTMAXDESELLIST]; + + int m_partiSel[4]; + + ResetCap m_resetCap; + BOOL m_bResetBusy; + D3DVECTOR m_resetPosition; + D3DVECTOR m_resetAngle; + int m_resetRun; + + int m_infoTotal; + Info m_info[OBJECTMAXINFO]; + float m_infoReturn; + BOOL m_bInfoUpdate; + + float m_cmdLine[OBJECTMAXCMDLINE]; +}; + + +#endif //_OBJECT_H_ diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp new file mode 100644 index 0000000..a6d92e5 --- /dev/null +++ b/src/object/robotmain.cpp @@ -0,0 +1,7031 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// robotmain.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "CBot/CBotDll.h" +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "language.h" +#include "global.h" +#include "event.h" +#include "misc.h" +#include "profile.h" +#include "iman.h" +#include "restext.h" +#include "math3d.h" +#include "light.h" +#include "particule.h" +#include "terrain.h" +#include "water.h" +#include "cloud.h" +#include "blitz.h" +#include "planet.h" +#include "object.h" +#include "motion.h" +#include "motiontoto.h" +#include "motionhuman.h" +#include "physics.h" +#include "brain.h" +#include "pyro.h" +#include "modfile.h" +#include "model.h" +#include "camera.h" +#include "task.h" +#include "taskmanip.h" +#include "taskbuild.h" +#include "auto.h" +#include "autobase.h" +#include "displayinfo.h" +#include "interface.h" +#include "shortcut.h" +#include "map.h" +#include "label.h" +#include "button.h" +#include "slider.h" +#include "window.h" +#include "edit.h" +#include "displaytext.h" +#include "text.h" +#include "sound.h" +#include "cbottoken.h" +#include "cmdtoken.h" +#include "mainmovie.h" +#include "maindialog.h" +#include "mainshort.h" +#include "mainmap.h" +#include "script.h" +#include "robotmain.h" + + + +#define CBOT_STACK TRUE // saves the stack of programs CBOT +#define UNIT 4.0f + + + +// Global variables. + +long g_id; // unique identifier +long g_build; // constructible buildings +long g_researchDone; // research done +long g_researchEnable; // research available +float g_unit; // conversion factor + + + +#include "ClassFILE.cpp" + + + +// Compilation of class "point". + +CBotTypResult cPoint(CBotVar* pThis, CBotVar* &var) +{ + if ( !pThis->IsElemOfClass("point") ) return CBotTypResult(CBotErrBadNum); + + if ( var == NULL ) return CBotTypResult(0); // ok if no parameter + + // First parameter (x): + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + // Second parameter (y): + if ( var == NULL ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + // Third parameter (z): + if ( var == NULL ) // only 2 parameters? + { + return CBotTypResult(0); // this function returns void + } + + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + if ( var != NULL ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(0); // this function returns void +} + +//Execution of the class "point". + +BOOL rPoint(CBotVar* pThis, CBotVar* var, CBotVar* pResult, int& Exception) +{ + CBotVar *pX, *pY, *pZ; + + if ( var == NULL ) return TRUE; // constructor with no parameters is ok + + if ( var->GivType() > CBotTypDouble ) + { + Exception = CBotErrBadNum; return FALSE; + } + + pX = pThis->GivItem("x"); + if ( pX == NULL ) + { + Exception = CBotErrUndefItem; return FALSE; + } + pX->SetValFloat( var->GivValFloat() ); + var = var->GivNext(); + + if ( var == NULL ) + { + Exception = CBotErrLowParam; return FALSE; + } + + if ( var->GivType() > CBotTypDouble ) + { + Exception = CBotErrBadNum; return FALSE; + } + + pY = pThis->GivItem("y"); + if ( pY == NULL ) + { + Exception = CBotErrUndefItem; return FALSE; + } + pY->SetValFloat( var->GivValFloat() ); + var = var->GivNext(); + + if ( var == NULL ) + { + return TRUE; // ok with only two parameters + } + + pZ = pThis->GivItem("z"); + if ( pZ == NULL ) + { + Exception = CBotErrUndefItem; return FALSE; + } + pZ->SetValFloat( var->GivValFloat() ); + var = var->GivNext(); + + if ( var != NULL ) + { + Exception = CBotErrOverParam; return FALSE; + } + + return TRUE; // no interruption +} + + + + +// Constructor of robot application. + +CRobotMain::CRobotMain(CInstanceManager* iMan) +{ + ObjectType type; + float fValue; + int iValue, i; + char* token; + + m_iMan = iMan; + m_iMan->AddInstance(CLASS_MAIN, this); + + m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); + m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); + m_cloud = (CCloud*)m_iMan->SearchInstance(CLASS_CLOUD); + m_blitz = (CBlitz*)m_iMan->SearchInstance(CLASS_BLITZ); + m_planet = (CPlanet*)m_iMan->SearchInstance(CLASS_PLANET); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + + m_interface = new CInterface(m_iMan); + m_terrain = new CTerrain(m_iMan); + m_model = new CModel(m_iMan); + m_camera = new CCamera(m_iMan); + m_displayText = new CDisplayText(m_iMan); + m_movie = new CMainMovie(m_iMan); + m_dialog = new CMainDialog(m_iMan); + m_short = new CMainShort(m_iMan); + m_map = new CMainMap(m_iMan); + m_displayInfo = 0; + + m_engine->SetTerrain(m_terrain); + m_filesDir = m_dialog->RetFilesDir(); + + m_time = 0.0f; + m_gameTime = 0.0f; + m_checkEndTime = 0.0f; + + m_phase = PHASE_NAME; + m_cameraRank = -1; + m_visitLast = EVENT_NULL; + m_visitObject = 0; + m_visitArrow = 0; + m_audioTrack = 0; + m_bAudioRepeat = TRUE; + m_delayWriteMessage = 0; + m_selectObject = 0; + m_infoUsed = 0; + + m_bBeginSatCom = FALSE; + m_bMovieLock = FALSE; + m_bSatComLock = FALSE; + m_bEditLock = FALSE; + m_bEditFull = FALSE; + m_bPause = FALSE; + m_bHilite = FALSE; + m_bFreePhoto = FALSE; + m_bShowPos = FALSE; + m_bSelectInsect = FALSE; + m_bShowSoluce = FALSE; + m_bShowAll = FALSE; + m_bCheatRadar = FALSE; + m_bFixScene = FALSE; + m_bTrainerPilot = FALSE; + m_bSuspend = FALSE; + m_bFriendAim = FALSE; + m_bResetCreate = FALSE; + m_bShortCut = TRUE; + + m_engine->SetMovieLock(m_bMovieLock); + + m_movie->Flush(); + m_movieInfoIndex = -1; + + m_tooltipPos = FPOINT(0.0f, 0.0f); + m_tooltipName[0] = 0; + m_tooltipTime = 0.0f; + + m_endingWinRank = 0; + m_endingLostRank = 0; + m_bWinTerminate = FALSE; + + FlushDisplayInfo(); + + m_fontSize = 9.0f; + m_windowPos = FPOINT(0.15f, 0.17f); + m_windowDim = FPOINT(0.70f, 0.66f); + + if ( GetProfileFloat("Edit", "FontSize", fValue) ) m_fontSize = fValue; + if ( GetProfileFloat("Edit", "WindowPos.x", fValue) ) m_windowPos.x = fValue; + if ( GetProfileFloat("Edit", "WindowPos.y", fValue) ) m_windowPos.y = fValue; + if ( GetProfileFloat("Edit", "WindowDim.x", fValue) ) m_windowDim.x = fValue; + if ( GetProfileFloat("Edit", "WindowDim.y", fValue) ) m_windowDim.y = fValue; + + m_IOPublic = FALSE; + m_IODim = FPOINT(320.0f/640.0f, (121.0f+18.0f*8)/480.0f); + m_IOPos.x = (1.0f-m_IODim.x)/2.0f; // in the middle + m_IOPos.y = (1.0f-m_IODim.y)/2.0f; + + if ( GetProfileInt ("Edit", "IOPublic", iValue) ) m_IOPublic = iValue; + if ( GetProfileFloat("Edit", "IOPos.x", fValue) ) m_IOPos.x = fValue; + if ( GetProfileFloat("Edit", "IOPos.y", fValue) ) m_IOPos.y = fValue; + if ( GetProfileFloat("Edit", "IODim.x", fValue) ) m_IODim.x = fValue; + if ( GetProfileFloat("Edit", "IODim.y", fValue) ) m_IODim.y = fValue; + + m_short->FlushShortcuts(); + InitEye(); + + m_engine->SetTracePrecision(1.0f); + + m_cameraPan = 0.0f; + m_cameraZoom = 0.0f; + + g_id = 0; + g_build = 0; + g_researchDone = 0; // no research done + g_researchEnable = 0; + g_unit = 4.0f; + + m_gamerName[0] = 0; + GetProfileString("Gamer", "LastName", m_gamerName, 100); + SetGlobalGamerName(m_gamerName); + ReadFreeParam(); + m_dialog->SetupRecall(); + + for ( i=0 ; iAddItem("x", CBotTypFloat); + bc->AddItem("y", CBotTypFloat); + bc->AddItem("z", CBotTypFloat); + bc->AddFunction("point", rPoint, cPoint); + + // Adds the class Object. + bc = new CBotClass("object", NULL); + bc->AddItem("category", CBotTypResult(CBotTypInt), PR_READ); + bc->AddItem("position", CBotTypResult(CBotTypClass, "point"), PR_READ); + bc->AddItem("orientation", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("pitch", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("roll", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("energyLevel", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("shieldLevel", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("temperature", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("altitude", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("lifeTime", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("material", CBotTypResult(CBotTypInt), PR_READ); + bc->AddItem("energyCell", CBotTypResult(CBotTypPointer, "object"), PR_READ); + bc->AddItem("load", CBotTypResult(CBotTypPointer, "object"), PR_READ); + + // Initializes the class FILE. + InitClassFILE(); + + CScript::InitFonctions(); +} + +// Destructor of robot application. + +CRobotMain::~CRobotMain() +{ + delete m_movie; + delete m_dialog; + delete m_short; + delete m_map; + delete m_terrain; + delete m_model; +} + + +// Creates the file colobot.ini at the first time. + +void CRobotMain::CreateIni() +{ + int iValue; + + // colobot.ini don't exist? + if ( !GetProfileInt("Setup", "TotoMode", iValue) ) + { + m_dialog->SetupMemorize(); + } +} + + +// Changes phase. + +void CRobotMain::ChangePhase(Phase phase) +{ + CEdit* pe; + CButton* pb; + D3DCOLORVALUE color; + FPOINT pos, dim, ddim; + float ox, oy, sx, sy; + char* read; + int rank, numTry; + BOOL bLoading; + + if ( m_phase == PHASE_SIMUL ) // ends a simulation? + { + SaveAllScript(); + m_sound->StopMusic(); + m_camera->SetObject(0); + +#if _SCHOOL + if ( TRUE ) +#else + if ( m_gameTime > 10.0f ) // did you play at least 10 seconds? +#endif + { + rank = m_dialog->RetSceneRank(); + numTry = m_dialog->RetGamerInfoTry(rank); + m_dialog->SetGamerInfoTry(rank, numTry+1); + m_dialog->WriteGamerInfo(); + } + } + + if ( phase == PHASE_WIN ) // wins a simulation? + { + rank = m_dialog->RetSceneRank(); + m_dialog->SetGamerInfoPassed(rank, TRUE); + m_dialog->NextMission(); // passes to the next mission + m_dialog->WriteGamerInfo(); + } + + DeleteAllObjects(); // removes all the current 3D Scene + + m_phase = phase; + m_winDelay = 0.0f; + m_lostDelay = 0.0f; + m_bBeginSatCom = FALSE; + m_bMovieLock = FALSE; + m_bSatComLock = FALSE; + m_bEditLock = FALSE; + m_bFreePhoto = FALSE; + m_bResetCreate = FALSE; + + m_engine->SetMovieLock(m_bMovieLock); + ChangePause(FALSE); + FlushDisplayInfo(); + m_engine->SetRankView(0); + m_engine->FlushObject(); + color.r = color.g = color.b = color.a = 0.0f; + m_engine->SetWaterAddColor(color); + m_engine->SetBackground(""); + m_engine->SetBackForce(FALSE); + m_engine->SetFrontsizeName(""); + m_engine->SetOverColor(); + m_engine->GroundMarkDelete(0); + SetSpeed(1.0f); + m_terrain->SetWind(D3DVECTOR(0.0f, 0.0f, 0.0f)); + m_terrain->FlushBuildingLevel(); + m_terrain->FlushFlyingLimit(); + m_light->FlushLight(); + m_particule->FlushParticule(); + m_water->Flush(); + m_cloud->Flush(); + m_blitz->Flush(); + m_planet->Flush(); + m_iMan->Flush(CLASS_OBJECT); + m_iMan->Flush(CLASS_PHYSICS); + m_iMan->Flush(CLASS_BRAIN); + m_iMan->Flush(CLASS_PYRO); + m_model->StopUserAction(); + m_interface->Flush(); + ClearInterface(); + FlushNewScriptName(); + m_sound->SetListener(D3DVECTOR(0.0f, 0.0f, 0.0f), D3DVECTOR(0.0f, 0.0f, 1.0f)); + m_camera->SetType(CAMERA_DIALOG); + m_movie->Flush(); + m_movieInfoIndex = -1; + m_cameraPan = 0.0f; + m_cameraZoom = 0.0f; + m_bShortCut = TRUE; + + // Creates and hide the command console. + dim.x = 200.0f/640.0f; + dim.y = 18.0f/480.0f; + pos.x = 50.0f/640.0f; + pos.y = 452.0f/480.0f; + pe = m_interface->CreateEdit(pos, dim, 0, EVENT_CMD); + if ( pe == 0 ) return; + pe->ClearState(STATE_VISIBLE); + m_bCmdEdit = FALSE; // hidden for now + + // Creates the speedometer. +#if _TEEN + dim.x = 30.0f/640.0f; + dim.y = 20.0f/480.0f; + pos.x = 4.0f/640.0f; + pos.y = 454.0f/480.0f; +#else + dim.x = 30.0f/640.0f; + dim.y = 20.0f/480.0f; + pos.x = 4.0f/640.0f; + pos.y = 426.0f/480.0f; +#endif + pb = m_interface->CreateButton(pos, dim, 0, EVENT_SPEED); + if ( pb == 0 ) return; + pb->SetState(STATE_SIMPLY); + pb->ClearState(STATE_VISIBLE); + + m_dialog->ChangePhase(m_phase); + + dim.x = 32.0f/640.0f; + dim.y = 32.0f/480.0f; + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = (32.0f+2.0f)/640.0f; + sy = (32.0f+2.0f)/480.0f; + + if ( m_phase != PHASE_PERSO ) + { + m_engine->SetDrawWorld(TRUE); + m_engine->SetDrawFront(FALSE); + m_bFixScene = FALSE; + } + + if ( m_phase == PHASE_INIT ) + { +#if _NEWLOOK + m_engine->FreeTexture("generna.tga"); + m_engine->FreeTexture("genernb.tga"); + m_engine->FreeTexture("genernc.tga"); + m_engine->FreeTexture("genernd.tga"); +#else +#if _FRENCH +#if _DEMO + m_engine->FreeTexture("genedfa.tga"); + m_engine->FreeTexture("genedfb.tga"); + m_engine->FreeTexture("genedfc.tga"); + m_engine->FreeTexture("genedfd.tga"); +#else + m_engine->FreeTexture("generfa.tga"); + m_engine->FreeTexture("generfb.tga"); + m_engine->FreeTexture("generfc.tga"); + m_engine->FreeTexture("generfd.tga"); +#endif +#endif +#if _ENGLISH +#if _DEMO + m_engine->FreeTexture("genedea.tga"); + m_engine->FreeTexture("genedeb.tga"); + m_engine->FreeTexture("genedec.tga"); + m_engine->FreeTexture("geneded.tga"); +#else + m_engine->FreeTexture("generea.tga"); + m_engine->FreeTexture("genereb.tga"); + m_engine->FreeTexture("generec.tga"); + m_engine->FreeTexture("genered.tga"); +#endif +#endif +#if _GERMAN +#if _DEMO + m_engine->FreeTexture("genedda.tga"); + m_engine->FreeTexture("geneddb.tga"); + m_engine->FreeTexture("geneddc.tga"); + m_engine->FreeTexture("geneddd.tga"); +#else + m_engine->FreeTexture("generea.tga"); + m_engine->FreeTexture("genereb.tga"); + m_engine->FreeTexture("generec.tga"); + m_engine->FreeTexture("genered.tga"); +#endif +#endif +#if _WG +#if _DEMO + m_engine->FreeTexture("genedda.tga"); + m_engine->FreeTexture("geneddb.tga"); + m_engine->FreeTexture("geneddc.tga"); + m_engine->FreeTexture("geneddd.tga"); +#else + m_engine->FreeTexture("generda.tga"); + m_engine->FreeTexture("generdb.tga"); + m_engine->FreeTexture("generdc.tga"); + m_engine->FreeTexture("generdd.tga"); +#endif +#endif +#if _POLISH +#if _DEMO + m_engine->FreeTexture("genedpa.tga"); + m_engine->FreeTexture("genedpb.tga"); + m_engine->FreeTexture("genedpc.tga"); + m_engine->FreeTexture("genedpd.tga"); +#else + m_engine->FreeTexture("generpa.tga"); + m_engine->FreeTexture("generpb.tga"); + m_engine->FreeTexture("generpc.tga"); + m_engine->FreeTexture("generpd.tga"); +#endif +#endif +#endif + } + + if ( m_phase == PHASE_SIMUL ) + { + m_engine->FreeTexture("inter01a.tga"); + m_engine->FreeTexture("inter01b.tga"); + m_engine->FreeTexture("inter01c.tga"); + m_engine->FreeTexture("inter01d.tga"); + + read = m_dialog->RetSceneRead(); + bLoading = (read[0] != 0); + + m_map->CreateMap(); + CreateScene(m_dialog->RetSceneSoluce(), FALSE, FALSE); // interactive scene + if ( m_bMapImage ) + { + m_map->SetFixImage(m_mapFilename); + } + + pos.x = 620.0f/640.0f; + pos.y = 460.0f/480.0f; + ddim.x = 20.0f/640.0f; + ddim.y = 20.0f/480.0f; + m_interface->CreateButton(pos, ddim, 11, EVENT_BUTTON_QUIT); + + if ( m_bImmediatSatCom && !bLoading && + m_infoFilename[SATCOM_HUSTON][0] != 0 ) + { + StartDisplayInfo(SATCOM_HUSTON, FALSE); // shows the instructions + } + + m_sound->StopMusic(); + if ( !m_bBase || bLoading ) StartMusic(); + } + + if ( m_phase == PHASE_WIN ) + { + if ( m_endingWinRank == -1 ) + { + ChangePhase(PHASE_TERM); + } + else + { +#if _TEEN + m_bWinTerminate = (m_endingWinRank == 900); + m_dialog->SetSceneName("teenw"); +#else + m_bWinTerminate = (m_endingWinRank == 904); + m_dialog->SetSceneName("win"); +#endif + m_dialog->SetSceneRank(m_endingWinRank); + CreateScene(FALSE, TRUE, FALSE); // sets scene + + pos.x = ox+sx*1; pos.y = oy+sy*1; + ddim.x = dim.x*2; ddim.y = dim.y*2; + m_interface->CreateButton(pos, ddim, 16, EVENT_BUTTON_OK); + + if ( m_bWinTerminate ) + { +#if _TEEN + pos.x = ox+sx*3; pos.y = oy+sy*1; + ddim.x = dim.x*15; ddim.y = dim.y*2; + pe = m_interface->CreateEdit(pos, ddim, 0, EVENT_EDIT0); + pe->SetFontType(FONT_COLOBOT); + pe->SetEditCap(FALSE); + pe->SetHiliteCap(FALSE); + pe->ReadText("help\\teenw.txt"); +#else + pos.x = ox+sx*3; pos.y = oy+sy*0.2f; + ddim.x = dim.x*15; ddim.y = dim.y*3.0f; + pe = m_interface->CreateEdit(pos, ddim, 0, EVENT_EDIT0); + pe->SetGenericMode(TRUE); + pe->SetFontType(FONT_COLOBOT); + pe->SetEditCap(FALSE); + pe->SetHiliteCap(FALSE); + pe->ReadText("help\\win.txt"); +#endif + } + else + { + m_displayText->DisplayError(INFO_WIN, D3DVECTOR(0.0f,0.0f,0.0f), 15.0f, 60.0f, 1000.0f); + } + } + m_sound->StopAll(); + StartMusic(); + } + + if ( m_phase == PHASE_LOST ) + { + if ( m_endingLostRank == -1 ) + { + ChangePhase(PHASE_TERM); + } + else + { + m_bWinTerminate = FALSE; + m_dialog->SetSceneName("lost"); + m_dialog->SetSceneRank(m_endingLostRank); + CreateScene(FALSE, TRUE, FALSE); // sets scene + + pos.x = ox+sx*1; pos.y = oy+sy*1; + ddim.x = dim.x*2; ddim.y = dim.y*2; + m_interface->CreateButton(pos, ddim, 16, EVENT_BUTTON_OK); + m_displayText->DisplayError(INFO_LOST, D3DVECTOR(0.0f,0.0f,0.0f), 15.0f, 60.0f, 1000.0f); + } + m_sound->StopAll(); + StartMusic(); + } + + if ( m_phase == PHASE_MODEL ) + { + pos.x = ox+sx*0; pos.y = oy+sy*0; + m_interface->CreateButton(pos, dim, 11, EVENT_BUTTON_CANCEL); + + CreateModel(); + } + + if ( m_phase == PHASE_LOADING ) + { + m_engine->SetMouseHide(TRUE); + } + else + { + m_engine->SetMouseHide(FALSE); + } + + m_engine->LoadAllTexture(); +} + + +// Processes an event. + +BOOL CRobotMain::EventProcess(const Event &event) +{ + CEdit* pe; + CObject* pObj; + Event newEvent; + MainMovieType type; + int i; + + if ( event.event == EVENT_FRAME ) + { + if ( !m_movie->EventProcess(event) ) // end of the movie? + { + type = m_movie->RetStopType(); + if ( type == MM_SATCOMopen ) + { + ChangePause(FALSE); + SelectObject(m_infoObject, FALSE); // hands over the command buttons + m_map->ShowMap(m_bMapShow); + m_displayText->HideText(FALSE); + i = m_movieInfoIndex; + StartDisplayInfo(m_movieInfoIndex, FALSE); + m_movieInfoIndex = i; + } + } + + m_dialog->EventProcess(event); + m_displayText->EventProcess(event); + RemoteCamera(m_cameraPan, m_cameraZoom, event.rTime); + + m_interface->EventProcess(event); + if ( m_displayInfo != 0 ) // current edition? + { + m_displayInfo->EventProcess(event); + } + return EventFrame(event); + } + + // Management of the console. +#if 0 + if ( m_phase != PHASE_NAME && + !m_movie->IsExist() && + event.event == EVENT_KEYDOWN && + event.param == VK_PAUSE && + (event.keyState&KS_CONTROL) != 0 ) +#else + if ( m_phase != PHASE_NAME && + !m_movie->IsExist() && + event.event == EVENT_KEYDOWN && + event.param == VK_CANCEL ) // Ctrl+Pause ? +#endif + { + pe = (CEdit*)m_interface->SearchControl(EVENT_CMD); + if ( pe == 0 ) return FALSE; + pe->SetState(STATE_VISIBLE); + pe->SetFocus(TRUE); + if ( m_phase == PHASE_SIMUL ) ChangePause(TRUE); + m_bCmdEdit = TRUE; + return FALSE; + } + if ( event.event == EVENT_KEYDOWN && + event.param == VK_RETURN && m_bCmdEdit ) + { + char cmd[50]; + pe = (CEdit*)m_interface->SearchControl(EVENT_CMD); + if ( pe == 0 ) return FALSE; + pe->GetText(cmd, 50); + pe->SetText(""); + pe->ClearState(STATE_VISIBLE); + if ( m_phase == PHASE_SIMUL ) ChangePause(FALSE); + ExecuteCmd(cmd); + m_bCmdEdit = FALSE; + return FALSE; + } + + // Management of the speed change. + if ( event.event == EVENT_SPEED ) + { + SetSpeed(1.0f); + } + + if ( !m_dialog->EventProcess(event) ) + { + if ( event.event == EVENT_MOUSEMOVE ) + { + m_lastMousePos = event.pos; + HiliteObject(event.pos); + } + return FALSE; + } + + if ( !m_displayText->EventProcess(event) ) + { + return FALSE; + } + + if ( event.event == EVENT_MOUSEMOVE ) + { + m_lastMousePos = event.pos; + HiliteObject(event.pos); + } + + if ( m_displayInfo != 0 ) // current info? + { + m_displayInfo->EventProcess(event); + + if ( event.event == EVENT_KEYDOWN ) + { + if ( event.param == m_engine->RetKey(KEYRANK_HELP, 0) || + event.param == m_engine->RetKey(KEYRANK_HELP, 1) || + event.param == m_engine->RetKey(KEYRANK_PROG, 0) || + event.param == m_engine->RetKey(KEYRANK_PROG, 1) || + event.param == VK_ESCAPE ) + { + StopDisplayInfo(); + } + } + if ( event.event == EVENT_OBJECT_INFOOK ) + { + StopDisplayInfo(); + } + return FALSE; + } + + // Simulation phase of the game + if ( m_phase == PHASE_SIMUL ) + { + UpdateInfoText(); + + if ( !m_bEditFull ) + { + m_camera->EventProcess(event); + } + + switch( event.event ) + { + case EVENT_KEYDOWN: + KeyCamera(event.event, event.param); + HiliteClear(); + if ( event.param == VK_F11 ) + { + m_particule->WriteWheelTrace("Savegame\\t.bmp", 256, 256, D3DVECTOR(16.0f, 0.0f, -368.0f), D3DVECTOR(140.0f, 0.0f, -248.0f)); + return FALSE; + } + if ( m_bEditLock ) // current edition? + { + if ( event.param == m_engine->RetKey(KEYRANK_HELP, 0) || + event.param == m_engine->RetKey(KEYRANK_HELP, 1) ) + { + StartDisplayInfo(SATCOM_HUSTON, FALSE); + return FALSE; + } + if ( event.param == m_engine->RetKey(KEYRANK_PROG, 0) || + event.param == m_engine->RetKey(KEYRANK_PROG, 1) ) + { + StartDisplayInfo(SATCOM_PROG, FALSE); + return FALSE; + } + break; + } + if ( m_bMovieLock ) // current movie? + { + if ( event.param == m_engine->RetKey(KEYRANK_QUIT, 0) || + event.param == m_engine->RetKey(KEYRANK_QUIT, 1) || + event.param == VK_ESCAPE ) + { + AbortMovie(); + } + return FALSE; + } + if ( m_camera->RetType() == CAMERA_VISIT ) + { + if ( event.param == m_engine->RetKey(KEYRANK_VISIT, 0) || + event.param == m_engine->RetKey(KEYRANK_VISIT, 1) ) + { + StartDisplayVisit(EVENT_NULL); + } + if ( event.param == m_engine->RetKey(KEYRANK_QUIT, 0) || + event.param == m_engine->RetKey(KEYRANK_QUIT, 1) || + event.param == VK_ESCAPE ) + { + StopDisplayVisit(); + } + return FALSE; + } + if ( event.param == m_engine->RetKey(KEYRANK_QUIT, 0) || + event.param == m_engine->RetKey(KEYRANK_QUIT, 1) ) + { + if ( m_movie->IsExist() ) + { + StartDisplayInfo(SATCOM_HUSTON, FALSE); + } + else if ( m_winDelay > 0.0f ) + { + ChangePhase(PHASE_WIN); + } + else if ( m_lostDelay > 0.0f ) + { + ChangePhase(PHASE_LOST); + } + else + { + m_dialog->StartAbort(); // do you want to leave? + } + } + if ( event.param == VK_PAUSE ) + { + if ( !m_bMovieLock && !m_bEditLock && !m_bCmdEdit && + m_camera->RetType() != CAMERA_VISIT && + !m_movie->IsExist() ) + { + ChangePause(!m_engine->RetPause()); + } + } + if ( event.param == m_engine->RetKey(KEYRANK_CAMERA, 0) || + event.param == m_engine->RetKey(KEYRANK_CAMERA, 1) ) + { + ChangeCamera(); + } + if ( event.param == m_engine->RetKey(KEYRANK_DESEL, 0) || + event.param == m_engine->RetKey(KEYRANK_DESEL, 1) ) + { + if ( m_bShortCut ) + { + DeselectObject(); + } + } + if ( event.param == m_engine->RetKey(KEYRANK_HUMAN, 0) || + event.param == m_engine->RetKey(KEYRANK_HUMAN, 1) ) + { + SelectHuman(); + } + if ( event.param == m_engine->RetKey(KEYRANK_NEXT, 0) || + event.param == m_engine->RetKey(KEYRANK_NEXT, 1) ) + { + if ( m_bShortCut ) + { + m_short->SelectNext(); + } + } + if ( event.param == m_engine->RetKey(KEYRANK_HELP, 0) || + event.param == m_engine->RetKey(KEYRANK_HELP, 1) ) + { + StartDisplayInfo(SATCOM_HUSTON, TRUE); + } + if ( event.param == m_engine->RetKey(KEYRANK_PROG, 0) || + event.param == m_engine->RetKey(KEYRANK_PROG, 1) ) + { + StartDisplayInfo(SATCOM_PROG, TRUE); + } + if ( event.param == m_engine->RetKey(KEYRANK_VISIT, 0) || + event.param == m_engine->RetKey(KEYRANK_VISIT, 1) ) + { + StartDisplayVisit(EVENT_NULL); + } + if ( event.param == m_engine->RetKey(KEYRANK_SPEED10, 0) || + event.param == m_engine->RetKey(KEYRANK_SPEED10, 1) ) + { + SetSpeed(1.0f); + } + if ( event.param == m_engine->RetKey(KEYRANK_SPEED15, 0) || + event.param == m_engine->RetKey(KEYRANK_SPEED15, 1) ) + { + SetSpeed(1.5f); + } + if ( event.param == m_engine->RetKey(KEYRANK_SPEED20, 0) || + event.param == m_engine->RetKey(KEYRANK_SPEED20, 1) ) + { + SetSpeed(2.0f); + } + if ( event.param == m_engine->RetKey(KEYRANK_SPEED30, 0) || + event.param == m_engine->RetKey(KEYRANK_SPEED30, 1) ) + { + SetSpeed(3.0f); + } + break; + + case EVENT_KEYUP: + KeyCamera(event.event, event.param); + break; + + case EVENT_LBUTTONDOWN: + pObj = DetectObject(event.pos); + if ( !m_bShortCut ) pObj = 0; + if ( pObj != 0 && pObj->RetType() == OBJECT_TOTO ) + { + if ( m_displayInfo != 0 ) // current info? + { + StopDisplayInfo(); + } + else + { + if ( !m_bEditLock ) + { + StartDisplayInfo(SATCOM_HUSTON, TRUE); + } + } + } + else + { + SelectObject(pObj); + } + break; + + case EVENT_LBUTTONUP: + m_cameraPan = 0.0f; + m_cameraZoom = 0.0f; + break; + + case EVENT_BUTTON_QUIT: + if ( m_movie->IsExist() ) + { + StartDisplayInfo(SATCOM_HUSTON, FALSE); + } + else if ( m_winDelay > 0.0f ) + { + ChangePhase(PHASE_WIN); + } + else if ( m_lostDelay > 0.0f ) + { + ChangePhase(PHASE_LOST); + } + else + { + m_dialog->StartAbort(); // do you want to leave? + } + break; + + case EVENT_OBJECT_LIMIT: + StartShowLimit(); + break; + + case EVENT_OBJECT_DESELECT: + if ( m_bShortCut ) + { + DeselectObject(); + } + break; + + case EVENT_OBJECT_HELP: + HelpObject(); + break; + + case EVENT_OBJECT_CAMERA: + ChangeCamera(); + break; + + case EVENT_OBJECT_CAMERAleft: + m_cameraPan = -1.0f; + break; + case EVENT_OBJECT_CAMERAright: + m_cameraPan = 1.0f; + break; + case EVENT_OBJECT_CAMERAnear: + m_cameraZoom = -1.0f; + break; + case EVENT_OBJECT_CAMERAaway: + m_cameraZoom = 1.0f; + break; + + case EVENT_OBJECT_DELETE: + m_dialog->StartDeleteObject(); // do you want to destroy it? + break; + + case EVENT_OBJECT_BHELP: + StartDisplayInfo(SATCOM_HUSTON, TRUE); + break; + + case EVENT_OBJECT_SOLUCE: + StartDisplayInfo(SATCOM_SOLUCE, TRUE); + break; + + case EVENT_OBJECT_MAPZOOM: + m_map->ZoomMap(); + break; + + case EVENT_DT_VISIT0: + case EVENT_DT_VISIT1: + case EVENT_DT_VISIT2: + case EVENT_DT_VISIT3: + case EVENT_DT_VISIT4: + StartDisplayVisit(event.event); + break; + + case EVENT_DT_END: + StopDisplayVisit(); + break; + + case EVENT_OBJECT_SHORTCUT00: + case EVENT_OBJECT_SHORTCUT01: + case EVENT_OBJECT_SHORTCUT02: + case EVENT_OBJECT_SHORTCUT03: + case EVENT_OBJECT_SHORTCUT04: + case EVENT_OBJECT_SHORTCUT05: + case EVENT_OBJECT_SHORTCUT06: + case EVENT_OBJECT_SHORTCUT07: + case EVENT_OBJECT_SHORTCUT08: + case EVENT_OBJECT_SHORTCUT09: + case EVENT_OBJECT_SHORTCUT10: + case EVENT_OBJECT_SHORTCUT11: + case EVENT_OBJECT_SHORTCUT12: + case EVENT_OBJECT_SHORTCUT13: + case EVENT_OBJECT_SHORTCUT14: + case EVENT_OBJECT_SHORTCUT15: + case EVENT_OBJECT_SHORTCUT16: + case EVENT_OBJECT_SHORTCUT17: + case EVENT_OBJECT_SHORTCUT18: + case EVENT_OBJECT_SHORTCUT19: + m_short->SelectShortcut(event.event); + break; + + case EVENT_OBJECT_MOVIELOCK: + AbortMovie(); + break; + + case EVENT_WIN: + ChangePhase(PHASE_WIN); + break; + + case EVENT_LOST: + ChangePhase(PHASE_LOST); + break; + } + + EventObject(event); + return FALSE; + } + + if ( m_phase == PHASE_PERSO ) + { + EventObject(event); + } + + if ( m_phase == PHASE_WIN || + m_phase == PHASE_LOST ) + { + EventObject(event); + + switch( event.event ) + { + case EVENT_KEYDOWN: + if ( event.param == VK_ESCAPE || + event.param == VK_RETURN ) + { + if ( m_bWinTerminate ) + { + ChangePhase(PHASE_INIT); + } + else + { + ChangePhase(PHASE_TERM); + } + } + break; + + case EVENT_BUTTON_OK: + if ( m_bWinTerminate ) + { + ChangePhase(PHASE_INIT); + } + else + { + ChangePhase(PHASE_TERM); + } + break; + } + } + + if ( m_phase == PHASE_MODEL ) + { + switch( event.event ) + { + case EVENT_KEYDOWN: + if ( event.param == VK_ESCAPE ) + { + ChangePhase(PHASE_INIT); + } + if ( event.param == VK_HOME ) + { + InitEye(); + } + break; + + case EVENT_BUTTON_CANCEL: + ChangePhase(PHASE_INIT); + break; + } + + m_model->EventProcess(event); + return FALSE; + } + + return TRUE; +} + + + +// Executes a command. + +void CRobotMain::ExecuteCmd(char *cmd) +{ + if ( cmd[0] == 0 ) return; + + if ( m_phase == PHASE_SIMUL ) + { + if ( strcmp(cmd, "winmission") == 0 ) + { + Event newEvent; + m_event->MakeEvent(newEvent, EVENT_WIN); + m_event->AddEvent(newEvent); + } + + if ( strcmp(cmd, "lostmission") == 0 ) + { + Event newEvent; + m_event->MakeEvent(newEvent, EVENT_LOST); + m_event->AddEvent(newEvent); + } + + if ( strcmp(cmd, "trainerpilot") == 0 ) + { + m_bTrainerPilot = !m_bTrainerPilot; + return; + } + + if ( strcmp(cmd, "fly") == 0 ) + { + Event newEvent; + + g_researchDone |= RESEARCH_FLY; + + m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); + m_event->AddEvent(newEvent); + return; + } + + if ( strcmp(cmd, "allresearch") == 0 ) + { + Event newEvent; + + g_researchDone = -1; // all research are done + + m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); + m_event->AddEvent(newEvent); + return; + } + + if ( strcmp(cmd, "nolimit") == 0 ) + { + m_terrain->SetFlyingMaxHeight(280.0f); + return; + } + + if ( strcmp(cmd, "photo1") == 0 ) + { + m_bFreePhoto = !m_bFreePhoto; + if ( m_bFreePhoto ) + { + m_camera->SetType(CAMERA_FREE); + ChangePause(TRUE); + } + else + { + m_camera->SetType(CAMERA_BACK); + ChangePause(FALSE); + } + return; + } + + if ( strcmp(cmd, "photo2") == 0 ) + { + m_bFreePhoto = !m_bFreePhoto; + if ( m_bFreePhoto ) + { + m_camera->SetType(CAMERA_FREE); + ChangePause(TRUE); + DeselectAll(); // removes the control buttons + m_map->ShowMap(FALSE); + m_displayText->HideText(TRUE); + } + else + { + m_camera->SetType(CAMERA_BACK); + ChangePause(FALSE); + m_map->ShowMap(m_bMapShow); + m_displayText->HideText(FALSE); + } + return; + } + + if ( strcmp(cmd, "noclip") == 0 ) + { + CObject* object; + + object = RetSelect(); + if ( object != 0 ) + { + object->SetClip(FALSE); + } + return; + } + + if ( strcmp(cmd, "clip") == 0 ) + { + CObject* object; + + object = RetSelect(); + if ( object != 0 ) + { + object->SetClip(TRUE); + } + return; + } + + if ( strcmp(cmd, "addhusky") == 0 ) + { + CObject* object; + + object = RetSelect(); + if ( object != 0 ) + { + object->SetMagnifyDamage(object->RetMagnifyDamage()*0.1f); + } + return; + } + + if ( strcmp(cmd, "addfreezer") == 0 ) + { + CObject* object; + + object = RetSelect(); + if ( object != 0 ) + { + object->SetRange(object->RetRange()*10.0f); + } + return; + } + + if ( strcmp(cmd, "fullpower") == 0 ) + { + CObject* object; + CObject* power; + CPhysics* physics; + + object = RetSelect(); + if ( object != 0 ) + { + power = object->RetPower(); + if ( power != 0 ) + { + power->SetEnergy(1.0f); + } + object->SetShield(1.0f); + physics = object->RetPhysics(); + if ( physics != 0 ) + { + physics->SetReactorRange(1.0f); + } + } + return; + } + + if ( strcmp(cmd, "fullenergy") == 0 ) + { + CObject* object; + CObject* power; + + object = RetSelect(); + if ( object != 0 ) + { + power = object->RetPower(); + if ( power != 0 ) + { + power->SetEnergy(1.0f); + } + } + return; + } + + if ( strcmp(cmd, "fullshield") == 0 ) + { + CObject* object; + + object = RetSelect(); + if ( object != 0 ) + { + object->SetShield(1.0f); + } + return; + } + + if ( strcmp(cmd, "fullrange") == 0 ) + { + CObject* object; + CPhysics* physics; + + object = RetSelect(); + if ( object != 0 ) + { + physics = object->RetPhysics(); + if ( physics != 0 ) + { + physics->SetReactorRange(1.0f); + } + } + return; + } + } + + if ( strcmp(cmd, "debugmode") == 0 ) + { + m_engine->SetDebugMode(!m_engine->RetDebugMode()); + return; + } + + if ( strcmp(cmd, "showstat") == 0 ) + { + m_engine->SetShowStat(!m_engine->RetShowStat()); + return; + } + + if ( strcmp(cmd, "invshadow") == 0 ) + { + m_engine->SetShadow(!m_engine->RetShadow()); + return; + } + + if ( strcmp(cmd, "invdirty") == 0 ) + { + m_engine->SetDirty(!m_engine->RetDirty()); + return; + } + + if ( strcmp(cmd, "invfog") == 0 ) + { + m_engine->SetFog(!m_engine->RetFog()); + return; + } + + if ( strcmp(cmd, "invlens") == 0 ) + { + m_engine->SetLensMode(!m_engine->RetLensMode()); + return; + } + + if ( strcmp(cmd, "invwater") == 0 ) + { + m_engine->SetWaterMode(!m_engine->RetWaterMode()); + return; + } + + if ( strcmp(cmd, "invsky") == 0 ) + { + m_engine->SetSkyMode(!m_engine->RetSkyMode()); + return; + } + + if ( strcmp(cmd, "invplanet") == 0 ) + { + m_engine->SetPlanetMode(!m_engine->RetPlanetMode()); + return; + } + + if ( strcmp(cmd, "showpos") == 0 ) + { + m_bShowPos = !m_bShowPos; + return; + } + + if ( strcmp(cmd, "selectinsect") == 0 ) + { + m_bSelectInsect = !m_bSelectInsect; + return; + } + + if ( strcmp(cmd, "showsoluce") == 0 ) + { + m_bShowSoluce = !m_bShowSoluce; + m_dialog->ShowSoluceUpdate(); + return; + } + +#if _TEEN + if ( strcmp(cmd, "allteens") == 0 ) +#else + if ( strcmp(cmd, "allmission") == 0 ) +#endif + { + m_bShowAll = !m_bShowAll; + m_dialog->AllMissionUpdate(); + return; + } + + if ( strcmp(cmd, "invradar") == 0 ) + { + m_bCheatRadar = !m_bCheatRadar; + return; + } + + if ( m_phase == PHASE_SIMUL ) + { + m_displayText->DisplayError(ERR_CMD, D3DVECTOR(0.0f,0.0f,0.0f)); + } +} + + + +// Returns the type of current movie. + +MainMovieType CRobotMain::RetMainMovie() +{ + return m_movie->RetType(); +} + + +// Clears the display of instructions. + +void CRobotMain::FlushDisplayInfo() +{ + int i; + + for ( i=0 ; iRetType() == OBJECT_HUMAN ); + + if ( !m_bEditLock && bMovie && !m_movie->IsExist() && bHuman ) + { + motion = pObj->RetMotion(); + if ( motion != 0 && motion->RetAction() == -1 ) + { + m_movieInfoIndex = index; + m_movie->Start(MM_SATCOMopen, 2.5f); + ChangePause(TRUE); +//? m_map->ShowMap(FALSE); + m_infoObject = DeselectAll(); // removes the control buttons + m_displayText->HideText(TRUE); + return; + } + } + + if ( m_movie->IsExist() ) + { + m_movie->Stop(); + ChangePause(FALSE); + SelectObject(m_infoObject, FALSE); // hands over the command buttons +//? m_map->ShowMap(m_bMapShow); + m_displayText->HideText(FALSE); + } + + StartDisplayInfo(m_infoFilename[index], index); +} + +// Beginning of the displaying of instructions. + +void CRobotMain::StartDisplayInfo(char *filename, int index) +{ + CButton* pb; + BOOL bSoluce; + + if ( m_bCmdEdit ) return; + + m_movieInfoIndex = -1; + ClearInterface(); // removes setting evidence and tooltip + + if ( !m_bEditLock ) + { +//? m_map->ShowMap(FALSE); + m_infoObject = DeselectAll(); // removes the control buttons + m_displayText->HideText(TRUE); + m_sound->MuteAll(TRUE); + } + + pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); + if ( pb != 0 ) + { + pb->ClearState(STATE_VISIBLE); + } + + bSoluce = m_dialog->RetSceneSoluce(); + + m_displayInfo = new CDisplayInfo(m_iMan); + m_displayInfo->StartDisplayInfo(filename, index, bSoluce); + + m_infoIndex = index; + if ( index != -1 ) + { + m_displayInfo->SetPosition(m_infoPos[index]); + } +} + +// End of displaying of instructions. + +void CRobotMain::StopDisplayInfo() +{ + CButton* pb; + + if ( m_movieInfoIndex != -1 ) // film to read the SatCom? + { + m_movie->Start(MM_SATCOMclose, 2.0f); + } + + if ( m_infoIndex != -1 ) + { + m_infoPos[m_infoIndex] = m_displayInfo->RetPosition(); + } + m_displayInfo->StopDisplayInfo(); + + delete m_displayInfo; + m_displayInfo = 0; + + if ( !m_bEditLock ) + { + pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); + if ( pb != 0 ) + { + pb->SetState(STATE_VISIBLE); + } + + SelectObject(m_infoObject, FALSE); // gives the command buttons +//? m_map->ShowMap(m_bMapShow); + m_displayText->HideText(FALSE); + + m_sound->MuteAll(FALSE); + } + + if ( m_infoUsed == 0 ) + { + m_displayText->ClearText(); // removes message "see SatCom ..." + } + m_infoUsed ++; +} + +// Returns the name of the text display. + +char* CRobotMain::RetDisplayInfoName(int index) +{ + return m_infoFilename[index]; +} + +// Returns the name of the text display. + +int CRobotMain::RetDisplayInfoPosition(int index) +{ + return m_infoPos[index]; +} + +// Returns the name of the text display. + +void CRobotMain::SetDisplayInfoPosition(int index, int pos) +{ + m_infoPos[index] = pos; +} + + +// Beginning of a dialogue during the game, + +void CRobotMain::StartSuspend() +{ + CButton* pb; + + m_map->ShowMap(FALSE); + m_infoObject = DeselectAll(); // removes the control buttons + m_displayText->HideText(TRUE); + + pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); + if ( pb != 0 ) + { + pb->ClearState(STATE_VISIBLE); + } + + m_bSuspend = TRUE; +} + +// End of dialogue during the game, + +void CRobotMain::StopSuspend() +{ + CButton* pb; + + pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); + if ( pb != 0 ) + { + pb->SetState(STATE_VISIBLE); + } + + SelectObject(m_infoObject, FALSE); // gives the command buttons + m_map->ShowMap(m_bMapShow); + m_displayText->HideText(FALSE); + + m_bSuspend = FALSE; +} + + +// Returns the absolute time of the game + +float CRobotMain::RetGameTime() +{ + return m_gameTime; +} + + + +// Managing the size of the default fonts. + +void CRobotMain::SetFontSize(float size) +{ + m_fontSize = size; + SetProfileFloat("Edit", "FontSize", m_fontSize); +} + +float CRobotMain::RetFontSize() +{ + return m_fontSize; +} + +// Managing the size of the default window. + +void CRobotMain::SetWindowPos(FPOINT pos) +{ + m_windowPos = pos; + SetProfileFloat("Edit", "WindowPos.x", m_windowPos.x); + SetProfileFloat("Edit", "WindowPos.y", m_windowPos.y); +} + +FPOINT CRobotMain::RetWindowPos() +{ + return m_windowPos; +} + +void CRobotMain::SetWindowDim(FPOINT dim) +{ + m_windowDim = dim; + SetProfileFloat("Edit", "WindowDim.x", m_windowDim.x); + SetProfileFloat("Edit", "WindowDim.y", m_windowDim.y); +} + +FPOINT CRobotMain::RetWindowDim() +{ + return m_windowDim; +} + + +// Managing windows open/save. + +void CRobotMain::SetIOPublic(BOOL bMode) +{ + m_IOPublic = bMode; + SetProfileInt("Edit", "IOPublic", m_IOPublic); +} + +BOOL CRobotMain::RetIOPublic() +{ + return m_IOPublic; +} + +void CRobotMain::SetIOPos(FPOINT pos) +{ + m_IOPos = pos; + SetProfileFloat("Edit", "IOPos.x", m_IOPos.x); + SetProfileFloat("Edit", "IOPos.y", m_IOPos.y); +} + +FPOINT CRobotMain::RetIOPos() +{ + return m_IOPos; +} + +void CRobotMain::SetIODim(FPOINT dim) +{ + m_IODim = dim; + SetProfileFloat("Edit", "IODim.x", m_IODim.x); + SetProfileFloat("Edit", "IODim.y", m_IODim.y); +} + +FPOINT CRobotMain::RetIODim() +{ + return m_IODim; +} + + + +// Start of the visit instead of an error. + +void CRobotMain::StartDisplayVisit(EventMsg event) +{ + CWindow* pw; + CButton* button; + CGroup* group; + D3DVECTOR goal; + FPOINT pos, dim; + int i, j; + + if ( m_bEditLock ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); + if ( pw == 0 ) return; + + if ( event == EVENT_NULL ) // visit by keyboard shortcut? + { + if ( m_visitLast != EVENT_NULL ) // already a current visit? + { + i = m_visitLast-EVENT_DT_VISIT0; + } + else + { + i = MAXDTLINE; + } + + // Seeks the last. + for ( j=0 ; jSearchControl(EventMsg(EVENT_DT_VISIT0+i)); + if ( button == 0 || !button->TestState(STATE_ENABLE) ) continue; + + group = (CGroup*)pw->SearchControl(EventMsg(EVENT_DT_GROUP0+i)); + if ( group != 0 ) + { + event = EventMsg(EVENT_DT_VISIT0+i); + break; + } + } + } + if ( event == EVENT_NULL ) + { + m_sound->Play(SOUND_TZOING); // nothing to do! + return; + } + + m_visitLast = event; + + ClearInterface(); // removes setting evidence and tooltip + + if ( m_camera->RetType() == CAMERA_VISIT ) // already a current visit? + { + m_camera->StopVisit(); + m_displayText->ClearVisit(); + } + else + { + m_visitObject = DeselectAll(); // removes the control buttons + } + + // Creates the "continue" button. + if ( m_interface->SearchControl(EVENT_DT_END) == 0 ) + { + pos.x = 10.0f/640.0f; + pos.y = 10.0f/480.0f; + dim.x = 50.0f/640.0f; + dim.y = 50.0f/480.0f; + m_interface->CreateButton(pos, dim, 16, EVENT_DT_END); + } + + // Creates the arrow to show the place. + if ( m_visitArrow != 0 ) + { + m_visitArrow->DeleteObject(); + delete m_visitArrow; + m_visitArrow = 0; + } + goal = m_displayText->RetVisitGoal(event); + m_visitArrow = CreateObject(goal, 0.0f, 1.0f, 10.0f, OBJECT_SHOW, FALSE, FALSE, 0); + + m_visitPos = m_visitArrow->RetPosition(0); + m_visitPosArrow = m_visitPos; + m_visitPosArrow.y += m_displayText->RetVisitHeight(event); + m_visitArrow->SetPosition(0, m_visitPosArrow); + + m_visitTime = 0.0; + m_visitParticule = 0.0f; + + m_particule->DeleteParticule(PARTISHOW); + + m_camera->StartVisit(m_displayText->RetVisitGoal(event), + m_displayText->RetVisitDist(event)); + m_displayText->SetVisit(event); + ChangePause(TRUE); +} + +// Move the arrow to visit. + +void CRobotMain::FrameVisit(float rTime) +{ + D3DVECTOR pos, speed; + FPOINT dim; + float level; + + if ( m_visitArrow == 0 ) return; + + // Moves the arrow. + m_visitTime += rTime; + + pos = m_visitPosArrow; + pos.y += 1.5f+sinf(m_visitTime*4.0f)*4.0f; + m_visitArrow->SetPosition(0, pos); + m_visitArrow->SetAngleY(0, m_visitTime*2.0f); + + // Manages the particles "arrows". + m_visitParticule -= rTime; + if ( m_visitParticule <= 0.0f ) + { + m_visitParticule = 1.5f; + + pos = m_visitPos; + level = m_terrain->RetFloorLevel(pos)+2.0f; + if ( pos.y < level ) pos.y = level; // not below the ground + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 30.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISHOW, 2.0f); + } +} + +// End of the visit instead of an error. + +void CRobotMain::StopDisplayVisit() +{ + m_visitLast = EVENT_NULL; + + // Removes the button. + m_interface->DeleteControl(EVENT_DT_END); + + // Removes the arrow. + if ( m_visitArrow != 0 ) + { + m_visitArrow->DeleteObject(); + delete m_visitArrow; + m_visitArrow = 0; + } + + // Removes particles "arrows". + m_particule->DeleteParticule(PARTISHOW); + + m_camera->StopVisit(); + m_displayText->ClearVisit(); + ChangePause(FALSE); + if ( m_visitObject != 0 ) + { + SelectObject(m_visitObject, FALSE); // gives the command buttons + m_visitObject = 0; + } +} + + + +// Updates all the shortcuts. + +void CRobotMain::UpdateShortcuts() +{ + m_short->UpdateShortcuts(); +} + +// Returns the object that default was select after the creation of a scene. + +CObject* CRobotMain::RetSelectObject() +{ + if ( m_selectObject != 0 ) return m_selectObject; + return SearchHuman(); +} + +// Deselects everything, and returns the object that was selected. + +CObject* CRobotMain::DeselectAll() +{ + CObject* pObj; + CObject* pPrev; + int i; + + pPrev = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj->RetSelect() ) pPrev = pObj; + pObj->SetSelect(FALSE); + } + return pPrev; +} + +// Selects an object, without attending to deselect the rest. + +void CRobotMain::SelectOneObject(CObject* pObj, BOOL bDisplayError) +{ + ObjectType type; + CObject* toto; + CMotionToto* mt; + + pObj->SetSelect(TRUE, bDisplayError); + m_camera->SetObject(pObj); + + type = pObj->RetType(); + if ( type == OBJECT_HUMAN || + type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEft || + type == OBJECT_MOBILEtt || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEit || + type == OBJECT_MOBILEdr || + type == OBJECT_APOLLO2 ) + { + m_camera->SetType(pObj->RetCameraType()); + m_camera->SetDist(pObj->RetCameraDist()); + } + else + { + m_camera->SetType(CAMERA_BACK); + } + + toto = SearchToto(); + if ( toto != 0 ) + { + mt = (CMotionToto*)toto->RetMotion(); + if ( mt != 0 ) + { + mt->SetLinkType(type); + } + } +} + +// Selects the object aimed by the mouse. + +BOOL CRobotMain::SelectObject(CObject* pObj, BOOL bDisplayError) +{ + CObject* pPrev; + + if ( m_camera->RetType() == CAMERA_VISIT ) + { + StopDisplayVisit(); + } + + if ( m_bMovieLock || m_bEditLock || m_bPause ) return FALSE; + if ( m_movie->IsExist() ) return FALSE; + if ( pObj == 0 || !IsSelectable(pObj) ) return FALSE; + + pPrev = DeselectAll(); + + if ( pPrev != 0 && pPrev != pObj ) + { + pObj->AddDeselList(pPrev); + } + + SelectOneObject(pObj, bDisplayError); + m_short->UpdateShortcuts(); + return TRUE; +} + +// Deselects the selected object. + +BOOL CRobotMain::DeselectObject() +{ + CObject* pObj; + CObject* pPrev; + + pPrev = DeselectAll(); + + if ( pPrev == 0 ) + { + pObj = SearchHuman(); + } + else + { + pObj = pPrev->SubDeselList(); + } + if ( pObj == 0 ) + { + pObj = SearchHuman(); + } + + if ( pObj != 0 ) + { + SelectOneObject(pObj); + } + else + { + m_camera->SetType(CAMERA_FREE); + } + + m_short->UpdateShortcuts(); + return TRUE; +} + +// Quickly removes all objects. + +void CRobotMain::DeleteAllObjects() +{ + CPyro* pyro; + CObject* pObj; + int i; + + // Removes all pyrotechnic effects in progress. + while ( TRUE ) + { + pyro = (CPyro*)m_iMan->SearchInstance(CLASS_PYRO, 0); + if ( pyro == 0 ) break; + + pyro->DeleteObject(); + delete pyro; + } + + // Removes the arrow. + if ( m_visitArrow != 0 ) + { + m_visitArrow->DeleteObject(); + delete m_visitArrow; + m_visitArrow = 0; + } + + for ( i=0 ; iSearchInstance(CLASS_OBJECT, 0); + if ( pObj == 0 ) break; + + pObj->DeleteObject(TRUE); // destroys rapidly + delete pObj; + } +} + +// Selects the human. + +void CRobotMain::SelectHuman() +{ + SelectObject(SearchHuman()); +} + +// Returns the object human. + +CObject* CRobotMain::SearchHuman() +{ + ObjectType type; + CObject* pObj; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type == OBJECT_HUMAN ) + { + return pObj; + } + } + return 0; +} + +// Returns the object toto. + +CObject* CRobotMain::SearchToto() +{ + ObjectType type; + CObject* pObj; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type == OBJECT_TOTO ) + { + return pObj; + } + } + return 0; +} + +// Returns the nearest selectable object from a given position. + +CObject* CRobotMain::SearchNearest(D3DVECTOR pos, CObject* pExclu) +{ + ObjectType type; + CObject *pObj, *pBest; + D3DVECTOR oPos; + float min, dist; + int i; + + min = 100000.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj == pExclu ) continue; + if ( !IsSelectable(pObj) ) continue; + + type = pObj->RetType(); + if ( type == OBJECT_TOTO ) continue; + + oPos = pObj->RetPosition(0); + dist = Length2d(oPos, pos); + if ( dist < min ) + { + min = dist; + pBest = pObj; + } + } + return pBest; +} + +// Returns the selected object. + +CObject* CRobotMain::RetSelect() +{ + CObject* pObj; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj->RetSelect() ) + { + return pObj; + } + } + return 0; +} + +CObject* CRobotMain::SearchObject(ObjectType type) +{ + CObject* pObj; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj->RetType() == type ) + { + return pObj; + } + } + return 0; +} + +// Detects the object aimed by the mouse. + +CObject* CRobotMain::DetectObject(FPOINT pos) +{ + ObjectType type; + CObject *pObj, *pTarget; + int objRank, i, j, rank; + + objRank = m_engine->DetectObject(pos); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetActif() ) continue; + if ( pObj->RetProxyActivate() ) continue; + + pTarget = 0; + type = pObj->RetType(); + if ( type == OBJECT_PORTICO || + type == OBJECT_BASE || + type == OBJECT_DERRICK || + type == OBJECT_FACTORY || + type == OBJECT_REPAIR || + type == OBJECT_DESTROYER || + type == OBJECT_STATION || + type == OBJECT_CONVERT || + type == OBJECT_TOWER || + type == OBJECT_RESEARCH || + type == OBJECT_RADAR || + type == OBJECT_INFO || + type == OBJECT_ENERGY || + type == OBJECT_LABO || + type == OBJECT_NUCLEAR || + type == OBJECT_PARA || + type == OBJECT_SAFE || + type == OBJECT_HUSTON || + type == OBJECT_TARGET1 || + type == OBJECT_TARGET2 || + type == OBJECT_START || + type == OBJECT_END || + type == OBJECT_STONE || + type == OBJECT_URANIUM || + type == OBJECT_BULLET || + type == OBJECT_METAL || + type == OBJECT_BBOX || + type == OBJECT_KEYa || + type == OBJECT_KEYb || + type == OBJECT_KEYc || + type == OBJECT_KEYd || + type == OBJECT_TNT || + type == OBJECT_SCRAP1 || + type == OBJECT_SCRAP2 || + type == OBJECT_SCRAP3 || + type == OBJECT_SCRAP4 || + type == OBJECT_SCRAP5 || + type == OBJECT_BOMB || + type == OBJECT_BAG || + type == OBJECT_WAYPOINT || + type == OBJECT_FLAGb || + type == OBJECT_FLAGr || + type == OBJECT_FLAGg || + type == OBJECT_FLAGy || + type == OBJECT_FLAGv || + type == OBJECT_MARKPOWER || + type == OBJECT_MARKSTONE || + type == OBJECT_MARKURANIUM || + type == OBJECT_MARKKEYa || + type == OBJECT_MARKKEYb || + type == OBJECT_MARKKEYc || + type == OBJECT_MARKKEYd || + type == OBJECT_HUMAN || + type == OBJECT_TECH || + type == OBJECT_TOTO || + type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEtg || + type == OBJECT_MOBILEft || + type == OBJECT_MOBILEtt || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEit || + type == OBJECT_MOBILEdr || + type == OBJECT_MOTHER || + type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_BEE || + type == OBJECT_WORM || + type == OBJECT_EGG || + type == OBJECT_RUINmobilew1 || + type == OBJECT_RUINmobilew2 || + type == OBJECT_RUINmobilet1 || + type == OBJECT_RUINmobilet2 || + type == OBJECT_RUINmobiler1 || + type == OBJECT_RUINmobiler2 || + type == OBJECT_RUINfactory || + type == OBJECT_RUINdoor || + type == OBJECT_RUINsupport || + type == OBJECT_RUINradar || + type == OBJECT_RUINconvert || + type == OBJECT_RUINbase || + type == OBJECT_RUINhead || + type == OBJECT_APOLLO1 || + type == OBJECT_APOLLO2 || + type == OBJECT_APOLLO3 || + type == OBJECT_APOLLO4 || + type == OBJECT_APOLLO5 ) + { + pTarget = pObj; + } + else if ( (type == OBJECT_POWER || + type == OBJECT_ATOMIC ) && + pObj->RetTruck() != 0 ) // battery used? + { + pTarget = pObj->RetTruck(); + } + else if ( type == OBJECT_POWER || + type == OBJECT_ATOMIC ) + { + pTarget = pObj; + } + + for ( j=0 ; jRetObjectRank(j); + if ( rank == -1 ) continue; + if ( rank != objRank ) continue; + return pTarget; + } + } + return 0; +} + +// Indicates whether an object is selectable. + +BOOL CRobotMain::IsSelectable(CObject* pObj) +{ + ObjectType type; + + if ( !pObj->RetSelectable() ) return FALSE; + + type = pObj->RetType(); + if ( type == OBJECT_HUMAN || + type == OBJECT_TOTO || + type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEft || + type == OBJECT_MOBILEtt || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEit || + type == OBJECT_MOBILEdr || + type == OBJECT_APOLLO2 || + type == OBJECT_BASE || + type == OBJECT_DERRICK || + type == OBJECT_FACTORY || + type == OBJECT_REPAIR || + type == OBJECT_DESTROYER|| + type == OBJECT_STATION || + type == OBJECT_CONVERT || + type == OBJECT_TOWER || + type == OBJECT_RESEARCH || + type == OBJECT_RADAR || + type == OBJECT_INFO || + type == OBJECT_ENERGY || + type == OBJECT_LABO || + type == OBJECT_NUCLEAR || + type == OBJECT_PARA || + type == OBJECT_SAFE || + type == OBJECT_HUSTON ) + { + return TRUE; + } + + if ( m_bSelectInsect ) + { + if ( type == OBJECT_MOTHER || + type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_BEE || + type == OBJECT_WORM || + type == OBJECT_MOBILEtg ) + { + return TRUE; + } + } + + return FALSE; +} + + +// Deletes the selected object. + +BOOL CRobotMain::DeleteObject() +{ + CObject* pObj; + CPyro* pyro; + + pObj = RetSelect(); + if ( pObj == 0 ) return FALSE; + + pyro = new CPyro(m_iMan); + pyro->Create(PT_FRAGT, pObj); + + pObj->SetSelect(FALSE); // deselects the object + m_camera->SetType(CAMERA_EXPLO); + DeselectAll(); + pObj->DeleteDeselList(pObj); + + return TRUE; +} + + +// Removes setting evidence of the object with the mouse hovers over. + +void CRobotMain::HiliteClear() +{ + CObject* pObj; + int i; + + ClearTooltip(); + m_tooltipName[0] = 0; // really removes the tooltip + + if ( !m_bHilite ) return; + + i = -1; + m_engine->SetHiliteRank(&i); // nothing more selected + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + pObj->SetHilite(FALSE); + m_map->SetHilite(0); + m_short->SetHilite(0); + } + + m_bHilite = FALSE; +} + +// Highlights the object with the mouse hovers over. + +void CRobotMain::HiliteObject(FPOINT pos) +{ + CObject* pObj; + char name[100]; + BOOL bInMap; + + if ( m_bFixScene && m_phase != PHASE_PERSO ) return; + if ( m_bMovieLock ) return; + if ( m_movie->IsExist() ) return; + if ( m_engine->RetMouseHide() ) return; + + ClearInterface(); // removes setting evidence and tooltip + + pObj = m_short->DetectShort(pos); + + if ( m_dialog->RetTooltip() && m_interface->GetTooltip(pos, name) ) + { + m_tooltipPos = pos; + strcpy(m_tooltipName, name); + m_tooltipTime = 0.0f; + if ( pObj == 0 ) return; + } + + if ( m_bSuspend ) return; + + if ( pObj == 0 ) + { + pObj = m_map->DetectMap(pos, bInMap); + if ( pObj == 0 ) + { + if ( bInMap ) return; + + pObj = DetectObject(pos); + + if ( m_camera->RetType() == CAMERA_ONBOARD && + m_camera->RetObject() == pObj ) + { + return; + } + } + } + + if ( pObj != 0 ) + { + if ( m_dialog->RetTooltip() && pObj->GetTooltipName(name) ) + { + m_tooltipPos = pos; + strcpy(m_tooltipName, name); + m_tooltipTime = 0.0f; + } + + if ( IsSelectable(pObj) ) + { + pObj->SetHilite(TRUE); + m_map->SetHilite(pObj); + m_short->SetHilite(pObj); + m_bHilite = TRUE; + } + } +} + +// Highlights the object with the mouse hovers over. + +void CRobotMain::HiliteFrame(float rTime) +{ + if ( m_bFixScene && m_phase != PHASE_PERSO ) return; + if ( m_bMovieLock ) return; + if ( m_movie->IsExist() ) return; + + m_tooltipTime += rTime; + + ClearTooltip(); + + if ( m_tooltipTime >= 0.2f && + m_tooltipName[0] != 0 ) + { + CreateTooltip(m_tooltipPos, m_tooltipName); + } +} + +// Creates a tooltip. + +void CRobotMain::CreateTooltip(FPOINT pos, char* text) +{ + CWindow* pw; + FPOINT start, end, dim, offset, corner; + + corner.x = pos.x+0.022f; + corner.y = pos.y-0.052f; + + m_engine->RetText()->DimText(text, corner, 1, + SMALLFONT, NORMSTRETCH, FONT_COLOBOT, + start, end); + start.x -= 0.010f; + start.y -= 0.002f; + end.x += 0.010f; + end.y += 0.004f; // ch'tite (?) margin + + pos.x = start.x; + pos.y = start.y; + dim.x = end.x-start.x; + dim.y = end.y-start.y; + + offset.x = 0.0f; + offset.y = 0.0f; + if ( pos.x+dim.x > 1.0f ) offset.x = 1.0f-(pos.x+dim.x); + if ( pos.y < 0.0f ) offset.y = -pos.y; + + corner.x += offset.x; + corner.y += offset.y; + pos.x += offset.x; + pos.y += offset.y; + + m_interface->CreateWindows(pos, dim, 1, EVENT_TOOLTIP); + + pw = (CWindow*)m_interface->SearchControl(EVENT_TOOLTIP); + if ( pw != 0 ) + { + pw->SetState(STATE_SHADOW); + pw->SetTrashEvent(FALSE); + + pos.y -= m_engine->RetText()->RetHeight(SMALLFONT, FONT_COLOBOT)/2.0f; + pw->CreateLabel(pos, dim, -1, EVENT_LABEL2, text); + } +} + +// Clears the previous tooltip. + +void CRobotMain::ClearTooltip() +{ + m_interface->DeleteControl(EVENT_TOOLTIP); +} + + +// Displays help for an object. + +void CRobotMain::HelpObject() +{ + CObject* pObj; + char* filename; + + pObj = RetSelect(); + if ( pObj == 0 ) return; + + filename = RetHelpFilename(pObj->RetType()); + if ( filename[0] == 0 ) return; + + StartDisplayInfo(filename, -1); +} + + +// Change the mode of the camera. + +void CRobotMain::ChangeCamera() +{ + CObject* pObj; + ObjectType oType; + CameraType type; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj->RetSelect() ) + { + if ( pObj->RetCameraLock() ) return; + + oType = pObj->RetType(); + type = pObj->RetCameraType(); + + if ( oType != OBJECT_MOBILEfa && + oType != OBJECT_MOBILEta && + oType != OBJECT_MOBILEwa && + oType != OBJECT_MOBILEia && + oType != OBJECT_MOBILEfc && + oType != OBJECT_MOBILEtc && + oType != OBJECT_MOBILEwc && + oType != OBJECT_MOBILEic && + oType != OBJECT_MOBILEfi && + oType != OBJECT_MOBILEti && + oType != OBJECT_MOBILEwi && + oType != OBJECT_MOBILEii && + oType != OBJECT_MOBILEfs && + oType != OBJECT_MOBILEts && + oType != OBJECT_MOBILEws && + oType != OBJECT_MOBILEis && + oType != OBJECT_MOBILErt && + oType != OBJECT_MOBILErc && + oType != OBJECT_MOBILErr && + oType != OBJECT_MOBILErs && + oType != OBJECT_MOBILEsa && + oType != OBJECT_MOBILEtg && + oType != OBJECT_MOBILEft && + oType != OBJECT_MOBILEtt && + oType != OBJECT_MOBILEwt && + oType != OBJECT_MOBILEit && + oType != OBJECT_MOBILEdr && + oType != OBJECT_APOLLO2 ) return; + + if ( oType == OBJECT_MOBILEdr ) // designer? + { + if ( type == CAMERA_PLANE ) type = CAMERA_BACK; + else if ( type == CAMERA_BACK ) type = CAMERA_PLANE; + } + else if ( pObj->RetTrainer() ) // trainer? + { + if ( type == CAMERA_ONBOARD ) type = CAMERA_FIX; + else if ( type == CAMERA_FIX ) type = CAMERA_PLANE; + else if ( type == CAMERA_PLANE ) type = CAMERA_BACK; + else if ( type == CAMERA_BACK ) type = CAMERA_ONBOARD; + } + else + { + if ( type == CAMERA_ONBOARD ) type = CAMERA_BACK; + else if ( type == CAMERA_BACK ) type = CAMERA_ONBOARD; + } + + pObj->SetCameraType(type); + m_camera->SetType(type); + } + } +} + +// Remote control the camera using the arrow keys. + +void CRobotMain::KeyCamera(EventMsg event, long param) +{ + CObject* pObj; + + if ( event == EVENT_KEYUP ) + { + if ( param == m_engine->RetKey(KEYRANK_LEFT, 0) || + param == m_engine->RetKey(KEYRANK_LEFT, 1) ) + { + m_cameraPan = 0.0f; + } + + if ( param == m_engine->RetKey(KEYRANK_RIGHT, 0) || + param == m_engine->RetKey(KEYRANK_RIGHT, 1) ) + { + m_cameraPan = 0.0f; + } + + if ( param == m_engine->RetKey(KEYRANK_UP, 0) || + param == m_engine->RetKey(KEYRANK_UP, 1) ) + { + m_cameraZoom = 0.0f; + } + + if ( param == m_engine->RetKey(KEYRANK_DOWN, 0) || + param == m_engine->RetKey(KEYRANK_DOWN, 1) ) + { + m_cameraZoom = 0.0f; + } + } + + if ( m_phase != PHASE_SIMUL ) return; + if ( m_bEditLock ) return; // current edition? + if ( m_bTrainerPilot ) return; + + pObj = RetSelect(); + if ( pObj == 0 ) return; + if ( !pObj->RetTrainer() ) return; + + if ( event == EVENT_KEYDOWN ) + { + if ( param == m_engine->RetKey(KEYRANK_LEFT, 0) || + param == m_engine->RetKey(KEYRANK_LEFT, 1) ) + { + m_cameraPan = -1.0f; + } + + if ( param == m_engine->RetKey(KEYRANK_RIGHT, 0) || + param == m_engine->RetKey(KEYRANK_RIGHT, 1) ) + { + m_cameraPan = 1.0f; + } + + if ( param == m_engine->RetKey(KEYRANK_UP, 0) || + param == m_engine->RetKey(KEYRANK_UP, 1) ) + { + m_cameraZoom = -1.0f; + } + + if ( param == m_engine->RetKey(KEYRANK_DOWN, 0) || + param == m_engine->RetKey(KEYRANK_DOWN, 1) ) + { + m_cameraZoom = 1.0f; + } + } +} + +// Panned with the camera if a button is pressed. + +void CRobotMain::RemoteCamera(float pan, float zoom, float rTime) +{ + float value; + + if ( pan != 0.0f ) + { + value = m_camera->RetRemotePan(); + value += pan*rTime*1.5f; + m_camera->SetRemotePan(value); + } + + if ( zoom != 0.0f ) + { + value = m_camera->RetRemoteZoom(); + value += zoom*rTime*0.3f; + m_camera->SetRemoteZoom(value); + } +} + + + +// Cancels the current movie. + +void CRobotMain::AbortMovie() +{ + CObject* pObj; + CAuto* automat; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + automat = pObj->RetAuto(); + if ( automat != 0 ) + { + automat->Abort(); + } + } + + m_engine->SetMouseHide(FALSE); +} + + + +// Updates the text information. + +void CRobotMain::UpdateInfoText() +{ + CObject* pObj; + D3DVECTOR pos; + char info[100]; + + if ( m_bShowPos ) + { + pObj = RetSelect(); + if ( pObj != 0 ) + { + pos = pObj->RetPosition(0); + sprintf(info, "Pos = %.2f ; %.2f", pos.x/g_unit, pos.z/g_unit); + m_engine->SetInfoText(4, info); + } + } +} + + +// Initializes the view. + +void CRobotMain::InitEye() +{ + if ( m_phase == PHASE_SIMUL ) + { + m_camera->Init(D3DVECTOR( 0.0f, 10.0f, 0.0f), + D3DVECTOR(10.0f, 5.0f, 0.0f), 0.0f); + } + + if ( m_phase == PHASE_MODEL ) + { + m_model->InitView(); + } +} + +// Advances the entire scene. + +BOOL CRobotMain::EventFrame(const Event &event) +{ + ObjectType type; + CObject *pObj, *toto; + CPyro* pPyro; + CWindow* pw; + CMap* pm; + int i; + + m_time += event.rTime; + if ( !m_bMovieLock ) m_gameTime += event.rTime; + + if ( !m_bImmediatSatCom && !m_bBeginSatCom && + m_gameTime > 0.1f && m_phase == PHASE_SIMUL ) + { + m_displayText->DisplayError(INFO_BEGINSATCOM, D3DVECTOR(0.0f,0.0f,0.0f)); + m_bBeginSatCom = TRUE; // message appears + } + + m_water->EventProcess(event); + m_cloud->EventProcess(event); + m_blitz->EventProcess(event); + m_planet->EventProcess(event); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw == 0 ) + { + pm = 0; + } + else + { + pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); + if ( pm != 0 ) pm->FlushObject(); + } + + toto = 0; + if ( !m_bFreePhoto ) + { + // Advances all the robots, but not toto. + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + if ( pm != 0 ) pm->UpdateObject(pObj); + if ( pObj->RetTruck() != 0 ) continue; + type = pObj->RetType(); + if ( type == OBJECT_TOTO ) + { + toto = pObj; + } + else + { + pObj->EventProcess(event); + } + } + // Advances all objects transported by robots. + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + if ( pObj->RetTruck() == 0 ) continue; + pObj->EventProcess(event); + } + + // Advances pyrotechnic effects. + for ( i=0 ; i<1000000 ; i++ ) + { + pPyro = (CPyro*)m_iMan->SearchInstance(CLASS_PYRO, i); + if ( pPyro == 0 ) break; + + pPyro->EventProcess(event); + if ( pPyro->IsEnded() != ERR_CONTINUE ) + { + pPyro->DeleteObject(); + delete pPyro; + } + } + } + + // The camera follows the object, because its position + // may depend on the selected object (CAMERA_ONBOARD or CAMERA_BACK). + if ( m_phase == PHASE_SIMUL && !m_bEditFull ) + { + m_camera->EventProcess(event); + + if ( m_engine->RetFog() ) + { + m_camera->SetOverBaseColor(m_particule->RetFogColor(m_engine->RetEyePt())); + } + } + if ( m_phase == PHASE_PERSO || + m_phase == PHASE_WIN || + m_phase == PHASE_LOST ) + { + m_camera->EventProcess(event); + } + + // Advances toto following the camera, because its position depends on the camera. + if ( toto != 0 ) + { + toto->EventProcess(event); + } + + // Advances model. + if ( m_phase == PHASE_MODEL ) + { + m_model->ViewMove(event, 2.0f); + m_model->UpdateView(); + m_model->EventProcess(event); + } + + HiliteFrame(event.rTime); + + // Moves the film indicator. + if ( m_bMovieLock && !m_bEditLock ) // movie in progress? + { + CControl* pc; + FPOINT pos, dim; + float zoom; + + pc = m_interface->SearchControl(EVENT_OBJECT_MOVIELOCK); + if ( pc != 0 ) + { + dim.x = 32.0f/640.0f; + dim.y = 32.0f/480.0f; + pos.x = 20.0f/640.0f; + pos.y = (480.0f-24.0f)/480.0f; + + zoom = 1.0f+sinf(m_time*6.0f)*0.1f; // 0.9 .. 1.1 + dim.x *= zoom; + dim.y *= zoom; + pos.x -= dim.x/2.0f; + pos.y -= dim.y/2.0f; + + pc->SetPos(pos); + pc->SetDim(dim); + } + } + + // Moves edition indicator. + if ( m_bEditLock || m_bPause ) // edition in progress? + { + CControl* pc; + FPOINT pos, dim; + float zoom; + + pc = m_interface->SearchControl(EVENT_OBJECT_EDITLOCK); + if ( pc != 0 ) + { + if ( m_bEditFull || m_bEditLock ) + { + dim.x = 10.0f/640.0f; + dim.y = 10.0f/480.0f; + pos.x = -20.0f/640.0f; + pos.y = -20.0f/480.0f; // invisible! + } + else + { + dim.x = 32.0f/640.0f; + dim.y = 32.0f/480.0f; + pos.x = 20.0f/640.0f; + pos.y = (480.0f-24.0f)/480.0f; + + zoom = 1.0f+sinf(m_time*6.0f)*0.1f; // 0.9 .. 1.1 + dim.x *= zoom; + dim.y *= zoom; + pos.x -= dim.x/2.0f; + pos.y -= dim.y/2.0f; + } + pc->SetPos(pos); + pc->SetDim(dim); + } + } + + // Will move the arrow to visit. + if ( m_camera->RetType() == CAMERA_VISIT ) + { + FrameVisit(event.rTime); + } + + // Moves the boundaries. + FrameShowLimit(event.rTime); + + if ( m_phase == PHASE_SIMUL ) + { + if ( !m_bEditLock && m_checkEndTime+1.0f < m_time ) + { + m_checkEndTime = m_time; + CheckEndMission(TRUE); + } + + if ( m_winDelay > 0.0f && !m_bEditLock ) + { + m_winDelay -= event.rTime; + if ( m_winDelay <= 0.0f ) + { + if ( m_bMovieLock ) + { + m_winDelay = 1.0f; + } + else + { + Event newEvent; + m_event->MakeEvent(newEvent, EVENT_WIN); + m_event->AddEvent(newEvent); + } + } + } + + if ( m_lostDelay > 0.0f && !m_bEditLock ) + { + m_lostDelay -= event.rTime; + if ( m_lostDelay <= 0.0f ) + { + if ( m_bMovieLock ) + { + m_winDelay = 1.0f; + } + else + { + Event newEvent; + m_event->MakeEvent(newEvent, EVENT_LOST); + m_event->AddEvent(newEvent); + } + } + } + } + + if ( m_delayWriteMessage > 0 ) + { + m_delayWriteMessage --; + if ( m_delayWriteMessage == 0 ) + { + m_displayText->DisplayError(INFO_WRITEOK, D3DVECTOR(0.0f,0.0f,0.0f)); + } + } + + return S_OK; +} + +// Makes the event for all robots. + +BOOL CRobotMain::EventObject(const Event &event) +{ + CObject* pObj; + int i; + + if ( m_bFreePhoto ) return S_OK; + + m_bResetCreate = FALSE; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + pObj->EventProcess(event); + } + + if ( m_bResetCreate ) + { + ResetCreate(); + } + + return S_OK; +} + + +// Calculates the point of arrival of the camera. + +D3DVECTOR CRobotMain::LookatPoint(D3DVECTOR eye, float angleH, float angleV, + float length) +{ + D3DVECTOR lookat; + + lookat = eye; + lookat.z += length; + + RotatePoint(eye, angleH, angleV, lookat); + return lookat; +} + + + +char* SkipNum(char *p) +{ + while ( *p == ' ' || *p == '.' || *p == '-' || (*p >= '0' && *p <= '9') ) + { + p++; + } + return p; +} + +// Conversion of units. + +void CRobotMain::Convert() +{ + FILE* file = NULL; + FILE* fileNew = NULL; + char line[500]; + char lineNew[500]; + char s[200]; + char* base; + char* p; + int rank; + D3DVECTOR pos; + float value; + + base = m_dialog->RetSceneName(); + rank = m_dialog->RetSceneRank(); + + m_dialog->BuildSceneName(line, base, rank); + file = fopen(line, "r"); + if ( file == NULL ) return; + + strcpy(line+strlen(line)-4, ".new"); + fileNew = fopen(line, "w"); + if ( fileNew == NULL ) return; + + while ( fgets(line, 500, file) != NULL ) + { + strcpy(lineNew, line); + + if ( Cmd(line, "DeepView") ) + { + p = strstr(line, "air="); + if ( p != 0 ) + { + value = OpFloat(line, "air", 500.0f); + value /= g_unit; + p[0] = 0; + p = SkipNum(p+4); + strcpy(lineNew, line); + strcat(lineNew, "air="); + sprintf(s, "%.2f", value); + strcat(lineNew, s); + strcat(lineNew, " "); + strcat(lineNew, p); + } + strcpy(line, lineNew); + + p = strstr(line, "water="); + if ( p != 0 ) + { + value = OpFloat(line, "water", 100.0f); + value /= g_unit; + p[0] = 0; + p = SkipNum(p+6); + strcpy(lineNew, line); + strcat(lineNew, "water="); + sprintf(s, "%.2f", value); + strcat(lineNew, s); + strcat(lineNew, " "); + strcat(lineNew, p); + } + strcpy(line, lineNew); + } + + if ( Cmd(line, "TerrainGenerate") ) + { + p = strstr(line, "vision="); + if ( p != 0 ) + { + value = OpFloat(line, "vision", 500.0f); + value /= g_unit; + p[0] = 0; + p = SkipNum(p+7); + strcpy(lineNew, line); + strcat(lineNew, "vision="); + sprintf(s, "%.2f", value); + strcat(lineNew, s); + strcat(lineNew, " "); + strcat(lineNew, p); + } + } + + if ( Cmd(line, "CreateObject") || + Cmd(line, "CreateSpot") ) + { + p = strstr(line, "pos="); + if ( p != 0 ) + { + pos = OpPos(line, "pos"); + pos.x /= g_unit; + pos.y /= g_unit; + pos.z /= g_unit; + p[0] = 0; + p = SkipNum(p+4); + p = SkipNum(p+1); + strcpy(lineNew, line); + strcat(lineNew, "pos="); + sprintf(s, "%.2f", pos.x); + strcat(lineNew, s); + strcat(lineNew, ";"); + sprintf(s, "%.2f", pos.z); + strcat(lineNew, s); + strcat(lineNew, " "); + strcat(lineNew, p); + } + } + + if ( Cmd(line, "EndMissionTake") ) + { + p = strstr(line, "pos="); + if ( p != 0 ) + { + pos = OpPos(line, "pos"); + pos.x /= g_unit; + pos.y /= g_unit; + pos.z /= g_unit; + p[0] = 0; + p = SkipNum(p+4); + p = SkipNum(p+1); + strcpy(lineNew, line); + strcat(lineNew, "pos="); + sprintf(s, "%.2f", pos.x); + strcat(lineNew, s); + strcat(lineNew, ";"); + sprintf(s, "%.2f", pos.z); + strcat(lineNew, s); + strcat(lineNew, " "); + strcat(lineNew, p); + } + strcpy(line, lineNew); + + p = strstr(line, "dist="); + if ( p != 0 ) + { + value = OpFloat(line, "dist", 32.0f); + value /= g_unit; + p[0] = 0; + p = SkipNum(p+5); + strcpy(lineNew, line); + strcat(lineNew, "dist="); + sprintf(s, "%.2f", value); + strcat(lineNew, s); + strcat(lineNew, " "); + strcat(lineNew, p); + } + strcpy(line, lineNew); + } + + if ( Cmd(line, "Camera") ) + { + p = strstr(line, "pos="); + if ( p != 0 ) + { + pos = OpPos(line, "pos"); + pos.x /= g_unit; + pos.y /= g_unit; + pos.z /= g_unit; + p[0] = 0; + p = SkipNum(p+4); + p = SkipNum(p+1); + strcpy(lineNew, line); + strcat(lineNew, "pos="); + sprintf(s, "%.2f", pos.x); + strcat(lineNew, s); + strcat(lineNew, ";"); + sprintf(s, "%.2f", pos.z); + strcat(lineNew, s); + strcat(lineNew, " "); + strcat(lineNew, p); + } + strcpy(line, lineNew); + + p = strstr(line, "h="); + if ( p != 0 ) + { + value = OpFloat(line, "h", 32.0f); + value /= g_unit; + p[0] = 0; + p = SkipNum(p+2); + strcpy(lineNew, line); + strcat(lineNew, "h="); + sprintf(s, "%.2f", value); + strcat(lineNew, s); + strcat(lineNew, " "); + strcat(lineNew, p); + } + strcpy(line, lineNew); + } + + fputs(lineNew, fileNew); + } + + fclose(fileNew); + fclose(file); +} + +// Load the scene for the character. + +void CRobotMain::ScenePerso() +{ + CObject* pObj; + + DeleteAllObjects(); // removes all the current 3D Scene + m_engine->FlushObject(); + m_terrain->FlushRelief(); // all flat + m_terrain->FlushBuildingLevel(); + m_terrain->FlushFlyingLimit(); + m_light->FlushLight(); + m_particule->FlushParticule(); + m_iMan->Flush(CLASS_OBJECT); + m_iMan->Flush(CLASS_PHYSICS); + m_iMan->Flush(CLASS_BRAIN); + m_iMan->Flush(CLASS_PYRO); + + m_dialog->SetSceneName("perso"); + m_dialog->SetSceneRank(0); + CreateScene(FALSE, TRUE, FALSE); // sets scene + + m_engine->SetDrawWorld(FALSE); // does not draw anything on the interface + m_engine->SetDrawFront(TRUE); // draws on the human interface + pObj = SearchHuman(); + if ( pObj != 0 ) + { + CMotionHuman* mh; + + pObj->SetDrawFront(TRUE); // draws the interface + + mh = (CMotionHuman*)pObj->RetMotion(); + if ( mh != 0 ) + { + mh->StartDisplayPerso(); + } + } +} + +// Creates the whole stage. + +void CRobotMain::CreateScene(BOOL bSoluce, BOOL bFixScene, BOOL bResetObject) +{ + CObject* pObj; + CObject* pSel; + CMotion* motion; + FILE* file = NULL; + char line[500]; + char name[200]; + char dir[100]; + char op[100]; + char* read; + char* stack; + char* base; + D3DCOLORVALUE color; + D3DVECTOR pos; + int rank, obj, i, rankObj, rankGadget; + +//? Convert(); + + base = m_dialog->RetSceneName(); + rank = m_dialog->RetSceneRank(); + read = m_dialog->RetSceneRead(); + stack = m_dialog->RetStackRead(); + m_dialog->SetUserDir(base, rank); + + m_bFixScene = bFixScene; + + g_id = 0; + m_bBase = FALSE; + + if ( !bResetObject ) + { + g_build = 0; + g_researchDone = 0; // no research done + g_researchEnable = 0; + + FlushDisplayInfo(); + m_terrain->LevelFlush(); + m_audioTrack = 0; + m_bAudioRepeat = TRUE; + m_displayText->SetDelay(1.0f); + m_displayText->SetEnable(TRUE); + m_bImmediatSatCom = FALSE; + m_endingWinRank = 0; + m_endingLostRank = 0; + m_endTakeTotal = 0; + m_endTakeResearch = 0; + m_endTakeWinDelay = 2.0f; + m_endTakeLostDelay = 2.0f; + m_obligatoryTotal = 0; + m_prohibitedTotal = 0; + m_bMapShow = TRUE; + m_bMapImage = FALSE; + m_mapFilename[0] = 0; + + m_colorRefBot.r = 10.0f/256.0f; + m_colorRefBot.g = 166.0f/256.0f; + m_colorRefBot.b = 254.0f/256.0f; // blue + m_colorRefBot.a = 0.0f; + m_colorNewBot = m_colorRefBot; + + m_colorRefAlien.r = 135.0f/256.0f; + m_colorRefAlien.g = 170.0f/256.0f; + m_colorRefAlien.b = 13.0f/256.0f; // green + m_colorRefAlien.a = 0.0f; + m_colorNewAlien = m_colorRefAlien; + + m_colorRefGreen.r = 135.0f/256.0f; + m_colorRefGreen.g = 170.0f/256.0f; + m_colorRefGreen.b = 13.0f/256.0f; // green + m_colorRefGreen.a = 0.0f; + m_colorNewGreen = m_colorRefGreen; + + m_colorRefWater.r = 25.0f/256.0f; + m_colorRefWater.g = 255.0f/256.0f; + m_colorRefWater.b = 240.0f/256.0f; // cyan + m_colorRefWater.a = 0.0f; + m_colorNewWater = m_colorRefWater; + + m_dialog->BuildResumeName(m_title, base, rank); + m_dialog->BuildResumeName(m_resume, base, rank); + GetResource(RES_TEXT, RT_SCRIPT_NEW, m_scriptName); + m_scriptFile[0] = 0; + } + + m_dialog->BuildSceneName(line, base, rank); + file = fopen(line, "r"); + if ( file == NULL ) return; + + rankObj = 0; + rankGadget = 0; + pSel = 0; + + while ( fgets(line, 500, file) != NULL ) + { + for ( i=0 ; i<500 ; i++ ) + { + if ( line[i] == '\t' ) line[i] = ' '; // replace tab by space + if ( line[i] == '/' && line[i+1] == '/' ) + { + line[i] = 0; + break; + } + } + + sprintf(op, "Title.%c", RetLanguageLetter()); + if ( Cmd(line, op) && !bResetObject ) + { + OpString(line, "text", m_title); + } + + sprintf(op, "Resume.%c", RetLanguageLetter()); + if ( Cmd(line, op) && !bResetObject ) + { + OpString(line, "text", m_resume); + } + + sprintf(op, "ScriptName.%c", RetLanguageLetter()); + if ( Cmd(line, op) && !bResetObject ) + { + OpString(line, "text", m_scriptName); + } + + if ( Cmd(line, "ScriptFile") && !bResetObject ) + { + OpString(line, "name", m_scriptFile); + } + + if ( Cmd(line, "Instructions") && !bResetObject ) + { + OpString(line, "name", name); +//? sprintf(m_infoFilename[SATCOM_HUSTON], "help\\%s", name); + UserDir(m_infoFilename[SATCOM_HUSTON], name, "help"); + + m_bImmediatSatCom = OpInt(line, "immediat", 0); + } + + if ( Cmd(line, "Satellite") && !bResetObject ) + { + OpString(line, "name", name); +//? sprintf(m_infoFilename[SATCOM_SAT], "help\\%s", name); + UserDir(m_infoFilename[SATCOM_SAT], name, "help"); + } + + if ( Cmd(line, "Loading") && !bResetObject ) + { + OpString(line, "name", name); +//? sprintf(m_infoFilename[SATCOM_LOADING], "help\\%s", name); + UserDir(m_infoFilename[SATCOM_LOADING], name, "help"); + } + + if ( Cmd(line, "HelpFile") && !bResetObject ) + { + OpString(line, "name", name); +//? sprintf(m_infoFilename[SATCOM_PROG], "help\\%s", name); + UserDir(m_infoFilename[SATCOM_PROG], name, "help"); + } + if ( Cmd(line, "SoluceFile") && !bResetObject ) + { + OpString(line, "name", name); +//? sprintf(m_infoFilename[SATCOM_SOLUCE], "help\\%s", name); + UserDir(m_infoFilename[SATCOM_SOLUCE], name, "help"); + } + + if ( Cmd(line, "EndingFile") && !bResetObject ) + { + m_endingWinRank = OpInt(line, "win", 0); + m_endingLostRank = OpInt(line, "lost", 0); + } + + if ( Cmd(line, "MessageDelay") && !bResetObject ) + { + m_displayText->SetDelay(OpFloat(line, "factor", 1.0f)); + } + + if ( Cmd(line, "Audio") && !bResetObject ) + { + m_audioTrack = OpInt(line, "track", 0); + m_bAudioRepeat = OpInt(line, "repeat", 1); + } + + if ( Cmd(line, "AmbiantColor") && !bResetObject ) + { + m_engine->SetAmbiantColor(OpColor(line, "air", 0x88888888), 0); + m_engine->SetAmbiantColor(OpColor(line, "water", 0x88888888), 1); + } + + if ( Cmd(line, "FogColor") && !bResetObject ) + { + m_engine->SetFogColor(OpColor(line, "air", 0x88888888), 0); + m_engine->SetFogColor(OpColor(line, "water", 0x88888888), 1); + } + + if ( Cmd(line, "VehicleColor") && !bResetObject ) + { + m_colorNewBot = RetColor(OpColor(line, "color", 0x88888888)); + } + + if ( Cmd(line, "InsectColor") && !bResetObject ) + { + m_colorNewAlien = RetColor(OpColor(line, "color", 0x88888888)); + } + + if ( Cmd(line, "GreeneryColor") && !bResetObject ) + { + m_colorNewGreen = RetColor(OpColor(line, "color", 0x88888888)); + } + + if ( Cmd(line, "DeepView") && !bResetObject ) + { + m_engine->SetDeepView(OpFloat(line, "air", 500.0f)*UNIT, 0, TRUE); + m_engine->SetDeepView(OpFloat(line, "water", 100.0f)*UNIT, 1, TRUE); + } + + if ( Cmd(line, "FogStart") && !bResetObject ) + { + m_engine->SetFogStart(OpFloat(line, "air", 0.5f), 0); + m_engine->SetFogStart(OpFloat(line, "water", 0.5f), 1); + } + + if ( Cmd(line, "SecondTexture") && !bResetObject ) + { + m_engine->SetSecondTexture(OpInt(line, "rank", 1)); + } + + if ( Cmd(line, "Background") && !bResetObject ) + { + OpString(line, "image", name); + UserDir(dir, name, ""); + m_engine->SetBackground(dir, + OpColor(line, "up", 0x00000000), + OpColor(line, "down", 0x00000000), + OpColor(line, "cloudUp", 0x00000000), + OpColor(line, "cloudDown", 0x00000000), + OpInt(line, "full", 0)); + } + + if ( Cmd(line, "Planet") && !bResetObject ) + { + D3DVECTOR ppos, uv1, uv2; + + ppos = OpPos(line, "pos"); + uv1 = OpPos(line, "uv1"); + uv2 = OpPos(line, "uv2"); + OpString(line, "image", name); + UserDir(dir, name, ""); + m_planet->Create(OpInt(line, "mode", 0), + FPOINT(ppos.x, ppos.z), + OpFloat(line, "dim", 0.2f), + OpFloat(line, "speed", 0.0f), + OpFloat(line, "dir", 0.0f), + dir, + FPOINT(uv1.x, uv1.z), + FPOINT(uv2.x, uv2.z)); + } + + if ( Cmd(line, "FrontsizeName") && !bResetObject ) + { + OpString(line, "image", name); + UserDir(dir, name, ""); + m_engine->SetFrontsizeName(dir); + } + + if ( Cmd(line, "Global") && !bResetObject ) + { + g_unit = OpFloat(line, "unitScale", 4.0f); + m_engine->SetTracePrecision(OpFloat(line, "traceQuality", 1.0f)); + m_bShortCut = OpInt(line, "shortcut", 1); + } + + if ( Cmd(line, "TerrainGenerate") && !bResetObject ) + { + m_terrain->Generate(OpInt(line, "mosaic", 20), + OpInt(line, "brick", 3), + OpFloat(line, "size", 20.0f), + OpFloat(line, "vision", 500.0f)*UNIT, + OpInt(line, "depth", 2), + OpFloat(line, "hard", 0.5f)); + } + + if ( Cmd(line, "TerrainWind") && !bResetObject ) + { + m_terrain->SetWind(OpPos(line, "speed")); + } + + if ( Cmd(line, "TerrainRelief") && !bResetObject ) + { + OpString(line, "image", name); + UserDir(dir, name, "textures"); + m_terrain->ReliefFromBMP(dir, OpFloat(line, "factor", 1.0f), OpInt(line, "border", 1)); + } + + if ( Cmd(line, "TerrainReliefDXF") && !bResetObject ) + { + OpString(line, "image", name); + UserDir(dir, name, "textures"); + m_terrain->ReliefFromDXF(dir, OpFloat(line, "factor", 1.0f)); + } + + if ( Cmd(line, "TerrainResource") && !bResetObject ) + { + OpString(line, "image", name); + UserDir(dir, name, "textures"); + m_terrain->ResFromBMP(dir); + } + + if ( Cmd(line, "TerrainWater") && !bResetObject ) + { + OpString(line, "image", name); + UserDir(dir, name, ""); + pos.x = OpFloat(line, "moveX", 0.0f); + pos.y = OpFloat(line, "moveY", 0.0f); + pos.z = pos.x; + m_water->Create(OpTypeWater(line, "air", WATER_TT), + OpTypeWater(line, "water", WATER_TT), + dir, + RetColor(OpColor(line, "diffuse", 0xffffffff)), + RetColor(OpColor(line, "ambiant", 0xffffffff)), + OpFloat(line, "level", 100.0f)*UNIT, + OpFloat(line, "glint", 1.0f), + pos); + m_colorNewWater = RetColor(OpColor(line, "color", RetColor(m_colorRefWater))); + m_colorShiftWater = OpFloat(line, "brightness", 0.0f); + } + + if ( Cmd(line, "TerrainLava") && !bResetObject ) + { + m_water->SetLava(OpInt(line, "mode", 0)); + } + + if ( Cmd(line, "TerrainCloud") && !bResetObject ) + { + OpString(line, "image", name); + UserDir(dir, name, ""); + m_cloud->Create(dir, + RetColor(OpColor(line, "diffuse", 0xffffffff)), + RetColor(OpColor(line, "ambiant", 0xffffffff)), + OpFloat(line, "level", 500.0f)*UNIT); + } + + if ( Cmd(line, "TerrainBlitz") && !bResetObject ) + { + m_blitz->Create(OpFloat(line, "sleep", 0.0f), + OpFloat(line, "delay", 3.0f), + OpFloat(line, "magnetic", 50.0f)*UNIT); + } + + if ( Cmd(line, "TerrainInitTextures") && !bResetObject ) + { + int dx, dy, tt[100]; + char* op; + + OpString(line, "image", name); + AddExt(name, ".tga"); + dx = OpInt(line, "dx", 1); + dy = OpInt(line, "dy", 1); + op = SearchOp(line, "table"); + for ( i=0 ; iInitTextures(name, tt, dx, dy); + } + + if ( Cmd(line, "TerrainInit") && !bResetObject ) + { + m_terrain->LevelInit(OpInt(line, "id", 1)); + } + + if ( Cmd(line, "TerrainMaterial") && !bResetObject ) + { + OpString(line, "image", name); + AddExt(name, ".tga"); + if ( strstr(name, "%user%") != 0 ) + { + CopyFileToTemp(name); + } + + m_terrain->LevelMaterial(OpInt(line, "id", 0), + name, + OpFloat(line, "u", 0.0f), + OpFloat(line, "v", 0.0f), + OpInt(line, "up", 1), + OpInt(line, "right", 1), + OpInt(line, "down", 1), + OpInt(line, "left", 1), + OpFloat(line, "hard", 0.5f)); + } + + if ( Cmd(line, "TerrainLevel") && !bResetObject ) + { + int id[50]; + char* op; + + op = SearchOp(line, "id"); + i = 0; + while ( TRUE ) + { + id[i] = GetInt(op, i, 0); + if ( id[i++] == 0 ) break; + } + + m_terrain->LevelGenerate(id, + OpFloat(line, "min", 0.0f)*UNIT, + OpFloat(line, "max", 100.0f)*UNIT, + OpFloat(line, "slope", 5.0f), + OpFloat(line, "freq", 100.0f), + OpPos(line, "center")*g_unit, + OpFloat(line, "radius", 0.0f)*g_unit); + } + + if ( Cmd(line, "TerrainCreate") && !bResetObject ) + { + m_terrain->CreateObjects(TRUE); + } + + if ( Cmd(line, "BeginObject") ) + { + InitEye(); + SetMovieLock(FALSE); + if ( !m_bFixScene ) + { +//? CreateObject(D3DVECTOR(0.0f, 0.0f, 0.0f), 0.0f, 0.0f, OBJECT_TOTO); + } + + if ( read[0] != 0 ) // loading file ? + { + pSel = IOReadScene(read, stack); + } + } + + if ( Cmd(line, "CreateObject") && read[0] == 0 ) + { + CObject* pObj; + CBrain* pBrain; + CAuto* pAuto; + CPyro* pyro; + ObjectType type; + PyroType pType; + CameraType cType; + Info info; + float dir; + char op[20]; + char text[100]; + char* p; + int run, gadget; + + type = OpTypeObject(line, "type", OBJECT_NULL); + + gadget = OpInt(line, "gadget", -1); + if ( gadget == -1 ) + { + gadget = 0; + if ( type == OBJECT_TECH || + (type >= OBJECT_PLANT0 && + type <= OBJECT_PLANT19 ) || + (type >= OBJECT_TREE0 && + type <= OBJECT_TREE9 ) || + (type >= OBJECT_TEEN0 && + type <= OBJECT_TEEN49 ) || + (type >= OBJECT_QUARTZ0 && + type <= OBJECT_QUARTZ9 ) || + (type >= OBJECT_ROOT0 && + type <= OBJECT_ROOT4 ) ) // not ROOT5! + { + if ( type != OBJECT_TEEN11 && // lamp? + type != OBJECT_TEEN12 && // coke? + type != OBJECT_TEEN20 && // wall? + type != OBJECT_TEEN21 && // wall? + type != OBJECT_TEEN22 && // wall? + type != OBJECT_TEEN26 && // lamp? + type != OBJECT_TEEN28 && // bottle? + type != OBJECT_TEEN34 ) // stone? + { + gadget = 1; + } + } + } + if ( gadget != 0 ) // is this a gadget? + { + if ( !TestGadgetQuantity(rankGadget++) ) continue; + } + + pos = OpPos(line, "pos")*g_unit; + dir = OpFloat(line, "dir", 0.0f)*PI; + pObj = CreateObject(pos, dir, + OpFloat(line, "z", 1.0f), + OpFloat(line, "h", 0.0f), + type, + OpFloat(line, "power", 1.0f), + OpInt(line, "trainer", 0), + OpInt(line, "toy", 0), + OpInt(line, "option", 0)); + + if ( pObj != 0 ) + { + pObj->SetDefRank(rankObj); + + if ( type == OBJECT_BASE ) m_bBase = TRUE; + + cType = OpCamera(line, "camera"); + if ( cType != CAMERA_NULL ) + { + pObj->SetCameraType(cType); + } + pObj->SetCameraDist(OpFloat(line, "cameraDist", 50.0f)); + pObj->SetCameraLock(OpInt(line, "cameraLock", 0)); + + pType = OpPyro(line, "pyro"); + if ( pType != PT_NULL ) + { + pyro = new CPyro(m_iMan); + pyro->Create(pType, pObj); + } + + // Puts information in terminal (OBJECT_INFO). + for ( i=0 ; iSearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + if ( pObj->RetTruck() != 0 ) continue; + + brain = pObj->RetBrain(); + if ( brain == 0 ) continue; + + for ( j=0 ; j<10 ; j++ ) + { + if ( brain->RetCompile(j) ) continue; + + name = brain->RetScriptName(j); + if ( name[0] != 0 ) + { + brain->ReadProgram(j, name); + if ( !brain->RetCompile(j) ) nbError++; + } + } + + LoadOneScript(pObj, nbError); + } + } + while ( nbError > 0 && nbError != lastError ); + + // Load all solutions. + if ( bSoluce ) + { + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + if ( pObj->RetTruck() != 0 ) continue; + + brain = pObj->RetBrain(); + if ( brain == 0 ) continue; + + name = brain->RetSoluceName(); + if ( name[0] != 0 ) + { + brain->ReadSoluce(name); // load solution + } + } + } + + // Start all programs according to the command "run". + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + if ( pObj->RetTruck() != 0 ) continue; + + brain = pObj->RetBrain(); + if ( brain == 0 ) continue; + + run = brain->RetScriptRun(); + if ( run != -1 ) + { + brain->RunProgram(run); // starts the program + } + } +} + +// Load all programs of the robot. + +void CRobotMain::LoadOneScript(CObject *pObj, int &nbError) +{ + ObjectType type; + CBrain* brain; + char filename[_MAX_FNAME]; + char* name; + int rank, i, objRank; + + brain = pObj->RetBrain(); + if ( brain == 0 ) return; + + if ( !IsSelectable(pObj) ) return; + + type = pObj->RetType(); + if ( type == OBJECT_HUMAN ) return; + + objRank = pObj->RetDefRank(); + if ( objRank == -1 ) return; + + name = m_dialog->RetSceneName(); + rank = m_dialog->RetSceneRank(); + + for ( i=0 ; iRetCompile(i) ) continue; +//? if ( brain->ProgramExist(i) ) continue; + + sprintf(filename, "%s\\%s\\%c%.3d%.3d%.1d.txt", + RetSavegameDir(), m_gamerName, name[0], rank, objRank, i); + brain->ReadProgram(i, filename); + if ( !brain->RetCompile(i) ) nbError++; + } +} + +// Load all programs of the robot. + +void CRobotMain::LoadFileScript(CObject *pObj, char* filename, int objRank, + int &nbError) +{ + ObjectType type; + CBrain* brain; + char fn[_MAX_FNAME]; + char* ldir; + char* name; + int rank, i; + + if ( objRank == -1 ) return; + + brain = pObj->RetBrain(); + if ( brain == 0 ) return; + + type = pObj->RetType(); + if ( type == OBJECT_HUMAN ) return; + + name = m_dialog->RetSceneName(); + rank = m_dialog->RetSceneRank(); + + strcpy(fn, filename); + ldir = SearchLastDir(fn); + if ( ldir == 0 ) return; + + for ( i=0 ; iRetCompile(i) ) continue; +//? if ( brain->ProgramExist(i) ) continue; + + sprintf(ldir, "\\prog%.3d%.1d.txt", objRank, i); + brain->ReadProgram(i, fn); + if ( !brain->RetCompile(i) ) nbError++; + } +} + +// Saves all programs of all the robots. + +void CRobotMain::SaveAllScript() +{ + CObject* pObj; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + SaveOneScript(pObj); + } +} + +// Saves all programs of the robot. +// If a program does not exist, the corresponding file is destroyed. + +void CRobotMain::SaveOneScript(CObject *pObj) +{ + ObjectType type; + CBrain* brain; + char filename[_MAX_FNAME]; + char* name; + int rank, i, objRank; + + brain = pObj->RetBrain(); + if ( brain == 0 ) return; + + if ( !IsSelectable(pObj) ) return; + + type = pObj->RetType(); + if ( type == OBJECT_HUMAN ) return; + + objRank = pObj->RetDefRank(); + if ( objRank == -1 ) return; + + name = m_dialog->RetSceneName(); + rank = m_dialog->RetSceneRank(); + + for ( i=0 ; iWriteProgram(i, filename); + } +} + +// Saves all programs of the robot. +// If a program does not exist, the corresponding file is destroyed. + +void CRobotMain::SaveFileScript(CObject *pObj, char* filename, int objRank) +{ + ObjectType type; + CBrain* brain; + char fn[_MAX_FNAME]; + char* ldir; + char* name; + int rank, i; + + if ( objRank == -1 ) return; + + brain = pObj->RetBrain(); + if ( brain == 0 ) return; + + type = pObj->RetType(); + if ( type == OBJECT_HUMAN ) return; + + name = m_dialog->RetSceneName(); + rank = m_dialog->RetSceneRank(); + + strcpy(fn, filename); + ldir = SearchLastDir(fn); + if ( ldir == 0 ) return; + + for ( i=0 ; iWriteProgram(i, fn); + } +} + +// Saves the stack of the program in execution of a robot. + +BOOL CRobotMain::SaveFileStack(CObject *pObj, FILE *file, int objRank) +{ + ObjectType type; + CBrain* brain; + + if ( objRank == -1 ) return TRUE; + + brain = pObj->RetBrain(); + if ( brain == 0 ) return TRUE; + + type = pObj->RetType(); + if ( type == OBJECT_HUMAN ) return TRUE; + + return brain->WriteStack(file); +} + +// Resumes the execution stack of the program in a robot. + +BOOL CRobotMain::ReadFileStack(CObject *pObj, FILE *file, int objRank) +{ + ObjectType type; + CBrain* brain; + + if ( objRank == -1 ) return TRUE; + + brain = pObj->RetBrain(); + if ( brain == 0 ) return TRUE; + + type = pObj->RetType(); + if ( type == OBJECT_HUMAN ) return TRUE; + + return brain->ReadStack(file); +} + + +// Empty the list. + +BOOL CRobotMain::FlushNewScriptName() +{ + int i; + + for ( i=0 ; i 0 ) return TRUE; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + pBrain = pObj->RetBrain(); + if ( pBrain != 0 ) + { + if ( pBrain->IsBusy() ) return TRUE; + } + +//? pAuto = pObj->RetAuto(); +//? if ( pAuto != 0 ) +//? { +//? if ( pAuto->RetBusy() ) return TRUE; +//? } + } + return FALSE; +} + +// Writes an object into the backup file. + +void CRobotMain::IOWriteObject(FILE *file, CObject* pObj, char *cmd) +{ + D3DVECTOR pos; + CBrain* pBrain; + char line[3000]; + char name[100]; + int run, i; + + if ( pObj->RetType() == OBJECT_FIX ) return; + + strcpy(line, cmd); + + sprintf(name, " type=%s", GetTypeObject(pObj->RetType())); + strcat(line, name); + + sprintf(name, " id=%d", pObj->RetID()); + strcat(line, name); + + pos = pObj->RetPosition(0)/g_unit; + sprintf(name, " pos=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); + strcat(line, name); + + pos = pObj->RetAngle(0)/(PI/180.0f); + sprintf(name, " angle=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); + strcat(line, name); + + pos = pObj->RetZoom(0); + sprintf(name, " zoom=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); + strcat(line, name); + + for ( i=1 ; iRetObjectRank(i) == -1 ) continue; + + pos = pObj->RetPosition(i); + if ( pos.x != 0.0f || pos.y != 0.0f || pos.z != 0.0f ) + { + pos /= g_unit; + sprintf(name, " p%d=%.2f;%.2f;%.2f", i, pos.x, pos.y, pos.z); + strcat(line, name); + } + + pos = pObj->RetAngle(i); + if ( pos.x != 0.0f || pos.y != 0.0f || pos.z != 0.0f ) + { + pos /= (PI/180.0f); + sprintf(name, " a%d=%.2f;%.2f;%.2f", i, pos.x, pos.y, pos.z); + strcat(line, name); + } + + pos = pObj->RetZoom(i); + if ( pos.x != 1.0f || pos.y != 1.0f || pos.z != 1.0f ) + { + sprintf(name, " z%d=%.2f;%.2f;%.2f", i, pos.x, pos.y, pos.z); + strcat(line, name); + } + } + + sprintf(name, " trainer=%d", pObj->RetTrainer()); + strcat(line, name); + + sprintf(name, " option=%d", pObj->RetOption()); + strcat(line, name); + + if ( pObj == m_infoObject ) // selects object? + { + sprintf(name, " select=1"); + strcat(line, name); + } + + pObj->Write(line); + + if ( pObj->RetType() == OBJECT_BASE ) + { + sprintf(name, " run=3"); // stops and open (PARAM_FIXSCENE) + strcat(line, name); + } + + pBrain = pObj->RetBrain(); + if ( pBrain != 0 ) + { + run = pBrain->RetProgram(); + if ( run != -1 ) + { + sprintf(name, " run=%d", run+1); + strcat(line, name); + } + } + + strcat(line, "\n"); + fputs(line, file); +} + +// Saves the current game. + +BOOL CRobotMain::IOWriteScene(char *filename, char *filecbot, char *info) +{ + FILE* file; + char line[500]; + char* name; + CObject *pObj, *pPower, *pFret; + float sleep, delay, magnetic, progress; + int i, objRank; + long version; + + file = fopen(filename, "w"); + if ( file == NULL ) return FALSE; + + sprintf(line, "Title text=\"%s\"\n", info); + fputs(line, file); + + sprintf(line, "Version maj=%d min=%d\n", 0, 1); + fputs(line, file); + + name = m_dialog->RetSceneName(); + if ( strcmp(name, "user") == 0 ) + { + sprintf(line, "Mission base=\"%s\" rank=%.3d dir=\"%s\"\n", name, m_dialog->RetSceneRank(), m_dialog->RetSceneDir()); + } + else + { + sprintf(line, "Mission base=\"%s\" rank=%.3d\n", name, m_dialog->RetSceneRank()); + } + fputs(line, file); + + sprintf(line, "Map zoom=%.2f\n", m_map->RetZoomMap()); + fputs(line, file); + + sprintf(line, "DoneResearch bits=%d\n", g_researchDone); + fputs(line, file); + + if ( m_blitz->GetStatus(sleep, delay, magnetic, progress) ) + { + sprintf(line, "BlitzMode sleep=%.2f delay=%.2f magnetic=%.2f progress=%.2f\n", sleep, delay, magnetic/g_unit, progress); + fputs(line, file); + } + + objRank = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj->RetType() == OBJECT_TOTO ) continue; + if ( pObj->RetType() == OBJECT_FIX ) continue; + if ( pObj->RetTruck() != 0 ) continue; + if ( pObj->RetBurn() ) continue; + if ( pObj->RetDead() ) continue; + if ( pObj->RetExplo() ) continue; + + pPower = pObj->RetPower(); + pFret = pObj->RetFret(); + + if ( pFret != 0 ) // object transported? + { + IOWriteObject(file, pFret, "CreateFret"); + } + + if ( pPower != 0 ) // battery transported? + { + IOWriteObject(file, pPower, "CreatePower"); + } + + IOWriteObject(file, pObj, "CreateObject"); + + SaveFileScript(pObj, filename, objRank++); + } + fclose(file); + +#if CBOT_STACK + // Writes the file of stacks of execution. + file = fOpen(filecbot, "wb"); + if ( file == NULL ) return FALSE; + + version = 1; + fWrite(&version, sizeof(long), 1, file); // version of COLOBOT + version = CBotProgram::GivVersion(); + fWrite(&version, sizeof(long), 1, file); // version of CBOT + + objRank = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj->RetType() == OBJECT_TOTO ) continue; + if ( pObj->RetType() == OBJECT_FIX ) continue; + if ( pObj->RetTruck() != 0 ) continue; + if ( pObj->RetBurn() ) continue; + if ( pObj->RetDead() ) continue; + + if ( !SaveFileStack(pObj, file, objRank++) ) break; + } + CBotClass::SaveStaticState(file); + fClose(file); +#endif + + m_delayWriteMessage = 4; // displays message in 3 frames + return TRUE; +} + +// Resumes the game. + +CObject* CRobotMain::IOReadObject(char *line, char* filename, int objRank) +{ + CObject* pObj; +//? CBrain* pBrain; + CAuto* pAuto; + D3DVECTOR pos, dir, zoom; + ObjectType type; + int id, run, trainer, toy, option, i; + char op[10]; + + pos = OpDir(line, "pos")*g_unit; + dir = OpDir(line, "angle")*(PI/180.0f); + zoom = OpDir(line, "zoom"); + type = OpTypeObject(line, "type", OBJECT_NULL); + id = OpInt(line, "id", 0); + if ( type == OBJECT_NULL ) return 0; + trainer = OpInt(line, "trainer", 0); + toy = OpInt(line, "toy", 0); + option = OpInt(line, "option", 0); + pObj = CreateObject(pos, dir.y, 1.0f, 0.0f, type, 0.0f, trainer, toy, option); + pObj->SetDefRank(objRank); + pObj->SetPosition(0, pos); + pObj->SetAngle(0, dir); + pObj->SetID(id); + if ( g_id < id ) g_id = id; + + if ( zoom.x != 0.0f || zoom.y != 0.0f || zoom.z != 0.0f ) + { + pObj->SetZoom(0, zoom); + } + + for ( i=1 ; iRetObjectRank(i) == -1 ) continue; + + sprintf(op, "p%d", i); + pos = OpDir(line, op); + if ( pos.x != 0.0f || pos.y != 0.0f || pos.z != 0.0f ) + { + pObj->SetPosition(i, pos*g_unit); + } + + sprintf(op, "a%d", i); + dir = OpDir(line, op); + if ( dir.x != 0.0f || dir.y != 0.0f || dir.z != 0.0f ) + { + pObj->SetAngle(i, dir*(PI/180.0f)); + } + + sprintf(op, "z%d", i); + zoom = OpDir(line, op); + if ( zoom.x != 0.0f || zoom.y != 0.0f || zoom.z != 0.0f ) + { + pObj->SetZoom(i, zoom); + } + } + + if ( type == OBJECT_BASE ) m_bBase = TRUE; + + pObj->Read(line); + +#if CBOT_STACK +#else + LoadFileScript(pObj, filename, objRank, i); +#endif + + run = OpInt(line, "run", -1); + if ( run != -1 ) + { +#if CBOT_STACK +#else + pBrain = pObj->RetBrain(); + if ( pBrain != 0 ) + { + pBrain->RunProgram(run-1); // starts the program + } +#endif + + pAuto = pObj->RetAuto(); + if ( pAuto != 0 ) + { + pAuto->Start(run); // starts the film + } + } + + return pObj; +} + +// Resumes some part of the game. + +CObject* CRobotMain::IOReadScene(char *filename, char *filecbot) +{ + FILE* file; + CObject *pObj, *pPower, *pFret, *pSel; + char line[3000]; + float sleep, delay, progress, magnetic; + int i, objRank, nbError, lastError; + long version; + + m_bBase = FALSE; + + file = fopen(filename, "r"); + if ( file == NULL ) return 0; + + pFret = 0; + pPower = 0; + pSel = 0; + objRank = 0; + while ( fgets(line, 3000, file) != NULL ) + { + for ( i=0 ; i<3000 ; i++ ) + { + if ( line[i] == '\t' ) line[i] = ' '; // replace tab by space + if ( line[i] == '/' && line[i+1] == '/' ) + { + line[i] = 0; + break; + } + } + + if ( Cmd(line, "Map") ) + { + m_map->ZoomMap(OpFloat(line, "zoom", 1.0f)); + } + + if ( Cmd(line, "DoneResearch") ) + { + g_researchDone = OpInt(line, "bits", 0); + } + + if ( Cmd(line, "BlitzMode") ) + { + sleep = OpFloat(line, "sleep", 0.0f); + delay = OpFloat(line, "delay", 3.0f); + magnetic = OpFloat(line, "magnetic", 50.0f)*g_unit; + progress = OpFloat(line, "progress", 0.0f); + m_blitz->SetStatus(sleep, delay, magnetic, progress); + } + + if ( Cmd(line, "CreateFret") ) + { + pFret = IOReadObject(line, filename, -1); + } + + if ( Cmd(line, "CreatePower") ) + { + pPower = IOReadObject(line, filename, -1); + } + + if ( Cmd(line, "CreateObject") ) + { + pObj = IOReadObject(line, filename, objRank++); + + if ( OpInt(line, "select", 0) ) + { + pSel = pObj; + } + + if ( pFret != 0 ) + { + CTaskManip* task; + + pObj->SetFret(pFret); + task = new CTaskManip(m_iMan, pObj); + task->Start(TMO_AUTO, TMA_GRAB); // holds the object! + delete task; + } + + if ( pPower != 0 ) + { + pObj->SetPower(pPower); + pPower->SetTruck(pObj); + } + + pFret = 0; + pPower = 0; + } + } + fclose(file); + +#if CBOT_STACK + // Compiles scripts. + nbError = 0; + do + { + lastError = nbError; + nbError = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + if ( pObj->RetTruck() != 0 ) continue; + + objRank = pObj->RetDefRank(); + if ( objRank == -1 ) continue; + + LoadFileScript(pObj, filename, objRank, nbError); + } + } + while ( nbError > 0 && nbError != lastError ); + + // Reads the file of stacks of execution. + file = fOpen(filecbot, "rb"); + if ( file != NULL ) + { + fRead(&version, sizeof(long), 1, file); // version of COLOBOT + if ( version == 1 ) + { + fRead(&version, sizeof(long), 1, file); // version of CBOT + if ( version == CBotProgram::GivVersion() ) + { + objRank = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj->RetType() == OBJECT_TOTO ) continue; + if ( pObj->RetType() == OBJECT_FIX ) continue; + if ( pObj->RetTruck() != 0 ) continue; + if ( pObj->RetBurn() ) continue; + if ( pObj->RetDead() ) continue; + + if ( !ReadFileStack(pObj, file, objRank++) ) break; + } + } + } + CBotClass::RestoreStaticState(file); + fClose(file); + } +#endif + + return pSel; +} + + +// Writes the global parameters for free play. + +void CRobotMain::WriteFreeParam() +{ + FILE* file; + char filename[_MAX_FNAME]; + char line[100]; + + m_freeResearch |= g_researchDone; + m_freeBuild |= g_build; + + if ( m_gamerName[0] == 0 ) return; + + sprintf(filename, "%s\\%s\\research.gam", RetSavegameDir(), m_gamerName); + file = fopen(filename, "w"); + if ( file == NULL ) return; + + sprintf(line, "research=%d build=%d\n", m_freeResearch, m_freeBuild); + fputs(line, file); + fclose(file); +} + +// Reads the global parameters for free play. + +void CRobotMain::ReadFreeParam() +{ + FILE* file; + char filename[_MAX_FNAME]; + char line[100]; + + m_freeResearch = 0; + m_freeBuild = 0; + + if ( m_gamerName[0] == 0 ) return; + + sprintf(filename, "%s\\%s\\research.gam", RetSavegameDir(), m_gamerName); + file = fopen(filename, "r"); + if ( file == NULL ) return; + + if ( fgets(line, 100, file) != NULL ) + { + sscanf(line, "research=%d build=%d\n", &m_freeResearch, &m_freeBuild); + } + + fclose(file); +} + + +// Resets all objects to their original position. + +void CRobotMain::ResetObject() +{ +#if 0 + CObject* pObj; + CObject* pTruck; + CAuto* pAuto; + CBrain* brain; + CPyro* pyro; + ResetCap cap; + D3DVECTOR pos, angle; + int i; + + // Removes all pyrotechnic effects in progress. + while ( TRUE ) + { + pyro = (CPyro*)m_iMan->SearchInstance(CLASS_PYRO, 0); + if ( pyro == 0 ) break; + + pyro->DeleteObject(); + delete pyro; + } + + // Removes all bullets in progress. + m_particule->DeleteParticule(PARTIGUN1); + m_particule->DeleteParticule(PARTIGUN2); + m_particule->DeleteParticule(PARTIGUN3); + m_particule->DeleteParticule(PARTIGUN4); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + cap = pObj->RetResetCap(); + if ( cap == RESET_NONE ) continue; + + if ( cap == RESET_DELETE ) + { + pTruck = pObj->RetTruck(); + if ( pTruck != 0 ) + { + pTruck->SetFret(0); + pObj->SetTruck(0); + } + pObj->DeleteObject(); + delete pObj; + i --; + continue; + } + + pAuto = pObj->RetAuto(); + if ( pAuto != 0 ) + { + pAuto->Abort(); + } + + if ( pObj->RetEnable() ) // object still active? + { + brain = pObj->RetBrain(); + if ( brain != 0 ) + { + pos = pObj->RetResetPosition(); + angle = pObj->RetResetAngle(); + + if ( pos == pObj->RetPosition(0) && + angle == pObj->RetAngle(0) ) continue; + brain->StartTaskReset(pos, angle); + continue; + } + } + + pObj->SetEnable(TRUE); // active again + + pos = pObj->RetResetPosition(); + angle = pObj->RetResetAngle(); + + if ( pos == pObj->RetPosition(0) && + angle == pObj->RetAngle(0) ) continue; + + pyro = new CPyro(m_iMan); + pyro->Create(PT_RESET, pObj); + + brain = pObj->RetBrain(); + if ( brain != 0 ) + { + brain->RunProgram(pObj->RetResetRun()); + } + } +#else + m_bResetCreate = TRUE; +#endif +} + +// Resets all objects to their original position. + +void CRobotMain::ResetCreate() +{ + CObject* pObj; + CPyro* pyro; + ResetCap cap; + int i; + + SaveAllScript(); + + // Removes all bullets in progress. + m_particule->DeleteParticule(PARTIGUN1); + m_particule->DeleteParticule(PARTIGUN2); + m_particule->DeleteParticule(PARTIGUN3); + m_particule->DeleteParticule(PARTIGUN4); + + DeselectAll(); // removes the control buttons + DeleteAllObjects(); // removes all the current 3D Scene + + m_particule->FlushParticule(); + m_terrain->FlushBuildingLevel(); + m_iMan->Flush(CLASS_OBJECT); + m_iMan->Flush(CLASS_PHYSICS); + m_iMan->Flush(CLASS_BRAIN); + m_iMan->Flush(CLASS_PYRO); + m_camera->SetType(CAMERA_DIALOG); + + CreateScene(m_dialog->RetSceneSoluce(), FALSE, TRUE); + + if ( !RetNiceReset() ) return; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + cap = pObj->RetResetCap(); + if ( cap == RESET_NONE ) continue; + + pyro = new CPyro(m_iMan); + pyro->Create(PT_RESET, pObj); + } +} + +// Checks if the mission is over. + +Error CRobotMain::CheckEndMission(BOOL bFrame) +{ + CObject* pObj; + D3DVECTOR bPos, oPos; + ObjectType type; + int t, i, nb; + + for ( t=0 ; tSearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + // Do not use RetActif () because an invisible worm (underground) + // should be regarded as existing here! + if ( pObj->RetLock() ) continue; + if ( pObj->RetRuin() ) continue; + if ( !pObj->RetEnable() ) continue; + + type = pObj->RetType(); + if ( type == OBJECT_SCRAP2 || + type == OBJECT_SCRAP3 || + type == OBJECT_SCRAP4 || + type == OBJECT_SCRAP5 ) // wastes? + { + type = OBJECT_SCRAP1; + } + if ( type != m_endTake[t].type ) continue; + + if ( pObj->RetTruck() == 0 ) + { + oPos = pObj->RetPosition(0); + } + else + { + oPos = pObj->RetTruck()->RetPosition(0); + } + oPos.y = 0.0f; + if ( Length2d(oPos, bPos) <= m_endTake[t].dist ) + { + nb ++; + } + } + + if ( nb <= m_endTake[t].lost ) + { + if ( m_endTake[t].type == OBJECT_HUMAN ) + { + if ( m_lostDelay == 0.0f ) + { + m_lostDelay = 0.1f; // lost immediately + m_winDelay = 0.0f; + } + m_displayText->SetEnable(FALSE); + return INFO_LOSTq; + } + else + { + if ( m_lostDelay == 0.0f ) + { + m_displayText->DisplayError(INFO_LOST, D3DVECTOR(0.0f,0.0f,0.0f)); + m_lostDelay = m_endTakeLostDelay; // lost in 6 seconds + m_winDelay = 0.0f; + } + m_displayText->SetEnable(FALSE); + return INFO_LOST; + } + } + if ( nb < m_endTake[t].min || + nb > m_endTake[t].max ) + { + m_displayText->SetEnable(TRUE); + return ERR_MISSION_NOTERM; + } + if ( m_endTake[t].bImmediat ) + { + if ( m_winDelay == 0.0f ) + { + m_winDelay = m_endTakeWinDelay; // wins in x seconds + m_lostDelay = 0.0f; + } + m_displayText->SetEnable(FALSE); + return ERR_OK; // mission ended + } + } + + if ( m_endTakeResearch != 0 ) + { + if ( m_endTakeResearch != (m_endTakeResearch&g_researchDone) ) + { + m_displayText->SetEnable(TRUE); + return ERR_MISSION_NOTERM; + } + } + + if ( m_endTakeWinDelay == -1.0f ) + { + m_winDelay = 1.0f; // wins in one second + m_lostDelay = 0.0f; + m_displayText->SetEnable(FALSE); + return ERR_OK; // mission ended + } + + if ( bFrame && m_bBase ) return ERR_MISSION_NOTERM; + + if ( m_winDelay == 0.0f ) + { + m_displayText->DisplayError(INFO_WIN, D3DVECTOR(0.0f,0.0f,0.0f)); + m_winDelay = m_endTakeWinDelay; // wins in two seconds + m_lostDelay = 0.0f; + } + m_displayText->SetEnable(FALSE); + return ERR_OK; // mission ended +} + +// Checks if the mission is finished after displaying a message. + +void CRobotMain::CheckEndMessage(char *message) +{ + int t; + + for ( t=0 ; tDisplayError(INFO_WIN, D3DVECTOR(0.0f,0.0f,0.0f)); + m_winDelay = m_endTakeWinDelay; // wins in 2 seconds + m_lostDelay = 0.0f; + } + } +} + + +// Returns the number of instructions required. + +int CRobotMain::RetObligatoryToken() +{ + return m_obligatoryTotal; +} + +// Returns the name of a required instruction. + +char* CRobotMain::RetObligatoryToken(int i) +{ + return m_obligatoryToken[i]; +} + +// Checks if an instruction is part of the obligatory list. + +int CRobotMain::IsObligatoryToken(char *token) +{ + int i; + + for ( i=0 ; iRetGlint(); +} + +BOOL CRobotMain::RetSoluce4() +{ + return m_dialog->RetSoluce4(); +} + +BOOL CRobotMain::RetMovies() +{ + return m_dialog->RetMovies(); +} + +BOOL CRobotMain::RetNiceReset() +{ + return m_dialog->RetNiceReset(); +} + +BOOL CRobotMain::RetHimselfDamage() +{ + return m_dialog->RetHimselfDamage(); +} + +BOOL CRobotMain::RetShowSoluce() +{ + return m_bShowSoluce; +} + +BOOL CRobotMain::RetSceneSoluce() +{ + if ( m_infoFilename[SATCOM_SOLUCE][0] == 0 ) return FALSE; + return m_dialog->RetSceneSoluce(); +} + +BOOL CRobotMain::RetShowAll() +{ + return m_bShowAll; +} + +BOOL CRobotMain::RetCheatRadar() +{ + return m_bCheatRadar; +} + +char* CRobotMain::RetSavegameDir() +{ + return m_dialog->RetSavegameDir(); +} + +char* CRobotMain::RetPublicDir() +{ + return m_dialog->RetPublicDir(); +} + +char* CRobotMain::RetFilesDir() +{ + return m_dialog->RetFilesDir(); +} + + +// Change the player's name. + +void CRobotMain::SetGamerName(char *name) +{ + strcpy(m_gamerName, name); + SetGlobalGamerName(m_gamerName); + ReadFreeParam(); +} + +// Gives the player's name. + +char* CRobotMain::RetGamerName() +{ + return m_gamerName; +} + + +// Returns the representation to use for the player. + +int CRobotMain::RetGamerFace() +{ + return m_dialog->RetGamerFace(); +} + +// Returns the representation to use for the player. + +int CRobotMain::RetGamerGlasses() +{ + return m_dialog->RetGamerGlasses(); +} + +// Returns the mode with just the head. + +BOOL CRobotMain::RetGamerOnlyHead() +{ + return m_dialog->RetGamerOnlyHead(); +} + +// Returns the angle of presentation. + +float CRobotMain::RetPersoAngle() +{ + return m_dialog->RetPersoAngle(); +} + + +// Changes on the pause mode. + +void CRobotMain::ChangePause(BOOL bPause) +{ + m_bPause = bPause; + m_engine->SetPause(m_bPause); + + m_sound->MuteAll(m_bPause); + CreateShortcuts(); + if ( m_bPause ) HiliteClear(); +} + + +// Changes game speed + +void CRobotMain::SetSpeed(float speed) +{ + CButton* pb; + char text[10]; + + m_engine->SetSpeed(speed); + + pb = (CButton*)m_interface->SearchControl(EVENT_SPEED); + if ( pb != 0 ) + { + if ( speed == 1.0f ) + { + pb->ClearState(STATE_VISIBLE); + } + else + { + sprintf(text, "x%.1f", speed); + pb->SetName(text); + pb->SetState(STATE_VISIBLE); + } + } +} + +float CRobotMain::RetSpeed() +{ + return m_engine->RetSpeed(); +} + + +// Creates interface shortcuts to the units. + +BOOL CRobotMain::CreateShortcuts() +{ + if ( m_phase != PHASE_SIMUL ) return FALSE; + if ( !m_bShortCut ) return FALSE; + return m_short->CreateShortcuts(); +} + +// Updates the map. + +void CRobotMain::UpdateMap() +{ + m_map->UpdateMap(); +} + +// Indicates whether the mini-map is visible. + +BOOL CRobotMain::RetShowMap() +{ + return m_map->RetShowMap() && m_bMapShow; +} + + +// Management of the lock mode for movies. + +void CRobotMain::SetMovieLock(BOOL bLock) +{ + m_bMovieLock = bLock; + m_engine->SetMovieLock(m_bMovieLock); + + CreateShortcuts(); + m_map->ShowMap(!m_bMovieLock && m_bMapShow); + if ( m_bMovieLock ) HiliteClear(); + m_engine->SetMouseHide(m_bMovieLock); +} + +BOOL CRobotMain::RetMovieLock() +{ + return m_bMovieLock; +} + +BOOL CRobotMain::RetInfoLock() +{ + return ( m_displayInfo != 0 ); // info in progress? +} + +// Management of the blocking of the call of SatCom. + +void CRobotMain::SetSatComLock(BOOL bLock) +{ + m_bSatComLock = bLock; +} + +BOOL CRobotMain::RetSatComLock() +{ + return m_bSatComLock; +} + +// Management of the lock mode for the edition. + +void CRobotMain::SetEditLock(BOOL bLock, BOOL bEdit) +{ + m_bEditLock = bLock; + + CreateShortcuts(); + + // Do not remove the card if it contains a still image. + if ( !bLock || !m_map->RetFixImage() ) + { + m_map->ShowMap(!m_bEditLock && m_bMapShow); + } + + m_displayText->HideText(bLock); + m_engine->FlushPressKey(); + + if ( m_bEditLock ) + { + HiliteClear(); + } + else + { + m_bEditFull = FALSE; + } +} + +BOOL CRobotMain::RetEditLock() +{ + return m_bEditLock; +} + +// Management of the fullscreen mode during editing. + +void CRobotMain::SetEditFull(BOOL bFull) +{ + m_bEditFull = bFull; +} + +BOOL CRobotMain::RetEditFull() +{ + return m_bEditFull; +} + + +BOOL CRobotMain::RetFreePhoto() +{ + return m_bFreePhoto; +} + + +// Indicates whether mouse is on an friend object, on which we should not shoot. + +void CRobotMain::SetFriendAim(BOOL bFriend) +{ + m_bFriendAim = bFriend; +} + +BOOL CRobotMain::RetFriendAim() +{ + return m_bFriendAim; +} + + +// Management of the precision of drawing the ground. + +void CRobotMain::SetTracePrecision(float factor) +{ + m_engine->SetTracePrecision(factor); +} + +float CRobotMain::RetTracePrecision() +{ + return m_engine->RetTracePrecision(); +} + + +// Starts music with a mission. + +void CRobotMain::StartMusic() +{ + if ( m_audioTrack != 0 ) + { + m_sound->StopMusic(); + m_sound->PlayMusic(m_audioTrack, m_bAudioRepeat); + } +} + +// Removes hilite and tooltip. + +void CRobotMain::ClearInterface() +{ + HiliteClear(); // removes setting evidence + m_tooltipName[0] = 0; // really removes the tooltip +} + + diff --git a/src/object/robotmain.h b/src/object/robotmain.h new file mode 100644 index 0000000..bafa62a --- /dev/null +++ b/src/object/robotmain.h @@ -0,0 +1,463 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// robotmain.h + +#ifndef _ROBOTMAIN_H_ +#define _ROBOTMAIN_H_ + + +#include "d3dengine.h" +#include "struct.h" +#include "object.h" +#include "mainmovie.h" +#include "camera.h" +#include "particule.h" + + +enum Phase +{ + PHASE_INIT, + PHASE_TERM, + PHASE_NAME, + PHASE_PERSO, + PHASE_TRAINER, + PHASE_DEFI, + PHASE_MISSION, + PHASE_FREE, + PHASE_TEEN, + PHASE_USER, + PHASE_PROTO, + PHASE_LOADING, + PHASE_SIMUL, + PHASE_MODEL, + PHASE_SETUPd, + PHASE_SETUPg, + PHASE_SETUPp, + PHASE_SETUPc, + PHASE_SETUPs, + PHASE_SETUPds, + PHASE_SETUPgs, + PHASE_SETUPps, + PHASE_SETUPcs, + PHASE_SETUPss, + PHASE_WRITE, + PHASE_READ, + PHASE_WRITEs, + PHASE_READs, + PHASE_WIN, + PHASE_LOST, + PHASE_WELCOME1, + PHASE_WELCOME2, + PHASE_WELCOME3, + PHASE_GENERIC, +}; + + +class CInstanceManager; +class CMainDialog; +class CMainShort; +class CMainMap; +class CEvent; +class CD3DEngine; +class CLight; +class CWater; +class CCloud; +class CBlitz; +class CPlanet; +class CTerrain; +class CModel; +class CInterface; +class CWindow; +class CControl; +class CDisplayText; +class CDisplayInfo; +class CSound; + + +typedef struct +{ + D3DVECTOR pos; + float dist; + ObjectType type; + int min; // wins if> + int max; // wins if < + int lost; // lost if <= + BOOL bImmediat; + char message[100]; +} +EndTake; + + +#define MAXNEWSCRIPTNAME 20 + +typedef struct +{ + BOOL bUsed; + ObjectType type; + char name[40]; +} +NewScriptName; + + +#define MAXSHOWLIMIT 5 +#define MAXSHOWPARTI 200 +#define SHOWLIMITTIME 20.0f + +typedef struct +{ + BOOL bUsed; + D3DVECTOR pos; + float radius; + int total; + int parti[MAXSHOWPARTI]; + CObject* link; + float duration; + float time; +} +ShowLimit; + + +#define SATCOM_HUSTON 0 +#define SATCOM_SAT 1 +#define SATCOM_OBJECT 2 +#define SATCOM_LOADING 3 +#define SATCOM_PROG 4 +#define SATCOM_SOLUCE 5 +#define SATCOM_MAX 6 + + + +class CRobotMain +{ +public: + CRobotMain(CInstanceManager* iMan); + ~CRobotMain(); + + void CreateIni(); + + void ChangePhase(Phase phase); + BOOL EventProcess(const Event &event); + + BOOL CreateShortcuts(); + void ScenePerso(); + + void SetMovieLock(BOOL bLock); + BOOL RetMovieLock(); + BOOL RetInfoLock(); + void SetSatComLock(BOOL bLock); + BOOL RetSatComLock(); + void SetEditLock(BOOL bLock, BOOL bEdit); + BOOL RetEditLock(); + void SetEditFull(BOOL bFull); + BOOL RetEditFull(); + BOOL RetFreePhoto(); + void SetFriendAim(BOOL bFriend); + BOOL RetFriendAim(); + + void SetTracePrecision(float factor); + float RetTracePrecision(); + + void ChangePause(BOOL bPause); + + void SetSpeed(float speed); + float RetSpeed(); + + void UpdateShortcuts(); + void SelectHuman(); + CObject* SearchHuman(); + CObject* SearchToto(); + CObject* SearchNearest(D3DVECTOR pos, CObject* pExclu); + BOOL SelectObject(CObject* pObj, BOOL bDisplayError=TRUE); + CObject* RetSelectObject(); + CObject* DeselectAll(); + BOOL DeleteObject(); + + void ResetObject(); + void ResetCreate(); + Error CheckEndMission(BOOL bFrame); + void CheckEndMessage(char *message); + int RetObligatoryToken(); + char* RetObligatoryToken(int i); + int IsObligatoryToken(char *token); + BOOL IsProhibitedToken(char *token); + void UpdateMap(); + BOOL RetShowMap(); + + MainMovieType RetMainMovie(); + + void FlushDisplayInfo(); + void StartDisplayInfo(int index, BOOL bMovie); + void StartDisplayInfo(char *filename, int index); + void StopDisplayInfo(); + char* RetDisplayInfoName(int index); + int RetDisplayInfoPosition(int index); + void SetDisplayInfoPosition(int index, int pos); + + void StartSuspend(); + void StopSuspend(); + + float RetGameTime(); + + void SetFontSize(float size); + float RetFontSize(); + void SetWindowPos(FPOINT pos); + FPOINT RetWindowPos(); + void SetWindowDim(FPOINT dim); + FPOINT RetWindowDim(); + + void SetIOPublic(BOOL bMode); + BOOL RetIOPublic(); + void SetIOPos(FPOINT pos); + FPOINT RetIOPos(); + void SetIODim(FPOINT dim); + FPOINT RetIODim(); + + char* RetTitle(); + char* RetResume(); + char* RetScriptName(); + char* RetScriptFile(); + BOOL RetTrainerPilot(); + BOOL RetFixScene(); + BOOL RetGlint(); + BOOL RetSoluce4(); + BOOL RetMovies(); + BOOL RetNiceReset(); + BOOL RetHimselfDamage(); + BOOL RetShowSoluce(); + BOOL RetSceneSoluce(); + BOOL RetShowAll(); + BOOL RetCheatRadar(); + char* RetSavegameDir(); + char* RetPublicDir(); + char* RetFilesDir(); + + void SetGamerName(char *name); + char* RetGamerName(); + int RetGamerFace(); + int RetGamerGlasses(); + BOOL RetGamerOnlyHead(); + float RetPersoAngle(); + + void StartMusic(); + void ClearInterface(); + void ChangeColor(); + + float SearchNearestObject(D3DVECTOR center, CObject *exclu); + BOOL FreeSpace(D3DVECTOR ¢er, float minRadius, float maxRadius, float space, CObject *exclu); + float RetFlatZoneRadius(D3DVECTOR center, float maxRadius, CObject *exclu); + void HideDropZone(CObject* metal); + void ShowDropZone(CObject* metal, CObject* truck); + void FlushShowLimit(int i); + void SetShowLimit(int i, ParticuleType parti, CObject *pObj, D3DVECTOR pos, float radius, float duration=SHOWLIMITTIME); + void AdjustShowLimit(int i, D3DVECTOR pos); + void StartShowLimit(); + void FrameShowLimit(float rTime); + + void CompileScript(BOOL bSoluce); + void LoadOneScript(CObject *pObj, int &nbError); + void LoadFileScript(CObject *pObj, char* filename, int objRank, int &nbError); + void SaveAllScript(); + void SaveOneScript(CObject *pObj); + void SaveFileScript(CObject *pObj, char* filename, int objRank); + BOOL SaveFileStack(CObject *pObj, FILE *file, int objRank); + BOOL ReadFileStack(CObject *pObj, FILE *file, int objRank); + + BOOL FlushNewScriptName(); + BOOL AddNewScriptName(ObjectType type, char *name); + char* RetNewScriptName(ObjectType type, int rank); + + void WriteFreeParam(); + void ReadFreeParam(); + + BOOL IsBusy(); + BOOL IOWriteScene(char *filename, char *filecbot, char *info); + CObject* IOReadScene(char *filename, char *filecbot); + void IOWriteObject(FILE *file, CObject* pObj, char *cmd); + CObject* IOReadObject(char *line, char* filename, int objRank); + + int CreateSpot(D3DVECTOR pos, D3DCOLORVALUE color); + +protected: + BOOL EventFrame(const Event &event); + BOOL EventObject(const Event &event); + void InitEye(); + + void Convert(); + void CreateScene(BOOL bSoluce, BOOL bFixScene, BOOL bResetObject); + + void CreateModel(); + D3DVECTOR LookatPoint( D3DVECTOR eye, float angleH, float angleV, float length ); + CObject* CreateObject(D3DVECTOR pos, float angle, float zoom, float height, ObjectType type, float power=1.0f, BOOL bTrainer=FALSE, BOOL bToy=FALSE, int option=0); + int CreateLight(D3DVECTOR direction, D3DCOLORVALUE color); + void HiliteClear(); + void HiliteObject(FPOINT pos); + void HiliteFrame(float rTime); + void CreateTooltip(FPOINT pos, char* text); + void ClearTooltip(); + CObject* DetectObject(FPOINT pos); + void ChangeCamera(); + void RemoteCamera(float pan, float zoom, float rTime); + void KeyCamera(EventMsg event, long param); + void AbortMovie(); + BOOL IsSelectable(CObject* pObj); + void SelectOneObject(CObject* pObj, BOOL bDisplayError=TRUE); + void HelpObject(); + BOOL DeselectObject(); + void DeleteAllObjects(); + void UpdateInfoText(); + CObject* SearchObject(ObjectType type); + CObject* RetSelect(); + void StartDisplayVisit(EventMsg event); + void FrameVisit(float rTime); + void StopDisplayVisit(); + void ExecuteCmd(char *cmd); + BOOL TestGadgetQuantity(int rank); + +protected: + CInstanceManager* m_iMan; + CMainMovie* m_movie; + CMainDialog* m_dialog; + CMainShort* m_short; + CMainMap* m_map; + CEvent* m_event; + CD3DEngine* m_engine; + CParticule* m_particule; + CWater* m_water; + CCloud* m_cloud; + CBlitz* m_blitz; + CPlanet* m_planet; + CLight* m_light; + CTerrain* m_terrain; + CModel* m_model; + CInterface* m_interface; + CCamera* m_camera; + CDisplayText* m_displayText; + CDisplayInfo* m_displayInfo; + CSound* m_sound; + + float m_time; + float m_gameTime; + float m_checkEndTime; + float m_winDelay; + float m_lostDelay; + BOOL m_bFixScene; // scene fixed, no interraction + BOOL m_bBase; // OBJECT_BASE exists in mission + FPOINT m_lastMousePos; + CObject* m_selectObject; + + Phase m_phase; + int m_cameraRank; + D3DCOLORVALUE m_color; + BOOL m_bFreePhoto; + BOOL m_bCmdEdit; + BOOL m_bShowPos; + BOOL m_bSelectInsect; + BOOL m_bShowSoluce; + BOOL m_bShowAll; + BOOL m_bCheatRadar; + BOOL m_bAudioRepeat; + BOOL m_bShortCut; + int m_audioTrack; + int m_delayWriteMessage; + int m_movieInfoIndex; + + BOOL m_bImmediatSatCom; // SatCom immediately? + BOOL m_bBeginSatCom; // messages SatCom poster? + BOOL m_bMovieLock; // movie in progress? + BOOL m_bSatComLock; // call of SatCom is possible? + BOOL m_bEditLock; // edition in progress? + BOOL m_bEditFull; // edition in full screen? + BOOL m_bPause; // simulation paused + BOOL m_bHilite; + BOOL m_bTrainerPilot; // remote trainer? + BOOL m_bSuspend; + BOOL m_bFriendAim; + BOOL m_bResetCreate; + BOOL m_bMapShow; + BOOL m_bMapImage; + char m_mapFilename[100]; + + FPOINT m_tooltipPos; + char m_tooltipName[100]; + float m_tooltipTime; + + char m_infoFilename[SATCOM_MAX][100]; // names of text files + CObject* m_infoObject; + int m_infoIndex; + int m_infoPos[SATCOM_MAX]; + int m_infoUsed; + + char m_title[100]; + char m_resume[500]; + char m_scriptName[100]; + char m_scriptFile[100]; + int m_endingWinRank; + int m_endingLostRank; + BOOL m_bWinTerminate; + + float m_fontSize; + FPOINT m_windowPos; + FPOINT m_windowDim; + + BOOL m_IOPublic; + FPOINT m_IOPos; + FPOINT m_IODim; + + NewScriptName m_newScriptName[MAXNEWSCRIPTNAME]; + + float m_cameraPan; + float m_cameraZoom; + + EventMsg m_visitLast; + CObject* m_visitObject; + CObject* m_visitArrow; + float m_visitTime; + float m_visitParticule; + D3DVECTOR m_visitPos; + D3DVECTOR m_visitPosArrow; + + int m_endTakeTotal; + EndTake m_endTake[10]; + long m_endTakeResearch; + float m_endTakeWinDelay; + float m_endTakeLostDelay; + + int m_obligatoryTotal; + char m_obligatoryToken[100][20]; + int m_prohibitedTotal; + char m_prohibitedToken[100][20]; + + char m_gamerName[100]; + + long m_freeBuild; // constructible buildings + long m_freeResearch; // researches possible + + ShowLimit m_showLimit[MAXSHOWLIMIT]; + + D3DCOLORVALUE m_colorRefBot; + D3DCOLORVALUE m_colorNewBot; + D3DCOLORVALUE m_colorRefAlien; + D3DCOLORVALUE m_colorNewAlien; + D3DCOLORVALUE m_colorRefGreen; + D3DCOLORVALUE m_colorNewGreen; + D3DCOLORVALUE m_colorRefWater; + D3DCOLORVALUE m_colorNewWater; + float m_colorShiftWater; +}; + + +#endif //_ROBOTMAIN_H_ diff --git a/src/object/task/task.cpp b/src/object/task/task.cpp new file mode 100644 index 0000000..6b8222e --- /dev/null +++ b/src/object/task/task.cpp @@ -0,0 +1,109 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// task.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "light.h" +#include "particule.h" +#include "terrain.h" +#include "water.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "motion.h" +#include "camera.h" +#include "sound.h" +#include "robotmain.h" +#include "displaytext.h" +#include "task.h" + + + + +// Object's constructor. + +CTask::CTask(CInstanceManager* iMan, CObject* object) +{ + m_iMan = iMan; + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); + m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); + m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + + m_object = object; + m_physics = m_object->RetPhysics(); + m_brain = m_object->RetBrain(); + m_motion = m_object->RetMotion(); +} + +// Object's destructor. + +CTask::~CTask() +{ +} + + +// Management of an event. + +BOOL CTask::EventProcess(const Event &event) +{ + return TRUE; +} + + +// Indicates whether the action is finished. + +Error CTask::IsEnded() +{ + return ERR_STOP; +} + + +// Indicates whether the action is pending. + +BOOL CTask::IsBusy() +{ + return TRUE; +} + + +// Suddenly ends the current action. + +BOOL CTask::Abort() +{ + return TRUE; +} + + diff --git a/src/object/task/task.h b/src/object/task/task.h new file mode 100644 index 0000000..f5685ef --- /dev/null +++ b/src/object/task/task.h @@ -0,0 +1,89 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// task.h + +#ifndef _TASK_H_ +#define _TASK_H_ + + +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CEngine; +class CLight; +class CParticule; +class CTerrain; +class CWater; +class CCamera; +class CBrain; +class CPhysics; +class CMotion; +class CObject; +class CRobotMain; +class CDisplayText; +class CSound; + + +#define TAKE_DIST 6.0f // distance to an object to pick it +#define TAKE_DIST_OTHER 1.5f // additional distance if on friend + +//?#define ARM_NEUTRAL_ANGLE1 155.0f*PI/180.0f +//?#define ARM_NEUTRAL_ANGLE2 -125.0f*PI/180.0f +//?#define ARM_NEUTRAL_ANGLE3 -45.0f*PI/180.0f +#define ARM_NEUTRAL_ANGLE1 110.0f*PI/180.0f +#define ARM_NEUTRAL_ANGLE2 -130.0f*PI/180.0f +#define ARM_NEUTRAL_ANGLE3 -50.0f*PI/180.0f + +#define ARM_STOCK_ANGLE1 110.0f*PI/180.0f +#define ARM_STOCK_ANGLE2 -100.0f*PI/180.0f +#define ARM_STOCK_ANGLE3 -70.0f*PI/180.0f + + +class CTask +{ +public: + CTask(CInstanceManager* iMan, CObject* object); + virtual ~CTask(); + + virtual BOOL EventProcess(const Event &event); + virtual Error IsEnded(); + virtual BOOL IsBusy(); + virtual BOOL Abort(); + +protected: + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CLight* m_light; + CParticule* m_particule; + CTerrain* m_terrain; + CWater* m_water; + CCamera* m_camera; + CMotion* m_motion; + CBrain* m_brain; + CPhysics* m_physics; + CObject* m_object; + CRobotMain* m_main; + CDisplayText* m_displayText; + CSound* m_sound; +}; + + +#endif //_TASK_H_ diff --git a/src/object/task/taskadvance.cpp b/src/object/task/taskadvance.cpp new file mode 100644 index 0000000..7860cb2 --- /dev/null +++ b/src/object/task/taskadvance.cpp @@ -0,0 +1,159 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskadvance.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "task.h" +#include "taskadvance.h" + + + + +// Object's constructor. + +CTaskAdvance::CTaskAdvance(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); +} + +// Object's destructor. + +CTaskAdvance::~CTaskAdvance() +{ +} + + +// Management of an event. + +BOOL CTaskAdvance::EventProcess(const Event &event) +{ + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_fixTime += event.rTime; + + // Momentarily stationary object (ant on the back)? + if ( m_object->RetFixed() ) + { + m_physics->SetMotorSpeedX(0.0f); // stops the advance + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + m_bError = TRUE; + return TRUE; + } + + m_timeLimit -= event.rTime; + return TRUE; +} + + +// Assigns the goal was achieved. + +Error CTaskAdvance::Start(float length) +{ + m_direction = (length>=0.0f)?1.0f:-1.0f; + m_totalLength = Abs(length); + m_advanceLength = m_physics->RetLinLength(length); + m_startPos = m_object->RetPosition(0); + m_lastDist = 0.0f; + m_fixTime = 0.0f; + + m_timeLimit = m_physics->RetLinTimeLength(m_totalLength, m_direction)*3.0f; + if ( m_timeLimit < 2.0f ) m_timeLimit = 2.0f; + + m_physics->SetMotorSpeedX(m_direction*1.0f); // forward/backward + m_physics->SetMotorSpeedY(0.0f); + m_physics->SetMotorSpeedZ(0.0f); + + m_bError = FALSE; + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskAdvance::IsEnded() +{ + D3DVECTOR pos; + float length; + + if ( m_engine->RetPause() ) return ERR_CONTINUE; + + if ( m_bError ) + { + return ERR_STOP; + } + + if ( m_timeLimit < 0.0f ) + { + m_physics->SetMotorSpeedX(0.0f); + return ERR_MOVE_IMPOSSIBLE; + } + + pos = m_object->RetPosition(0); + length = Length2d(pos, m_startPos); + + if ( length > m_lastDist ) // forward? + { + m_fixTime = 0.0f; + } + else // still stands? + { + if ( m_fixTime > 1.0f ) // for more than a second? + { + m_physics->SetMotorSpeedX(0.0f); + return ERR_MOVE_IMPOSSIBLE; + } + } + m_lastDist = length; + + if ( length >= m_totalLength ) + { + m_physics->SetMotorSpeedX(0.0f); + m_physics->SetLinMotionX(MO_CURSPEED, 0.0f); + + if ( length != 0.0f ) + { + pos = m_startPos+((pos-m_startPos)*m_totalLength/length); + m_object->SetPosition(0, pos); + } + return ERR_STOP; + } + + if ( length >= m_advanceLength ) + { + m_physics->SetMotorSpeedX(m_direction*0.1f); + } + return ERR_CONTINUE; +} + + diff --git a/src/object/task/taskadvance.h b/src/object/task/taskadvance.h new file mode 100644 index 0000000..284cf12 --- /dev/null +++ b/src/object/task/taskadvance.h @@ -0,0 +1,59 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskadvance.h + +#ifndef _TASKADVANCE_H_ +#define _TASKADVANCE_H_ + + +#include "misc.h" +#include "d3dengine.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + +class CTaskAdvance : public CTask +{ +public: + CTaskAdvance(CInstanceManager* iMan, CObject* object); + ~CTaskAdvance(); + + BOOL EventProcess(const Event &event); + + Error Start(float length); + Error IsEnded(); + +protected: + +protected: + float m_totalLength; + float m_advanceLength; + float m_direction; + float m_timeLimit; + D3DVECTOR m_startPos; + float m_lastDist; + float m_fixTime; + BOOL m_bError; +}; + + +#endif //_TASKADVANCE_H_ diff --git a/src/object/task/taskbuild.cpp b/src/object/task/taskbuild.cpp new file mode 100644 index 0000000..cc1303b --- /dev/null +++ b/src/object/task/taskbuild.cpp @@ -0,0 +1,822 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskbuild.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "light.h" +#include "particule.h" +#include "terrain.h" +#include "water.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "auto.h" +#include "camera.h" +#include "motion.h" +#include "motionhuman.h" +#include "robotmain.h" +#include "sound.h" +#include "displaytext.h" +#include "task.h" +#include "taskbuild.h" + + + + +// Object's constructor. + +CTaskBuild::CTaskBuild(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + int i; + + CTask::CTask(iMan, object); + + m_type = OBJECT_DERRICK; + m_time = 0.0f; + m_soundChannel = -1; + + for ( i=0 ; iFlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + for ( i=0 ; iDeleteLight(m_lightRank[i]); + } +} + + +// Creates a building. + +BOOL CTaskBuild::CreateBuilding(D3DVECTOR pos, float angle) +{ + m_building = new CObject(m_iMan); + if ( !m_building->CreateBuilding(pos, angle, 0.0f, m_type, 0.0f) ) + { + delete m_building; + m_building = 0; + return FALSE; + } + m_building->UpdateMapping(); + m_building->SetLock(TRUE); // not yet usable + + if ( m_type == OBJECT_DERRICK ) m_buildingHeight = 35.0f; + if ( m_type == OBJECT_FACTORY ) m_buildingHeight = 28.0f; + if ( m_type == OBJECT_REPAIR ) m_buildingHeight = 30.0f; + if ( m_type == OBJECT_STATION ) m_buildingHeight = 13.0f; + if ( m_type == OBJECT_CONVERT ) m_buildingHeight = 20.0f; + if ( m_type == OBJECT_TOWER ) m_buildingHeight = 30.0f; + if ( m_type == OBJECT_RESEARCH ) m_buildingHeight = 22.0f; + if ( m_type == OBJECT_RADAR ) m_buildingHeight = 19.0f; + if ( m_type == OBJECT_ENERGY ) m_buildingHeight = 20.0f; + if ( m_type == OBJECT_LABO ) m_buildingHeight = 16.0f; + if ( m_type == OBJECT_NUCLEAR ) m_buildingHeight = 40.0f; + if ( m_type == OBJECT_PARA ) m_buildingHeight = 68.0f; + if ( m_type == OBJECT_INFO ) m_buildingHeight = 19.0f; + m_buildingHeight *= 0.25f; + + m_buildingPos = m_building->RetPosition(0); + m_buildingPos.y -= m_buildingHeight; + m_building->SetPosition(0, m_buildingPos); + return TRUE; +} + +// Creates lights for the effects. + +void CTaskBuild::CreateLight() +{ + D3DLIGHT7 light; + D3DCOLORVALUE color; + D3DVECTOR center, pos, dir; + FPOINT c, p; + float angle; + int i; + + if ( !m_engine->RetLightMode() ) return; + + center = m_metal->RetPosition(0); + + angle = 0; + for ( i=0 ; iCreateLight(); + if ( m_lightRank[i] == -1 ) continue; + + c.x = center.x; + c.y = center.z; + p.x = center.x+40.0f; + p.y = center.z; + p = RotatePoint(c, angle, p); + pos.x = p.x; + pos.z = p.y; + pos.y = center.y+40.0f; + dir = center-pos; + + ZeroMemory( &light, sizeof(light) ); + light.dltType = D3DLIGHT_SPOT; + light.dcvDiffuse.r = 0.0f; + light.dcvDiffuse.g = 0.0f; + light.dcvDiffuse.b = 0.0f; // white (invisible) + light.dvPosition.x = pos.x; + light.dvPosition.y = pos.y; + light.dvPosition.z = pos.z; + light.dvDirection.x = dir.x; + light.dvDirection.y = dir.y; + light.dvDirection.z = dir.z; + light.dvRange = D3DLIGHT_RANGE_MAX; + light.dvFalloff = 1.0f; + light.dvAttenuation0 = 1.0f; + light.dvAttenuation1 = 0.0f; + light.dvAttenuation2 = 0.0f; + light.dvTheta = 0.0f; + light.dvPhi = PI/4.0f; + m_light->SetLight(m_lightRank[i], light); + + color.r = -1.0f; + color.g = -1.0f; + color.b = -0.5f; // violet + color.a = 0.0f; + m_light->SetLightColor(m_lightRank[i], color); + m_light->SetLightColorSpeed(m_lightRank[i], 1.0f/((1.0f/m_speed)*0.25f)); + + angle += (PI*2.0f)/TBMAXLIGHT; + } + + m_bBlack = FALSE; +} + +// Switches the lights from black to white. + +void CTaskBuild::BlackLight() +{ + D3DCOLORVALUE color; + int i; + + for ( i=0 ; iSetLightColor(m_lightRank[i], color); + m_light->SetLightColorSpeed(m_lightRank[i], 1.0f/((1.0f/m_speed)*0.75f)); + } + + m_bBlack = TRUE; +} + +// Management of an event. + +BOOL CTaskBuild::EventProcess(const Event &event) +{ + D3DMATRIX* mat; + D3DVECTOR pos, dir, speed; + FPOINT dim; + float a, g, cirSpeed, dist, linSpeed; + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_bError ) return FALSE; + + m_time += event.rTime; + + m_progress += event.rTime*m_speed; // other advance + + if ( m_phase == TBP_TURN ) // preliminary rotation? + { + a = m_object->RetAngleY(0); + g = m_angleY; + cirSpeed = Direction(a, g)*1.0f; + if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; + if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; + + m_physics->SetMotorSpeedZ(cirSpeed); // turns left/right + return TRUE; + } + + if ( m_phase == TBP_MOVE ) // preliminary forward/backward? + { + dist = Length(m_object->RetPosition(0), m_metal->RetPosition(0)); + linSpeed = 0.0f; + if ( dist > 30.0f ) linSpeed = 1.0f; + if ( dist < 30.0f ) linSpeed = -1.0f; + m_physics->SetMotorSpeedX(linSpeed); // forward/backward + return TRUE; + } + + if ( m_phase == TBP_RECEDE ) // terminal back? + { + m_physics->SetMotorSpeedX(-1.0f); // back + return TRUE; + } + + if ( m_phase == TBP_TAKE ) // takes gun? + { + return TRUE; + } + + if ( m_phase == TBP_PREP ) // prepares? + { + return TRUE; + } + + if ( m_phase == TBP_TERM ) // ends? + { + return TRUE; + } + + if ( !m_bBuild ) // building to build? + { + m_bBuild = TRUE; + + pos = m_metal->RetPosition(0); + a = m_object->RetAngleY(0); + if ( !CreateBuilding(pos, a+PI) ) + { + m_metal->SetLock(FALSE); // usable again + m_motion->SetAction(-1); + m_object->SetObjectParent(14, 0); + m_object->SetPosition(14, D3DVECTOR(-1.5f, 0.3f, -1.35f)); + m_object->SetAngleZ(14, PI); + m_camera->FlushEffect(); + Abort(); + m_bError = TRUE; + m_displayText->DisplayError(ERR_TOOMANY, m_object->RetPosition(0)); + return FALSE; + } + CreateLight(); + } + + pos = m_buildingPos; + pos.y += m_buildingHeight*m_progress; + m_building->SetPosition(0, pos); // the building rises + + m_building->SetZoom(0, m_progress*0.75f+0.25f); + m_metal->SetZoom(0, 1.0f-m_progress); + + a = (2.0f-2.0f*m_progress); + if ( a > 1.0f ) a = 1.0f; + dir.x = (Rand()-0.5f)*a*0.1f; + dir.z = (Rand()-0.5f)*a*0.1f; + dir.y = (Rand()-0.5f)*a*0.1f; + m_building->SetCirVibration(dir); + + if ( !m_bBlack && m_progress >= 0.25f ) + { + BlackLight(); + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_metal->RetPosition(0); + speed.x = (Rand()-0.5f)*20.0f; + speed.z = (Rand()-0.5f)*20.0f; + speed.y = Rand()*10.0f; + dim.x = Rand()*6.0f+4.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFIRE); + + pos = D3DVECTOR(0.0f, 0.5f, 0.0f); + mat = m_object->RetWorldMatrix(14); + pos = Transform(*mat, pos); + speed = m_metal->RetPosition(0); + speed.x += (Rand()-0.5f)*5.0f; + speed.z += (Rand()-0.5f)*5.0f; + speed -= pos; + dim.x = 2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ); + + if ( Rand() < 0.3f ) + { + m_sound->Play(SOUND_BUILD, m_object->RetPosition(0), 0.5f, 1.0f*Rand()*1.5f); + } + } + + return TRUE; +} + + +// Assigns the goal was achieved. + +Error CTaskBuild::Start(ObjectType type) +{ + D3DVECTOR pos, speed, pv, pm; + Error err; + float iAngle, oAngle; + + m_type = type; + m_lastParticule = 0.0f; + m_progress = 0.0f; + + iAngle = m_object->RetAngleY(0); + iAngle = NormAngle(iAngle); // 0..2*PI + oAngle = iAngle; + + m_bError = TRUE; // operation impossible + + pos = m_object->RetPosition(0); + if ( pos.y < m_water->RetLevel() ) return ERR_BUILD_WATER; + + if ( !m_physics->RetLand() ) return ERR_BUILD_FLY; + + speed = m_physics->RetMotorSpeed(); + if ( speed.x != 0.0f || + speed.z != 0.0f ) return ERR_BUILD_MOTOR; + + if ( m_object->RetFret() != 0 ) return ERR_MANIP_BUSY; + + m_metal = SearchMetalObject(oAngle, 2.0f, 100.0f, PI*0.25f, err); + if ( err == ERR_BUILD_METALNEAR && m_metal != 0 ) + { + err = FlatFloor(); + if ( err != ERR_OK ) return err; + return ERR_BUILD_METALNEAR; + } + if ( err != ERR_OK ) return err; + + err = FlatFloor(); + if ( err != ERR_OK ) return err; + + m_metal->SetLock(TRUE); // not usable + m_camera->StartCentering(m_object, PI*0.15f, 99.9f, 0.0f, 1.0f); + + m_phase = TBP_TURN; // rotation necessary preliminary + m_angleY = oAngle; // angle was reached + + pv = m_object->RetPosition(0); + pv.y += 8.3f; + pm = m_metal->RetPosition(0); + m_angleZ = RotateAngle(Length2d(pv, pm), Abs(pv.y-pm.y)); + + m_physics->SetFreeze(TRUE); // it does not move + + m_bBuild = FALSE; // not yet built + m_bError = FALSE; // ok + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskBuild::IsEnded() +{ + CAuto* automat; + float angle, dist, time; + + if ( m_engine->RetPause() ) return ERR_CONTINUE; + if ( m_bError ) return ERR_STOP; + + if ( m_phase == TBP_TURN ) // preliminary rotation? + { + angle = m_object->RetAngleY(0); + angle = NormAngle(angle); // 0..2*PI + + if ( TestAngle(angle, m_angleY-PI*0.01f, m_angleY+PI*0.01f) ) + { + m_physics->SetMotorSpeedZ(0.0f); + + dist = Length(m_object->RetPosition(0), m_metal->RetPosition(0)); + if ( dist > 30.0f ) + { + time = m_physics->RetLinTimeLength(dist-30.0f, 1.0f); + m_speed = 1.0f/time; + } + else + { + time = m_physics->RetLinTimeLength(30.0f-dist, -1.0f); + m_speed = 1.0f/time; + } + m_phase = TBP_MOVE; + m_progress = 0.0f; + } + return ERR_CONTINUE; + } + + if ( m_phase == TBP_MOVE ) // preliminary forward/backward? + { + dist = Length(m_object->RetPosition(0), m_metal->RetPosition(0)); + + if ( dist >= 25.0f && dist <= 35.0f ) + { + m_physics->SetMotorSpeedX(0.0f); + m_motion->SetAction(MHS_GUN); // takes gun + + m_phase = TBP_TAKE; + m_speed = 1.0f/1.0f; + m_progress = 0.0f; + } + else + { + if ( m_progress > 1.0f ) // timeout? + { + m_metal->SetLock(FALSE); // usable again + if ( dist < 30.0f ) return ERR_BUILD_METALNEAR; + else return ERR_BUILD_METALAWAY; + } + } + return ERR_CONTINUE; + } + + if ( m_phase == TBP_TAKE ) // takes gun + { + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + m_motion->SetAction(MHS_FIRE); // shooting position + m_object->SetObjectParent(14, 4); + m_object->SetPosition(14, D3DVECTOR(0.6f, 0.1f, 0.3f)); + m_object->SetAngleZ(14, 0.0f); + + m_phase = TBP_PREP; + m_speed = 1.0f/1.0f; + m_progress = 0.0f; + } + + if ( m_phase == TBP_PREP ) // prepares? + { + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + m_soundChannel = m_sound->Play(SOUND_TREMBLE, m_object->RetPosition(0), 0.0f, 1.0f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 0.7f, 1.0f, 1.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.7f, 1.5f, 7.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.5f, 2.0f, SOPER_STOP); + + m_camera->StartEffect(CE_VIBRATION, m_metal->RetPosition(0), 1.0f); + + m_phase = TBP_BUILD; + m_speed = 1.0f/10.f; // duration of 10s + m_progress = 0.0f; + } + + if ( m_phase == TBP_BUILD ) // construction? + { + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + DeleteMark(m_metal->RetPosition(0), 20.0f); + + m_metal->DeleteObject(); // removes the metal + delete m_metal; + m_metal = 0; + + m_building->SetZoom(0, 1.0f); + m_building->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); + m_building->SetLock(FALSE); // building usable + m_main->CreateShortcuts(); + m_displayText->DisplayError(INFO_BUILD, m_buildingPos, 10.0f, 50.0f); + + automat = m_building->RetAuto(); + if ( automat != 0 ) + { + automat->Init(); + } + + m_motion->SetAction(MHS_GUN); // hands gun + m_phase = TBP_TERM; + m_speed = 1.0f/1.0f; + m_progress = 0.0f; + } + + if ( m_phase == TBP_TERM ) // rotation terminale ? + { + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + m_motion->SetAction(-1); + m_object->SetObjectParent(14, 0); + m_object->SetPosition(14, D3DVECTOR(-1.5f, 0.3f, -1.35f)); + m_object->SetAngleZ(14, PI); + + if ( m_type == OBJECT_FACTORY || + m_type == OBJECT_RESEARCH || + m_type == OBJECT_NUCLEAR ) + { + + m_phase = TBP_RECEDE; + m_speed = 1.0f/1.5f; + m_progress = 0.0f; + } + } + + if ( m_phase == TBP_RECEDE ) // back? + { + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + m_physics->SetMotorSpeedX(0.0f); + } + + Abort(); + return ERR_STOP; +} + +// Suddenly ends the current action. + +BOOL CTaskBuild::Abort() +{ + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + m_camera->StopCentering(m_object, 2.0f); + m_physics->SetFreeze(FALSE); // is moving again + return TRUE; +} + + +// Checks whether the terrain is fairly flat +// and if there is not too close to another object. + +Error CTaskBuild::FlatFloor() +{ + CObject *pObj; + ObjectType type; + D3DVECTOR center, pos, oPos, bPos; + FPOINT c, p; + float radius, max, oRadius, bRadius, angle, dist; + int i, j; + BOOL bLittleFlat, bBase; + + radius = 0.0f; + if ( m_type == OBJECT_DERRICK ) radius = 5.0f; + if ( m_type == OBJECT_FACTORY ) radius = 15.0f; + if ( m_type == OBJECT_REPAIR ) radius = 12.0f; + if ( m_type == OBJECT_STATION ) radius = 12.0f; + if ( m_type == OBJECT_CONVERT ) radius = 12.0f; + if ( m_type == OBJECT_TOWER ) radius = 7.0f; + if ( m_type == OBJECT_RESEARCH ) radius = 10.0f; + if ( m_type == OBJECT_RADAR ) radius = 5.0f; + if ( m_type == OBJECT_ENERGY ) radius = 8.0f; + if ( m_type == OBJECT_LABO ) radius = 12.0f; + if ( m_type == OBJECT_NUCLEAR ) radius = 20.0f; + if ( m_type == OBJECT_PARA ) radius = 20.0f; + if ( m_type == OBJECT_INFO ) radius = 5.0f; + if ( radius == 0.0f ) return ERR_GENERIC; + + center = m_metal->RetPosition(0); + angle = m_terrain->RetFineSlope(center); + bLittleFlat = ( angle < FLATLIMIT ); + + max = m_terrain->RetFlatZoneRadius(center, radius); + if ( max < radius ) // area too small? + { + if ( bLittleFlat ) + { + m_main->SetShowLimit(1, PARTILIMIT3, m_metal, center, max, 10.0f); + } + return bLittleFlat?ERR_BUILD_FLATLIT:ERR_BUILD_FLAT; + } + + max = 100000.0f; + bBase = FALSE; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetActif() ) continue; // inactive? + if ( pObj->RetTruck() != 0 ) continue; // object transported? + if ( pObj == m_metal ) continue; + if ( pObj == m_object ) continue; + + type = pObj->RetType(); + if ( type == OBJECT_BASE ) + { + oPos = pObj->RetPosition(0); + dist = Length(center, oPos)-80.0f; + if ( dist < max ) + { + max = dist; + bPos = oPos; + bRadius = oRadius; + bBase = TRUE; + } + } + else + { + j = 0; + while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) + { + dist = Length(center, oPos)-oRadius; + if ( dist < max ) + { + max = dist; + bPos = oPos; + bRadius = oRadius; + bBase = FALSE; + } + } + } + } + if ( max < radius ) + { + m_main->SetShowLimit(1, PARTILIMIT2, m_metal, center, max, 10.0f); + if ( bRadius < 2.0f ) bRadius = 2.0f; + m_main->SetShowLimit(2, PARTILIMIT3, m_metal, bPos, bRadius, 10.0f); + return bBase?ERR_BUILD_BASE:ERR_BUILD_BUSY; + } + + max = 100000.0f; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetActif() ) continue; // inactive? + if ( pObj->RetTruck() != 0 ) continue; // object transported? + if ( pObj == m_metal ) continue; + if ( pObj == m_object ) continue; + + type = pObj->RetType(); + if ( type == OBJECT_DERRICK || + type == OBJECT_FACTORY || + type == OBJECT_STATION || + type == OBJECT_CONVERT || + type == OBJECT_REPAIR || + type == OBJECT_TOWER || + type == OBJECT_RESEARCH || + type == OBJECT_RADAR || + type == OBJECT_ENERGY || + type == OBJECT_LABO || + type == OBJECT_NUCLEAR || + type == OBJECT_START || + type == OBJECT_END || + type == OBJECT_INFO || + type == OBJECT_PARA || + type == OBJECT_SAFE || + type == OBJECT_HUSTON ) // building? + { + j = 0; + while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) + { + dist = Length(center, oPos)-oRadius; + if ( dist < max ) + { + max = dist; + bPos = oPos; + bRadius = oRadius; + } + } + } + } + if ( max-BUILDMARGIN < radius ) + { + m_main->SetShowLimit(1, PARTILIMIT2, m_metal, center, max-BUILDMARGIN, 10.0f); + m_main->SetShowLimit(2, PARTILIMIT3, m_metal, bPos, bRadius+BUILDMARGIN, 10.0f); + return bBase?ERR_BUILD_BASE:ERR_BUILD_NARROW; + } + + return ERR_OK; +} + +// Seeks the nearest metal object. + +CObject* CTaskBuild::SearchMetalObject(float &angle, float dMin, float dMax, + float aLimit, Error &err) +{ + CObject *pObj, *pBest; + D3DVECTOR iPos, oPos; + ObjectType type; + float min, iAngle, a, aa, aBest, distance, magic; + int i; + BOOL bMetal; + + iPos = m_object->RetPosition(0); + iAngle = m_object->RetAngleY(0); + iAngle = NormAngle(iAngle); // 0..2*PI + + min = 1000000.0f; + pBest = 0; + bMetal = FALSE; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetActif() ) continue; // objet inactive? + if ( pObj->RetTruck() != 0 ) continue; // object transported? + + type = pObj->RetType(); + if ( type != OBJECT_METAL ) continue; + + bMetal = TRUE; // metal exists + + oPos = pObj->RetPosition(0); + distance = Length(oPos, iPos); + a = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW! + + if ( distance > dMax ) continue; + if ( !TestAngle(a, iAngle-aLimit, iAngle+aLimit) ) continue; + + if ( distance < dMin ) + { + err = ERR_BUILD_METALNEAR; // too close + return pObj; + } + + aa = Abs(a-iAngle); + if ( aa > PI ) aa = PI*2.0f-aa; + magic = distance*aa; + + if ( magic < min ) + { + min = magic; + aBest = a; + pBest = pObj; + } + } + + if ( pBest == 0 ) + { + if ( bMetal ) err = ERR_BUILD_METALAWAY; // too far + else err = ERR_BUILD_METALINEX; // non-existent + } + else + { + angle = aBest; + err = ERR_OK; + } + return pBest; +} + +// Destroys all the close marks. + +void CTaskBuild::DeleteMark(D3DVECTOR pos, float radius) +{ + CObject* pObj; + D3DVECTOR oPos; + ObjectType type; + float distance; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_MARKSTONE && + type != OBJECT_MARKURANIUM && + type != OBJECT_MARKKEYa && + type != OBJECT_MARKKEYb && + type != OBJECT_MARKKEYc && + type != OBJECT_MARKKEYd && + type != OBJECT_MARKPOWER ) continue; + + oPos = pObj->RetPosition(0); + distance = Length(oPos, pos); + if ( distance <= radius ) + { + pObj->DeleteObject(); // removes the mark + delete pObj; + i --; + } + } +} + diff --git a/src/object/task/taskbuild.h b/src/object/task/taskbuild.h new file mode 100644 index 0000000..75a44f7 --- /dev/null +++ b/src/object/task/taskbuild.h @@ -0,0 +1,93 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskbuild.h + +#ifndef _TASKBUILD_H_ +#define _TASKBUILD_H_ + + +#include "misc.h" +#include "object.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; + + + +#define BUILDMARGIN 16.0f +#define TBMAXLIGHT 4 + + +enum TaskBuildPhase +{ + TBP_TURN = 1, // turns + TBP_MOVE = 2, // forward/backward + TBP_TAKE = 3, // takes gun + TBP_PREP = 4, // prepares + TBP_BUILD = 5, // builds + TBP_TERM = 6, // ends + TBP_RECEDE = 7, // back terminal +}; + + + +class CTaskBuild : public CTask +{ +public: + CTaskBuild(CInstanceManager* iMan, CObject* object); + ~CTaskBuild(); + + BOOL EventProcess(const Event &event); + + Error Start(ObjectType type); + Error IsEnded(); + BOOL Abort(); + +protected: + Error FlatFloor(); + BOOL CreateBuilding(D3DVECTOR pos, float angle); + void CreateLight(); + void BlackLight(); + CObject* SearchMetalObject(float &angle, float dMin, float dMax, float aLimit, Error &err); + void DeleteMark(D3DVECTOR pos, float radius); + +protected: + ObjectType m_type; // type of construction + CObject* m_metal; // transforms metal object + CObject* m_power; // the vehicle battery + CObject* m_building; // building built + TaskBuildPhase m_phase; // phase of the operation + BOOL m_bError; // TRUE -> operation impossible + BOOL m_bBuild; // TRUE -> building built + BOOL m_bBlack; // TRUE -> lights black -> white + float m_time; // absolute time + float m_lastParticule; // time of generation last particle + float m_progress; // progression (0..1) + float m_speed; // speed of progression + float m_angleY; // rotation angle of the vehicle + float m_angleZ; // angle of rotation of the gun + D3DVECTOR m_buildingPos; // initial position of the building + float m_buildingHeight; // height of the building + int m_lightRank[TBMAXLIGHT];// lights for the effects + int m_soundChannel; +}; + + +#endif //_TASKBUILD_H_ diff --git a/src/object/task/taskfire.cpp b/src/object/task/taskfire.cpp new file mode 100644 index 0000000..4fc0af5 --- /dev/null +++ b/src/object/task/taskfire.cpp @@ -0,0 +1,398 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskfire.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "sound.h" +#include "task.h" +#include "taskfire.h" + + + +#define ENERGY_FIRE (0.25f/2.5f) // energy consumed/shot +#define ENERGY_FIREr (0.25f/1.5f) // energy consumed/ray +#define ENERGY_FIREi (0.10f/2.5f) // energy consumed/organic + + +// Object's constructor. + +CTaskFire::CTaskFire(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); + m_soundChannel = -1; +} + +// Object's destructor. + +CTaskFire::~CTaskFire() +{ + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } +} + + +// Management of an event. + +BOOL CTaskFire::EventProcess(const Event &event) +{ + CObject* power; + CPhysics* physics; + D3DMATRIX* mat; + D3DVECTOR pos, speed, dir, vib; + ObjectType type; + FPOINT dim; + float energy, fire; + int i, channel; + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_bError ) return FALSE; + + m_time += event.rTime; + m_lastSound -= event.rTime; + m_progress += event.rTime*m_speed; + + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + if ( m_bOrganic ) fire = ENERGY_FIREi; + else if ( m_bRay ) fire = ENERGY_FIREr; + else fire = ENERGY_FIRE; + energy -= event.rTime*fire/power->RetCapacity(); + power->SetEnergy(energy); + } + + if ( m_lastParticule+0.05f <= m_time ) + { + m_lastParticule = m_time; + + if ( m_bOrganic ) + { + mat = m_object->RetWorldMatrix(1); // insect-cannon + + for ( i=0 ; i<6 ; i++ ) + { + pos = D3DVECTOR(0.0f, 2.5f, 0.0f); + pos = Transform(*mat, pos); + + speed = D3DVECTOR(200.0f, 0.0f, 0.0f); + + physics = m_object->RetPhysics(); + if ( physics != 0 ) + { + speed += physics->RetLinMotion(MO_REASPEED); + } + + speed.x += (Rand()-0.5f)*10.0f; + speed.y += (Rand()-0.5f)*20.0f; + speed.z += (Rand()-0.5f)*30.0f; + speed = Transform(*mat, speed); + speed -= pos; + + dim.x = Rand()*0.5f+0.5f; + dim.y = dim.x; + + channel = m_particule->CreateParticule(pos, speed, dim, PARTIGUN4, 0.8f, 0.0f, 0.0f); + m_particule->SetObjectFather(channel, m_object); + } + } + else if ( m_bRay ) + { + mat = m_object->RetWorldMatrix(2); // cannon + + for ( i=0 ; i<4 ; i++ ) + { + pos = D3DVECTOR(4.0f, 0.0f, 0.0f); + pos.y += (rand()%3-1)*1.5f; + pos.z += (rand()%3-1)*1.5f; + pos = Transform(*mat, pos); + + speed = D3DVECTOR(200.0f, 0.0f, 0.0f); + speed.x += (Rand()-0.5f)*6.0f; + speed.y += (Rand()-0.5f)*12.0f; + speed.z += (Rand()-0.5f)*12.0f; + speed = Transform(*mat, speed); + speed -= pos; + + dim.x = 1.0f; + dim.y = dim.x; + channel = m_particule->CreateTrack(pos, speed, dim, PARTITRACK11, + 2.0f, 200.0f, 0.5f, 1.0f); + m_particule->SetObjectFather(channel, m_object); + + speed = D3DVECTOR(5.0f, 0.0f, 0.0f); + speed.x += (Rand()-0.5f)*1.0f; + speed.y += (Rand()-0.5f)*2.0f; + speed.z += (Rand()-0.5f)*2.0f; + speed = Transform(*mat, speed); + speed -= pos; + speed.y += 5.0f; + + dim.x = 2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE2, 2.0f, 0.0f, 0.5f); + } + } + else + { + type = m_object->RetType(); + + if ( type == OBJECT_MOBILErc ) + { + mat = m_object->RetWorldMatrix(2); // cannon + } + else + { + mat = m_object->RetWorldMatrix(1); // cannon + } + + for ( i=0 ; i<3 ; i++ ) + { + if ( type == OBJECT_MOBILErc ) + { + pos = D3DVECTOR(0.0f, 0.0f, 0.0f); + } + else + { + pos = D3DVECTOR(3.0f, 1.0f, 0.0f); + } + pos.y += (Rand()-0.5f)*1.0f; + pos.z += (Rand()-0.5f)*1.0f; + pos = Transform(*mat, pos); + + speed = D3DVECTOR(200.0f, 0.0f, 0.0f); + + physics = m_object->RetPhysics(); + if ( physics != 0 ) + { + speed += physics->RetLinMotion(MO_REASPEED); + } + + speed.x += (Rand()-0.5f)*3.0f; + speed.y += (Rand()-0.5f)*6.0f; + speed.z += (Rand()-0.5f)*6.0f; + speed = Transform(*mat, speed); + speed -= pos; + + dim.x = Rand()*0.7f+0.7f; + dim.y = dim.x; + + channel = m_particule->CreateParticule(pos, speed, dim, PARTIGUN1, 0.8f, 0.0f, 0.0f); + m_particule->SetObjectFather(channel, m_object); + } + + if ( type != OBJECT_MOBILErc && + m_progress > 0.3f ) + { + pos = D3DVECTOR(-1.0f, 1.0f, 0.0f); + pos.y += (Rand()-0.5f)*0.4f; + pos.z += (Rand()-0.5f)*0.4f; + pos = Transform(*mat, pos); + + speed = D3DVECTOR(-4.0f, 0.0f, 0.0f); + speed.x += (Rand()-0.5f)*2.0f; + speed.y += (Rand()-0.2f)*4.0f; + speed.z += (Rand()-0.5f)*4.0f; + speed = Transform(*mat, speed); + speed -= pos; + + dim.x = Rand()*1.2f+1.2f; + dim.y = dim.x; + + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.0f); +//? m_particule->CreateParticule(pos, speed, dim, PARTISMOKE2, 4.0f, 0.0f, 0.0f); + } + } + + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + if ( m_progress < 0.1f ) + { + dir.z = (PI*0.04f)*(m_progress*10.0f); + } + else if ( m_progress < 0.9f ) + { + dir.z = (PI*0.04f); + } + else + { + dir.z = (PI*0.04f)*(1.0f-(m_progress-0.9f)*10.0f); + } + m_object->SetInclinaison(dir); + + vib.x = (Rand()-0.5f)*0.01f; + vib.y = (Rand()-0.5f)*0.02f; + vib.z = (Rand()-0.5f)*0.02f; + m_object->SetCirVibration(vib); + + vib.x = (Rand()-0.5f)*0.20f; + vib.y = (Rand()-0.5f)*0.05f; + vib.z = (Rand()-0.5f)*0.20f; + m_object->SetLinVibration(vib); + } + + if ( m_bRay && m_lastSound <= 0.0f ) + { + m_lastSound = Rand()*0.4f+0.4f; + m_sound->Play(SOUND_FIREp, m_object->RetPosition(0)); + } + + return TRUE; +} + + +// Assigns the goal was achieved. + +Error CTaskFire::Start(float delay) +{ + CObject* power; + D3DVECTOR pos, goal, speed; + float energy, fire; + ObjectType type; + + m_bError = TRUE; // operation impossible + + type = m_object->RetType(); + if ( type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILErc ) return ERR_FIRE_VEH; + +//? if ( !m_physics->RetLand() ) return ERR_FIRE_FLY; + + speed = m_physics->RetMotorSpeed(); +//? if ( speed.x != 0.0f || +//? speed.z != 0.0f ) return ERR_FIRE_MOTOR; + + m_bRay = (type == OBJECT_MOBILErc); + + m_bOrganic = FALSE; + if ( type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii ) + { + m_bOrganic = TRUE; + } + + if ( delay == 0.0f ) + { + if ( m_bRay ) delay = 1.2f; + else delay = 2.0f; + } + m_delay = delay; + + power = m_object->RetPower(); + if ( power == 0 ) return ERR_FIRE_ENERGY; + energy = power->RetEnergy(); + if ( m_bOrganic ) fire = m_delay*ENERGY_FIREi; + else if ( m_bRay ) fire = m_delay*ENERGY_FIREr; + else fire = m_delay*ENERGY_FIRE; + if ( energy < fire/power->RetCapacity()+0.05f ) return ERR_FIRE_ENERGY; + + m_speed = 1.0f/m_delay; + m_progress = 0.0f; + m_time = 0.0f; + m_lastParticule = 0.0f; + m_lastSound = 0.0f; + m_bError = FALSE; // ok + +//? m_camera->StartCentering(m_object, PI*0.15f, 99.9f, 0.0f, 1.0f); + + if ( m_bOrganic ) + { + m_soundChannel = m_sound->Play(SOUND_FIREi, m_object->RetPosition(0), 1.0f, 1.0f, TRUE); + if ( m_soundChannel != -1 ) + { + m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, m_delay, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 0.5f, SOPER_STOP); + } + } + else if ( m_bRay ) + { + } + else + { + m_soundChannel = m_sound->Play(SOUND_FIRE, m_object->RetPosition(0), 1.0f, 1.0f, TRUE); + if ( m_soundChannel != -1 ) + { + m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, m_delay, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 0.5f, SOPER_STOP); + } + } + + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskFire::IsEnded() +{ + if ( m_engine->RetPause() ) return ERR_CONTINUE; + if ( m_bError ) return ERR_STOP; + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + Abort(); + return ERR_STOP; +} + +// Suddenly ends the current action. + +BOOL CTaskFire::Abort() +{ + m_object->SetInclinaison(D3DVECTOR(0.0f, 0.0f, 0.0f)); + m_object->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); + m_object->SetLinVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + +//? m_camera->StopCentering(m_object, 1.0f); + return TRUE; +} + diff --git a/src/object/task/taskfire.h b/src/object/task/taskfire.h new file mode 100644 index 0000000..af371b2 --- /dev/null +++ b/src/object/task/taskfire.h @@ -0,0 +1,61 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskfire.h + +#ifndef _TASKFIRE_H_ +#define _TASKTIRE_H_ + + +#include "misc.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + +class CTaskFire : public CTask +{ +public: + CTaskFire(CInstanceManager* iMan, CObject* object); + ~CTaskFire(); + + BOOL EventProcess(const Event &event); + + Error Start(float delay); + Error IsEnded(); + BOOL Abort(); + +protected: + +protected: + float m_delay; + float m_progress; + BOOL m_bError; + BOOL m_bRay; + BOOL m_bOrganic; + float m_time; + float m_speed; + float m_lastParticule; + float m_lastSound; + int m_soundChannel; +}; + + +#endif //_TASKFIRE_H_ diff --git a/src/object/task/taskfireant.cpp b/src/object/task/taskfireant.cpp new file mode 100644 index 0000000..2c47adf --- /dev/null +++ b/src/object/task/taskfireant.cpp @@ -0,0 +1,227 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskfireant.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "motion.h" +#include "motionant.h" +#include "task.h" +#include "taskfireant.h" + + + + +// Object's constructor. + +CTaskFireAnt::CTaskFireAnt(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); + + m_phase = TFA_NULL; +} + +// Object's destructor. + +CTaskFireAnt::~CTaskFireAnt() +{ +} + + +// Management of an event. + +BOOL CTaskFireAnt::EventProcess(const Event &event) +{ + D3DVECTOR dir, vib; + float a, g, cirSpeed; + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_bError ) return FALSE; + + if ( m_object->RetFixed() ) // insect on its back? + { + m_bError = TRUE; + return FALSE; + } + + m_time += event.rTime; + m_progress += event.rTime*m_speed; + + if ( m_phase == TFA_TURN ) // preliminary rotation? + { + a = m_object->RetAngleY(0); + g = m_angle; + cirSpeed = Direction(a, g)*2.0f; + if ( cirSpeed > 2.0f ) cirSpeed = 2.0f; + if ( cirSpeed < -2.0f ) cirSpeed = -2.0f; + + m_physics->SetMotorSpeedZ(cirSpeed); // turns left/right + } + + return TRUE; +} + + +// Assigns the goal was achieved. + +Error CTaskFireAnt::Start(D3DVECTOR impact) +{ + D3DVECTOR pos; + ObjectType type; + + m_impact = impact; + + m_bError = TRUE; // operation impossible + if ( !m_physics->RetLand() ) return ERR_FIRE_VEH; + + type = m_object->RetType(); + if ( type != OBJECT_ANT ) return ERR_FIRE_VEH; + + // Insect on its back? + if ( m_object->RetFixed() ) return ERR_FIRE_VEH; + + m_physics->SetMotorSpeed(D3DVECTOR(0.0f, 0.0f, 0.0f)); + + pos = m_object->RetPosition(0); + m_angle = RotateAngle(m_impact.x-pos.x, pos.z-m_impact.z); // CW ! + + m_phase = TFA_TURN; + m_speed = 1.0f/1.0f; + m_progress = 0.0f; + m_time = 0.0f; + m_lastParticule = 0.0f; + m_bError = FALSE; // ok + m_bFire = FALSE; // once! + + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskFireAnt::IsEnded() +{ + D3DMATRIX* mat; + D3DVECTOR pos, speed; + FPOINT dim; + float angle, dist; + int i, channel; + + if ( m_engine->RetPause() ) return ERR_CONTINUE; + if ( m_bError ) return ERR_STOP; + if ( m_object->RetFixed() ) return ERR_STOP; // insect on its back? + + if ( m_phase == TFA_TURN ) // rotation ? + { + angle = m_object->RetAngleY(0); + angle = NormAngle(angle); // 0..2*PI + if ( !TestAngle(angle, m_angle-PI*0.05f, m_angle+PI*0.05f) ) return ERR_CONTINUE; + + m_physics->SetMotorSpeedZ(0.0f); // rotation ended + + m_phase = TFA_PREPARE; +//? m_speed = 1.0f/1.5f; + m_speed = 1.0f/0.4f; + m_progress = 0.0f; +//? m_motion->SetAction(MAS_PREPARE, 1.5f); + m_motion->SetAction(MAS_PREPARE, 0.4f); + } + + if ( m_phase == TFA_PREPARE ) // preparation? + { + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + m_phase = TFA_FIRE; +//? m_speed = 1.0f/2.0f; + m_speed = 1.0f/0.5f; + m_progress = 0.0f; +//? m_motion->SetAction(MAS_FIRE, 2.0f); + m_motion->SetAction(MAS_FIRE, 0.5f); + } + + if ( m_phase == TFA_FIRE ) // shooting? + { + if ( m_progress > 0.75f && !m_bFire ) + { + m_bFire = TRUE; // once + + for ( i=0 ; i<20 ; i++ ) + { + pos = D3DVECTOR(-2.5f, -0.7f, 0.0f); + mat = m_object->RetWorldMatrix(2); + pos = Transform(*mat, pos); + dist = Length(pos, m_impact); + speed = m_impact-pos; + speed.x += (Rand()-0.5f)*dist*1.2f; + speed.y += (Rand()-0.5f)*dist*0.4f+50.0f; + speed.z += (Rand()-0.5f)*dist*1.2f; + dim.x = 1.0f; + dim.y = dim.x; + channel = m_particule->CreateParticule(pos, speed, dim, PARTIGUN2, 2.0f, 100.0f, 0.0f); + m_particule->SetObjectFather(channel, m_object); + } + } + + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + m_phase = TFA_TERMINATE; +//? m_speed = 1.0f/0.9f; + m_speed = 1.0f/0.4f; + m_progress = 0.0f; +//? m_motion->SetAction(MAS_TERMINATE, 0.9f); + m_motion->SetAction(MAS_TERMINATE, 0.4f); + } + + if ( m_phase == TFA_TERMINATE ) // ends? + { + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + m_phase = TFA_NULL; + m_speed = 1.0f/1.0f; + m_progress = 0.0f; + } + + Abort(); + return ERR_STOP; +} + + +// Suddenly ends the current action. + +BOOL CTaskFireAnt::Abort() +{ + m_motion->SetAction(-1); + return TRUE; +} + diff --git a/src/object/task/taskfireant.h b/src/object/task/taskfireant.h new file mode 100644 index 0000000..2504241 --- /dev/null +++ b/src/object/task/taskfireant.h @@ -0,0 +1,72 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskfireant.h + +#ifndef _TASKFIREANT_H_ +#define _TASKTIREANT_H_ + + +#include "d3dengine.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + + +enum TaskFireAnt +{ + TFA_NULL = 0, // nothing to do + TFA_TURN = 1, // turns + TFA_PREPARE = 2, // prepares shooting position + TFA_FIRE = 3, // shooting + TFA_TERMINATE = 4, // ends shooting position +}; + + + +class CTaskFireAnt : public CTask +{ +public: + CTaskFireAnt(CInstanceManager* iMan, CObject* object); + ~CTaskFireAnt(); + + BOOL EventProcess(const Event &event); + + Error Start(D3DVECTOR impact); + Error IsEnded(); + BOOL Abort(); + +protected: + +protected: + D3DVECTOR m_impact; + TaskFireAnt m_phase; + float m_progress; + float m_speed; + float m_angle; + BOOL m_bError; + BOOL m_bFire; + float m_time; + float m_lastParticule; +}; + + +#endif //_TASKFIREANT_H_ diff --git a/src/object/task/taskflag.cpp b/src/object/task/taskflag.cpp new file mode 100644 index 0000000..b965d08 --- /dev/null +++ b/src/object/task/taskflag.cpp @@ -0,0 +1,321 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskflag.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "terrain.h" +#include "water.h" +#include "object.h" +#include "pyro.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "motion.h" +#include "motionhuman.h" +#include "sound.h" +#include "task.h" +#include "taskflag.h" + + + + + +// Object's constructor. + +CTaskFlag::CTaskFlag(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); +} + +// Object's destructor. + +CTaskFlag::~CTaskFlag() +{ +} + + +// Management of an event. + +BOOL CTaskFlag::EventProcess(const Event &event) +{ + if ( m_bError ) return TRUE; + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_time += event.rTime; + + return TRUE; +} + + + +// Assigns the goal was achieved. + +Error CTaskFlag::Start(TaskFlagOrder order, int rank) +{ + D3DVECTOR pos, speed; + Error err; + + m_order = order; + m_time = 0.0f; + + m_bError = TRUE; // operation impossible + if ( !m_physics->RetLand() ) + { + pos = m_object->RetPosition(0); + if ( pos.y < m_water->RetLevel() ) return ERR_FLAG_WATER; + return ERR_FLAG_FLY; + } + + speed = m_physics->RetMotorSpeed(); + if ( speed.x != 0.0f || + speed.z != 0.0f ) return ERR_FLAG_MOTOR; + + if ( m_object->RetFret() != 0 ) return ERR_FLAG_BUSY; + + if ( order == TFL_CREATE ) + { + err = CreateFlag(rank); + if ( err != ERR_OK ) return err; + } + + if ( order == TFL_DELETE ) + { + err = DeleteFlag(); + if ( err != ERR_OK ) return err; + } + + m_bError = FALSE; + + m_motion->SetAction(MHS_FLAG); // sets/removes flag + m_camera->StartCentering(m_object, PI*0.3f, 99.9f, 0.0f, 0.5f); + + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskFlag::IsEnded() +{ + if ( m_engine->RetPause() ) return ERR_CONTINUE; + + if ( m_bError ) return ERR_STOP; + if ( m_time < 2.0f ) return ERR_CONTINUE; + + Abort(); + return ERR_STOP; +} + +// Suddenly ends the current action. + +BOOL CTaskFlag::Abort() +{ + m_motion->SetAction(-1); + m_camera->StopCentering(m_object, 2.0f); + return TRUE; +} + + + +// Returns the closest object to a given position. + +CObject* CTaskFlag::SearchNearest(D3DVECTOR pos, ObjectType type) +{ + ObjectType oType; + CObject *pObj, *pBest; + D3DVECTOR oPos; + float min, dist; + int i; + + min = 100000.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetEnable() ) continue; + + oType = pObj->RetType(); + if ( type == OBJECT_NULL ) + { + if ( oType != OBJECT_FLAGb && + oType != OBJECT_FLAGr && + oType != OBJECT_FLAGg && + oType != OBJECT_FLAGy && + oType != OBJECT_FLAGv ) continue; + } + else + { + if ( oType != type ) continue; + } + + oPos = pObj->RetPosition(0); + dist = Length2d(oPos, pos); + if ( dist < min ) + { + min = dist; + pBest = pObj; + } + } + return pBest; +} + +// Counts the number of existing objects. + +int CTaskFlag::CountObject(ObjectType type) +{ + ObjectType oType; + CObject *pObj; + D3DVECTOR oPos; + int i, count; + + count = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetEnable() ) continue; + + oType = pObj->RetType(); + if ( type == OBJECT_NULL ) + { + if ( oType != OBJECT_FLAGb && + oType != OBJECT_FLAGr && + oType != OBJECT_FLAGg && + oType != OBJECT_FLAGy && + oType != OBJECT_FLAGv ) continue; + } + else + { + if ( oType != type ) continue; + } + + count ++; + } + return count; +} + +// Creates a color indicator. + +Error CTaskFlag::CreateFlag(int rank) +{ + CObject* pObj; + CObject* pNew; + CPyro* pyro; + D3DMATRIX* mat; + D3DVECTOR pos; + float dist; + int i; + + ObjectType table[5] = + { + OBJECT_FLAGb, + OBJECT_FLAGr, + OBJECT_FLAGg, + OBJECT_FLAGy, + OBJECT_FLAGv, + }; + + mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, D3DVECTOR(4.0f, 0.0f, 0.0f)); + + pObj = SearchNearest(pos, OBJECT_NULL); + if ( pObj != 0 ) + { + dist = Length(pos, pObj->RetPosition(0)); + if ( dist < 10.0f ) + { + return ERR_FLAG_PROXY; + } + } + + i = rank; + if ( CountObject(table[i]) >= 5 ) + { + return ERR_FLAG_CREATE; + } + + pNew = new CObject(m_iMan); + if ( !pNew->CreateFlag(pos, 0.0f, table[i]) ) + { + delete pNew; + return ERR_TOOMANY; + } + pNew->SetZoom(0, 0.0f); + + m_sound->Play(SOUND_WAYPOINT, pos); + pyro = new CPyro(m_iMan); + pyro->Create(PT_FLCREATE, pNew); + + return ERR_OK; +} + +// Deletes a color indicator. + +Error CTaskFlag::DeleteFlag() +{ + CObject* pObj; + CPyro* pyro; + D3DVECTOR iPos, oPos; + float iAngle, angle, aLimit, dist; + + iPos = m_object->RetPosition(0); + iAngle = m_object->RetAngleY(0); + iAngle = NormAngle(iAngle); // 0..2*PI + + pObj = SearchNearest(iPos, OBJECT_NULL); + if ( pObj == 0 ) + { + return ERR_FLAG_DELETE; + } + dist = Length(iPos, pObj->RetPosition(0)); + if ( dist > 10.0f ) + { + return ERR_FLAG_DELETE; + } + + oPos = pObj->RetPosition(0); + angle = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! + aLimit = 45.0f*PI/180.0f; + if ( !TestAngle(angle, iAngle-aLimit, iAngle+aLimit) ) + { + return ERR_FLAG_DELETE; + } + + m_sound->Play(SOUND_WAYPOINT, iPos); + pyro = new CPyro(m_iMan); + pyro->Create(PT_FLDELETE, pObj); + + return ERR_OK; +} + diff --git a/src/object/task/taskflag.h b/src/object/task/taskflag.h new file mode 100644 index 0000000..aa979f8 --- /dev/null +++ b/src/object/task/taskflag.h @@ -0,0 +1,66 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. +// taskflag.h + +#ifndef _TASKFLAG_H_ +#define _TASKFLAG_H_ + + +#include "misc.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + + +enum TaskFlagOrder +{ + TFL_CREATE = 0, // sets + TFL_DELETE = 1, // removes +}; + + + +class CTaskFlag : public CTask +{ +public: + CTaskFlag(CInstanceManager* iMan, CObject* object); + ~CTaskFlag(); + + BOOL EventProcess(const Event &event); + + Error Start(TaskFlagOrder order, int rank); + Error IsEnded(); + BOOL Abort(); + +protected: + Error CreateFlag(int rank); + Error DeleteFlag(); + CObject* SearchNearest(D3DVECTOR pos, ObjectType type); + int CountObject(ObjectType type); + +protected: + TaskFlagOrder m_order; + float m_time; + BOOL m_bError; +}; + + +#endif //_TASKFLAG_H_ diff --git a/src/object/task/taskgoto.cpp b/src/object/task/taskgoto.cpp new file mode 100644 index 0000000..a6c836f --- /dev/null +++ b/src/object/task/taskgoto.cpp @@ -0,0 +1,2352 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskgoto.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "terrain.h" +#include "water.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "task.h" +#include "taskgoto.h" + + + +#define FLY_DIST_GROUND 80.0f // minimum distance to remain on the ground +#define FLY_DEF_HEIGHT 50.0f // default flying height +#define BM_DIM_STEP 5.0f + + + + +// Object's constructor. + +CTaskGoto::CTaskGoto(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); + + m_bmArray = 0; +} + +// Object's destructor. + +CTaskGoto::~CTaskGoto() +{ + BitmapClose(); +} + + +// Management of an event. + +BOOL CTaskGoto::EventProcess(const Event &event) +{ + D3DVECTOR pos, goal; + FPOINT rot, repulse; + float a, g, dist, linSpeed, cirSpeed, h, hh, factor, dir; + Error ret; + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + // Momentarily stationary object (ant on the back)? + if ( m_object->RetFixed() ) + { + m_physics->SetMotorSpeedX(0.0f); // stops the advance + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + return TRUE; + } + + if ( m_error != ERR_OK ) return FALSE; + + if ( m_bWorm ) + { + WormFrame(event.rTime); + } + + if ( m_phase == TGP_BEAMLEAK ) // leak? + { + m_leakTime += event.rTime; + + pos = m_object->RetPosition(0); + + rot.x = m_leakPos.x-pos.x; + rot.y = m_leakPos.z-pos.z; + dist = Length(rot.x, rot.y); + rot.x /= dist; + rot.y /= dist; + + a = m_object->RetAngleY(0); + g = RotateAngle(rot.x, -rot.y); // CW ! + a = Direction(a, g)*1.0f; + cirSpeed = a; + if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; + if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; + + a = NormAngle(a); + if ( a > PI*0.5f && a < PI*1.5f ) + { + linSpeed = 1.0f; // obstacle behind -> advance + cirSpeed = -cirSpeed; + } + else + { + linSpeed = -1.0f; // obstacle in front -> back + } + + if ( m_bLeakRecede ) + { + linSpeed = -1.0f; + cirSpeed = 0.0f; + } + + m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right + m_physics->SetMotorSpeedX(linSpeed); // advance + return TRUE; + } + + if ( m_phase == TGP_BEAMSEARCH ) // search path? + { + if ( m_bmStep == 0 ) + { + // Frees the area around the departure. + BitmapClearCircle(m_object->RetPosition(0), BM_DIM_STEP*1.8f); + } + + pos = m_object->RetPosition(0); + + if ( m_bmFretObject == 0 ) + { + goal = m_goal; + dist = 0.0f; + } + else + { + goal = m_goalObject; + dist = TAKE_DIST+2.0f; + if ( m_bmFretObject->RetType() == OBJECT_BASE ) dist = 12.0f; + } + + ret = BeamSearch(pos, goal, dist); + if ( ret == ERR_OK ) + { +#if 0 + D3DVECTOR min, max; + min = pos; + max = m_goal; + if ( min.x > max.x ) Swap(min.x, max.x); + if ( min.z > max.z ) Swap(min.z, max.z); + min.x -= 50.0f; + min.z -= 50.0f; + max.x += 50.0f; + max.z += 50.0f; + BitmapDebug(min, max, m_object->RetPosition(0), m_goal); +#endif + if ( m_physics->RetLand() ) m_phase = TGP_BEAMWCOLD; + else m_phase = TGP_BEAMGOTO; + m_bmIndex = 0; + m_bmWatchDogPos = m_object->RetPosition(0); + m_bmWatchDogTime = 0.0f; + } + if ( ret == ERR_GOTO_IMPOSSIBLE || ret == ERR_GOTO_ITER ) + { +#if 0 + D3DVECTOR min, max; + min = pos; + max = m_goal; + if ( min.x > max.x ) Swap(min.x, max.x); + if ( min.z > max.z ) Swap(min.z, max.z); + min.x -= 50.0f; + min.z -= 50.0f; + max.x += 50.0f; + max.z += 50.0f; + BitmapDebug(min, max, m_object->RetPosition(0), m_goal); +#endif + m_error = ret; + return FALSE; + } + return TRUE; + } + + if ( m_phase == TGP_BEAMWCOLD ) // expects cooled reactor? + { + return TRUE; + } + + if ( m_phase == TGP_BEAMUP ) // off? + { + m_physics->SetMotorSpeedY(1.0f); // up + return TRUE; + } + + if ( m_phase == TGP_BEAMGOTO ) // goto dot list? (?) + { + if ( m_physics->RetCollision() ) // collision? + { + m_physics->SetCollision(FALSE); // there's more + } + + pos = m_object->RetPosition(0); + + if ( m_physics->RetType() == TYPE_FLYING && m_altitude == 0.0f ) + { + if ( m_physics->RetLand() ) + { + m_physics->SetMotorSpeedY(0.0f); + } + else + { + m_physics->SetMotorSpeedY(-1.0f); + } + } + + if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f ) + { + goal = m_bmPoints[m_bmIndex]; + goal.y = pos.y; + h = m_terrain->RetFloorHeight(goal, TRUE, TRUE); + dist = Length2d(pos, goal); + if ( dist != 0.0f ) // anticipates? + { + linSpeed = m_physics->RetLinMotionX(MO_REASPEED); + linSpeed /= m_physics->RetLinMotionX(MO_ADVSPEED); + goal.x = pos.x + (goal.x-pos.x)*linSpeed*20.0f/dist; + goal.z = pos.z + (goal.z-pos.z)*linSpeed*20.0f/dist; + } + goal.y = pos.y; + hh = m_terrain->RetFloorHeight(goal, TRUE, TRUE); + h = Min(h, hh); + linSpeed = 0.0f; + if ( h < m_altitude-1.0f ) + { + linSpeed = 0.2f+((m_altitude-1.0f)-h)*0.1f; // up + if ( linSpeed > 1.0f ) linSpeed = 1.0f; + } + if ( h > m_altitude+1.0f ) + { + linSpeed = -0.2f; // down + } + m_physics->SetMotorSpeedY(linSpeed); + } + + rot.x = m_bmPoints[m_bmIndex].x-pos.x; + rot.y = m_bmPoints[m_bmIndex].z-pos.z; + dist = Length(rot.x, rot.y); + rot.x /= dist; + rot.y /= dist; + + a = m_object->RetAngleY(0); + g = RotateAngle(rot.x, -rot.y); // CW ! + cirSpeed = Direction(a, g)*2.0f; + if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; + if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; + if ( dist < 4.0f ) cirSpeed *= dist/4.0f; // so close -> turns less + + if ( m_bmIndex == m_bmTotal ) // last point? + { + linSpeed = dist/(m_physics->RetLinStopLength()*1.5f); + if ( linSpeed > 1.0f ) linSpeed = 1.0f; + } + else + { + linSpeed = 1.0f; // dark without stopping + } + + linSpeed *= 1.0f-(1.0f-0.3f)*Abs(cirSpeed); + +//? if ( dist < 20.0f && Abs(cirSpeed) >= 0.5f ) + if ( Abs(cirSpeed) >= 0.2f ) + { + linSpeed = 0.0f; // turns first, then advance + } + + dist = Length2d(pos, m_bmWatchDogPos); + if ( dist < 1.0f && linSpeed != 0.0f ) + { + m_bmWatchDogTime += event.rTime; + } + else + { + m_bmWatchDogTime = 0.0f; + m_bmWatchDogPos = pos; + } + + if ( m_bmWatchDogTime >= 1.0f ) // immobile for a long time? + { + m_physics->SetMotorSpeedX(0.0f); // stops the advance + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + BeamStart(); // we start all + return TRUE; + } + + m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right + m_physics->SetMotorSpeedX(linSpeed); // advance + return TRUE; + } + + if ( m_phase == TGP_BEAMDOWN ) // landed? + { + m_physics->SetMotorSpeedY(-0.5f); // tomb + return TRUE; + } + + if ( m_phase == TGP_LAND ) // landed? + { + m_physics->SetMotorSpeedY(-0.5f); // tomb + return TRUE; + } + + if ( m_goalMode == TGG_EXPRESS ) + { + if ( m_crashMode == TGC_HALT ) + { + if ( m_physics->RetCollision() ) // collision? + { + m_physics->SetCollision(FALSE); // there's more + m_error = ERR_STOP; + return TRUE; + } + } + + pos = m_object->RetPosition(0); + + if ( m_altitude > 0.0f ) + { + h = m_terrain->RetFloorHeight(pos, TRUE, TRUE); + linSpeed = 0.0f; + if ( h < m_altitude ) + { + linSpeed = 0.1f; // up + } + if ( h > m_altitude ) + { + linSpeed = -0.2f; // down + } + m_physics->SetMotorSpeedY(linSpeed); + } + + rot.x = m_goal.x-pos.x; + rot.y = m_goal.z-pos.z; + a = m_object->RetAngleY(0); + g = RotateAngle(rot.x, -rot.y); // CW ! + cirSpeed = Direction(a, g)*1.0f; + if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; + if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; + + m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right + m_physics->SetMotorSpeedX(1.0f); // advance + return TRUE; + } + + if ( m_phase != TGP_TURN && + m_physics->RetType() == TYPE_FLYING && + m_altitude > 0.0f ) + { + pos = m_object->RetPosition(0); + dist = Length2d(m_goal, pos); + factor = (dist-20.0f)/20.0f; + if ( factor < 0.0f ) factor = 0.0f; + if ( factor > 1.0f ) factor = 1.0f; + + h = m_terrain->RetFloorHeight(m_object->RetPosition(0), TRUE, TRUE); + linSpeed = 0.0f; + if ( h < (m_altitude-0.5f)*factor && factor == 1.0f ) + { + linSpeed = 0.1f; // up + } + if ( h > m_altitude*factor ) + { + linSpeed = -0.2f; // down + } + ComputeFlyingRepulse(dir); + linSpeed += dir*0.2f; + + m_physics->SetMotorSpeedY(linSpeed); + } + + if ( m_phase == TGP_ADVANCE ) // going towards the goal? + { + if ( m_physics->RetCollision() ) // collision? + { + m_physics->SetCollision(FALSE); // there's more + m_time = 0.0f; + m_phase = TGP_CRWAIT; + return TRUE; + } + +#if 0 + pos = m_object->RetPosition(0); + a = m_object->RetAngleY(0); + g = RotateAngle(m_goal.x-pos.x, pos.z-m_goal.z); // CW ! + cirSpeed = Direction(a, g)*1.0f; + if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; + if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; + + dist = Length2d(m_goal, pos); + linSpeed = dist/(m_physics->RetLinStopLength()*1.5f); + if ( linSpeed > 1.0f ) linSpeed = 1.0f; + + if ( dist < 20.0f && Abs(cirSpeed) >= 0.5f ) + { + linSpeed = 0.0f; // turns first, then advance + } +#else + pos = m_object->RetPosition(0); + + rot.x = m_goal.x-pos.x; + rot.y = m_goal.z-pos.z; + dist = Length(rot.x, rot.y); + rot.x /= dist; + rot.y /= dist; + + ComputeRepulse(repulse); + rot.x += repulse.x*2.0f; + rot.y += repulse.y*2.0f; + + a = m_object->RetAngleY(0); + g = RotateAngle(rot.x, -rot.y); // CW ! + cirSpeed = Direction(a, g)*1.0f; +//? if ( m_physics->RetType() == TYPE_FLYING && +//? m_physics->RetLand() ) // flying on the ground? +//? { +//? cirSpeed *= 4.0f; // more fishing +//? } + if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; + if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; + + dist = Length2d(m_goal, pos); + linSpeed = dist/(m_physics->RetLinStopLength()*1.5f); +//? if ( m_physics->RetType() == TYPE_FLYING && +//? m_physics->RetLand() ) // flying on the ground? +//? { +//? linSpeed *= 8.0f; // more fishing +//? } + if ( linSpeed > 1.0f ) linSpeed = 1.0f; + + linSpeed *= 1.0f-(1.0f-0.3f)*Abs(cirSpeed); + + if ( dist < 20.0f && Abs(cirSpeed) >= 0.5f ) + { + linSpeed = 0.0f; // turns first, then advance + } +#endif + + m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right + m_physics->SetMotorSpeedX(linSpeed); // advance + } + + if ( m_phase == TGP_TURN || // turns to the object? + m_phase == TGP_CRTURN || // turns after collision? + m_phase == TGP_CLTURN ) // turns after collision? + { + a = m_object->RetAngleY(0); + g = m_angle; + cirSpeed = Direction(a, g)*1.0f; + if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; + if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; + + m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right + } + + if ( m_phase == TGP_CRWAIT || // waits after collision? + m_phase == TGP_CLWAIT ) // waits after collision? + { + m_time += event.rTime; + m_physics->SetMotorSpeedX(0.0f); // stops the advance + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + } + + if ( m_phase == TGP_CRADVANCE ) // advance after collision? + { + if ( m_physics->RetCollision() ) // collision? + { + m_physics->SetCollision(FALSE); // there's more + m_time = 0.0f; + m_phase = TGP_CLWAIT; + return TRUE; + } + m_physics->SetMotorSpeedX(0.5f); // advance mollo + } + + if ( m_phase == TGP_CLADVANCE ) // advance after collision? + { + if ( m_physics->RetCollision() ) // collision? + { + m_physics->SetCollision(FALSE); // there's more + m_time = 0.0f; + m_phase = TGP_CRWAIT; + return TRUE; + } + m_physics->SetMotorSpeedX(0.5f); // advance mollo + } + + if ( m_phase == TGP_MOVE ) // final advance? + { + m_bmTimeLimit -= event.rTime; + m_physics->SetMotorSpeedX(1.0f); + } + + return TRUE; +} + + +// Sought a target for the worm. + +CObject* CTaskGoto::WormSearch(D3DVECTOR &impact) +{ + CObject* pObj; + CObject* pBest = 0; + D3DVECTOR iPos, oPos; + ObjectType oType; + float distance, min, radius; + int i; + + iPos = m_object->RetPosition(0); + min = 1000000.0f; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( oType != OBJECT_MOBILEfa && + oType != OBJECT_MOBILEta && + oType != OBJECT_MOBILEwa && + oType != OBJECT_MOBILEia && + oType != OBJECT_MOBILEfc && + oType != OBJECT_MOBILEtc && + oType != OBJECT_MOBILEwc && + oType != OBJECT_MOBILEic && + oType != OBJECT_MOBILEfi && + oType != OBJECT_MOBILEti && + oType != OBJECT_MOBILEwi && + oType != OBJECT_MOBILEii && + oType != OBJECT_MOBILEfs && + oType != OBJECT_MOBILEts && + oType != OBJECT_MOBILEws && + oType != OBJECT_MOBILEis && + oType != OBJECT_MOBILErt && + oType != OBJECT_MOBILErc && + oType != OBJECT_MOBILErr && + oType != OBJECT_MOBILErs && + oType != OBJECT_MOBILEsa && + oType != OBJECT_MOBILEtg && + oType != OBJECT_MOBILEft && + oType != OBJECT_MOBILEtt && + oType != OBJECT_MOBILEwt && + oType != OBJECT_MOBILEit && + oType != OBJECT_MOBILEdr && + oType != OBJECT_DERRICK && + oType != OBJECT_STATION && + oType != OBJECT_FACTORY && + oType != OBJECT_REPAIR && + oType != OBJECT_DESTROYER && + oType != OBJECT_CONVERT && + oType != OBJECT_TOWER && + oType != OBJECT_RESEARCH && + oType != OBJECT_RADAR && + oType != OBJECT_INFO && + oType != OBJECT_ENERGY && + oType != OBJECT_LABO && + oType != OBJECT_NUCLEAR && + oType != OBJECT_PARA && + oType != OBJECT_SAFE && + oType != OBJECT_HUSTON ) continue; + + if ( pObj->RetVirusMode() ) continue; // object infected? + + if ( !pObj->GetCrashSphere(0, oPos, radius) ) continue; + distance = Length2d(oPos, iPos); + if ( distance < min ) + { + min = distance; + pBest = pObj; + } + } + if ( pBest == 0 ) return 0; + + impact = pBest->RetPosition(0); + return pBest; +} + +// Contaminate objects near the worm. + +void CTaskGoto::WormFrame(float rTime) +{ + CObject* pObj; + D3DVECTOR impact, pos; + float dist; + + m_wormLastTime += rTime; + + if ( m_wormLastTime >= 0.5f ) + { + m_wormLastTime = 0.0f; + + pObj = WormSearch(impact); + if ( pObj != 0 ) + { + pos = m_object->RetPosition(0); + dist = Length(pos, impact); + if ( dist <= 15.0f ) + { + pObj->SetVirusMode(TRUE); // bam, infected! + } + } + } +} + + + +// Assigns the goal was achieved. +// "dist" is the distance that needs to go far to make a deposit or object. + +Error CTaskGoto::Start(D3DVECTOR goal, float altitude, + TaskGotoGoal goalMode, TaskGotoCrash crashMode) +{ + D3DVECTOR pos; + CObject* target; + ObjectType type; + float dist; + int x, y; + + type = m_object->RetType(); + + if ( goalMode == TGG_DEFAULT ) + { + goalMode = TGG_STOP; + if ( type == OBJECT_MOTHER || + type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_WORM ) + { + goalMode = TGG_EXPRESS; + } + } + + if ( crashMode == TGC_DEFAULT ) + { +//? crashMode = TGC_RIGHTLEFT; + crashMode = TGC_BEAM; + if ( type == OBJECT_MOTHER || + type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_WORM || + type == OBJECT_BEE ) + { + crashMode = TGC_HALT; + } + } + + m_altitude = altitude; + m_goalMode = goalMode; + m_crashMode = crashMode; + m_goalObject = goal; + m_goal = goal; + + m_bTake = FALSE; + m_phase = TGP_ADVANCE; + m_error = ERR_OK; + m_try = 0; + m_bmFretObject = 0; + m_bmFinalMove = 0.0f; + + pos = m_object->RetPosition(0); + dist = Length2d(pos, m_goal); + if ( dist < 10.0f && m_crashMode == TGC_BEAM ) + { + m_crashMode = TGC_RIGHTLEFT; + } + + m_bWorm = FALSE; + if ( type == OBJECT_WORM ) + { + m_bWorm = TRUE; + m_wormLastTime = 0.0f; + } + + m_bApprox = FALSE; + if ( type == OBJECT_HUMAN || + type == OBJECT_TECH || + type == OBJECT_MOTHER || + type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_BEE || + type == OBJECT_WORM || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) + { + m_bApprox = TRUE; + } + + if ( !m_bApprox && m_crashMode != TGC_BEAM ) + { + target = SearchTarget(goal, 1.0f); + if ( target != 0 ) + { + m_goal = target->RetPosition(0); + dist = 0.0f; + if ( !AdjustBuilding(m_goal, 1.0f, dist) ) + { + dist = 0.0f; + AdjustTarget(target, m_goal, dist); + } + m_bTake = TRUE; // object was taken on arrival (final rotation) + } + } + + m_lastDistance = 1000.0f; + m_physics->SetCollision(FALSE); + + if ( m_crashMode == TGC_BEAM ) // with the algorithm of rays? + { + target = SearchTarget(goal, 1.0f); + if ( target != 0 ) + { + m_goal = target->RetPosition(0); + dist = 4.0f; + if ( AdjustBuilding(m_goal, 1.0f, dist) ) + { + m_bmFinalMove = dist; + } + else + { + dist = 4.0f; + if ( AdjustTarget(target, m_goal, dist) ) + { + m_bmFretObject = target; // cargo on the ground + } + else + { + m_bmFinalMove = dist; + } + } + m_bTake = TRUE; // object was taken on arrival (final rotation) + } + + if ( m_physics->RetType() == TYPE_FLYING && m_altitude == 0.0f ) + { + pos = m_object->RetPosition(0); + dist = Length2d(pos, m_goal); + if ( dist > FLY_DIST_GROUND ) // over 20 meters? + { + m_altitude = FLY_DEF_HEIGHT; // default altitude + } + } + + BeamStart(); + + if ( m_bmFretObject == 0 ) + { + x = (int)((m_goal.x+1600.0f)/BM_DIM_STEP); + y = (int)((m_goal.z+1600.0f)/BM_DIM_STEP); + if ( BitmapTestDot(0, x, y) ) // arrival occupied? + { +#if 0 + D3DVECTOR min, max; + min = m_object->RetPosition(0); + max = m_goal; + if ( min.x > max.x ) Swap(min.x, max.x); + if ( min.z > max.z ) Swap(min.z, max.z); + min.x -= 50.0f; + min.z -= 50.0f; + max.x += 50.0f; + max.z += 50.0f; + BitmapDebug(min, max, m_object->RetPosition(0), m_goal); +#endif + m_error = ERR_GOTO_BUSY; + return m_error; + } + } + } + + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskGoto::IsEnded() +{ + D3DVECTOR pos; + float limit, angle, dist, h, level; + + if ( m_engine->RetPause() ) return ERR_CONTINUE; + if ( m_error != ERR_OK ) return m_error; + + pos = m_object->RetPosition(0); + + if ( m_phase == TGP_BEAMLEAK ) // leak? + { + if ( m_leakTime >= m_leakDelay ) + { + m_physics->SetMotorSpeedX(0.0f); // stops the advance + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + BeamInit(); + m_phase = TGP_BEAMSEARCH; // will seek the path + } + return ERR_CONTINUE; + } + + if ( m_phase == TGP_BEAMSEARCH ) // search path? + { + return ERR_CONTINUE; + } + + if ( m_phase == TGP_BEAMWCOLD ) // expects cool reactor? + { + if ( m_altitude != 0.0f && + m_physics->RetReactorRange() < 1.0f ) return ERR_CONTINUE; + m_phase = TGP_BEAMUP; + } + + if ( m_phase == TGP_BEAMUP ) // off? + { + if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f ) + { + level = m_terrain->RetFloorLevel(pos, TRUE, TRUE); + h = level+m_altitude-20.0f; + limit = m_terrain->RetFlyingMaxHeight(); + if ( h > limit ) h = limit; + if ( pos.y < h-1.0f ) return ERR_CONTINUE; + + m_physics->SetMotorSpeedY(0.0f); // stops the ascent + } + m_phase = TGP_BEAMGOTO; + } + + if ( m_phase == TGP_BEAMGOTO ) // goto dot list ? + { + if ( m_altitude != 0.0f && + m_physics->RetReactorRange() < 0.1f ) // overheating? + { + m_physics->SetMotorSpeedX(0.0f); // stops the advance + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + m_physics->SetMotorSpeedY(-1.0f); // tomb + m_phase = TGP_BEAMWCOLD; + return ERR_CONTINUE; + } + + if ( m_physics->RetLand() ) // on the ground? + { + limit = 1.0f; + } + else // in flight? + { + limit = 2.0f; + if ( m_bmIndex < m_bmTotal ) limit *= 2.0f; // intermediate point + } + if ( m_bApprox ) limit = 2.0f; + + if ( Abs(pos.x - m_bmPoints[m_bmIndex].x) < limit && + Abs(pos.z - m_bmPoints[m_bmIndex].z) < limit ) + { + m_physics->SetMotorSpeedX(0.0f); // stops the advance + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + + m_bmIndex = BeamShortcut(); + + if ( m_bmIndex > m_bmTotal ) + { + m_phase = TGP_BEAMDOWN; + } + } + } + + if ( m_phase == TGP_BEAMDOWN ) // landed? + { + if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f ) + { + if ( !m_physics->RetLand() ) return ERR_CONTINUE; + m_physics->SetMotorSpeedY(0.0f); // stops the descent + + m_altitude = 0.0f; + m_phase = TGP_BEAMGOTO; // advance finely on the ground to finish + m_bmIndex = m_bmTotal; + return ERR_CONTINUE; + } + + if ( m_bTake ) + { + m_angle = RotateAngle(m_goalObject.x-pos.x, pos.z-m_goalObject.z); + m_phase = TGP_TURN; + } + else + { + m_physics->SetMotorSpeedX(0.0f); // stops the advance + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + return ERR_STOP; + } + } + + if ( m_goalMode == TGG_EXPRESS ) + { + dist = Length2d(m_goal, pos); + if ( dist < 10.0f && dist > m_lastDistance ) + { + return ERR_STOP; + } + m_lastDistance = dist; + } + + if ( m_phase == TGP_ADVANCE ) // going towards the goal? + { + if ( m_physics->RetLand() ) limit = 0.1f; // on the ground + else limit = 1.0f; // flying + if ( m_bApprox ) limit = 2.0f; + + if ( Abs(pos.x - m_goal.x) < limit && + Abs(pos.z - m_goal.z) < limit ) + { + m_physics->SetMotorSpeedX(0.0f); // stops the advance + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + m_phase = TGP_LAND; + } + } + + if ( m_phase == TGP_LAND ) // landed? + { + if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f ) + { + if ( !m_physics->RetLand() ) return ERR_CONTINUE; + m_physics->SetMotorSpeedY(0.0f); + } + + if ( m_bTake ) + { + m_angle = RotateAngle(m_goalObject.x-pos.x, pos.z-m_goalObject.z); + m_phase = TGP_TURN; + } + else + { + return ERR_STOP; + } + } + + if ( m_phase == TGP_TURN ) // turns to the object? + { + angle = NormAngle(m_object->RetAngleY(0)); + limit = 0.02f; + if ( m_bApprox ) limit = 0.10f; + if ( Abs(angle-m_angle) < limit ) + { + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + if ( m_bmFinalMove == 0.0f ) return ERR_STOP; + + m_bmFinalPos = m_object->RetPosition(0); + m_bmFinalDist = m_physics->RetLinLength(m_bmFinalMove); + m_bmTimeLimit = m_physics->RetLinTimeLength(Abs(m_bmFinalMove))*1.5f; + if ( m_bmTimeLimit < 0.5f ) m_bmTimeLimit = 0.5f; + m_phase = TGP_MOVE; + } + } + + if ( m_phase == TGP_CRWAIT ) // waits after collision? + { + if ( m_crashMode == TGC_HALT ) + { + m_physics->SetMotorSpeedX(0.0f); // stops the advance + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + m_error = ERR_GENERIC; + return m_error; + } + if ( m_time >= 1.0f ) + { + if ( m_crashMode == TGC_RIGHTLEFT || + m_crashMode == TGC_RIGHT ) angle = PI/2.0f; // 90 deegres to the right + else angle = -PI/2.0f; // 90 deegres to the left + m_angle = NormAngle(m_object->RetAngleY(0)+angle); + m_phase = TGP_CRTURN; +//? m_phase = TGP_ADVANCE; + } + } + + if ( m_phase == TGP_CRTURN ) // turns after collision? + { + angle = NormAngle(m_object->RetAngleY(0)); + limit = 0.1f; + if ( Abs(angle-m_angle) < limit ) + { + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + m_pos = pos; + m_phase = TGP_CRADVANCE; + } + } + + if ( m_phase == TGP_CRADVANCE ) // advance after collision? + { + if ( Length(pos, m_pos) >= 5.0f ) + { + m_phase = TGP_ADVANCE; + } + } + + if ( m_phase == TGP_CLWAIT ) // waits after collision? + { + if ( m_time >= 1.0f ) + { + if ( m_crashMode == TGC_RIGHTLEFT ) angle = -PI; + if ( m_crashMode == TGC_LEFTRIGHT ) angle = PI; + if ( m_crashMode == TGC_RIGHT ) angle = PI/2.0f; + if ( m_crashMode == TGC_LEFT ) angle = -PI/2.0f; + m_angle = NormAngle(m_object->RetAngleY(0)+angle); + m_phase = TGP_CLTURN; + } + } + + if ( m_phase == TGP_CLTURN ) // turns after collision? + { + angle = NormAngle(m_object->RetAngleY(0)); + limit = 0.1f; + if ( Abs(angle-m_angle) < limit ) + { + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + m_pos = pos; + m_phase = TGP_CLADVANCE; + } + } + + if ( m_phase == TGP_CLADVANCE ) // advance after collision? + { + if ( Length(pos, m_pos) >= 10.0f ) + { + m_phase = TGP_ADVANCE; + m_try ++; + } + } + + if ( m_phase == TGP_MOVE ) // final advance? + { + if ( m_bmTimeLimit <= 0.0f ) + { + m_physics->SetMotorSpeedX(0.0f); // stops + Abort(); + return ERR_STOP; + } + + dist = Length(m_bmFinalPos, m_object->RetPosition(0)); + if ( dist < m_bmFinalDist ) return ERR_CONTINUE; + m_physics->SetMotorSpeedX(0.0f); // stops the advance + return ERR_STOP; + } + + return ERR_CONTINUE; +} + + +// Tries the object is the target position. + +CObject* CTaskGoto::SearchTarget(D3DVECTOR pos, float margin) +{ + CObject *pObj, *pBest; + D3DVECTOR oPos; + float dist, min; + int i; + + pBest = 0; + min = 1000000.0f; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetActif() ) continue; + if ( pObj->RetTruck() != 0 ) continue; // object transtorted? + + oPos = pObj->RetPosition(0); + dist = Length2d(pos, oPos); + + if ( dist <= margin && dist <= min ) + { + min = dist; + pBest = pObj; + } + } + + return pBest; +} + +// Adjusts the target as a function of the object. +// Returns TRUE if it is cargo laying on the ground, which can be approached from any site. + +BOOL CTaskGoto::AdjustTarget(CObject* pObj, D3DVECTOR &pos, float &distance) +{ + ObjectType type; + Character* character; + D3DMATRIX* mat; + D3DVECTOR goal; + float dist, suppl; + + type = m_object->RetType(); + if ( type == OBJECT_BEE || + type == OBJECT_WORM ) + { + pos = pObj->RetPosition(0); + return FALSE; // single approach + } + + type = pObj->RetType(); + + if ( type == OBJECT_FRET || + type == OBJECT_STONE || + type == OBJECT_URANIUM || + type == OBJECT_METAL || + type == OBJECT_POWER || + type == OBJECT_ATOMIC || + type == OBJECT_BULLET || + type == OBJECT_BBOX || + type == OBJECT_KEYa || + type == OBJECT_KEYb || + type == OBJECT_KEYc || + type == OBJECT_KEYd || + type == OBJECT_TNT || + type == OBJECT_SCRAP1 || + type == OBJECT_SCRAP2 || + type == OBJECT_SCRAP3 || + type == OBJECT_SCRAP4 || + type == OBJECT_SCRAP5 || + type == OBJECT_BOMB || + type == OBJECT_RUINmobilew1 || + type == OBJECT_RUINmobilew2 || + type == OBJECT_RUINmobilet1 || + type == OBJECT_RUINmobilet2 || + type == OBJECT_RUINmobiler1 || + type == OBJECT_RUINmobiler2 ) + { + pos = m_object->RetPosition(0); + goal = pObj->RetPosition(0); + dist = Length(goal, pos); + pos = (pos-goal)*(TAKE_DIST+distance)/dist + goal; + return TRUE; // approach from all sites + } + + if ( type == OBJECT_BASE ) + { + pos = m_object->RetPosition(0); + goal = pObj->RetPosition(0); + dist = Length(goal, pos); + pos = (pos-goal)*(TAKE_DIST+distance)/dist + goal; + return TRUE; // approach from all sites + } + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEtg || + type == OBJECT_MOBILEft || + type == OBJECT_MOBILEtt || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEit || + type == OBJECT_MOBILEdr ) + { + character = pObj->RetCharacter(); + pos = character->posPower; + pos.x -= TAKE_DIST+TAKE_DIST_OTHER+distance; + mat = pObj->RetWorldMatrix(0); + pos = Transform(*mat, pos); + return FALSE; // single approach + } + + if ( GetHotPoint(pObj, goal, TRUE, distance, suppl) ) + { + pos = goal; + distance += suppl; + return FALSE; // single approach + } + + pos = pObj->RetPosition(0); + distance = 0.0f; + return FALSE; // single approach +} + +// If you are on an object produced by a building (ore produced by derrick), +// changes the position by report the building. + +BOOL CTaskGoto::AdjustBuilding(D3DVECTOR &pos, float margin, float &distance) +{ + CObject* pObj; + D3DVECTOR oPos; + float dist, suppl; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetActif() ) continue; + if ( pObj->RetTruck() != 0 ) continue; // object transported? + + if ( !GetHotPoint(pObj, oPos, FALSE, 0.0f, suppl) ) continue; + dist = Length2d(pos, oPos); + if ( dist <= margin ) + { + GetHotPoint(pObj, pos, TRUE, distance, suppl); + distance += suppl; + return TRUE; + } + } + return FALSE; +} + +// Returns the item or product or pose is something on a building. + +BOOL CTaskGoto::GetHotPoint(CObject *pObj, D3DVECTOR &pos, + BOOL bTake, float distance, float &suppl) +{ + ObjectType type; + D3DMATRIX* mat; + + pos = D3DVECTOR(0.0f, 0.0f, 0.0f); + suppl = 0.0f; + type = pObj->RetType(); + + if ( type == OBJECT_DERRICK ) + { + mat = pObj->RetWorldMatrix(0); + pos.x += 8.0f; + if ( bTake && distance != 0.0f ) suppl = 4.0f; + if ( bTake ) pos.x += TAKE_DIST+distance+suppl; + pos = Transform(*mat, pos); + return TRUE; + } + + if ( type == OBJECT_CONVERT ) + { + mat = pObj->RetWorldMatrix(0); + pos.x += 0.0f; + if ( bTake && distance != 0.0f ) suppl = 4.0f; + if ( bTake ) pos.x += TAKE_DIST+distance+suppl; + pos = Transform(*mat, pos); + return TRUE; + } + + if ( type == OBJECT_RESEARCH ) + { + mat = pObj->RetWorldMatrix(0); + pos.x += 10.0f; + if ( bTake && distance != 0.0f ) suppl = 2.5f; + if ( bTake ) pos.x += TAKE_DIST+TAKE_DIST_OTHER+distance+suppl; + pos = Transform(*mat, pos); + return TRUE; + } + + if ( type == OBJECT_ENERGY ) + { + mat = pObj->RetWorldMatrix(0); + pos.x += 6.0f; + if ( bTake && distance != 0.0f ) suppl = 6.0f; + if ( bTake ) pos.x += TAKE_DIST+TAKE_DIST_OTHER+distance; + pos = Transform(*mat, pos); + return TRUE; + } + + if ( type == OBJECT_TOWER ) + { + mat = pObj->RetWorldMatrix(0); + pos.x += 5.0f; + if ( bTake && distance != 0.0f ) suppl = 4.0f; + if ( bTake ) pos.x += TAKE_DIST+TAKE_DIST_OTHER+distance+suppl; + pos = Transform(*mat, pos); + return TRUE; + } + + if ( type == OBJECT_LABO ) + { + mat = pObj->RetWorldMatrix(0); + pos.x += 6.0f; + if ( bTake && distance != 0.0f ) suppl = 6.0f; + if ( bTake ) pos.x += TAKE_DIST+TAKE_DIST_OTHER+distance; + pos = Transform(*mat, pos); + return TRUE; + } + + if ( type == OBJECT_NUCLEAR ) + { + mat = pObj->RetWorldMatrix(0); + pos.x += 22.0f; + if ( bTake && distance != 0.0f ) suppl = 4.0f; + if ( bTake ) pos.x += TAKE_DIST+TAKE_DIST_OTHER+distance+suppl; + pos = Transform(*mat, pos); + return TRUE; + } + + if ( type == OBJECT_FACTORY ) + { + mat = pObj->RetWorldMatrix(0); + pos.x += 4.0f; + if ( bTake && distance != 0.0f ) suppl = 6.0f; + if ( bTake ) pos.x += TAKE_DIST+distance+suppl; + pos = Transform(*mat, pos); + return TRUE; + } + + if ( type == OBJECT_STATION ) + { + mat = pObj->RetWorldMatrix(0); + pos.x += 4.0f; + if ( bTake && distance != 0.0f ) suppl = 4.0f; + if ( bTake ) pos.x += distance; + pos = Transform(*mat, pos); + return TRUE; + } + + if ( type == OBJECT_REPAIR ) + { + mat = pObj->RetWorldMatrix(0); + pos.x += 4.0f; + if ( bTake && distance != 0.0f ) suppl = 4.0f; + if ( bTake ) pos.x += distance; + pos = Transform(*mat, pos); + return TRUE; + } + + if ( type == OBJECT_DESTROYER ) + { + mat = pObj->RetWorldMatrix(0); + pos.x += 0.0f; + if ( bTake && distance != 0.0f ) suppl = 4.0f; + if ( bTake ) pos.x += TAKE_DIST+distance+suppl; + pos = Transform(*mat, pos); + return TRUE; + } + + if ( type == OBJECT_PARA && m_physics->RetType() == TYPE_FLYING ) + { + mat = pObj->RetWorldMatrix(0); + if ( bTake && distance != 0.0f ) suppl = 20.0f; + if ( bTake ) pos.x += distance+suppl; + pos = Transform(*mat, pos); + return TRUE; + } + + suppl = 0.0f; + return FALSE; +} + + +// Seeks an object too close that he must flee. + +BOOL CTaskGoto::LeakSearch(D3DVECTOR &pos, float &delay) +{ + CObject *pObj, *pObstacle; + D3DVECTOR iPos, oPos, bPos; + float iRadius, oRadius, bRadius, dist, min, dir; + int i, j; + + if ( !m_physics->RetLand() ) return FALSE; // in flight? + + m_object->GetCrashSphere(0, iPos, iRadius); + + min = 100000.0f; + bRadius = 0.0f; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj == m_object ) continue; + if ( !pObj->RetActif() ) continue; + if ( pObj->RetTruck() != 0 ) continue; // object transported? + + j = 0; + while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) + { + dist = Length2d(oPos, iPos); + if ( dist < min ) + { + min = dist; + bPos = oPos; + bRadius = oRadius; + pObstacle = pObj; + } + } + } + if ( min > iRadius+bRadius+4.0f ) return FALSE; + + m_bLeakRecede = FALSE; + + dist = 4.0f; + dir = 1.0f; + if ( pObstacle->RetType() == OBJECT_FACTORY ) + { + dist = 16.0f; + dir = -1.0f; + m_bLeakRecede = TRUE; // simply recoils + } + + pos = bPos; + delay = m_physics->RetLinTimeLength(dist, dir); + return TRUE; +} + + +// Calculates the force of repulsion due to obstacles. +// The vector length rendered is between 0 and 1. + +void CTaskGoto::ComputeRepulse(FPOINT &dir) +{ +#if 0 + D3DVECTOR iPos, oPos; + FPOINT repulse; + CObject *pObj; + float dist, iRadius, oRadius; + int i; + + dir.x = 0.0f; + dir.y = 0.0f; + + m_object->GetCrashSphere(0, iPos, iRadius); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj == m_object ) continue; + if ( pObj->RetTruck() != 0 ) continue; + + oPos = pObj->RetPosition(0); + dist = Length(oPos, m_goalObject); + if ( dist <= 1.0f ) continue; + + pObj->GetGlobalSphere(oPos, oRadius); + oRadius += iRadius+m_physics->RetLinStopLength()*1.1f; + dist = Length2d(oPos, iPos); + if ( dist <= oRadius ) + { + repulse.x = iPos.x-oPos.x; + repulse.y = iPos.z-oPos.z; + +//? dist = 0.2f-(0.2f*dist/oRadius); + dist = powf(dist/oRadius, 2.0f); + dist = 0.2f-0.2f*dist; + repulse.x *= dist; + repulse.y *= dist; +//? repulse.x /= dist; +//? repulse.y /= dist; + + dir.x += repulse.x; + dir.y += repulse.y; + } + } +#else + ObjectType iType, oType; + D3DVECTOR iPos, oPos; + FPOINT repulse; + CObject *pObj; + float gDist, add, addi, fac, dist, iRadius, oRadius; + int i, j; + BOOL bAlien; + + dir.x = 0.0f; + dir.y = 0.0f; + + // The worm goes everywhere and through everything! + iType = m_object->RetType(); + if ( iType == OBJECT_WORM ) return; + + m_object->GetCrashSphere(0, iPos, iRadius); + gDist = Length(iPos, m_goal); + + add = m_physics->RetLinStopLength()*1.1f; // braking distance + fac = 2.0f; + + if ( iType == OBJECT_MOBILEwa || + iType == OBJECT_MOBILEwc || + iType == OBJECT_MOBILEwi || + iType == OBJECT_MOBILEws || + iType == OBJECT_MOBILEwt ) // wheels? + { + add = 5.0f; + fac = 1.5f; + } + if ( iType == OBJECT_MOBILEta || + iType == OBJECT_MOBILEtc || + iType == OBJECT_MOBILEti || + iType == OBJECT_MOBILEts || + iType == OBJECT_MOBILEtt || + iType == OBJECT_MOBILEdr ) // caterpillars? + { + add = 4.0f; + fac = 1.5f; + } + if ( iType == OBJECT_MOBILEfa || + iType == OBJECT_MOBILEfc || + iType == OBJECT_MOBILEfi || + iType == OBJECT_MOBILEfs || + iType == OBJECT_MOBILEft ) // flying? + { + if ( m_physics->RetLand() ) + { + add = 5.0f; + fac = 1.5f; + } + else + { + add = 10.0f; + fac = 1.5f; + } + } + if ( iType == OBJECT_MOBILEia || + iType == OBJECT_MOBILEic || + iType == OBJECT_MOBILEii || + iType == OBJECT_MOBILEis || + iType == OBJECT_MOBILEit ) // legs? + { + add = 4.0f; + fac = 1.5f; + } + if ( iType == OBJECT_BEE ) // wasp? + { + if ( m_physics->RetLand() ) + { + add = 3.0f; + fac = 1.5f; + } + else + { + add = 5.0f; + fac = 1.5f; + } + } + + bAlien = FALSE; + if ( iType == OBJECT_MOTHER || + iType == OBJECT_ANT || + iType == OBJECT_SPIDER || + iType == OBJECT_BEE || + iType == OBJECT_WORM ) + { + bAlien = TRUE; + } + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj == m_object ) continue; + if ( pObj->RetTruck() != 0 ) continue; + + oType = pObj->RetType(); + + if ( oType == OBJECT_WORM ) continue; + + if ( bAlien ) + { + if ( oType == OBJECT_STONE || + oType == OBJECT_URANIUM || + oType == OBJECT_METAL || + oType == OBJECT_POWER || + oType == OBJECT_ATOMIC || + oType == OBJECT_BULLET || + oType == OBJECT_BBOX || + oType == OBJECT_KEYa || + oType == OBJECT_KEYb || + oType == OBJECT_KEYc || + oType == OBJECT_KEYd || + oType == OBJECT_TNT || + oType == OBJECT_SCRAP1 || + oType == OBJECT_SCRAP2 || + oType == OBJECT_SCRAP3 || + oType == OBJECT_SCRAP4 || + oType == OBJECT_SCRAP5 || + oType == OBJECT_BOMB || + (oType >= OBJECT_PLANT0 && + oType <= OBJECT_PLANT19 ) || + (oType >= OBJECT_MUSHROOM0 && + oType <= OBJECT_MUSHROOM9 ) ) continue; + } + + addi = add; + if ( iType == OBJECT_BEE && + oType == OBJECT_BEE ) + { + addi = 2.0f; // between wasps, do not annoy too much + } + + j = 0; + while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) + { + if ( oPos.y-oRadius > iPos.y+iRadius ) continue; + if ( oPos.y+oRadius < iPos.y-iRadius ) continue; + + dist = Length(oPos, m_goal); + if ( dist <= 1.0f ) continue; // on purpose? + + oRadius += iRadius+addi; + dist = Length2d(oPos, iPos); + if ( dist > gDist ) continue; // beyond the goal? + if ( dist <= oRadius ) + { + repulse.x = iPos.x-oPos.x; + repulse.y = iPos.z-oPos.z; + + dist = powf(dist/oRadius, fac); + dist = 0.2f-0.2f*dist; + repulse.x *= dist; + repulse.y *= dist; + + dir.x += repulse.x; + dir.y += repulse.y; + } + } + } +#endif +} + +// Calculates the force of vertical repulsion according to barriers. +// The vector length is made​between -1 and 1. + +void CTaskGoto::ComputeFlyingRepulse(float &dir) +{ + ObjectType oType; + D3DVECTOR iPos, oPos; + CObject *pObj; + float add, fac, dist, iRadius, oRadius, repulse; + int i, j; + + m_object->GetCrashSphere(0, iPos, iRadius); + + add = 0.0f; + fac = 1.5f; + dir = 0.0f; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj == m_object ) continue; + if ( pObj->RetTruck() != 0 ) continue; + + oType = pObj->RetType(); + + if ( oType == OBJECT_WORM ) continue; + + j = 0; + while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) + { + oRadius += iRadius+add; + dist = Length2d(oPos, iPos); + if ( dist <= oRadius ) + { + repulse = iPos.y-oPos.y; + + dist = powf(dist/oRadius, fac); + dist = 0.2f-0.2f*dist; + repulse *= dist; + + dir += repulse; + } + } + } + + if ( dir < -1.0f ) dir = -1.0f; + if ( dir > 1.0f ) dir = 1.0f; +} + + + +// Among all of the following, seek if there is one allowing to go directly to the crow flies. +// If yes, skip all the unnecessary intermediate points. + +int CTaskGoto::BeamShortcut() +{ + int i; + + for ( i=m_bmTotal ; i>=m_bmIndex+2 ; i-- ) // tries from the last + { + if ( BitmapTestLine(m_bmPoints[m_bmIndex], m_bmPoints[i], 0.0f, FALSE) ) + { + return i; // bingo, found + } + } + + return m_bmIndex+1; // simply goes to the next +} + +// That's the big start. + +void CTaskGoto::BeamStart() +{ + D3DVECTOR min, max; + + BitmapOpen(); + BitmapObject(); + + min = m_object->RetPosition(0); + max = m_goal; + if ( min.x > max.x ) Swap(min.x, max.x); + if ( min.z > max.z ) Swap(min.z, max.z); + min.x -= 10.0f*BM_DIM_STEP; + min.z -= 10.0f*BM_DIM_STEP; + max.x += 10.0f*BM_DIM_STEP; + max.z += 10.0f*BM_DIM_STEP; + BitmapTerrain(min, max); + + if ( LeakSearch(m_leakPos, m_leakDelay) ) + { + m_phase = TGP_BEAMLEAK; // must first leak + m_leakTime = 0.0f; + } + else + { + m_physics->SetMotorSpeedX(0.0f); // stops the advance + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + BeamInit(); + m_phase = TGP_BEAMSEARCH; // will seek the path + } +} + +// Initialization before the first BeamSearch. + +void CTaskGoto::BeamInit() +{ + int i; + + for ( i=0 ; i 20.0f ) step = 20.0f; + nbIter = 200; // in order not to lower the framerate + m_bmIterCounter = 0; + return BeamExplore(start, start, goal, goalRadius, 165.0f*PI/180.0f, 22, step, 0, nbIter); +} + +// prevPos: previous position +// curPos: current position +// goalPos: position that seeks to achieve +// angle: angle to the goal we explores +// nbDiv: number of subdivisions being done with angle +// step length of a step +// i number of recursions made +// nbIter maximum number of iterations you have the right to make before temporarily interrupt + +Error CTaskGoto::BeamExplore(const D3DVECTOR &prevPos, const D3DVECTOR &curPos, + const D3DVECTOR &goalPos, float goalRadius, + float angle, int nbDiv, float step, + int i, int nbIter) +{ + D3DVECTOR newPos; + Error ret; + int iDiv, iClear, iLar; + + iLar = 0; + if ( i >= MAXPOINTS ) return ERR_GOTO_ITER; // too many recursions + + if ( m_bmIter[i] == -1 ) + { + m_bmIter[i] = 0; + + if ( i == 0 ) + { + m_bmPoints[i] = curPos; + } + else + { + if ( !BitmapTestLine(prevPos, curPos, angle/nbDiv, TRUE) ) return ERR_GOTO_IMPOSSIBLE; + + m_bmPoints[i] = curPos; + + if ( Length2d(curPos, goalPos)-goalRadius <= step ) + { + if ( goalRadius == 0.0f ) + { + newPos = goalPos; + } + else + { + newPos = BeamPoint(curPos, goalPos, 0, Length2d(curPos, goalPos)-goalRadius); + } + if ( BitmapTestLine(curPos, newPos, angle/nbDiv, FALSE) ) + { + m_bmPoints[i+1] = newPos; + m_bmTotal = i+1; + return ERR_OK; + } + } + } + } + + if ( iLar >= m_bmIter[i] ) + { + newPos = BeamPoint(curPos, goalPos, 0, step); + ret = BeamExplore(curPos, newPos, goalPos, goalRadius, angle, nbDiv, step, i+1, nbIter); + if ( ret != ERR_GOTO_IMPOSSIBLE ) return ret; + m_bmIter[i] = iLar+1; + for ( iClear=i+1 ; iClear<=MAXPOINTS ; iClear++ ) m_bmIter[iClear] = -1; + m_bmIterCounter ++; + if ( m_bmIterCounter >= nbIter ) return ERR_CONTINUE; + } + iLar ++; + + for ( iDiv=1 ; iDiv<=nbDiv ; iDiv++ ) + { + if ( iLar >= m_bmIter[i] ) + { + newPos = BeamPoint(curPos, goalPos, angle*iDiv/nbDiv, step); + ret = BeamExplore(curPos, newPos, goalPos, goalRadius, angle, nbDiv, step, i+1, nbIter); + if ( ret != ERR_GOTO_IMPOSSIBLE ) return ret; + m_bmIter[i] = iLar+1; + for ( iClear=i+1 ; iClear<=MAXPOINTS ; iClear++ ) m_bmIter[iClear] = -1; + m_bmIterCounter ++; + if ( m_bmIterCounter >= nbIter ) return ERR_CONTINUE; + } + iLar ++; + + if ( iLar >= m_bmIter[i] ) + { + newPos = BeamPoint(curPos, goalPos, -angle*iDiv/nbDiv, step); + ret = BeamExplore(curPos, newPos, goalPos, goalRadius, angle, nbDiv, step, i+1, nbIter); + if ( ret != ERR_GOTO_IMPOSSIBLE ) return ret; + m_bmIter[i] = iLar+1; + for ( iClear=i+1 ; iClear<=MAXPOINTS ; iClear++ ) m_bmIter[iClear] = -1; + m_bmIterCounter ++; + if ( m_bmIterCounter >= nbIter ) return ERR_CONTINUE; + } + iLar ++; + } + + return ERR_GOTO_IMPOSSIBLE; +} + +// Is a right "start-goal". Calculates the point located at the distance "step" +// from the point "start" and an angle "angle" with the right. + +D3DVECTOR CTaskGoto::BeamPoint(const D3DVECTOR &startPoint, + const D3DVECTOR &goalPoint, + float angle, float step) +{ + D3DVECTOR resPoint; + float goalAngle; + + goalAngle = RotateAngle(goalPoint.x-startPoint.x, goalPoint.z-startPoint.z); + + resPoint.x = startPoint.x + cosf(goalAngle+angle)*step; + resPoint.z = startPoint.z + sinf(goalAngle+angle)*step; + resPoint.y = 0.0f; + + return resPoint; +} + +// Displays a bitmap part. + +void CTaskGoto::BitmapDebug(const D3DVECTOR &min, const D3DVECTOR &max, + const D3DVECTOR &start, const D3DVECTOR &goal) +{ + int minx, miny, maxx, maxy, x, y, i ,n; + char s[2000]; + + minx = (int)((min.x+1600.0f)/BM_DIM_STEP); + miny = (int)((min.z+1600.0f)/BM_DIM_STEP); + maxx = (int)((max.x+1600.0f)/BM_DIM_STEP); + maxy = (int)((max.z+1600.0f)/BM_DIM_STEP); + + if ( minx > maxx ) Swap(minx, maxx); + if ( miny > maxy ) Swap(miny, maxy); + + OutputDebugString("Bitmap :\n"); + for ( y=miny ; y<=maxy ; y++ ) + { + s[0] = 0; + for ( x=minx ; x<=maxx ; x++ ) + { + n = -1; + for ( i=0 ; i<=m_bmTotal ; i++ ) + { + if ( x == (int)((m_bmPoints[i].x+1600.0f)/BM_DIM_STEP) && + y == (int)((m_bmPoints[i].z+1600.0f)/BM_DIM_STEP) ) + { + n = i; + break; + } + } + + if ( BitmapTestDot(0, x,y) ) + { + strcat(s, "o"); + } + else + { + if ( BitmapTestDot(1, x,y) ) + { + strcat(s, "-"); + } + else + { + strcat(s, "."); + } + } + + if ( x == (int)((start.x+1600.0f)/BM_DIM_STEP) && + y == (int)((start.z+1600.0f)/BM_DIM_STEP) ) + { + strcat(s, "s"); + } + else + if ( x == (int)((goal.x+1600.0f)/BM_DIM_STEP) && + y == (int)((goal.z+1600.0f)/BM_DIM_STEP) ) + { + strcat(s, "g"); + } + else + if ( n != -1 ) + { + char ss[2]; + ss[0] = 'A'+n; + ss[1] = 0; + strcat(s, ss); + } + else + { + strcat(s, " "); + } + } + strcat(s, "\n"); + OutputDebugString(s); + } +} + +// Tests if a path along a straight line is possible. + +BOOL CTaskGoto::BitmapTestLine(const D3DVECTOR &start, const D3DVECTOR &goal, + float stepAngle, BOOL bSecond) +{ + D3DVECTOR pos, inc; + float dist, step; + float distNoB2; + int i, max, x, y; + + if ( m_bmArray == 0 ) return TRUE; + + dist = Length2d(start, goal); + if ( dist == 0.0f ) return TRUE; + step = BM_DIM_STEP*0.5f; + + inc.x = (goal.x-start.x)*step/dist; + inc.z = (goal.z-start.z)*step/dist; + + pos = start; + + if ( bSecond ) + { + x = (int)((pos.x+1600.0f)/BM_DIM_STEP); + y = (int)((pos.z+1600.0f)/BM_DIM_STEP); + BitmapSetDot(1, x, y); // puts the flag as the starting point + } + + max = (int)(dist/step); + if ( max == 0 ) max = 1; + distNoB2 = BM_DIM_STEP*sqrtf(2.0f)/sinf(stepAngle); + for ( i=0 ; i 2 && BitmapTestDot(1, x, y) ) return FALSE; + + if ( step*(i+1) > distNoB2 && i < max-2 ) + { + BitmapSetDot(1, x, y); + } + } + + if ( BitmapTestDot(0, x, y) ) return FALSE; + } + return TRUE; +} + +// Adds the objects in the bitmap. + +void CTaskGoto::BitmapObject() +{ + CObject *pObj; + ObjectType type; + D3DVECTOR iPos, oPos; + float iRadius, oRadius, h; + int i, j; + + m_object->GetCrashSphere(0, iPos, iRadius); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + + if ( pObj == m_object ) continue; + if ( pObj == m_bmFretObject ) continue; + if ( pObj->RetTruck() != 0 ) continue; + + h = m_terrain->RetFloorLevel(pObj->RetPosition(0), FALSE); + if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f ) + { + h += m_altitude; + } + + j = 0; + while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) + { + if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f ) // flying? + { + if ( oPos.y-oRadius > h+8.0f || + oPos.y+oRadius < h-8.0f ) continue; + } + else // crawling? + { + if ( oPos.y-oRadius > h+8.0f ) continue; + } + + if ( type == OBJECT_PARA ) oRadius -= 2.0f; + BitmapSetCircle(oPos, oRadius+iRadius+4.0f); + } + } +} + +// Adds a section of land in the bitmap. + +void CTaskGoto::BitmapTerrain(const D3DVECTOR &min, const D3DVECTOR &max) +{ + int minx, miny, maxx, maxy; + + minx = (int)((min.x+1600.0f)/BM_DIM_STEP); + miny = (int)((min.z+1600.0f)/BM_DIM_STEP); + maxx = (int)((max.x+1600.0f)/BM_DIM_STEP); + maxy = (int)((max.z+1600.0f)/BM_DIM_STEP); + + BitmapTerrain(minx, miny, maxx, maxy); +} + +// Adds a section of land in the bitmap. + +void CTaskGoto::BitmapTerrain(int minx, int miny, int maxx, int maxy) +{ + ObjectType type; + D3DVECTOR p; + float aLimit, angle, h; + int x, y; + BOOL bAcceptWater, bFly; + + if ( minx > maxx ) Swap(minx, maxx); + if ( miny > maxy ) Swap(miny, maxy); + + if ( minx < 0 ) minx = 0; + if ( miny < 0 ) miny = 0; + if ( maxx > m_bmSize-1 ) maxx = m_bmSize-1; + if ( maxy > m_bmSize-1 ) maxy = m_bmSize-1; + + if ( minx > m_bmMinX ) minx = m_bmMinX; + if ( miny > m_bmMinY ) miny = m_bmMinY; + if ( maxx < m_bmMaxX ) maxx = m_bmMaxX; + if ( maxy < m_bmMaxY ) maxy = m_bmMaxY; + + if ( minx >= m_bmMinX && maxx <= m_bmMaxX && + miny >= m_bmMinY && maxy <= m_bmMaxY ) return; + + aLimit = 20.0f*PI/180.0f; + bAcceptWater = FALSE; + bFly = FALSE; + + type = m_object->RetType(); + + if ( type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEtg ) // wheels? + { + aLimit = 20.0f*PI/180.0f; + } + + if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts ) // caterpillars? + { + aLimit = 35.0f*PI/180.0f; + } + + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) // large caterpillars? + { + aLimit = 35.0f*PI/180.0f; + } + + if ( type == OBJECT_MOBILEsa ) // submarine caterpillars? + { + aLimit = 35.0f*PI/180.0f; + bAcceptWater = TRUE; + } + + if ( type == OBJECT_MOBILEdr ) // designer caterpillars? + { + aLimit = 35.0f*PI/180.0f; + } + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEft ) // flying? + { + aLimit = 15.0f*PI/180.0f; + bFly = TRUE; + } + + if ( type == OBJECT_MOBILEia || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILEii ) // insect legs? + { + aLimit = 60.0f*PI/180.0f; + } + + for ( y=miny ; y<=maxy ; y++ ) + { + for ( x=minx ; x<=maxx ; x++ ) + { + if ( x >= m_bmMinX && x <= m_bmMaxX && + y >= m_bmMinY && y <= m_bmMaxY ) continue; + + p.x = x*BM_DIM_STEP-1600.0f; + p.z = y*BM_DIM_STEP-1600.0f; + + if ( bFly ) // flying robot? + { + h = m_terrain->RetFloorLevel(p, TRUE); + if ( h >= m_terrain->RetFlyingMaxHeight()-5.0f ) + { + BitmapSetDot(0, x, y); + } + continue; + } + + if ( !bAcceptWater ) // not going underwater? + { + h = m_terrain->RetFloorLevel(p, TRUE); + if ( h < m_water->RetLevel()-2.0f ) // under water (*)? + { +//? BitmapSetDot(0, x, y); + BitmapSetCircle(p, BM_DIM_STEP*1.0f); + continue; + } + } + + angle = m_terrain->RetFineSlope(p); + if ( angle > aLimit ) + { + BitmapSetDot(0, x, y); + } + } + } + + m_bmMinX = minx; + m_bmMinY = miny; + m_bmMaxX = maxx; + m_bmMaxY = maxy; // expanded rectangular area +} + +// (*) Accepts that a robot is 50cm under water, for example Tropica 3! + +// Opens an empty bitmap. + +BOOL CTaskGoto::BitmapOpen() +{ + BitmapClose(); + + m_bmSize = (int)(3200.0f/BM_DIM_STEP); + m_bmArray = (unsigned char*)malloc(m_bmSize*m_bmSize/8*2); + ZeroMemory(m_bmArray, m_bmSize*m_bmSize/8*2); + + m_bmOffset = m_bmSize/2; + m_bmLine = m_bmSize/8; + + m_bmMinX = m_bmSize; // non-existent rectangular area + m_bmMinY = m_bmSize; + m_bmMaxX = 0; + m_bmMaxY = 0; + + return TRUE; +} + +// Closes the bitmap. + +BOOL CTaskGoto::BitmapClose() +{ + free(m_bmArray); + m_bmArray = 0; + return TRUE; +} + +// Puts a circle in the bitmap. + +void CTaskGoto::BitmapSetCircle(const D3DVECTOR &pos, float radius) +{ + float d, r; + int cx, cy, ix, iy; + + cx = (int)((pos.x+1600.0f)/BM_DIM_STEP); + cy = (int)((pos.z+1600.0f)/BM_DIM_STEP); + r = radius/BM_DIM_STEP; + + for ( iy=cy-(int)r ; iy<=cy+(int)r ; iy++ ) + { + for ( ix=cx-(int)r ; ix<=cx+(int)r ; ix++ ) + { + d = Length((float)(ix-cx), (float)(iy-cy)); + if ( d > r ) continue; + BitmapSetDot(0, ix, iy); + } + } +} + +// Removes a circle in the bitmap. + +void CTaskGoto::BitmapClearCircle(const D3DVECTOR &pos, float radius) +{ + float d, r; + int cx, cy, ix, iy; + + cx = (int)((pos.x+1600.0f)/BM_DIM_STEP); + cy = (int)((pos.z+1600.0f)/BM_DIM_STEP); + r = radius/BM_DIM_STEP; + + for ( iy=cy-(int)r ; iy<=cy+(int)r ; iy++ ) + { + for ( ix=cx-(int)r ; ix<=cx+(int)r ; ix++ ) + { + d = Length((float)(ix-cx), (float)(iy-cy)); + if ( d > r ) continue; + BitmapClearDot(0, ix, iy); + } + } +} + +// Makes a point in the bitmap. +// x:y: 0..m_bmSize-1 + +void CTaskGoto::BitmapSetDot(int rank, int x, int y) +{ + if ( x < 0 || x >= m_bmSize || + y < 0 || y >= m_bmSize ) return; + + m_bmArray[rank*m_bmLine*m_bmSize + m_bmLine*y + x/8] |= (1<= m_bmSize || + y < 0 || y >= m_bmSize ) return; + + m_bmArray[rank*m_bmLine*m_bmSize + m_bmLine*y + x/8] &= ~(1<= m_bmSize || + y < 0 || y >= m_bmSize ) return FALSE; + + if ( x < m_bmMinX || x > m_bmMaxX || + y < m_bmMinY || y > m_bmMaxY ) + { + BitmapTerrain(x-10,y-10, x+10,y+10); // remade a layer + } + + return m_bmArray[rank*m_bmLine*m_bmSize + m_bmLine*y + x/8] & (1< +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "object.h" +#include "sound.h" +#include "task.h" +#include "taskgungoal.h" + + + + +// Object's constructor. + +CTaskGunGoal::CTaskGunGoal(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); +} + +// Object's destructor. + +CTaskGunGoal::~CTaskGunGoal() +{ +} + + +// Management of an event. + +BOOL CTaskGunGoal::EventProcess(const Event &event) +{ + float dir; + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_progress += event.rTime*m_speed; + + if ( m_progress < 1.0f ) + { + dir = m_initialDirV + (m_finalDirV-m_initialDirV)*m_progress; + } + else + { + dir = m_finalDirV; + } + m_object->SetGunGoalV(dir); + + if ( m_progress < 1.0f ) + { + dir = m_initialDirH + (m_finalDirH-m_initialDirH)*m_progress; + } + else + { + dir = m_finalDirH; + } + m_object->SetGunGoalH(dir); + + return TRUE; +} + + +// Assigns the goal was achieved. + +Error CTaskGunGoal::Start(float dirV, float dirH) +{ + float speedV, speedH; + int i; + + m_initialDirV = m_object->RetGunGoalV(); + m_object->SetGunGoalV(dirV); + m_finalDirV = m_object->RetGunGoalV(); // possible direction + m_object->SetGunGoalV(m_initialDirV); // gives initial direction + + if ( m_finalDirV == m_initialDirV ) + { + speedV = 100.0f; + } + else + { + speedV = 1.0f/(Abs(m_finalDirV-m_initialDirV)*1.0f); + } + + m_initialDirH = m_object->RetGunGoalH(); + m_object->SetGunGoalH(dirH); + m_finalDirH = m_object->RetGunGoalH(); // possible direction + m_object->SetGunGoalH(m_initialDirH); // gives initial direction + + if ( m_finalDirH == m_initialDirH ) + { + speedH = 100.0f; + } + else + { + speedH = 1.0f/(Abs(m_finalDirH-m_initialDirH)*1.0f); + } + + m_speed = Min(speedV, speedH); + + if ( m_finalDirV != m_initialDirV || + m_finalDirH != m_initialDirH ) + { + i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.3f, 1.5f, TRUE); + m_sound->AddEnvelope(i, 0.3f, 1.5f, 1.0f/m_speed, SOPER_STOP); + } + + m_progress = 0.0f; + + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskGunGoal::IsEnded() +{ + if ( m_engine->RetPause() ) return ERR_CONTINUE; + + if ( m_initialDirV == m_finalDirV && + m_initialDirH == m_finalDirH ) return ERR_STOP; + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + m_object->SetGunGoalV(m_finalDirV); + m_object->SetGunGoalH(m_finalDirH); + Abort(); + return ERR_STOP; +} + +// Suddenly ends the current action. + +BOOL CTaskGunGoal::Abort() +{ + return TRUE; +} + diff --git a/src/object/task/taskgungoal.h b/src/object/task/taskgungoal.h new file mode 100644 index 0000000..4b6cbc7 --- /dev/null +++ b/src/object/task/taskgungoal.h @@ -0,0 +1,57 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskgungoal.h + +#ifndef _TASKGUNGOAL_H_ +#define _TASKGUNGOAL_H_ + + +#include "misc.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + +class CTaskGunGoal : public CTask +{ +public: + CTaskGunGoal(CInstanceManager* iMan, CObject* object); + ~CTaskGunGoal(); + + BOOL EventProcess(const Event &event); + + Error Start(float dirV, float dirH); + Error IsEnded(); + BOOL Abort(); + +protected: + +protected: + float m_progress; + float m_speed; + float m_initialDirV; // initial direction + float m_finalDirV; // direction to reach + float m_initialDirH; // initial direction + float m_finalDirH; // direction to reach +}; + + +#endif //_TASKGUNGOAL_H_ diff --git a/src/object/task/taskinfo.cpp b/src/object/task/taskinfo.cpp new file mode 100644 index 0000000..51deb79 --- /dev/null +++ b/src/object/task/taskinfo.cpp @@ -0,0 +1,233 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskinfo.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "sound.h" +#include "auto.h" +#include "autoinfo.h" +#include "task.h" +#include "taskinfo.h" + + + + +// Object's constructor. + +CTaskInfo::CTaskInfo(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); +} + +// Object's destructor. + +CTaskInfo::~CTaskInfo() +{ +} + + +// Management of an event. + +BOOL CTaskInfo::EventProcess(const Event &event) +{ + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_bError ) return FALSE; + + m_progress += event.rTime*m_speed; // other advance + m_time += event.rTime; + + return TRUE; +} + + +// Assigns the goal was achieved. + +Error CTaskInfo::Start(char *name, float value, float power, BOOL bSend) +{ + CObject* pInfo; + CAutoInfo* pAuto; + D3DVECTOR pos, goal; + Info info; + int i, total, op; + + m_bError = TRUE; + m_object->SetInfoReturn(NAN); + + pInfo = SearchInfo(power); // seeks terminal + if ( pInfo == 0 ) + { + return ERR_INFO_NULL; + } + + pAuto = (CAutoInfo*)pInfo->RetAuto(); + if ( pAuto == 0 ) + { + return ERR_INFO_NULL; + } + + op = 1; // transmission impossible + if ( bSend ) // send? + { + total = pInfo->RetInfoTotal(); + for ( i=0 ; iRetInfo(i); + if ( strcmp(info.name, name) == 0 ) + { + info.value = value; + pInfo->SetInfo(i, info); + break; + } + } + if ( i == total ) + { + if ( total < OBJECTMAXINFO ) + { + strcpy(info.name, name); + info.value = value; + pInfo->SetInfo(total, info); + op = 2; // start of reception (for terminal) + } + } + else + { + op = 2; // start of reception (for terminal) + } + } + else // receive? + { + total = pInfo->RetInfoTotal(); + for ( i=0 ; iRetInfo(i); + if ( strcmp(info.name, name) == 0 ) + { + m_object->SetInfoReturn(info.value); + break; + } + } + if ( i < total ) + { + op = 0; // beginning of transmission (for terminal) + } + } + + pAuto->Start(op); + + if ( op == 0 ) // transmission? + { + pos = pInfo->RetPosition(0); + pos.y += 9.5f; + goal = m_object->RetPosition(0); + goal.y += 4.0f; + m_particule->CreateRay(pos, goal, PARTIRAY3, FPOINT(2.0f, 2.0f), 1.0f); + } + if ( op == 2 ) // reception? + { + goal = pInfo->RetPosition(0); + goal.y += 9.5f; + pos = m_object->RetPosition(0); + pos.y += 4.0f; + m_particule->CreateRay(pos, goal, PARTIRAY3, FPOINT(2.0f, 2.0f), 1.0f); + } + + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + m_time = 0.0f; + + m_bError = FALSE; // ok + + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskInfo::IsEnded() +{ + if ( m_engine->RetPause() ) return ERR_CONTINUE; + if ( m_bError ) return ERR_STOP; + + if ( m_progress < 1.0f ) return ERR_CONTINUE; + m_progress = 0.0f; + + Abort(); + return ERR_STOP; +} + +// Suddenly ends the current action. + +BOOL CTaskInfo::Abort() +{ + return TRUE; +} + + +// Seeks the nearest information terminal. + +CObject* CTaskInfo::SearchInfo(float power) +{ + CObject *pObj, *pBest; + D3DVECTOR iPos, oPos; + ObjectType type; + float dist, min; + int i; + + iPos = m_object->RetPosition(0); + + min = 100000.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_INFO ) continue; + + if ( !pObj->RetActif() ) continue; + + oPos = pObj->RetPosition(0); + dist = Length(oPos, iPos); + if ( dist > power ) continue; // too far? + if ( dist < min ) + { + min = dist; + pBest = pObj; + } + } + + return pBest; +} + diff --git a/src/object/task/taskinfo.h b/src/object/task/taskinfo.h new file mode 100644 index 0000000..26b2071 --- /dev/null +++ b/src/object/task/taskinfo.h @@ -0,0 +1,57 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskinfo.h + +#ifndef _TASKINFO_H_ +#define _TASKINFO_H_ + + +#include "misc.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + + +class CTaskInfo : public CTask +{ +public: + CTaskInfo(CInstanceManager* iMan, CObject* object); + ~CTaskInfo(); + + BOOL EventProcess(const Event &event); + + Error Start(char *name, float value, float power, BOOL bSend); + Error IsEnded(); + BOOL Abort(); + +protected: + CObject* SearchInfo(float power); + +protected: + float m_progress; + float m_speed; + float m_time; + BOOL m_bError; +}; + + +#endif //_TASKINFO_H_ diff --git a/src/object/task/taskmanager.cpp b/src/object/task/taskmanager.cpp new file mode 100644 index 0000000..ffc0d05 --- /dev/null +++ b/src/object/task/taskmanager.cpp @@ -0,0 +1,291 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskmanager.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "misc.h" +#include "iman.h" +#include "event.h" +#include "object.h" +#include "task.h" +#include "taskwait.h" +#include "taskadvance.h" +#include "taskturn.h" +#include "taskgoto.h" +#include "tasktake.h" +#include "taskmanip.h" +#include "taskflag.h" +#include "taskbuild.h" +#include "tasksearch.h" +#include "taskterraform.h" +#include "taskpen.h" +#include "taskrecover.h" +#include "taskshield.h" +#include "taskinfo.h" +#include "taskfire.h" +#include "taskfireant.h" +#include "taskgungoal.h" +#include "taskspiderexplo.h" +#include "taskreset.h" +#include "taskmanager.h" + + + + +// Object's constructor. + +CTaskManager::CTaskManager(CInstanceManager* iMan, CObject* object) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_TASKMANAGER, this, 100); + + m_task = 0; + m_object = object; + m_bPilot = FALSE; +} + +// Object's destructor. + +CTaskManager::~CTaskManager() +{ + delete m_task; +} + + + +// Waits for a while. + +Error CTaskManager::StartTaskWait(float time) +{ + m_task = new CTaskWait(m_iMan, m_object); + return ((CTaskWait*)m_task)->Start(time); +} + +// Advance straight ahead a certain distance. + +Error CTaskManager::StartTaskAdvance(float length) +{ + m_task = new CTaskAdvance(m_iMan, m_object); + return ((CTaskAdvance*)m_task)->Start(length); +} + +// Turns through an certain angle. + +Error CTaskManager::StartTaskTurn(float angle) +{ + m_task = new CTaskTurn(m_iMan, m_object); + return ((CTaskTurn*)m_task)->Start(angle); +} + +// Reaches a given position. + +Error CTaskManager::StartTaskGoto(D3DVECTOR pos, float altitude, TaskGotoGoal goalMode, TaskGotoCrash crashMode) +{ + m_task = new CTaskGoto(m_iMan, m_object); + return ((CTaskGoto*)m_task)->Start(pos, altitude, goalMode, crashMode); +} + +// Move the manipulator arm. + +Error CTaskManager::StartTaskTake() +{ + m_task = new CTaskTake(m_iMan, m_object); + return ((CTaskTake*)m_task)->Start(); +} + +// Move the manipulator arm. + +Error CTaskManager::StartTaskManip(TaskManipOrder order, TaskManipArm arm) +{ + m_task = new CTaskManip(m_iMan, m_object); + return ((CTaskManip*)m_task)->Start(order, arm); +} + +// Puts or removes a flag. + +Error CTaskManager::StartTaskFlag(TaskFlagOrder order, int rank) +{ + m_task = new CTaskFlag(m_iMan, m_object); + return ((CTaskFlag*)m_task)->Start(order, rank); +} + +// Builds a building. + +Error CTaskManager::StartTaskBuild(ObjectType type) +{ + m_task = new CTaskBuild(m_iMan, m_object); + return ((CTaskBuild*)m_task)->Start(type); +} + +// Probe the ground. + +Error CTaskManager::StartTaskSearch() +{ + m_task = new CTaskSearch(m_iMan, m_object); + return ((CTaskSearch*)m_task)->Start(); +} + +// Reads an information terminal. + +Error CTaskManager::StartTaskInfo(char *name, float value, float power, BOOL bSend) +{ + m_task = new CTaskInfo(m_iMan, m_object); + return ((CTaskInfo*)m_task)->Start(name, value, power, bSend); +} + +// Terraforms the ground. + +Error CTaskManager::StartTaskTerraform() +{ + m_task = new CTaskTerraform(m_iMan, m_object); + return ((CTaskTerraform*)m_task)->Start(); +} + +// Changes the pencil. + +Error CTaskManager::StartTaskPen(BOOL bDown, int color) +{ + m_task = new CTaskPen(m_iMan, m_object); + return ((CTaskPen*)m_task)->Start(bDown, color); +} + +// Recovers a ruin. + +Error CTaskManager::StartTaskRecover() +{ + m_task = new CTaskRecover(m_iMan, m_object); + return ((CTaskRecover*)m_task)->Start(); +} + +// Deploys the shield. + +Error CTaskManager::StartTaskShield(TaskShieldMode mode, float delay) +{ + if ( mode == TSM_UP ) + { + m_task = new CTaskShield(m_iMan, m_object); + return ((CTaskShield*)m_task)->Start(mode, delay); + } + if ( mode == TSM_DOWN && m_task != 0 ) + { + return ((CTaskShield*)m_task)->Start(mode, delay); + } + if ( mode == TSM_UPDATE && m_task != 0 ) + { + return ((CTaskShield*)m_task)->Start(mode, delay); + } + return ERR_GENERIC; +} + +// Shoots. + +Error CTaskManager::StartTaskFire(float delay) +{ + m_bPilot = TRUE; + m_task = new CTaskFire(m_iMan, m_object); + return ((CTaskFire*)m_task)->Start(delay); +} + +// Shoots with the ant. + +Error CTaskManager::StartTaskFireAnt(D3DVECTOR impact) +{ + m_task = new CTaskFireAnt(m_iMan, m_object); + return ((CTaskFireAnt*)m_task)->Start(impact); +} + +// Adjusts higher. + +Error CTaskManager::StartTaskGunGoal(float dirV, float dirH) +{ + m_task = new CTaskGunGoal(m_iMan, m_object); + return ((CTaskGunGoal*)m_task)->Start(dirV, dirH); +} + +// Suicide of the spider. + +Error CTaskManager::StartTaskSpiderExplo() +{ + m_task = new CTaskSpiderExplo(m_iMan, m_object); + return ((CTaskSpiderExplo*)m_task)->Start(); +} + +// Reset. + +Error CTaskManager::StartTaskReset(D3DVECTOR goal, D3DVECTOR angle) +{ + m_task = new CTaskReset(m_iMan, m_object); + return ((CTaskReset*)m_task)->Start(goal, angle); +} + + + + + +// Management of an event. + +BOOL CTaskManager::EventProcess(const Event &event) +{ + if ( m_task == 0 ) return FALSE; + return m_task->EventProcess(event); +} + + +// Indicates whether the action is finished. + +Error CTaskManager::IsEnded() +{ + if ( m_task == 0 ) return ERR_GENERIC; + return m_task->IsEnded(); +} + + +// Indicates whether the action is pending. + +BOOL CTaskManager::IsBusy() +{ + if ( m_task == 0 ) return FALSE; + return m_task->IsBusy(); +} + + +// Indicates whether it is possible to control the robot +// during the execution of the current task. + +BOOL CTaskManager::IsPilot() +{ + return m_bPilot; +} + + +// Suddenly ends the current action. + +BOOL CTaskManager::Abort() +{ + if ( m_task == 0 ) return FALSE; + return m_task->Abort(); +} + + diff --git a/src/object/task/taskmanager.h b/src/object/task/taskmanager.h new file mode 100644 index 0000000..2c6c21f --- /dev/null +++ b/src/object/task/taskmanager.h @@ -0,0 +1,77 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskmanager.h + +#ifndef _TASKMANAGER_H_ +#define _TASKMANAGER_H_ + +#include "misc.h" +#include "object.h" +#include "taskmanip.h" +#include "taskgoto.h" +#include "taskshield.h" +#include "taskflag.h" + + +class CInstanceManager; +class CTask; + + + +class CTaskManager +{ +public: + CTaskManager(CInstanceManager* iMan, CObject* object); + ~CTaskManager(); + + Error StartTaskWait(float time); + Error StartTaskAdvance(float length); + Error StartTaskTurn(float angle); + Error StartTaskGoto(D3DVECTOR pos, float altitude, TaskGotoGoal goalMode, TaskGotoCrash crashMode); + Error StartTaskTake(); + Error StartTaskManip(TaskManipOrder order, TaskManipArm arm); + Error StartTaskFlag(TaskFlagOrder order, int rank); + Error StartTaskBuild(ObjectType type); + Error StartTaskSearch(); + Error StartTaskInfo(char *name, float value, float power, BOOL bSend); + Error StartTaskTerraform(); + Error StartTaskPen(BOOL bDown, int color); + Error StartTaskRecover(); + Error StartTaskShield(TaskShieldMode mode, float delay); + Error StartTaskFire(float delay); + Error StartTaskFireAnt(D3DVECTOR impact); + Error StartTaskGunGoal(float dirV, float dirH); + Error StartTaskSpiderExplo(); + Error StartTaskReset(D3DVECTOR goal, D3DVECTOR angle); + + BOOL EventProcess(const Event &event); + Error IsEnded(); + BOOL IsBusy(); + BOOL IsPilot(); + BOOL Abort(); + +protected: + +protected: + CInstanceManager* m_iMan; + CTask* m_task; + CObject* m_object; + BOOL m_bPilot; +}; + + +#endif //_TASKMANAGER_H_ diff --git a/src/object/task/taskmanip.cpp b/src/object/task/taskmanip.cpp new file mode 100644 index 0000000..672b96e --- /dev/null +++ b/src/object/task/taskmanip.cpp @@ -0,0 +1,1398 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskmanip.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "terrain.h" +#include "object.h" +#include "pyro.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "sound.h" +#include "robotmain.h" +#include "task.h" +#include "taskmanip.h" + + +//?#define MARGIN_FRONT 2.0f +//?#define MARGIN_BACK 2.0f +//?#define MARGIN_FRIEND 2.0f +//?#define MARGIN_BEE 5.0f +#define MARGIN_FRONT 4.0f //OK 1.9 +#define MARGIN_BACK 4.0f //OK 1.9 +#define MARGIN_FRIEND 4.0f //OK 1.9 +#define MARGIN_BEE 5.0f //OK 1.9 + + + + +// Object's constructor. + +CTaskManip::CTaskManip(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); + + m_arm = TMA_NEUTRAL; + m_hand = TMH_OPEN; +} + +// Object's destructor. + +CTaskManip::~CTaskManip() +{ +} + + +// Management of an event. + +BOOL CTaskManip::EventProcess(const Event &event) +{ + D3DVECTOR pos; + float angle, a, g, cirSpeed, progress; + int i; + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_bError ) return FALSE; + + if ( m_bBee ) // bee? + { + return TRUE; + } + + if ( m_bTurn ) // preliminary rotation? + { + a = m_object->RetAngleY(0); + g = m_angle; + cirSpeed = Direction(a, g)*1.0f; + if ( m_physics->RetType() == TYPE_FLYING ) // flying on the ground? + { + cirSpeed *= 4.0f; // more fishing + } + if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; + if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; + + m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right + return TRUE; + } + + if ( m_move != 0 ) // preliminary advance? + { + m_timeLimit -= event.rTime; + m_physics->SetMotorSpeedX(m_move); // forward/backward + return TRUE; + } + + m_progress += event.rTime*m_speed; // others advance + progress = m_progress; + if ( progress > 1.0f ) progress = 1.0f; + + if ( m_bSubm ) // submarine? + { + if ( m_order == TMO_GRAB ) + { + if ( m_step == 0 ) // fall? + { + pos = m_object->RetPosition(1); + pos.y = 3.0f-progress*2.0f; + m_object->SetPosition(1, pos); + } + if ( m_step == 1 ) // farm? + { + pos = m_object->RetPosition(2); + pos.z = -1.5f+progress*0.5f; + m_object->SetPosition(2, pos); + + pos = m_object->RetPosition(3); + pos.z = 1.5f-progress*0.5f; + m_object->SetPosition(3, pos); + } + if ( m_step == 2 ) // up? + { + pos = m_object->RetPosition(1); + pos.y = 3.0f-(1.0f-progress)*2.0f; + m_object->SetPosition(1, pos); + } + } + else + { + if ( m_step == 0 ) // fall? + { + pos = m_object->RetPosition(1); + pos.y = 3.0f-progress*2.0f; + m_object->SetPosition(1, pos); + } + if ( m_step == 1 ) // farm? + { + pos = m_object->RetPosition(2); + pos.z = -1.5f+(1.0f-progress)*0.5f; + m_object->SetPosition(2, pos); + + pos = m_object->RetPosition(3); + pos.z = 1.5f-(1.0f-progress)*0.5f; + m_object->SetPosition(3, pos); + } + if ( m_step == 2 ) // up? + { + pos = m_object->RetPosition(1); + pos.y = 3.0f-(1.0f-progress)*2.0f; + m_object->SetPosition(1, pos); + } + } + } + else + { + for ( i=0 ; i<5 ; i++ ) + { + angle = (m_finalAngle[i]-m_initialAngle[i])*progress; + angle += m_initialAngle[i]; + m_object->SetAngleZ(i+1, angle); + } + } + + return TRUE; +} + + +// Initializes the initial and final angles. + +void CTaskManip::InitAngle() +{ + CObject* power; + float max, energy; + int i; + + if ( m_bSubm || m_bBee ) return; + + if ( m_arm == TMA_NEUTRAL || + m_arm == TMA_GRAB ) + { + m_finalAngle[0] = ARM_NEUTRAL_ANGLE1; // arm + m_finalAngle[1] = ARM_NEUTRAL_ANGLE2; // forearm + m_finalAngle[2] = ARM_NEUTRAL_ANGLE3; // hand + } + if ( m_arm == TMA_STOCK ) + { + m_finalAngle[0] = ARM_STOCK_ANGLE1; // arm + m_finalAngle[1] = ARM_STOCK_ANGLE2; // forearm + m_finalAngle[2] = ARM_STOCK_ANGLE3; // hand + } + if ( m_arm == TMA_FFRONT ) + { + m_finalAngle[0] = 35.0f*PI/180.0f; // arm + m_finalAngle[1] = -95.0f*PI/180.0f; // forearm + m_finalAngle[2] = -27.0f*PI/180.0f; // hand + } + if ( m_arm == TMA_FBACK ) + { + m_finalAngle[0] = 145.0f*PI/180.0f; // arm + m_finalAngle[1] = 95.0f*PI/180.0f; // forearm + m_finalAngle[2] = 27.0f*PI/180.0f; // hand + } + if ( m_arm == TMA_POWER ) + { + m_finalAngle[0] = 95.0f*PI/180.0f; // arm + m_finalAngle[1] = 125.0f*PI/180.0f; // forearm + m_finalAngle[2] = 50.0f*PI/180.0f; // hand + } + if ( m_arm == TMA_OTHER ) + { + if ( m_height <= 3.0f ) + { + m_finalAngle[0] = 55.0f*PI/180.0f; // arm + m_finalAngle[1] = -90.0f*PI/180.0f; // forearm + m_finalAngle[2] = -35.0f*PI/180.0f; // hand + } + else + { + m_finalAngle[0] = 70.0f*PI/180.0f; // arm + m_finalAngle[1] = -90.0f*PI/180.0f; // forearm + m_finalAngle[2] = -50.0f*PI/180.0f; // hand + } + } + + if ( m_hand == TMH_OPEN ) // open clamp? + { + m_finalAngle[3] = -PI*0.10f; // clamp close + m_finalAngle[4] = PI*0.10f; // clamp remote + } + if ( m_hand == TMH_CLOSE ) // clamp closed? + { + m_finalAngle[3] = PI*0.05f; // clamp close + m_finalAngle[4] = -PI*0.05f; // clamp remote + } + + for ( i=0 ; i<5 ; i++ ) + { + m_initialAngle[i] = m_object->RetAngleZ(i+1); + } + + max = 0.0f; + for ( i=0 ; i<5 ; i++ ) + { + max = Max(max, Abs(m_initialAngle[i] - m_finalAngle[i])); + } + m_speed = (PI*1.0f)/max; + if ( m_speed > 3.0f ) m_speed = 3.0f; // piano, ma non troppo (?) + + energy = 0.0f; + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + } + + if ( energy == 0.0f ) + { + m_speed *= 0.7f; // slower if more energy! + } +} + + +// Tests whether an object is compatible with the operation TMA_OTHER. + +BOOL TestFriend(ObjectType oType, ObjectType fType) +{ + if ( oType == OBJECT_ENERGY ) + { + return ( fType == OBJECT_METAL ); + } + if ( oType == OBJECT_LABO ) + { + return ( fType == OBJECT_BULLET ); + } + if ( oType == OBJECT_NUCLEAR ) + { + return ( fType == OBJECT_URANIUM ); + } + + return ( fType == OBJECT_POWER || + fType == OBJECT_ATOMIC ); +} + +// Assigns the goal was achieved. + +Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) +{ + ObjectType type; + CObject *front, *other, *power; + CPyro *pyro; + float iAngle, dist, len; + float fDist, fAngle, oDist, oAngle, oHeight; + D3DVECTOR pos, fPos, oPos; + + m_arm = arm; + m_height = 0.0f; + m_step = 0; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + + iAngle = m_object->RetAngleY(0); + iAngle = NormAngle(iAngle); // 0..2*PI + oAngle = iAngle; + + m_bError = TRUE; // operation impossible + + if ( m_arm != TMA_FFRONT && + m_arm != TMA_FBACK && + m_arm != TMA_POWER && + m_arm != TMA_GRAB ) return ERR_MANIP_VEH; + + m_physics->SetMotorSpeed(D3DVECTOR(0.0f, 0.0f, 0.0f)); + + type = m_object->RetType(); + if ( type == OBJECT_BEE ) // bee? + { + if ( m_object->RetFret() == 0 ) + { + if ( !m_physics->RetLand() ) return ERR_MANIP_FLY; + + other = SearchTakeUnderObject(m_targetPos, MARGIN_BEE); + if ( other == 0 ) return ERR_MANIP_NIL; + m_object->SetFret(other); // takes the ball + other->SetTruck(m_object); + other->SetTruckPart(0); // taken with the base + other->SetPosition(0, D3DVECTOR(0.0f, -3.0f, 0.0f)); + } + else + { + other = m_object->RetFret(); // other = ball + m_object->SetFret(0); // lick the ball + other->SetTruck(0); + pos = m_object->RetPosition(0); + pos.y -= 3.0f; + other->SetPosition(0, pos); + + pos = m_object->RetPosition(0); + pos.y += 2.0f; + m_object->SetPosition(0, pos); // against the top of jump + + pyro = new CPyro(m_iMan); + pyro->Create(PT_FALL, other); // the ball falls + } + + m_bBee = TRUE; + m_bError = FALSE; // ok + return ERR_OK; + } + m_bBee = FALSE; + + m_bSubm = ( type == OBJECT_MOBILEsa ); // submarine? + + if ( m_arm == TMA_GRAB ) // takes immediately? + { + TruckTakeObject(); + Abort(); + return ERR_OK; + } + + m_energy = 0.0f; + power = m_object->RetPower(); + if ( power != 0 ) + { + m_energy = power->RetEnergy(); + } + + if ( !m_physics->RetLand() ) return ERR_MANIP_FLY; + + if ( type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEsa ) return ERR_MANIP_VEH; + + if ( m_bSubm ) // submarine? + { + m_arm = TMA_FFRONT; // only possible in front! + } + + m_move = 0.0f; // advance not necessary + m_angle = iAngle; + + if ( order == TMO_AUTO ) + { + if ( m_object->RetFret() == 0 ) + { + m_order = TMO_GRAB; + } + else + { + m_order = TMO_DROP; + } + } + else + { + m_order = order; + } + + if ( m_order == TMO_GRAB && m_object->RetFret() != 0 ) + { + return ERR_MANIP_BUSY; + } + if ( m_order == TMO_DROP && m_object->RetFret() == 0 ) + { + return ERR_MANIP_EMPTY; + } + +//? speed = m_physics->RetMotorSpeed(); +//? if ( speed.x != 0.0f || +//? speed.z != 0.0f ) return ERR_MANIP_MOTOR; + + if ( m_order == TMO_GRAB ) + { + if ( m_arm == TMA_FFRONT ) + { + front = SearchTakeFrontObject(TRUE, fPos, fDist, fAngle); + other = SearchOtherObject(TRUE, oPos, oDist, oAngle, oHeight); + + if ( front != 0 && fDist < oDist ) + { + m_targetPos = fPos; + m_angle = fAngle; + m_move = 1.0f; // advance required + } + else if ( other != 0 && oDist < fDist ) + { + if ( other->RetPower() == 0 ) return ERR_MANIP_NIL; + m_targetPos = oPos; + m_angle = oAngle; + m_height = oHeight; + m_move = 1.0f; // advance required + m_arm = TMA_OTHER; + } + else + { + return ERR_MANIP_NIL; + } + m_main->HideDropZone(front); // hides buildable area + } + if ( m_arm == TMA_FBACK ) + { + if ( SearchTakeBackObject(TRUE, m_targetPos, fDist, m_angle) == 0 ) + { + return ERR_MANIP_NIL; + } + m_angle += PI; + m_move = -1.0f; // back necessary + } + if ( m_arm == TMA_POWER ) + { + if ( m_object->RetPower() == 0 ) return ERR_MANIP_NIL; + } + } + + if ( m_order == TMO_DROP ) + { + if ( m_arm == TMA_FFRONT ) + { + other = SearchOtherObject(TRUE, oPos, oDist, oAngle, oHeight); + if ( other != 0 && other->RetPower() == 0 ) + { + m_targetPos = oPos; + m_angle = oAngle; + m_height = oHeight; + m_move = 1.0f; // advance required + m_arm = TMA_OTHER; + } + else + { + if ( !IsFreeDeposeObject(D3DVECTOR(TAKE_DIST, 0.0f, 0.0f)) ) return ERR_MANIP_OCC; + } + } + if ( m_arm == TMA_FBACK ) + { + if ( !IsFreeDeposeObject(D3DVECTOR(-TAKE_DIST, 0.0f, 0.0f)) ) return ERR_MANIP_OCC; + } + if ( m_arm == TMA_POWER ) + { + if ( m_object->RetPower() != 0 ) return ERR_MANIP_OCC; + } + } + + dist = Length(m_object->RetPosition(0), m_targetPos); + len = dist-TAKE_DIST; + if ( m_arm == TMA_OTHER ) len -= TAKE_DIST_OTHER; + if ( len < 0.0f ) len = 0.0f; + if ( m_arm == TMA_FBACK ) len = -len; + m_advanceLength = dist-m_physics->RetLinLength(len); + if ( dist <= m_advanceLength+0.2f ) m_move = 0.0f; // not necessary to advance + + if ( m_energy == 0.0f ) m_move = 0.0f; + + if ( m_move != 0.0f ) // forward or backward? + { + m_timeLimit = m_physics->RetLinTimeLength(Abs(len))*1.5f; + if ( m_timeLimit < 0.5f ) m_timeLimit = 0.5f; + } + + if ( m_object->RetFret() == 0 ) // not carrying anything? + { + m_hand = TMH_OPEN; // open clamp + } + else + { + m_hand = TMH_CLOSE; // closed clamp + } + + InitAngle(); + + if ( iAngle == m_angle || m_energy == 0.0f ) + { + m_bTurn = FALSE; // preliminary rotation unnecessary + SoundManip(1.0f/m_speed); + } + else + { + m_bTurn = TRUE; // preliminary rotation necessary + } + + if ( m_bSubm ) + { + m_camera->StartCentering(m_object, PI*0.8f, 99.9f, 0.0f, 0.5f); + } + + m_physics->SetFreeze(TRUE); // it does not move + + m_bError = FALSE; // ok + return ERR_OK; +} + +// Indicates whether the action is complete. + +Error CTaskManip::IsEnded() +{ + CObject* fret; + D3DVECTOR pos; + float angle, dist; + int i; + + if ( m_engine->RetPause() ) return ERR_CONTINUE; + if ( m_bError ) return ERR_STOP; + + if ( m_bBee ) // bee? + { + return ERR_STOP; + } + + if ( m_bTurn ) // preliminary rotation? + { + angle = m_object->RetAngleY(0); + angle = NormAngle(angle); // 0..2*PI + + if ( TestAngle(angle, m_angle-PI*0.01f, m_angle+PI*0.01f) ) + { + m_bTurn = FALSE; // rotation ended + m_physics->SetMotorSpeedZ(0.0f); + if ( m_move == 0.0f ) + { + SoundManip(1.0f/m_speed); + } + } + return ERR_CONTINUE; + } + + if ( m_move != 0.0f ) // preliminary advance? + { + if ( m_timeLimit <= 0.0f ) + { +//OK 1.9 + dist = Length(m_object->RetPosition(0), m_targetPos); + if ( dist <= m_advanceLength + 2.0f ) + { + m_move = 0.0f; // advance ended + m_physics->SetMotorSpeedX(0.0f); + SoundManip(1.0f/m_speed); + return ERR_CONTINUE; + } + else + { +//EOK 1.9 + m_move = 0.0f; // advance ended + m_physics->SetMotorSpeedX(0.0f); // stops + Abort(); + return ERR_STOP; + } + } + + dist = Length(m_object->RetPosition(0), m_targetPos); + if ( dist <= m_advanceLength ) + { + m_move = 0.0f; // advance ended + m_physics->SetMotorSpeedX(0.0f); + SoundManip(1.0f/m_speed); + } + return ERR_CONTINUE; + } + + if ( m_progress < 1.0f ) return ERR_CONTINUE; + m_progress = 0.0f; + + if ( !m_bSubm ) + { + for ( i=0 ; i<5 ; i++ ) + { + m_object->SetAngleZ(i+1, m_finalAngle[i]); + } + } + m_step ++; + + if ( m_order == TMO_GRAB ) + { + if ( m_step == 1 ) + { + if ( m_bSubm ) m_speed = 1.0f/0.7f; + m_hand = TMH_CLOSE; // closes the clamp to take + InitAngle(); + SoundManip(1.0f/m_speed, 0.8f, 1.5f); + return ERR_CONTINUE; + } + if ( m_step == 2 ) + { + if ( m_bSubm ) m_speed = 1.0f/1.5f; + if ( !TruckTakeObject() && + m_object->RetFret() == 0 ) + { + m_hand = TMH_OPEN; // reopens the clamp + m_arm = TMA_NEUTRAL; + InitAngle(); + SoundManip(1.0f/m_speed, 0.8f, 1.5f); + } + else + { + if ( (m_arm == TMA_OTHER || + m_arm == TMA_POWER ) && + (m_fretType == OBJECT_POWER || + m_fretType == OBJECT_ATOMIC ) ) + { + m_sound->Play(SOUND_POWEROFF, m_object->RetPosition(0)); + } + m_arm = TMA_STOCK; + InitAngle(); + SoundManip(1.0f/m_speed); + } + return ERR_CONTINUE; + } + } + + if ( m_order == TMO_DROP ) + { + if ( m_step == 1 ) + { + if ( m_bSubm ) m_speed = 1.0f/0.7f; + fret = m_object->RetFret(); + if ( TruckDeposeObject() ) + { + if ( (m_arm == TMA_OTHER || + m_arm == TMA_POWER ) && + (m_fretType == OBJECT_POWER || + m_fretType == OBJECT_ATOMIC ) ) + { + m_sound->Play(SOUND_POWERON, m_object->RetPosition(0)); + } + if ( fret != 0 && m_fretType == OBJECT_METAL && m_arm == TMA_FFRONT ) + { + m_main->ShowDropZone(fret, m_object); // shows buildable area + } + m_hand = TMH_OPEN; // opens the clamp to deposit + SoundManip(1.0f/m_speed, 0.8f, 1.5f); + } + InitAngle(); + return ERR_CONTINUE; + } + if ( m_step == 2 ) + { + if ( m_bSubm ) m_speed = 1.0f/1.5f; + m_arm = TMA_NEUTRAL; + InitAngle(); + SoundManip(1.0f/m_speed); + return ERR_CONTINUE; + } + } + + Abort(); + return ERR_STOP; +} + +// Suddenly ends the current action. + +BOOL CTaskManip::Abort() +{ + int i; + + if ( m_object->RetFret() == 0 ) // not carrying anything? + { + m_hand = TMH_OPEN; // open clamp + m_arm = TMA_NEUTRAL; + } + else + { + m_hand = TMH_CLOSE; // closed clamp + m_arm = TMA_STOCK; + } + InitAngle(); + + if ( !m_bSubm ) + { + for ( i=0 ; i<5 ; i++ ) + { + m_object->SetAngleZ(i+1, m_finalAngle[i]); + } + } + + m_camera->StopCentering(m_object, 2.0f); + m_physics->SetFreeze(FALSE); // is moving again + return TRUE; +} + + +// Seeks the object below to take (for bees). + +CObject* CTaskManip::SearchTakeUnderObject(D3DVECTOR &pos, float dLimit) +{ + CObject *pObj, *pBest; + D3DVECTOR iPos, oPos; + ObjectType type; + float min, distance; + int i; + + iPos = m_object->RetPosition(0); + + min = 1000000.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + + if ( type != OBJECT_FRET && + type != OBJECT_STONE && + type != OBJECT_URANIUM && + type != OBJECT_BULLET && + type != OBJECT_METAL && + type != OBJECT_POWER && + type != OBJECT_ATOMIC && + type != OBJECT_BBOX && + type != OBJECT_KEYa && + type != OBJECT_KEYb && + type != OBJECT_KEYc && + type != OBJECT_KEYd && + type != OBJECT_TNT ) continue; + + if ( pObj->RetTruck() != 0 ) continue; // object transported? + if ( pObj->RetLock() ) continue; + if ( pObj->RetZoomY(0) != 1.0f ) continue; + + oPos = pObj->RetPosition(0); + distance = Length(oPos, iPos); + if ( distance <= dLimit && + distance < min ) + { + min = distance; + pBest = pObj; + } + } + if ( pBest != 0 ) + { + pos = pBest->RetPosition(0); + } + return pBest; +} + +// Seeks the object in front to take. + +CObject* CTaskManip::SearchTakeFrontObject(BOOL bAdvance, D3DVECTOR &pos, + float &distance, float &angle) +{ + CObject *pObj, *pBest; + D3DVECTOR iPos, oPos; + ObjectType type; + float min, iAngle, bAngle, aLimit, dLimit, f; + int i; + + iPos = m_object->RetPosition(0); + iAngle = m_object->RetAngleY(0); + iAngle = NormAngle(iAngle); // 0..2*PI + + if ( bAdvance && m_energy > 0.0f ) + { + aLimit = 60.0f*PI/180.0f; + dLimit = MARGIN_FRONT+10.0f; + } + else + { +//? aLimit = 7.0f*PI/180.0f; + aLimit = 15.0f*PI/180.0f; //OK 1.9 + dLimit = MARGIN_FRONT; + } + + min = 1000000.0f; + pBest = 0; + bAngle = 0.0f; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + + if ( type != OBJECT_FRET && + type != OBJECT_STONE && + type != OBJECT_URANIUM && + type != OBJECT_BULLET && + type != OBJECT_METAL && + type != OBJECT_POWER && + type != OBJECT_ATOMIC && + type != OBJECT_BBOX && + type != OBJECT_KEYa && + type != OBJECT_KEYb && + type != OBJECT_KEYc && + type != OBJECT_KEYd && + type != OBJECT_TNT && + type != OBJECT_SCRAP1 && + type != OBJECT_SCRAP2 && + type != OBJECT_SCRAP3 && + type != OBJECT_SCRAP4 && + type != OBJECT_SCRAP5 ) continue; + + if ( pObj->RetTruck() != 0 ) continue; // object transported? + if ( pObj->RetLock() ) continue; + if ( pObj->RetZoomY(0) != 1.0f ) continue; + + oPos = pObj->RetPosition(0); + distance = Abs(Length(oPos, iPos)-TAKE_DIST); + f = 1.0f-distance/50.0f; + if ( f < 0.5f ) f = 0.5f; + + angle = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! + if ( !TestAngle(angle, iAngle-aLimit*f, iAngle+aLimit*f) ) continue; + + if ( distance < -dLimit || + distance > dLimit ) continue; + + if ( distance < min ) + { + min = distance; + pBest = pObj; + bAngle = angle; + } + } + if ( pBest == 0 ) + { + distance = 1000000.0f; + angle = 0.0f; + } + else + { + pos = pBest->RetPosition(0); + distance = min; + angle = bAngle; + } + return pBest; +} + +// Seeks the object back to take. + +CObject* CTaskManip::SearchTakeBackObject(BOOL bAdvance, D3DVECTOR &pos, + float &distance, float &angle) +{ + CObject *pObj, *pBest; + D3DVECTOR iPos, oPos; + ObjectType type; + float min, iAngle, bAngle, aLimit, dLimit, f; + int i; + + iPos = m_object->RetPosition(0); + iAngle = m_object->RetAngleY(0)+PI; + iAngle = NormAngle(iAngle); // 0..2*PI + + if ( bAdvance && m_energy > 0.0f ) + { + aLimit = 60.0f*PI/180.0f; + dLimit = MARGIN_BACK+5.0f; + } + else + { + aLimit = 7.0f*PI/180.0f; + dLimit = MARGIN_BACK; + } + + min = 1000000.0f; + pBest = 0; + bAngle = 0.0f; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + + if ( type != OBJECT_FRET && + type != OBJECT_STONE && + type != OBJECT_URANIUM && + type != OBJECT_BULLET && + type != OBJECT_METAL && + type != OBJECT_POWER && + type != OBJECT_ATOMIC && + type != OBJECT_BBOX && + type != OBJECT_KEYa && + type != OBJECT_KEYb && + type != OBJECT_KEYc && + type != OBJECT_KEYd && + type != OBJECT_TNT && + type != OBJECT_SCRAP1 && + type != OBJECT_SCRAP2 && + type != OBJECT_SCRAP3 && + type != OBJECT_SCRAP4 && + type != OBJECT_SCRAP5 ) continue; + + if ( pObj->RetTruck() != 0 ) continue; // object transported? + if ( pObj->RetLock() ) continue; + if ( pObj->RetZoomY(0) != 1.0f ) continue; + + oPos = pObj->RetPosition(0); + distance = Abs(Length(oPos, iPos)-TAKE_DIST); + f = 1.0f-distance/50.0f; + if ( f < 0.5f ) f = 0.5f; + + angle = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! + if ( !TestAngle(angle, iAngle-aLimit*f, iAngle+aLimit*f) ) continue; + + if ( distance < -dLimit || + distance > dLimit ) continue; + + if ( distance < min ) + { + min = distance; + pBest = pObj; + bAngle = angle; + } + } + if ( pBest == 0 ) + { + distance = 1000000.0f; + angle = 0.0f; + } + else + { + pos = pBest->RetPosition(0); + distance = min; + angle = bAngle; + } + return pBest; +} + +// Seeks the robot or building on which it wants to put a battery or or other object. + +CObject* CTaskManip::SearchOtherObject(BOOL bAdvance, D3DVECTOR &pos, + float &distance, float &angle, + float &height) +{ + Character* character; + CObject* pObj; + CObject* pPower; + D3DMATRIX* mat; + D3DVECTOR iPos, oPos; + ObjectType type, powerType; + float iAngle, iRad, oAngle, oLimit, aLimit, dLimit; + int i; + + distance = 1000000.0f; + angle = 0.0f; + + if ( m_bSubm ) return 0; // impossible with the submarine + + if ( !m_object->GetCrashSphere(0, iPos, iRad) ) return 0; + iAngle = m_object->RetAngleY(0); + iAngle = NormAngle(iAngle); // 0..2*PI + + if ( bAdvance && m_energy > 0.0f ) + { + aLimit = 60.0f*PI/180.0f; + dLimit = MARGIN_FRIEND+10.0f; + } + else + { + aLimit = 7.0f*PI/180.0f; + dLimit = MARGIN_FRIEND; + } + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj == m_object ) continue; // yourself? + + type = pObj->RetType(); + if ( type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_TOWER && + type != OBJECT_RESEARCH && + type != OBJECT_ENERGY && + type != OBJECT_LABO && + type != OBJECT_NUCLEAR ) continue; + + pPower = pObj->RetPower(); + if ( pPower != 0 ) + { + if ( pPower->RetLock() ) continue; + if ( pPower->RetZoomY(0) != 1.0f ) continue; + + powerType = pPower->RetType(); + if ( powerType == OBJECT_NULL || + powerType == OBJECT_FIX ) continue; + } + + mat = pObj->RetWorldMatrix(0); + character = pObj->RetCharacter(); + oPos = Transform(*mat, character->posPower); + + oAngle = pObj->RetAngleY(0); + if ( type == OBJECT_TOWER || + type == OBJECT_RESEARCH ) + { + oLimit = 45.0f*PI/180.0f; + } + else if ( type == OBJECT_ENERGY ) + { + oLimit = 90.0f*PI/180.0f; + } + else if ( type == OBJECT_LABO ) + { + oLimit = 120.0f*PI/180.0f; + } + else if ( type == OBJECT_NUCLEAR ) + { + oLimit = 45.0f*PI/180.0f; + } + else + { + oLimit = 45.0f*PI/180.0f; + oAngle += PI; // is behind + } + oAngle = NormAngle(oAngle); // 0..2*PI + angle = RotateAngle(iPos.x-oPos.x, oPos.z-iPos.z); // CW ! + if ( !TestAngle(angle, oAngle-oLimit, oAngle+oLimit) ) continue; + + distance = Abs(Length(oPos, iPos)-TAKE_DIST); + if ( distance <= dLimit ) + { + angle = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! + if ( TestAngle(angle, iAngle-aLimit, iAngle+aLimit) ) + { + character = pObj->RetCharacter(); + height = character->posPower.y; + pos = oPos; + return pObj; + } + } + } + + distance = 1000000.0f; + angle = 0.0f; + return 0; +} + +// Takes the object placed in front. + +BOOL CTaskManip::TruckTakeObject() +{ + CObject* fret; + CObject* other; + D3DMATRIX matRotate; + D3DVECTOR pos; + float angle, dist; + + if ( m_arm == TMA_GRAB ) // takes immediately? + { + fret = m_object->RetFret(); + if ( fret == 0 ) return FALSE; // nothing to take? + m_fretType = fret->RetType(); + + if ( m_object->RetType() == OBJECT_HUMAN || + m_object->RetType() == OBJECT_TECH ) + { + fret->SetTruck(m_object); + fret->SetTruckPart(4); // takes with the hand + + fret->SetPosition(0, D3DVECTOR(1.7f, -0.5f, 1.1f)); + fret->SetAngleY(0, 0.1f); + fret->SetAngleX(0, 0.0f); + fret->SetAngleZ(0, 0.8f); + } + else if ( m_bSubm ) + { + fret->SetTruck(m_object); + fret->SetTruckPart(2); // takes with the right claw + + pos = D3DVECTOR(1.1f, -1.0f, 1.0f); // relative + fret->SetPosition(0, pos); + fret->SetAngleX(0, 0.0f); + fret->SetAngleY(0, 0.0f); + fret->SetAngleZ(0, 0.0f); + } + else + { + fret->SetTruck(m_object); + fret->SetTruckPart(3); // takes with the hand + + pos = D3DVECTOR(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) + fret->SetPosition(0, pos); + fret->SetAngleX(0, 0.0f); + fret->SetAngleZ(0, PI/2.0f); + fret->SetAngleY(0, 0.0f); + } + + m_object->SetFret(fret); // takes + } + + if ( m_arm == TMA_FFRONT ) // takes on the ground in front? + { + fret = SearchTakeFrontObject(FALSE, pos, dist, angle); + if ( fret == 0 ) return FALSE; // nothing to take? + m_fretType = fret->RetType(); + + if ( m_bSubm ) + { + fret->SetTruck(m_object); + fret->SetTruckPart(2); // takes with the right claw + + pos = D3DVECTOR(1.1f, -1.0f, 1.0f); // relative + fret->SetPosition(0, pos); + fret->SetAngleX(0, 0.0f); + fret->SetAngleY(0, 0.0f); + fret->SetAngleZ(0, 0.0f); + } + else + { + fret->SetTruck(m_object); + fret->SetTruckPart(3); // takes with the hand + + pos = D3DVECTOR(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) + fret->SetPosition(0, pos); + fret->SetAngleX(0, 0.0f); + fret->SetAngleZ(0, PI/2.0f); + fret->SetAngleY(0, 0.0f); + } + + m_object->SetFret(fret); // takes + } + + if ( m_arm == TMA_FBACK ) // takes on the ground behind? + { + fret = SearchTakeBackObject(FALSE, pos, dist, angle); + if ( fret == 0 ) return FALSE; // nothing to take? + m_fretType = fret->RetType(); + + fret->SetTruck(m_object); + fret->SetTruckPart(3); // takes with the hand + + pos = D3DVECTOR(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) + fret->SetPosition(0, pos); + fret->SetAngleX(0, 0.0f); + fret->SetAngleZ(0, PI/2.0f); + fret->SetAngleY(0, 0.0f); + + m_object->SetFret(fret); // takes + } + + if ( m_arm == TMA_POWER ) // takes battery in the back? + { + fret = m_object->RetPower(); + if ( fret == 0 ) return FALSE; // no battery? + m_fretType = fret->RetType(); + + pos = D3DVECTOR(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) + fret->SetPosition(0, pos); + fret->SetAngleX(0, 0.0f); + fret->SetAngleZ(0, PI/2.0f); + fret->SetAngleY(0, 0.0f); + fret->SetTruckPart(3); // takes with the hand + + m_object->SetPower(0); + m_object->SetFret(fret); // takes + } + + if ( m_arm == TMA_OTHER ) // battery takes from friend? + { + other = SearchOtherObject(FALSE, pos, dist, angle, m_height); + if ( other == 0 ) return FALSE; + + fret = other->RetPower(); + if ( fret == 0 ) return FALSE; // the other does not have a battery? + m_fretType = fret->RetType(); + + other->SetPower(0); + fret->SetTruck(m_object); + fret->SetTruckPart(3); // takes with the hand + + pos = D3DVECTOR(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) + fret->SetPosition(0, pos); + fret->SetAngleX(0, 0.0f); + fret->SetAngleZ(0, PI/2.0f); + fret->SetAngleY(0, 0.0f); + + m_object->SetFret(fret); // takes + } + + return TRUE; +} + +// Deposes the object taken. + +BOOL CTaskManip::TruckDeposeObject() +{ + Character* character; + CObject* fret; + CObject* other; + D3DMATRIX* mat; + D3DVECTOR pos; + float angle, dist; + + if ( m_arm == TMA_FFRONT ) // deposits on the ground in front? + { + fret = m_object->RetFret(); + if ( fret == 0 ) return FALSE; // nothing transported? + m_fretType = fret->RetType(); + + mat = fret->RetWorldMatrix(0); + pos = Transform(*mat, D3DVECTOR(0.0f, 1.0f, 0.0f)); + m_terrain->MoveOnFloor(pos); + fret->SetPosition(0, pos); + fret->SetAngleY(0, m_object->RetAngleY(0)+PI/2.0f); + fret->SetAngleX(0, 0.0f); + fret->SetAngleZ(0, 0.0f); + fret->FloorAdjust(); // plate well on the ground + + fret->SetTruck(0); + m_object->SetFret(0); // deposit + } + + if ( m_arm == TMA_FBACK ) // deposited on the ground behind? + { + fret = m_object->RetFret(); + if ( fret == 0 ) return FALSE; // nothing transported? + m_fretType = fret->RetType(); + + mat = fret->RetWorldMatrix(0); + pos = Transform(*mat, D3DVECTOR(0.0f, 1.0f, 0.0f)); + m_terrain->MoveOnFloor(pos); + fret->SetPosition(0, pos); + fret->SetAngleY(0, m_object->RetAngleY(0)+PI/2.0f); + fret->SetAngleX(0, 0.0f); + fret->SetAngleZ(0, 0.0f); + + fret->SetTruck(0); + m_object->SetFret(0); // deposit + } + + if ( m_arm == TMA_POWER ) // deposits battery in the back? + { + fret = m_object->RetFret(); + if ( fret == 0 ) return FALSE; // nothing transported? + m_fretType = fret->RetType(); + + if ( m_object->RetPower() != 0 ) return FALSE; + + fret->SetTruck(m_object); + fret->SetTruckPart(0); // carried by the base + + character = m_object->RetCharacter(); + fret->SetPosition(0, character->posPower); + fret->SetAngleY(0, 0.0f); + fret->SetAngleX(0, 0.0f); + fret->SetAngleZ(0, 0.0f); + + m_object->SetPower(fret); // uses + m_object->SetFret(0); + } + + if ( m_arm == TMA_OTHER ) // deposits battery on friend? + { + other = SearchOtherObject(FALSE, pos, dist, angle, m_height); + if ( other == 0 ) return FALSE; + + fret = other->RetPower(); + if ( fret != 0 ) return FALSE; // the other already has a battery? + + fret = m_object->RetFret(); + if ( fret == 0 ) return FALSE; + m_fretType = fret->RetType(); + + other->SetPower(fret); + fret->SetTruck(other); + + character = other->RetCharacter(); + fret->SetPosition(0, character->posPower); + fret->SetAngleY(0, 0.0f); + fret->SetAngleX(0, 0.0f); + fret->SetAngleZ(0, 0.0f); + fret->SetTruckPart(0); // carried by the base + + m_object->SetFret(0); // deposit + } + + return TRUE; +} + +// Seeks if a location allows to deposit an object. + +BOOL CTaskManip::IsFreeDeposeObject(D3DVECTOR pos) +{ + CObject* pObj; + D3DMATRIX* mat; + D3DVECTOR iPos, oPos; + float oRadius; + int i, j; + + mat = m_object->RetWorldMatrix(0); + iPos = Transform(*mat, pos); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj == m_object ) continue; + if ( !pObj->RetActif() ) continue; // inactive? + if ( pObj->RetTruck() != 0 ) continue; // object transported? + + j = 0; + while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) + { + if ( Length(iPos, oPos)-(oRadius+1.0f) < 2.0f ) + { + return FALSE; // location occupied + } + } + } + return TRUE; // location free +} + +// Plays the sound of the manipulator arm. + +void CTaskManip::SoundManip(float time, float amplitude, float frequency) +{ + int i; + + i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f*frequency, TRUE); + m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, 0.1f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP); +} + diff --git a/src/object/task/taskmanip.h b/src/object/task/taskmanip.h new file mode 100644 index 0000000..bc746cf --- /dev/null +++ b/src/object/task/taskmanip.h @@ -0,0 +1,109 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskmanip.h + +#ifndef _TASKMANIP_H_ +#define _TASKMANIP_H_ + + +#include "task.h" +#include "misc.h" +#include "d3dengine.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + + +enum TaskManipOrder +{ + TMO_AUTO = 0, // deposits or takes automatically + TMO_GRAB = 1, // takes an object + TMO_DROP = 2, // deposits the object +}; + +enum TaskManipArm +{ + TMA_NEUTRAL = 1, // empty arm at rest + TMA_STOCK = 2, // right arm resting + TMA_FFRONT = 3, // arm on the ground + TMA_FBACK = 4, // arm behind the robot + TMA_POWER = 5, // arm behind the robot + TMA_OTHER = 6, // arm behind a friend robot + TMA_GRAB = 7, // takes immediately +}; + +enum TaskManipHand +{ + TMH_OPEN = 1, // open clamp + TMH_CLOSE = 2, // closed clamp +}; + + + +class CTaskManip : public CTask +{ +public: + CTaskManip(CInstanceManager* iMan, CObject* object); + ~CTaskManip(); + + BOOL EventProcess(const Event &event); + + Error Start(TaskManipOrder order, TaskManipArm arm); + Error IsEnded(); + BOOL Abort(); + +protected: + void InitAngle(); + CObject* SearchTakeUnderObject(D3DVECTOR &pos, float dLimit); + CObject* SearchTakeFrontObject(BOOL bAdvance, D3DVECTOR &pos, float &distance, float &angle); + CObject* SearchTakeBackObject(BOOL bAdvance, D3DVECTOR &pos, float &distance, float &angle); + CObject* SearchOtherObject(BOOL bAdvance, D3DVECTOR &pos, float &distance, float &angle, float &height); + BOOL TruckTakeObject(); + BOOL TruckDeposeObject(); + BOOL IsFreeDeposeObject(D3DVECTOR pos); + void SoundManip(float time, float amplitude=1.0f, float frequency=1.0f); + +protected: + TaskManipOrder m_order; + TaskManipArm m_arm; + TaskManipHand m_hand; + int m_step; + float m_speed; + float m_progress; + float m_initialAngle[5]; + float m_finalAngle[5]; + float m_height; + float m_advanceLength; + float m_energy; + BOOL m_bError; + BOOL m_bTurn; + BOOL m_bSubm; + BOOL m_bBee; + float m_angle; + float m_move; + D3DVECTOR m_targetPos; + float m_timeLimit; + ObjectType m_fretType; +}; + + +#endif //_TASKMANIP_H_ diff --git a/src/object/task/taskpen.cpp b/src/object/task/taskpen.cpp new file mode 100644 index 0000000..7d95f21 --- /dev/null +++ b/src/object/task/taskpen.cpp @@ -0,0 +1,304 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskpen.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "sound.h" +#include "motion.h" +#include "motionant.h" +#include "motionspider.h" +#include "task.h" +#include "taskpen.h" + + + +// Object's constructor. + +CTaskPen::CTaskPen(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); +} + +// Object's destructor. + +CTaskPen::~CTaskPen() +{ +} + + +// Management of an event. + +BOOL CTaskPen::EventProcess(const Event &event) +{ + D3DVECTOR pos, speed; + FPOINT dim; + int i; + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_bError ) return FALSE; + + if ( m_delay == 0.0f ) + { + m_progress = 1.0f; + } + else + { + m_progress += event.rTime*(1.0f/m_delay); // others advance + if ( m_progress > 1.0f ) m_progress = 1.0f; + } + + m_time += event.rTime; + + if ( m_phase == TPP_UP ) // back the pencil + { + i = AngleToRank(m_object->RetAngleY(1)); + pos = m_object->RetPosition(10+i); + pos.y = -3.2f*(1.0f-m_progress); + m_object->SetPosition(10+i, pos); + } + + if ( m_phase == TPP_TURN ) // turns the carousel? + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_supportPos; + pos.x += (Rand()-0.5f)*5.0f; + pos.z += (Rand()-0.5f)*5.0f; + speed.x = (Rand()-0.5f)*3.0f; + speed.z = (Rand()-0.5f)*3.0f; + speed.y = Rand()*2.0f; + dim.x = Rand()*1.5f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); + } + + m_object->SetAngleY(1, m_oldAngle+(m_newAngle-m_oldAngle)*m_progress); + } + + if ( m_phase == TPP_DOWN ) // down the pencil? + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_supportPos; + pos.x += (Rand()-0.5f)*5.0f; + pos.z += (Rand()-0.5f)*5.0f; + speed.x = (Rand()-0.5f)*3.0f; + speed.z = (Rand()-0.5f)*3.0f; + speed.y = Rand()*5.0f; + dim.x = Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIVAPOR, 4.0f); + } + + i = AngleToRank(m_object->RetAngleY(1)); + pos = m_object->RetPosition(10+i); + if ( m_timeDown == 0.0f ) + { + pos.y = 0.0f; + } + else + { + pos.y = -3.2f*Bounce(Min(m_progress*1.8f, 1.0f)); + } + m_object->SetPosition(10+i, pos); + } + + return TRUE; +} + + +// Assigns the goal has achieved. + +Error CTaskPen::Start(BOOL bDown, int color) +{ + D3DVECTOR pos; + D3DMATRIX* mat; + ObjectType type; + int i; + + m_bError = TRUE; // operation impossible + + type = m_object->RetType(); + if ( type != OBJECT_MOBILEdr ) return ERR_FIRE_VEH; + + m_bError = FALSE; // ok + + m_oldAngle = m_object->RetAngleY(1); + m_newAngle = ColorToAngle(color); + + i = AngleToRank(m_oldAngle); + pos = m_object->RetPosition(10+i); + + if ( pos.y == 0.0f ) // pencil at the top? + { + m_timeUp = 0.0f; + } + else // pencil on the bottom? + { + m_timeUp = 1.0f; // must rise up + } + + if ( bDown ) // must go down ? + { + m_timeDown = 0.7f; + } + else + { + m_timeDown = 0.0f; + } + + mat = m_object->RetWorldMatrix(0); + pos = D3DVECTOR(-3.0f, 7.0f, 0.0f); + pos = Transform(*mat, pos); // position of carousel + m_supportPos = pos; + + m_phase = TPP_UP; + m_progress = 0.0f; + m_delay = m_timeUp; + m_time = 0.0f; + + if ( m_timeUp > 0.0f ) + { + SoundManip(m_timeUp, 1.0f, 0.5f); + } + + m_lastParticule = 0.0f; + +//? m_camera->StartCentering(m_object, PI*0.60f, 99.9f, 5.0f, 0.5f); + + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskPen::IsEnded() +{ + if ( m_engine->RetPause() ) return ERR_CONTINUE; + if ( m_bError ) return ERR_STOP; + + if ( m_progress < 1.0f ) return ERR_CONTINUE; + m_progress = 0.0f; + + if ( m_phase == TPP_UP ) + { + m_phase = TPP_TURN; + m_progress = 0.0f; + m_delay = Abs(m_oldAngle-m_newAngle)/PI; + m_time = 0.0f; + m_lastParticule = 0.0f; + if ( m_delay > 0.0f ) + { + SoundManip(m_delay, 1.0f, 1.0f); + } + return ERR_CONTINUE; + } + + if ( m_phase == TPP_TURN ) + { + m_sound->Play(SOUND_PSHHH2, m_supportPos, 1.0f, 1.4f); + m_phase = TPP_DOWN; + m_progress = 0.0f; + m_delay = m_timeDown; + m_time = 0.0f; + m_lastParticule = 0.0f; + return ERR_CONTINUE; + } + + Abort(); + return ERR_STOP; +} + +// Suddenly ends the current action. + +BOOL CTaskPen::Abort() +{ +//? m_camera->StopCentering(m_object, 0.5f); + return TRUE; +} + + +// Plays the sound of the manipulator arm. + +void CTaskPen::SoundManip(float time, float amplitude, float frequency) +{ + int i; + + i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f*frequency, TRUE); + m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, 0.1f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP); +} + + +// Converting a angle to number of pencil. + +int CTaskPen::AngleToRank(float angle) +{ +//? return (int)(angle/(-45.0f*PI/180.0f)); + angle = -angle; + angle += (45.0f*PI/180.0f)/2.0f; + return (int)(angle/(45.0f*PI/180.0f)); +} + +// Converting a color to the angle of carousel of pencils. + +float CTaskPen::ColorToAngle(int color) +{ + return -45.0f*PI/180.0f*ColorToRank(color); +} + +// Converting a color number to the pencil (0 .. 7). + +int CTaskPen::ColorToRank(int color) +{ + if ( color == 8 ) return 1; // yellow + if ( color == 7 ) return 2; // orange + if ( color == 5 ) return 2; // pink + if ( color == 4 ) return 3; // red + if ( color == 6 ) return 4; // purple + if ( color == 14 ) return 5; // blue + if ( color == 15 ) return 5; // light blue + if ( color == 12 ) return 6; // green + if ( color == 13 ) return 6; // light green + if ( color == 10 ) return 7; // brown + if ( color == 9 ) return 7; // beige + return 0; // black +} + diff --git a/src/object/task/taskpen.h b/src/object/task/taskpen.h new file mode 100644 index 0000000..752a52d --- /dev/null +++ b/src/object/task/taskpen.h @@ -0,0 +1,77 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskpen.h + +#ifndef _TASKSPEN_H_ +#define _TASKSPEN_H_ + + +#include "d3dengine.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + + +enum TaskPenPhase +{ + TPP_UP = 1, // rises the pencil + TPP_TURN = 2, // turns the carousel + TPP_DOWN = 3, // descends the pencil +}; + + + +class CTaskPen : public CTask +{ +public: + CTaskPen(CInstanceManager* iMan, CObject* object); + ~CTaskPen(); + + BOOL EventProcess(const Event &event); + + Error Start(BOOL bDown, int color); + Error IsEnded(); + BOOL Abort(); + +protected: + void SoundManip(float time, float amplitude, float frequency); + int AngleToRank(float angle); + float ColorToAngle(int color); + int ColorToRank(int color); + +protected: + BOOL m_bError; + TaskPenPhase m_phase; + float m_progress; + float m_delay; + float m_time; + float m_lastParticule; + D3DVECTOR m_supportPos; + + float m_timeUp; + float m_oldAngle; + float m_newAngle; + float m_timeDown; +}; + + +#endif //_TASKSPEN_H_ diff --git a/src/object/task/taskrecover.cpp b/src/object/task/taskrecover.cpp new file mode 100644 index 0000000..1284bb5 --- /dev/null +++ b/src/object/task/taskrecover.cpp @@ -0,0 +1,431 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskrecover.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "sound.h" +#include "displaytext.h" +#include "task.h" +#include "taskrecover.h" + + +#define ENERGY_RECOVER 0.25f // energy consumed by recovery +#define RECOVER_DIST 11.8f + + + +// Object's constructor. + +CTaskRecover::CTaskRecover(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); + + m_ruin = 0; + m_soundChannel = -1; +} + +// Object's constructor. + +CTaskRecover::~CTaskRecover() +{ +} + + +// Management of an event. + +BOOL CTaskRecover::EventProcess(const Event &event) +{ + CObject* power; + D3DVECTOR pos, speed; + FPOINT dim; + float a, g, cirSpeed, angle, energy, dist, linSpeed; + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_bError ) return FALSE; + + if ( m_phase == TRP_TURN ) // preliminary rotation? + { + a = m_object->RetAngleY(0); + g = m_angle; + cirSpeed = Direction(a, g)*1.0f; + if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; + if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; + + m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right + return TRUE; + } + + m_progress += event.rTime*m_speed; // others advance + m_time += event.rTime; + + if ( m_phase == TRP_DOWN ) + { + angle = Prop(126, -10, m_progress); + m_object->SetAngleZ(2, angle); + m_object->SetAngleZ(4, angle); + + angle = Prop(-144, 0, m_progress); + m_object->SetAngleZ(3, angle); + m_object->SetAngleZ(5, angle); + } + + if ( m_phase == TRP_MOVE ) // preliminary forward/backward? + { + dist = Length(m_object->RetPosition(0), m_ruin->RetPosition(0)); + linSpeed = 0.0f; + if ( dist > RECOVER_DIST ) linSpeed = 1.0f; + if ( dist < RECOVER_DIST ) linSpeed = -1.0f; + m_physics->SetMotorSpeedX(linSpeed); // forward/backward + return TRUE; + } + + if ( m_phase == TRP_OPER ) + { + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + power->SetEnergy(energy-ENERGY_RECOVER*event.rTime*m_speed); + } + + speed.x = (Rand()-0.5f)*0.1f*m_progress; + speed.y = (Rand()-0.5f)*0.1f*m_progress; + speed.z = (Rand()-0.5f)*0.1f*m_progress; + m_ruin->SetCirVibration(speed); + + if ( m_progress >= 0.75f ) + { + m_ruin->SetZoom(0, 1.0f-(m_progress-0.75f)/0.25f); + } + + if ( m_progress > 0.5f && m_progress < 0.8f ) + { + m_metal->SetZoom(0, (m_progress-0.5f)/0.3f); + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.02f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_recoverPos; + pos.x += (Rand()-0.5f)*8.0f*(1.0f-m_progress); + pos.z += (Rand()-0.5f)*8.0f*(1.0f-m_progress); + pos.y -= 4.0f; + speed.x = (Rand()-0.5f)*0.0f; + speed.z = (Rand()-0.5f)*0.0f; + speed.y = Rand()*15.0f; + dim.x = Rand()*2.0f+1.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIRECOVER, 1.0f, 0.0f, 0.0f); + } + } + + if ( m_phase == TRP_UP ) + { + angle = Prop(-10, 126, m_progress); + m_object->SetAngleZ(2, angle); + m_object->SetAngleZ(4, angle); + + angle = Prop(0, -144, m_progress); + m_object->SetAngleZ(3, angle); + m_object->SetAngleZ(5, angle); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.02f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_recoverPos; + pos.y -= 4.0f; + speed.x = (Rand()-0.5f)*0.0f; + speed.z = (Rand()-0.5f)*0.0f; + speed.y = Rand()*15.0f; + dim.x = Rand()*2.0f+1.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIRECOVER, 1.0f, 0.0f, 0.0f); + } + } + + return TRUE; +} + + +// Assigns the goal was achieved. + +Error CTaskRecover::Start() +{ + CObject* power; + D3DMATRIX* mat; + D3DVECTOR pos, iPos, oPos; + float energy; + + ObjectType type; + + m_bError = TRUE; // operation impossible + if ( !m_physics->RetLand() ) return ERR_RECOVER_VEH; + + type = m_object->RetType(); + if ( type != OBJECT_MOBILErr ) return ERR_RECOVER_VEH; + + power = m_object->RetPower(); + if ( power == 0 ) return ERR_RECOVER_ENERGY; + energy = power->RetEnergy(); + if ( energy < ENERGY_RECOVER/power->RetCapacity()+0.05f ) return ERR_RECOVER_ENERGY; + + mat = m_object->RetWorldMatrix(0); + pos = D3DVECTOR(RECOVER_DIST, 3.3f, 0.0f); + pos = Transform(*mat, pos); // position in front + m_recoverPos = pos; + + m_ruin = SearchRuin(); + if ( m_ruin == 0 ) return ERR_RECOVER_NULL; + m_ruin->SetLock(TRUE); // ruin no longer usable + + iPos = m_object->RetPosition(0); + oPos = m_ruin->RetPosition(0); + m_angle = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! + + m_metal = 0; + + m_phase = TRP_TURN; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + m_time = 0.0f; + m_lastParticule = 0.0f; + + m_bError = FALSE; // ok + + m_camera->StartCentering(m_object, PI*0.85f, 99.9f, 10.0f, 3.0f); + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskRecover::IsEnded() +{ + D3DMATRIX* mat; + D3DVECTOR pos, speed, goal; + FPOINT dim; + float angle, dist, time; + int i; + + if ( m_engine->RetPause() ) return ERR_CONTINUE; + if ( m_bError ) return ERR_STOP; + + if ( m_phase == TRP_TURN ) // preliminary rotation? + { + angle = m_object->RetAngleY(0); + angle = NormAngle(angle); // 0..2*PI + + if ( TestAngle(angle, m_angle-PI*0.01f, m_angle+PI*0.01f) ) + { + m_physics->SetMotorSpeedZ(0.0f); + + dist = Length(m_object->RetPosition(0), m_ruin->RetPosition(0)); + if ( dist > RECOVER_DIST ) + { + time = m_physics->RetLinTimeLength(dist-RECOVER_DIST, 1.0f); + m_speed = 1.0f/time; + } + else + { + time = m_physics->RetLinTimeLength(RECOVER_DIST-dist, -1.0f); + m_speed = 1.0f/time; + } + m_phase = TRP_MOVE; + m_progress = 0.0f; + } + return ERR_CONTINUE; + } + + if ( m_phase == TRP_MOVE ) // preliminary advance? + { + dist = Length(m_object->RetPosition(0), m_ruin->RetPosition(0)); + + if ( dist >= RECOVER_DIST-1.0f && + dist <= RECOVER_DIST+1.0f ) + { + m_physics->SetMotorSpeedX(0.0f); + + mat = m_object->RetWorldMatrix(0); + pos = D3DVECTOR(RECOVER_DIST, 3.3f, 0.0f); + pos = Transform(*mat, pos); // position in front + m_recoverPos = pos; + + i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.9f, TRUE); + m_sound->AddEnvelope(i, 1.0f, 1.5f, 0.3f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 1.0f, 1.5f, 1.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.0f, 0.9f, 0.3f, SOPER_STOP); + + m_phase = TRP_DOWN; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + m_time = 0.0f; + } + else + { + if ( m_progress > 1.0f ) // timeout? + { + m_ruin->SetLock(FALSE); // usable again + m_camera->StopCentering(m_object, 2.0f); + return ERR_RECOVER_NULL; + } + } + return ERR_CONTINUE; + } + + if ( m_progress < 1.0f ) return ERR_CONTINUE; + m_progress = 0.0f; + + if ( m_phase == TRP_DOWN ) + { + m_metal = new CObject(m_iMan); + if ( !m_metal->CreateResource(m_recoverPos, 0.0f, OBJECT_METAL) ) + { + delete m_metal; + m_metal = 0; + Abort(); + m_bError = TRUE; + m_displayText->DisplayError(ERR_TOOMANY, m_object); + return ERR_STOP; + } + m_metal->SetLock(TRUE); // metal not yet usable + m_metal->SetZoom(0, 0.0f); + + mat = m_object->RetWorldMatrix(0); + pos = D3DVECTOR(RECOVER_DIST, 3.1f, 3.9f); + pos = Transform(*mat, pos); + goal = D3DVECTOR(RECOVER_DIST, 3.1f, -3.9f); + goal = Transform(*mat, goal); + m_particule->CreateRay(pos, goal, PARTIRAY2, + FPOINT(2.0f, 2.0f), 8.0f); + + m_soundChannel = m_sound->Play(SOUND_RECOVER, m_ruin->RetPosition(0), 0.0f, 1.0f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 0.6f, 1.0f, 2.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.6f, 1.0f, 4.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.7f, 2.0f, SOPER_STOP); + + m_phase = TRP_OPER; + m_speed = 1.0f/8.0f; + return ERR_CONTINUE; + } + + if ( m_phase == TRP_OPER ) + { + m_metal->SetZoom(0, 1.0f); + + m_ruin->DeleteObject(); // destroys the ruin + delete m_ruin; + m_ruin = 0; + + m_soundChannel = -1; + + i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.9f, TRUE); + m_sound->AddEnvelope(i, 1.0f, 1.5f, 0.3f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 1.0f, 1.5f, 1.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.0f, 0.9f, 0.3f, SOPER_STOP); + + m_phase = TRP_UP; + m_speed = 1.0f/1.5f; + return ERR_CONTINUE; + } + + m_metal->SetLock(FALSE); // metal usable + + Abort(); + return ERR_STOP; +} + +// Suddenly ends the current action. + +BOOL CTaskRecover::Abort() +{ + m_object->SetAngleZ(2, 126.0f*PI/180.0f); + m_object->SetAngleZ(4, 126.0f*PI/180.0f); + m_object->SetAngleZ(3, -144.0f*PI/180.0f); + m_object->SetAngleZ(5, -144.0f*PI/180.0f); // rest + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + m_camera->StopCentering(m_object, 2.0f); + return TRUE; +} + + +// Seeks if a ruin is in front of the vehicle. + +CObject* CTaskRecover::SearchRuin() +{ + CObject *pObj, *pBest; + D3DVECTOR oPos; + ObjectType type; + float dist, min; + int i; + + pBest = 0; + min = 100000.0f; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type == OBJECT_RUINmobilew1 || + type == OBJECT_RUINmobilew2 || + type == OBJECT_RUINmobilet1 || + type == OBJECT_RUINmobilet2 || + type == OBJECT_RUINmobiler1 || + type == OBJECT_RUINmobiler2 ) // vehicle in ruin? + { + oPos = pObj->RetPosition(0); + dist = Length(oPos, m_recoverPos); + if ( dist > 40.0f ) continue; + + if ( dist < min ) + { + min = dist; + pBest = pObj; + } + } + + } + return pBest; +} + diff --git a/src/object/task/taskrecover.h b/src/object/task/taskrecover.h new file mode 100644 index 0000000..cc2adce --- /dev/null +++ b/src/object/task/taskrecover.h @@ -0,0 +1,75 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskrecover.h + +#ifndef _TASKSRECOVER_H_ +#define _TASKSRECOVER_H_ + + +#include "d3dengine.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + + +enum TaskRecoverPhase +{ + TRP_TURN = 1, // turns + TRP_MOVE = 2, // advance + TRP_DOWN = 3, // descends + TRP_OPER = 4, // operates + TRP_UP = 5, // back +}; + + + +class CTaskRecover : public CTask +{ +public: + CTaskRecover(CInstanceManager* iMan, CObject* object); + ~CTaskRecover(); + + BOOL EventProcess(const Event &event); + + Error Start(); + Error IsEnded(); + BOOL Abort(); + +protected: + CObject* SearchRuin(); + +protected: + TaskRecoverPhase m_phase; + float m_progress; + float m_speed; + float m_time; + float m_angle; + float m_lastParticule; + BOOL m_bError; + CObject* m_ruin; + CObject* m_metal; + D3DVECTOR m_recoverPos; + int m_soundChannel; +}; + + +#endif //_TASKSRECOVER_H_ diff --git a/src/object/task/taskreset.cpp b/src/object/task/taskreset.cpp new file mode 100644 index 0000000..a626c02 --- /dev/null +++ b/src/object/task/taskreset.cpp @@ -0,0 +1,345 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskreset.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "sound.h" +#include "robotmain.h" +#include "task.h" +#include "taskreset.h" + + + +#define RESET_DELAY_ZOOM 0.7f +#define RESET_DELAY_MOVE 0.7f + + + + +// Object's constructor. + +CTaskReset::CTaskReset(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); +} + +// Object's destructor. + +CTaskReset::~CTaskReset() +{ +} + + +// Management of an event. + +BOOL CTaskReset::EventProcess(const Event &event) +{ + D3DVECTOR pos, speed; + FPOINT dim; + float angle, duration; + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_bError ) return FALSE; + + m_time += event.rTime; + m_progress += event.rTime*m_speed; + + if ( m_phase == TRSP_ZOUT ) + { + angle = m_iAngle; + angle += powf(m_progress*5.0f, 2.0f); // accelerates + m_object->SetAngleY(0, angle); + m_object->SetZoom(0, 1.0f-m_progress); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_begin; + pos.x += (Rand()-0.5f)*5.0f; + pos.z += (Rand()-0.5f)*5.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 5.0f+Rand()*5.0f; + dim.x = Rand()*2.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINTb, 2.0f); + + pos = m_begin; + speed.x = (Rand()-0.5f)*20.0f; + speed.z = (Rand()-0.5f)*20.0f; + speed.y = Rand()*10.0f; + speed *= 1.0f-m_progress*0.5f; + pos += speed*1.5f; + speed = -speed; + dim.x = 0.6f; + dim.y = dim.x; + pos.y += dim.y; + duration = Rand()*1.5f+1.5f; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK6, + duration, 0.0f, + duration*0.9f, 0.7f); + } + } + + if ( m_phase == TRSP_MOVE ) + { + pos = m_begin+(m_goal-m_begin)*m_progress; + m_object->SetPosition(0, pos); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos.x += (Rand()-0.5f)*5.0f; + pos.z += (Rand()-0.5f)*5.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 2.0f+Rand()*2.0f; + dim.x = Rand()*2.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINTb, 2.0f); + } + } + + if ( m_phase == TRSP_ZIN ) + { + angle = m_angle.y; + angle += -powf((1.0f-m_progress)*5.0f, 2.0f); // slows + m_object->SetAngleY(0, angle); + m_object->SetZoom(0, m_progress); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_goal; + pos.x += (Rand()-0.5f)*5.0f; + pos.z += (Rand()-0.5f)*5.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 5.0f+Rand()*5.0f; + dim.x = Rand()*2.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINTb, 2.0f); + + pos = m_goal; + speed.x = (Rand()-0.5f)*20.0f; + speed.z = (Rand()-0.5f)*20.0f; + speed.y = Rand()*10.0f; + speed *= 0.5f+m_progress*0.5f; + dim.x = 0.6f; + dim.y = dim.x; + pos.y += dim.y; + duration = Rand()*1.5f+1.5f; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK6, + duration, 0.0f, + duration*0.9f, 0.7f); + } + } + + return TRUE; +} + + +// Assigns the goal was achieved. +// A positive angle makes a turn right. + +Error CTaskReset::Start(D3DVECTOR goal, D3DVECTOR angle) +{ + CObject* fret; + int i; + + fret = m_object->RetFret(); + if ( fret != 0 && fret->RetResetCap() == RESET_MOVE ) + { + fret->SetTruck(0); + m_object->SetFret(0); // does nothing + } + + if ( !m_main->RetNiceReset() ) // quick return? + { + m_object->SetPosition(0, goal); + m_object->SetAngle(0, angle); + m_brain->RunProgram(m_object->RetResetRun()); + + m_bError = FALSE; + return ERR_OK; + } + + m_begin = m_object->RetPosition(0); + m_goal = goal; + m_angle = angle; + + if ( SearchVehicle() ) // starting location occupied? + { + m_bError = TRUE; + return ERR_RESET_NEAR; + } + + m_iAngle = m_object->RetAngleY(0); + m_time = 0.0f; + m_phase = TRSP_ZOUT; + m_speed = 1.0f/RESET_DELAY_ZOOM; + m_progress = 0.0f; + m_lastParticule = 0.0f; + + m_object->SetResetBusy(TRUE); + + i = m_sound->Play(SOUND_GGG, m_begin, 1.0f, 2.0f, TRUE); + m_sound->AddEnvelope(i, 0.0f, 0.5f, RESET_DELAY_ZOOM, SOPER_STOP); + + m_bError = FALSE; + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskReset::IsEnded() +{ + CObject* power; + float dist; + int i; + + if ( !m_main->RetNiceReset() ) // quick return? + { + return ERR_STOP; + } + + if ( m_engine->RetPause() ) return ERR_CONTINUE; + if ( m_bError ) return ERR_STOP; + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + if ( m_phase == TRSP_ZOUT ) + { + dist = Length(m_begin, m_goal); + m_phase = TRSP_MOVE; + m_speed = 1.0f/(dist*RESET_DELAY_MOVE/100.0f); + m_progress = 0.0f; + return ERR_CONTINUE; + } + + if ( m_phase == TRSP_MOVE ) + { + m_object->SetPosition(0, m_goal); + m_object->SetAngle(0, m_angle); + + i = m_sound->Play(SOUND_GGG, m_goal, 1.0f, 0.5f, TRUE); + m_sound->AddEnvelope(i, 0.0f, 2.0f, RESET_DELAY_ZOOM, SOPER_STOP); + + m_phase = TRSP_ZIN; + m_speed = 1.0f/RESET_DELAY_ZOOM; + m_progress = 0.0f; + return ERR_CONTINUE; + } + + m_object->SetAngle(0, m_angle); + m_object->SetZoom(0, 1.0f); + + power = m_object->RetPower(); + if ( power != 0 ) + { + power->SetEnergy(power->RetCapacity()); // refueling + } + + m_brain->RunProgram(m_object->RetResetRun()); + m_object->SetResetBusy(FALSE); + return ERR_STOP; +} + + +// Seeks if a vehicle is too close. + +BOOL CTaskReset::SearchVehicle() +{ + CObject* pObj; + D3DVECTOR oPos; + ObjectType type; + float oRadius, dist; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj == m_object ) continue; + + type = pObj->RetType(); + if ( type != OBJECT_HUMAN && + type != OBJECT_TECH && + type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr && + type != OBJECT_MOTHER && + type != OBJECT_ANT && + type != OBJECT_SPIDER && + type != OBJECT_BEE && + type != OBJECT_WORM ) continue; + + if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; + dist = Length(oPos, m_goal)-oRadius; + + if ( dist < 5.0f ) return TRUE; + } + + return FALSE; +} + diff --git a/src/object/task/taskreset.h b/src/object/task/taskreset.h new file mode 100644 index 0000000..a866d1f --- /dev/null +++ b/src/object/task/taskreset.h @@ -0,0 +1,73 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskreset.h + +#ifndef _TASKRESET_H_ +#define _TASKRESET_H_ + + +#include "misc.h" +#include "d3dengine.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + + +enum TaskResetPhase +{ + TRSP_ZOUT = 1, // disappears + TRSP_MOVE = 2, // moves + TRSP_ZIN = 3, // reappears +}; + + + +class CTaskReset : public CTask +{ +public: + CTaskReset(CInstanceManager* iMan, CObject* object); + ~CTaskReset(); + + BOOL EventProcess(const Event &event); + + Error Start(D3DVECTOR goal, D3DVECTOR angle); + Error IsEnded(); + +protected: + BOOL SearchVehicle(); + +protected: + D3DVECTOR m_begin; + D3DVECTOR m_goal; + D3DVECTOR m_angle; + + TaskResetPhase m_phase; + BOOL m_bError; + float m_time; + float m_speed; + float m_progress; + float m_lastParticule; // time of generation last particle + float m_iAngle; +}; + + +#endif //_TASKRESET_H_ diff --git a/src/object/task/tasksearch.cpp b/src/object/task/tasksearch.cpp new file mode 100644 index 0000000..8857e35 --- /dev/null +++ b/src/object/task/tasksearch.cpp @@ -0,0 +1,334 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// tasksearch.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "sound.h" +#include "displaytext.h" +#include "task.h" +#include "tasksearch.h" + + + + +// Object's constructor. + +CTaskSearch::CTaskSearch(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); + + m_hand = TSH_UP; +} + +// Object's destructor. + +CTaskSearch::~CTaskSearch() +{ +} + + +// Management of an event. + +BOOL CTaskSearch::EventProcess(const Event &event) +{ + D3DMATRIX* mat; + D3DVECTOR pos, speed; + FPOINT dim; + float angle; + int i; + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_bError ) return FALSE; + + m_progress += event.rTime*m_speed; // others advance + m_time += event.rTime; + + if ( m_phase == TSP_DOWN || + m_phase == TSP_UP ) + { + for ( i=0 ; i<3 ; i++ ) + { + angle = (m_finalAngle[i]-m_initialAngle[i])*m_progress; + angle += m_initialAngle[i]; + m_object->SetAngleZ(i+1, angle); + } + } + + if ( m_phase == TSP_SEARCH && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + mat = m_object->RetWorldMatrix(0); + pos = D3DVECTOR(6.5f, 0.2f, 0.0f); + pos = Transform(*mat, pos); // sensor position + + speed.x = (Rand()-0.5f)*20.0f; + speed.z = (Rand()-0.5f)*20.0f; + speed.y = 0.0f; + dim.x = Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGAS); + } + + return TRUE; +} + + +// Initializes the initial and final angles. + +void CTaskSearch::InitAngle() +{ + int i; + + if ( m_hand == TSH_UP ) + { + m_finalAngle[0] = 110.0f*PI/180.0f; // arm + m_finalAngle[1] = -110.0f*PI/180.0f; // forearm + m_finalAngle[2] = -65.0f*PI/180.0f; // sensor + } + if ( m_hand == TSH_DOWN ) + { + m_finalAngle[0] = 25.0f*PI/180.0f; // arm + m_finalAngle[1] = -70.0f*PI/180.0f; // forearm + m_finalAngle[2] = -45.0f*PI/180.0f; // sensor + } + + for ( i=0 ; i<3 ; i++ ) + { + m_initialAngle[i] = m_object->RetAngleZ(i+1); + } +} + + +// Assigns the goal was achieved. + +Error CTaskSearch::Start() +{ + ObjectType type; + D3DVECTOR speed; + int i; + + m_bError = TRUE; + if ( !m_physics->RetLand() ) return ERR_SEARCH_FLY; + + speed = m_physics->RetMotorSpeed(); + if ( speed.x != 0.0f || + speed.z != 0.0f ) return ERR_SEARCH_MOTOR; + + type = m_object->RetType(); + if ( type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis ) return ERR_SEARCH_VEH; + + m_hand = TSH_DOWN; + m_phase = TSP_DOWN; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + m_time = 0.0f; + m_lastParticule = 0.0f; + + InitAngle(); + m_bError = FALSE; // ok + + m_camera->StartCentering(m_object, PI*0.50f, 99.9f, 0.0f, 1.0f); + + i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f, TRUE); + m_sound->AddEnvelope(i, 0.5f, 1.0f, 0.1f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.5f, 1.0f, 0.9f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.0f, 0.3f, 0.1f, SOPER_STOP); + + m_physics->SetFreeze(TRUE); // it does not move + + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskSearch::IsEnded() +{ + int i; + + if ( m_engine->RetPause() ) return ERR_CONTINUE; + if ( m_bError ) return ERR_STOP; + + if ( m_progress < 1.0f ) return ERR_CONTINUE; + m_progress = 0.0f; + + if ( m_phase == TSP_DOWN || + m_phase == TSP_UP ) + { + for ( i=0 ; i<3 ; i++ ) + { + m_object->SetAngleZ(i+1, m_finalAngle[i]); + } + } + + if ( m_phase == TSP_DOWN ) + { + m_sound->Play(SOUND_REPAIR, m_object->RetPosition(0)); + + m_phase = TSP_SEARCH; + m_speed = 1.0f/4.0f; + return ERR_CONTINUE; + } + + if ( m_phase == TSP_SEARCH ) + { + CreateMark(); + + m_hand = TSH_UP; + InitAngle(); + + i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f, TRUE); + m_sound->AddEnvelope(i, 0.5f, 1.0f, 0.1f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.5f, 1.0f, 0.9f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.0f, 0.3f, 0.1f, SOPER_STOP); + + m_phase = TSP_UP; + m_speed = 1.0f/1.0f; + return ERR_CONTINUE; + } + + Abort(); + return ERR_STOP; +} + +// Suddenly ends the current action. + +BOOL CTaskSearch::Abort() +{ + m_camera->StopCentering(m_object, 2.0f); + m_physics->SetFreeze(FALSE); // is moving again + return TRUE; +} + + +// Creates a mark if possible. + +BOOL CTaskSearch::CreateMark() +{ + CObject* fret; + ObjectType type; + D3DMATRIX* mat; + D3DVECTOR pos; + TerrainRes res; + Error info; + + mat = m_object->RetWorldMatrix(0); + pos = D3DVECTOR(7.5f, 0.0f, 0.0f); + pos = Transform(*mat, pos); // sensor position + + res = m_terrain->RetResource(pos); + if ( res == TR_NULL ) return FALSE; + + type = OBJECT_NULL; + if ( res == TR_STONE ) + { + type = OBJECT_MARKSTONE; + info = INFO_MARKSTONE; + } + if ( res == TR_URANIUM ) + { + type = OBJECT_MARKURANIUM; + info = INFO_MARKURANIUM; + } + if ( res == TR_POWER ) + { + type = OBJECT_MARKPOWER; + info = INFO_MARKPOWER; + } + if ( res == TR_KEYa ) + { + type = OBJECT_MARKKEYa; + info = INFO_MARKKEYa; + } + if ( res == TR_KEYb ) + { + type = OBJECT_MARKKEYb; + info = INFO_MARKKEYb; + } + if ( res == TR_KEYc ) + { + type = OBJECT_MARKKEYc; + info = INFO_MARKKEYc; + } + if ( res == TR_KEYd ) + { + type = OBJECT_MARKKEYd; + info = INFO_MARKKEYd; + } + if ( type == OBJECT_NULL ) return FALSE; + +//? DeleteMark(type); + + fret = new CObject(m_iMan); + if ( !fret->CreateResource(pos, 0.0f, type) ) + { + delete fret; + m_displayText->DisplayError(ERR_TOOMANY, m_object); + return FALSE; + } + + m_displayText->DisplayError(info, pos, 5.0f, 50.0f); // displays the message + + return TRUE; +} + +// Destroys the marks of a given type. + +void CTaskSearch::DeleteMark(ObjectType type) +{ + CObject* pObj; + D3DVECTOR oPos; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( type == pObj->RetType() ) + { + pObj->DeleteObject(); // removes the mark + delete pObj; + break; + } + } +} + + diff --git a/src/object/task/tasksearch.h b/src/object/task/tasksearch.h new file mode 100644 index 0000000..80970e1 --- /dev/null +++ b/src/object/task/tasksearch.h @@ -0,0 +1,79 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// tasksearch.h + +#ifndef _TASKSEARCH_H_ +#define _TASKSEARCH_H_ + + +#include "misc.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + + +enum TaskSearchHand +{ + TSH_UP = 1, // sensor at the top + TSH_DOWN = 2, // sensor at the bottom +}; + +enum TaskSearchPhase +{ + TSP_DOWN = 1, // descends + TSP_SEARCH = 2, // seeks + TSP_UP = 3, // rises +}; + + + +class CTaskSearch : public CTask +{ +public: + CTaskSearch(CInstanceManager* iMan, CObject* object); + ~CTaskSearch(); + + BOOL EventProcess(const Event &event); + + Error Start(); + Error IsEnded(); + BOOL Abort(); + +protected: + void InitAngle(); + BOOL CreateMark(); + void DeleteMark(ObjectType type); + +protected: + TaskSearchHand m_hand; + TaskSearchPhase m_phase; + float m_progress; + float m_speed; + float m_time; + float m_lastParticule; + float m_initialAngle[3]; + float m_finalAngle[3]; + BOOL m_bError; +}; + + +#endif //_TASKSEARCH_H_ diff --git a/src/object/task/taskshield.cpp b/src/object/task/taskshield.cpp new file mode 100644 index 0000000..9269c4b --- /dev/null +++ b/src/object/task/taskshield.cpp @@ -0,0 +1,573 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskshield.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "light.h" +#include "sound.h" +#include "task.h" +#include "taskshield.h" + + +#define ENERGY_TIME 20.0f // maximum duration if full battery + + + +// Object's constructor. + +CTaskShield::CTaskShield(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); + + m_rankSphere = -1; + m_soundChannel = -1; + m_effectLight = -1; +} + +// Object's destructor. + +CTaskShield::~CTaskShield() +{ + Abort(); +} + + +// Management of an event. + +BOOL CTaskShield::EventProcess(const Event &event) +{ + CObject* power; + D3DMATRIX* mat; + D3DMATRIX matrix; + D3DVECTOR pos, speed, goal, angle; + D3DCOLORVALUE color; + FPOINT dim; + float energy; + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_bError ) return FALSE; + + m_progress += event.rTime*m_speed; // others advance + m_time += event.rTime; + m_delay -= event.rTime; + + mat = m_object->RetWorldMatrix(0); + pos = D3DVECTOR(7.0f, 15.0f, 0.0f); + pos = Transform(*mat, pos); // sphere position + m_shieldPos = pos; + + if ( m_rankSphere != -1 ) + { + m_particule->SetPosition(m_rankSphere, m_shieldPos); + dim.x = RetRadius(); + dim.y = dim.x; + m_particule->SetDimension(m_rankSphere, dim); + } + + if ( m_phase == TS_UP1 ) + { + pos.x = 7.0f; + pos.y = 4.5f+Bounce(m_progress)*3.0f; + pos.z = 0.0f; + m_object->SetPosition(2, pos); + } + + if ( m_phase == TS_UP2 ) + { + pos.x = 0.0f; + pos.y = 1.0f+Bounce(m_progress)*3.0f; + pos.z = 0.0f; + m_object->SetPosition(3, pos); + } + + if ( m_phase == TS_SHIELD ) + { + energy = (1.0f/ENERGY_TIME)*event.rTime; + energy *= RetRadius()/RADIUS_SHIELD_MAX; + power = m_object->RetPower(); + if ( power != 0 ) + { + power->SetEnergy(power->RetEnergy()-energy/power->RetCapacity()); + } + m_energyUsed += energy; + + if ( m_soundChannel == -1 ) + { + m_soundChannel = m_sound->Play(SOUND_SHIELD, m_shieldPos, 0.5f, 0.5f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 2.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 1.0f, SOPER_LOOP); + } + else + { + m_sound->Position(m_soundChannel, m_shieldPos); + } + + pos = m_shieldPos; + pos.y += RetRadius()*(2.0f+sinf(m_time*9.0f)*0.2f); + if ( m_effectLight == -1 ) + { + CreateLight(pos); + } + else + { + m_light->SetLightPos(m_effectLight, pos); + + color.r = 0.0f+sinf(m_time*33.2f)*0.2f; + color.g = 0.5f+sinf(m_time*20.0f)*0.5f; + color.b = 0.5f+sinf(m_time*21.3f)*1.0f; + color.a = 0.0f; + m_light->SetLightColor(m_effectLight, color); + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_shieldPos; + pos.x += (Rand()-0.5f)*5.0f; + pos.z += (Rand()-0.5f)*5.0f; + speed.x = (Rand()-0.5f)*0.0f; + speed.z = (Rand()-0.5f)*0.0f; + speed.y = Rand()*15.0f; + dim.x = Rand()*6.0f+4.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); + } + + if ( m_lastRay+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastRay = m_time; + + pos = m_shieldPos; + dim.x = RetRadius()/20.0f; + dim.y = dim.x; + angle.x = (Rand()-0.5f)*PI*1.2f; + angle.y = 0.0f; + angle.z = (Rand()-0.5f)*PI*1.2f; + MatRotateXZY(matrix, angle); + goal = Transform(matrix, D3DVECTOR(0.0f, RetRadius()-dim.x, 0.0f)); + goal += pos; + m_particule->CreateRay(pos, goal, PARTIRAY2, dim, 0.3f); + } + + if ( m_lastIncrease+0.2f <= m_time ) + { + m_lastIncrease = m_time; + IncreaseShield(); + } + } + + if ( m_phase == TS_SMOKE ) + { + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.5f, 2.0f, SOPER_STOP); + m_soundChannel = -1; + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_shieldPos; + pos.x += (Rand()-0.5f)*5.0f; + pos.z += (Rand()-0.5f)*5.0f; + speed.x = (Rand()-0.5f)*3.0f; + speed.z = (Rand()-0.5f)*3.0f; + speed.y = (Rand()-0.5f)*3.0f; + dim.x = Rand()*1.5f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); + } + } + + if ( m_phase == TS_DOWN1 ) + { + pos.x = 0.0f; + pos.y = 1.0f+(1.0f-Bounce(m_progress))*3.0f; + pos.z = 0.0f; + m_object->SetPosition(3, pos); + } + + if ( m_phase == TS_DOWN2 ) + { + pos.x = 7.0f; + pos.y = 4.5f+(1.0f-Bounce(m_progress))*3.0f; + pos.z = 0.0f; + m_object->SetPosition(2, pos); + } + + return TRUE; +} + + +// Deploys the shield. +// The period is only useful with TSM_UP! + +Error CTaskShield::Start(TaskShieldMode mode, float delay) +{ + CObject* power; + D3DMATRIX* mat; + D3DVECTOR pos, iPos, oPos, speed; + ObjectType type; + float energy; + + if ( mode == TSM_DOWN ) + { + return Stop(); + } + + if ( mode == TSM_UPDATE ) + { + if ( m_object->RetSelect() ) + { + m_brain->UpdateInterface(); + } + return ERR_OK; + } + + type = m_object->RetType(); + if ( type != OBJECT_MOBILErs ) return ERR_SHIELD_VEH; + + m_bError = TRUE; // operation impossible + if ( !m_physics->RetLand() ) return ERR_SHIELD_VEH; + + power = m_object->RetPower(); + if ( power == 0 ) return ERR_SHIELD_ENERGY; + energy = power->RetEnergy(); + if ( energy == 0.0f ) return ERR_SHIELD_ENERGY; + + mat = m_object->RetWorldMatrix(0); + pos = D3DVECTOR(7.0f, 15.0f, 0.0f); + pos = Transform(*mat, pos); // sphere position + m_shieldPos = pos; + + m_sound->Play(SOUND_PSHHH2, m_shieldPos, 1.0f, 0.7f); + + m_phase = TS_UP1; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + m_time = 0.0f; + m_delay = delay; + m_lastParticule = 0.0f; + m_lastRay = 0.0f; + m_lastIncrease = 0.0f; + m_energyUsed = 0.0f; + + m_bError = FALSE; // ok + + if ( m_object->RetSelect() ) + { + m_brain->UpdateInterface(); + } +//? m_camera->StartCentering(m_object, PI*0.85f, -PI*0.15f, RetRadius()+40.0f, 3.0f); + return ERR_OK; +} + +// Returns the shield. + +Error CTaskShield::Stop() +{ + float time; + + if ( m_phase == TS_SHIELD ) + { + m_object->SetShieldRadius(0.0f); + + if ( m_rankSphere != -1 ) + { + m_particule->SetPhase(m_rankSphere, PARPHEND, 3.0f); + m_rankSphere = -1; + } + + if ( m_effectLight != -1 ) + { + m_light->DeleteLight(m_effectLight); + m_effectLight = -1; + } + + time = m_energyUsed*4.0f; + if ( time < 1.0f ) time = 1.0f; + if ( time > 4.0f ) time = 4.0f; + + m_phase = TS_SMOKE; + m_speed = 1.0f/time; + + m_camera->StopCentering(m_object, 4.0f); + + if ( m_object->RetSelect() ) + { + m_brain->UpdateInterface(); + } + return ERR_CONTINUE; + } + + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskShield::IsEnded() +{ + CObject* power; + D3DVECTOR pos, speed; + FPOINT dim; + float energy; + + if ( m_engine->RetPause() ) return ERR_CONTINUE; + if ( m_bError ) return ERR_STOP; + + if ( m_phase == TS_SHIELD ) + { + m_object->SetShieldRadius(RetRadius()); + + power = m_object->RetPower(); + if ( power == 0 ) + { + energy = 0.0f; + } + else + { + energy = power->RetEnergy(); + } + + if ( energy == 0.0f || m_delay <= 0.0f ) + { + Stop(); + } + return ERR_CONTINUE; + } + + if ( m_progress < 1.0f ) return ERR_CONTINUE; + m_progress = 0.0f; + + if ( m_phase == TS_UP1 ) + { + pos.x = 7.0f; + pos.y = 4.5f+3.0f; + pos.z = 0.0f; + m_object->SetPosition(2, pos); + + m_sound->Play(SOUND_PSHHH2, m_shieldPos, 1.0f, 1.0f); + + m_phase = TS_UP2; + m_speed = 1.0f/0.8f; + return ERR_CONTINUE; + } + + if ( m_phase == TS_UP2 ) + { + pos.x = 0.0f; + pos.y = 1.0f+3.0f; + pos.z = 0.0f; + m_object->SetPosition(3, pos); + + m_object->SetShieldRadius(RetRadius()); + + pos = m_shieldPos; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = RetRadius(); + dim.y = dim.x; + m_rankSphere = m_particule->CreateParticule(pos, speed, dim, PARTISPHERE3, 2.0f, 0.0f, 0.0f); + + m_phase = TS_SHIELD; + m_speed = 1.0f/999.9f; + + if ( m_object->RetSelect() ) + { + m_brain->UpdateInterface(); + } + return ERR_CONTINUE; + } + + if ( m_phase == TS_SMOKE ) + { + m_sound->Play(SOUND_PSHHH2, m_shieldPos, 1.0f, 1.0f); + + m_phase = TS_DOWN1; + m_speed = 1.0f/0.8f; + return ERR_CONTINUE; + } + + if ( m_phase == TS_DOWN1 ) + { + m_sound->Play(SOUND_PSHHH2, m_shieldPos, 1.0f, 0.7f); + + m_phase = TS_DOWN2; + m_speed = 1.0f/1.0f; + return ERR_CONTINUE; + } + + Abort(); + return ERR_STOP; +} + +// Indicates whether the action is pending. + +BOOL CTaskShield::IsBusy() +{ + if ( m_phase == TS_SHIELD ) + { + return FALSE; + } + + return TRUE; +} + +// Suddenly ends the current action. + +BOOL CTaskShield::Abort() +{ + D3DVECTOR pos; + + m_object->SetShieldRadius(0.0f); + + pos.x = 7.0f; + pos.y = 4.5f; + pos.z = 0.0f; + m_object->SetPosition(2, pos); + + pos.x = 0.0f; + pos.y = 1.0f; + pos.z = 0.0f; + m_object->SetPosition(3, pos); + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.5f, 2.0f, SOPER_STOP); + m_soundChannel = -1; + } + + if ( m_rankSphere != -1 ) + { + m_particule->SetPhase(m_rankSphere, PARPHEND, 3.0f); + m_rankSphere = -1; + } + + if ( m_effectLight != -1 ) + { + m_light->DeleteLight(m_effectLight); + m_effectLight = -1; + } + + m_camera->StopCentering(m_object, 2.0f); + return TRUE; +} + + +// Creates the light to accompany a pyrotechnic effect. + +BOOL CTaskShield::CreateLight(D3DVECTOR pos) +{ + D3DLIGHT7 light; + + if ( !m_engine->RetLightMode() ) return TRUE; + + ZeroMemory( &light, sizeof(light) ); + light.dltType = D3DLIGHT_SPOT; + light.dcvDiffuse.r = 0.0f; + light.dcvDiffuse.g = 1.0f; + light.dcvDiffuse.b = 2.0f; + light.dvPosition.x = pos.x; + light.dvPosition.y = pos.y; + light.dvPosition.z = pos.z; + light.dvDirection.x = 0.0f; + light.dvDirection.y = -1.0f; // against the bottom + light.dvDirection.z = 0.0f; + light.dvRange = D3DLIGHT_RANGE_MAX; + light.dvFalloff = 1.0f; + light.dvAttenuation0 = 1.0f; + light.dvAttenuation1 = 0.0f; + light.dvAttenuation2 = 0.0f; + light.dvTheta = 0.0f; + light.dvPhi = PI/4.0f; + + m_effectLight = m_light->CreateLight(); + if ( m_effectLight == -1 ) return FALSE; + + m_light->SetLight(m_effectLight, light); + m_light->SetLightIntensity(m_effectLight, 1.0f); + + return TRUE; +} + + +// Repaired the shielded objects within the sphere of the shield. + +void CTaskShield::IncreaseShield() +{ + ObjectType type; + CObject* pObj; + D3DVECTOR oPos; + float dist, shield; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type == OBJECT_MOTHER || + type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_BEE || + type == OBJECT_WORM ) continue; + + oPos = pObj->RetPosition(0); + dist = Length(oPos, m_shieldPos); + if ( dist <= RetRadius()+10.0f ) + { + shield = pObj->RetShield(); + shield += 0.1f; + if ( shield > 1.0f ) shield = 1.0f; + pObj->SetShield(shield); + } + } +} + + +// Returns the radius of the shield. + +float CTaskShield::RetRadius() +{ + return RADIUS_SHIELD_MIN + (RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)*m_object->RetParam(); +} + + + diff --git a/src/object/task/taskshield.h b/src/object/task/taskshield.h new file mode 100644 index 0000000..8ec2d05 --- /dev/null +++ b/src/object/task/taskshield.h @@ -0,0 +1,94 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskshield.h + +#ifndef _TASKSHIELD_H_ +#define _TASKSHIELD_H_ + + +#include "misc.h" +#include "d3dengine.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + +#define RADIUS_SHIELD_MIN 40.0f // minimal radius of the protected zone +#define RADIUS_SHIELD_MAX 100.0f // maximal radius of the protected zone + + +enum TaskShieldPhase +{ + TS_UP1 = 1, // up + TS_UP2 = 2, // up + TS_SHIELD = 3, // shield deployed + TS_SMOKE = 4, // smoke + TS_DOWN1 = 5, // down + TS_DOWN2 = 6, // down +}; + +enum TaskShieldMode +{ + TSM_UP = 1, // deploys shield + TSM_DOWN = 2, // returns the shield + TSM_UPDATE = 3, // radius change +}; + + + +class CTaskShield : public CTask +{ +public: + CTaskShield(CInstanceManager* iMan, CObject* object); + ~CTaskShield(); + + BOOL EventProcess(const Event &event); + + Error Start(TaskShieldMode mode, float delay); + Error IsEnded(); + BOOL IsBusy(); + BOOL Abort(); + +protected: + Error Stop(); + BOOL CreateLight(D3DVECTOR pos); + void IncreaseShield(); + float RetRadius(); + +protected: + TaskShieldPhase m_phase; + float m_progress; + float m_speed; + float m_time; + float m_delay; + float m_lastParticule; + float m_lastRay; + float m_lastIncrease; + float m_energyUsed; + BOOL m_bError; + D3DVECTOR m_shieldPos; + int m_rankSphere; + int m_soundChannel; + int m_effectLight; +}; + + +#endif //_TASKSHIELD_H_ diff --git a/src/object/task/taskspiderexplo.cpp b/src/object/task/taskspiderexplo.cpp new file mode 100644 index 0000000..b655fe6 --- /dev/null +++ b/src/object/task/taskspiderexplo.cpp @@ -0,0 +1,124 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskspiderexplo.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "object.h" +#include "physics.h" +#include "pyro.h" +#include "motion.h" +#include "motionspider.h" +#include "task.h" +#include "taskspiderexplo.h" + + + + +// Object's constructor. + +CTaskSpiderExplo::CTaskSpiderExplo(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); + + m_time = 0.0f; + m_bError = FALSE; +} + +// Object's destructor. + +CTaskSpiderExplo::~CTaskSpiderExplo() +{ +} + + +// Management of an event. + +BOOL CTaskSpiderExplo::EventProcess(const Event &event) +{ + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + // Momentarily stationary object (ant on the back)? + if ( m_object->RetFixed() ) + { + m_bError = TRUE; + return TRUE; + } + + m_time += event.rTime; + + return TRUE; +} + + +// Assigns the goal was achieved. + +Error CTaskSpiderExplo::Start() +{ + m_motion->SetAction(MSS_EXPLO, 1.0f); // swells abdominal + m_time = 0.0f; + + m_physics->SetMotorSpeedX(0.0f); // stops the advance + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + + m_bError = FALSE; + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskSpiderExplo::IsEnded() +{ + CPyro* pyro; + + if ( m_engine->RetPause() ) return ERR_CONTINUE; + + if ( m_bError ) + { + Abort(); + return ERR_STOP; + } + + if ( m_time < 1.0f ) return ERR_CONTINUE; + + pyro = new CPyro(m_iMan); + pyro->Create(PT_SPIDER, m_object); // the spider explodes (suicide) + + Abort(); + return ERR_STOP; +} + +// Suddenly ends the current action. + +BOOL CTaskSpiderExplo::Abort() +{ + return TRUE; +} + diff --git a/src/object/task/taskspiderexplo.h b/src/object/task/taskspiderexplo.h new file mode 100644 index 0000000..fb7f5f6 --- /dev/null +++ b/src/object/task/taskspiderexplo.h @@ -0,0 +1,53 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskspiderexplo.h + +#ifndef _TASKSPIDEREXPLO_H_ +#define _TASKSPIDEREXPLO_H_ + + +#include "misc.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + +class CTaskSpiderExplo : public CTask +{ +public: + CTaskSpiderExplo(CInstanceManager* iMan, CObject* object); + ~CTaskSpiderExplo(); + + BOOL EventProcess(const Event &event); + + Error Start(); + Error IsEnded(); + BOOL Abort(); + +protected: + +protected: + float m_time; + BOOL m_bError; +}; + + +#endif //_TASKSPIDEREXPLO_H_ diff --git a/src/object/task/tasktake.cpp b/src/object/task/tasktake.cpp new file mode 100644 index 0000000..35de2b7 --- /dev/null +++ b/src/object/task/tasktake.cpp @@ -0,0 +1,612 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// tasktake.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "water.h" +#include "camera.h" +#include "motion.h" +#include "motionhuman.h" +#include "sound.h" +#include "robotmain.h" +#include "task.h" +#include "tasktake.h" + + + + +// Object's constructor. + +CTaskTake::CTaskTake(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); + + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + + m_arm = TTA_NEUTRAL; +} + +// Object's destructor. + +CTaskTake::~CTaskTake() +{ +} + + +// Management of an event. + +BOOL CTaskTake::EventProcess(const Event &event) +{ + float a, g, cirSpeed; + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_bError ) return FALSE; + + if ( m_bTurn ) // preliminary rotation? + { + a = m_object->RetAngleY(0); + g = m_angle; + cirSpeed = Direction(a, g)*2.0f; + if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; + if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; + + m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right + return TRUE; + } + + m_progress += event.rTime*m_speed; // others advance + + m_physics->SetMotorSpeed(D3DVECTOR(0.0f, 0.0f, 0.0f)); // immobile! + + return TRUE; +} + + +// Assigns the goal was achieved. + +Error CTaskTake::Start() +{ + ObjectType type; + CObject* other; + float iAngle, oAngle, h; + D3DVECTOR pos; + + m_height = 0.0f; + m_step = 0; + m_progress = 0.0f; + + iAngle = m_object->RetAngleY(0); + iAngle = NormAngle(iAngle); // 0..2*PI + oAngle = iAngle; + + m_bError = TRUE; // operation impossible + if ( !m_physics->RetLand() ) + { + pos = m_object->RetPosition(0); + h = m_water->RetLevel(m_object); + if ( pos.y < h ) return ERR_MANIP_WATER; // impossible under water + return ERR_MANIP_FLY; + } + + type = m_object->RetType(); + if ( type != OBJECT_HUMAN && + type != OBJECT_TECH ) return ERR_MANIP_VEH; + + m_physics->SetMotorSpeed(D3DVECTOR(0.0f, 0.0f, 0.0f)); + + if ( m_object->RetFret() == 0 ) + { + m_order = TTO_TAKE; + } + else + { + m_order = TTO_DEPOSE; + } + + if ( m_order == TTO_TAKE ) + { + pos = m_object->RetPosition(0); + h = m_water->RetLevel(m_object); + if ( pos.y < h ) return ERR_MANIP_WATER; // impossible under water + + other = SearchFriendObject(oAngle, 1.5f, PI*0.50f); + if ( other != 0 && other->RetPower() != 0 ) + { + type = other->RetPower()->RetType(); + if ( type == OBJECT_URANIUM ) return ERR_MANIP_RADIO; + if ( type != OBJECT_FRET && + type != OBJECT_STONE && + type != OBJECT_BULLET && + type != OBJECT_METAL && + type != OBJECT_POWER && + type != OBJECT_ATOMIC && + type != OBJECT_BBOX && + type != OBJECT_KEYa && + type != OBJECT_KEYb && + type != OBJECT_KEYc && + type != OBJECT_KEYd && + type != OBJECT_TNT ) return ERR_MANIP_FRIEND; +//? m_camera->StartCentering(m_object, PI*0.3f, -PI*0.1f, 0.0f, 0.8f); + m_arm = TTA_FRIEND; + } + else + { + other = SearchTakeObject(oAngle, 1.5f, PI*0.45f); + if ( other == 0 ) return ERR_MANIP_NIL; + type = other->RetType(); + if ( type == OBJECT_URANIUM ) return ERR_MANIP_RADIO; +//? m_camera->StartCentering(m_object, PI*0.3f, 99.9f, 0.0f, 0.8f); + m_arm = TTA_FFRONT; + m_main->HideDropZone(other); // hides buildable area + } + } + + if ( m_order == TTO_DEPOSE ) + { +//? speed = m_physics->RetMotorSpeed(); +//? if ( speed.x != 0.0f || +//? speed.z != 0.0f ) return ERR_MANIP_MOTOR; + + other = SearchFriendObject(oAngle, 1.5f, PI*0.50f); + if ( other != 0 && other->RetPower() == 0 ) + { +//? m_camera->StartCentering(m_object, PI*0.3f, -PI*0.1f, 0.0f, 0.8f); + m_arm = TTA_FRIEND; + } + else + { + if ( !IsFreeDeposeObject(D3DVECTOR(2.5f, 0.0f, 0.0f)) ) return ERR_MANIP_OCC; +//? m_camera->StartCentering(m_object, PI*0.3f, 99.9f, 0.0f, 0.8f); + m_arm = TTA_FFRONT; + } + } + + m_bTurn = TRUE; // preliminary rotation necessary + m_angle = oAngle; // angle was reached + + m_physics->SetFreeze(TRUE); // it does not move + + m_bError = FALSE; // ok + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskTake::IsEnded() +{ + CObject* fret; + float angle; + + if ( m_engine->RetPause() ) return ERR_CONTINUE; + if ( m_bError ) return ERR_STOP; + + if ( m_bTurn ) // preliminary rotation? + { + angle = m_object->RetAngleY(0); + angle = NormAngle(angle); // 0..2*PI + + if ( TestAngle(angle, m_angle-PI*0.01f, m_angle+PI*0.01f) ) + { + m_bTurn = FALSE; // rotation ended + m_physics->SetMotorSpeedZ(0.0f); + + if ( m_arm == TTA_FFRONT ) + { + m_motion->SetAction(MHS_TAKE, 0.2f); // will decrease + } + if ( m_arm == TTA_FRIEND ) + { + if ( m_height <= 3.0f ) + { + m_motion->SetAction(MHS_TAKEOTHER, 0.2f); // will decrease + } + else + { + m_motion->SetAction(MHS_TAKEHIGH, 0.2f); // will decrease + } + } + m_progress = 0.0f; + m_speed = 1.0f/0.6f; + } + return ERR_CONTINUE; + } + + if ( m_progress < 1.0f ) return ERR_CONTINUE; + m_progress = 0.0f; + + m_step ++; + + if ( m_order == TTO_TAKE ) + { + if ( m_step == 1 ) + { + if ( TruckTakeObject() ) + { + if ( m_arm == TTA_FRIEND && + (m_fretType == OBJECT_POWER || + m_fretType == OBJECT_ATOMIC ) ) + { + m_sound->Play(SOUND_POWEROFF, m_object->RetPosition(0)); + } + } + m_motion->SetAction(MHS_UPRIGHT, 0.4f); // gets up + m_progress = 0.0f; + m_speed = 1.0f/0.8f; + m_camera->StopCentering(m_object, 0.8f); + return ERR_CONTINUE; + } + } + + if ( m_order == TTO_DEPOSE ) + { + if ( m_step == 1 ) + { + fret = m_object->RetFret(); + TruckDeposeObject(); + if ( m_arm == TTA_FRIEND && + (m_fretType == OBJECT_POWER || + m_fretType == OBJECT_ATOMIC ) ) + { + m_sound->Play(SOUND_POWERON, m_object->RetPosition(0)); + } + if ( fret != 0 && m_fretType == OBJECT_METAL && m_arm == TTA_FFRONT ) + { + m_main->ShowDropZone(fret, m_object); // shows buildable area + } + m_motion->SetAction(-1); // gets up + m_progress = 0.0f; + m_speed = 1.0f/0.4f; + m_camera->StopCentering(m_object, 0.8f); + return ERR_CONTINUE; + } + } + + Abort(); + return ERR_STOP; +} + +// Suddenly ends the current action. + +BOOL CTaskTake::Abort() +{ + m_motion->SetAction(-1); + m_camera->StopCentering(m_object, 0.8f); + m_physics->SetFreeze(FALSE); // is moving again + return TRUE; +} + + +// Seeks the object to take in front. + +CObject* CTaskTake::SearchTakeObject(float &angle, + float dLimit, float aLimit) +{ + CObject *pObj, *pBest; + D3DVECTOR iPos, oPos; + ObjectType type; + float min, iAngle, bAngle, a, distance; + int i; + + iPos = m_object->RetPosition(0); + iAngle = m_object->RetAngleY(0); + iAngle = NormAngle(iAngle); // 0..2*PI + + min = 1000000.0f; + pBest = 0; + bAngle = 0.0f; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + + if ( type != OBJECT_FRET && + type != OBJECT_STONE && + type != OBJECT_URANIUM && + type != OBJECT_BULLET && + type != OBJECT_METAL && + type != OBJECT_POWER && + type != OBJECT_ATOMIC && + type != OBJECT_BBOX && + type != OBJECT_KEYa && + type != OBJECT_KEYb && + type != OBJECT_KEYc && + type != OBJECT_KEYd && + type != OBJECT_TNT ) continue; + + if ( pObj->RetTruck() != 0 ) continue; // object transported? + if ( pObj->RetLock() ) continue; + if ( pObj->RetZoomY(0) != 1.0f ) continue; + + oPos = pObj->RetPosition(0); + distance = Length(oPos, iPos); + if ( distance >= 4.0f-dLimit && + distance <= 4.0f+dLimit ) + { + angle = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! + if ( TestAngle(angle, iAngle-aLimit, iAngle+aLimit) ) + { + a = Abs(angle-iAngle); + if ( a > PI ) a = PI*2.0f-a; + if ( a < min ) + { + min = a; + pBest = pObj; + bAngle = angle; + } + } + } + } + angle = bAngle; + return pBest; +} + +// Seeks the robot on which you want take or put a battery. + +CObject* CTaskTake::SearchFriendObject(float &angle, + float dLimit, float aLimit) +{ + Character* character; + CObject* pObj; + CObject* pPower; + D3DMATRIX* mat; + D3DVECTOR iPos, oPos; + ObjectType type, powerType; + float iAngle, iRad, distance; + int i; + + if ( !m_object->GetCrashSphere(0, iPos, iRad) ) return 0; + iAngle = m_object->RetAngleY(0); + iAngle = NormAngle(iAngle); // 0..2*PI + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj == m_object ) continue; // yourself? + + type = pObj->RetType(); + if ( type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_TOWER && + type != OBJECT_RESEARCH && + type != OBJECT_ENERGY && + type != OBJECT_LABO && + type != OBJECT_NUCLEAR ) continue; + + pPower = pObj->RetPower(); + if ( pPower != 0 ) + { + if ( pPower->RetLock() ) continue; + if ( pPower->RetZoomY(0) != 1.0f ) continue; + + powerType = pPower->RetType(); + if ( powerType == OBJECT_NULL || + powerType == OBJECT_FIX ) continue; + } + + mat = pObj->RetWorldMatrix(0); + character = pObj->RetCharacter(); + oPos = Transform(*mat, character->posPower); + + distance = Abs(Length(oPos, iPos) - (iRad+1.0f)); + if ( distance <= dLimit ) + { + angle = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! + if ( TestAngle(angle, iAngle-aLimit, iAngle+aLimit) ) + { + character = pObj->RetCharacter(); + m_height = character->posPower.y; + return pObj; + } + } + } + + return 0; +} + +// Takes the object in front. + +BOOL CTaskTake::TruckTakeObject() +{ + CObject* fret; + CObject* other; + D3DMATRIX matRotate; + float angle; + + if ( m_arm == TTA_FFRONT ) // takes on the ground in front? + { +//? fret = SearchTakeObject(angle, 1.5f, PI*0.04f); + fret = SearchTakeObject(angle, 1.5f, PI*0.15f); //OK 1.9 + if ( fret == 0 ) return FALSE; // rien � prendre ? + m_fretType = fret->RetType(); + + fret->SetTruck(m_object); + fret->SetTruckPart(4); // takes with the hand + +//? fret->SetPosition(0, D3DVECTOR(2.2f, -1.0f, 1.1f)); + fret->SetPosition(0, D3DVECTOR(1.7f, -0.5f, 1.1f)); + fret->SetAngleY(0, 0.1f); + fret->SetAngleX(0, 0.0f); + fret->SetAngleZ(0, 0.8f); + + m_object->SetFret(fret); // takes + } + + if ( m_arm == TTA_FRIEND ) // takes friend's battery? + { + other = SearchFriendObject(angle, 1.5f, PI*0.04f); + if ( other == 0 ) return FALSE; + + fret = other->RetPower(); + if ( fret == 0 ) return FALSE; // the other does not have a battery? + m_fretType = fret->RetType(); + + other->SetPower(0); + fret->SetTruck(m_object); + fret->SetTruckPart(4); // takes with the hand + +//? fret->SetPosition(0, D3DVECTOR(2.2f, -1.0f, 1.1f)); + fret->SetPosition(0, D3DVECTOR(1.7f, -0.5f, 1.1f)); + fret->SetAngleY(0, 0.1f); + fret->SetAngleX(0, 0.0f); + fret->SetAngleZ(0, 0.8f); + + m_object->SetFret(fret); // takes + } + + return TRUE; +} + +// Deposes the object taken. + +BOOL CTaskTake::TruckDeposeObject() +{ + Character* character; + CObject* fret; + CObject* other; + D3DMATRIX* mat; + D3DVECTOR pos; + float angle; + + if ( m_arm == TTA_FFRONT ) // deposes on the ground in front? + { + fret = m_object->RetFret(); + if ( fret == 0 ) return FALSE; // does nothing? + m_fretType = fret->RetType(); + + mat = fret->RetWorldMatrix(0); + pos = Transform(*mat, D3DVECTOR(-0.5f, 1.0f, 0.0f)); + m_terrain->MoveOnFloor(pos); + fret->SetPosition(0, pos); + fret->SetAngleY(0, m_object->RetAngleY(0)+PI/2.0f); + fret->SetAngleX(0, 0.0f); + fret->SetAngleZ(0, 0.0f); + fret->FloorAdjust(); // plate well on the ground + + fret->SetTruck(0); + m_object->SetFret(0); // deposit + } + + if ( m_arm == TTA_FRIEND ) // deposes battery on friends? + { + other = SearchFriendObject(angle, 1.5f, PI*0.04f); + if ( other == 0 ) return FALSE; + + fret = other->RetPower(); + if ( fret != 0 ) return FALSE; // the other already has a battery? + + fret = m_object->RetFret(); + if ( fret == 0 ) return FALSE; + m_fretType = fret->RetType(); + + other->SetPower(fret); + fret->SetTruck(other); + + character = other->RetCharacter(); + fret->SetPosition(0, character->posPower); + fret->SetAngleY(0, 0.0f); + fret->SetAngleX(0, 0.0f); + fret->SetAngleZ(0, 0.0f); + fret->SetTruckPart(0); // carried by the base + + m_object->SetFret(0); // deposit + } + + return TRUE; +} + +// Seeks if a location allows to deposit an object. + +BOOL CTaskTake::IsFreeDeposeObject(D3DVECTOR pos) +{ + CObject* pObj; + D3DMATRIX* mat; + D3DVECTOR iPos, oPos; + float oRadius; + int i, j; + + mat = m_object->RetWorldMatrix(0); + iPos = Transform(*mat, pos); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj == m_object ) continue; + if ( !pObj->RetActif() ) continue; // inactive? + if ( pObj->RetTruck() != 0 ) continue; // object transported? + + j = 0; + while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) + { + if ( Length(iPos, oPos)-(oRadius+1.0f) < 1.0f ) + { + return FALSE; // location occupied + } + } + } + return TRUE; // location free +} + + diff --git a/src/object/task/tasktake.h b/src/object/task/tasktake.h new file mode 100644 index 0000000..80b8736 --- /dev/null +++ b/src/object/task/tasktake.h @@ -0,0 +1,85 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// tasktake.h + +#ifndef _TASKTAKE_H_ +#define _TASKTAKE_H_ + + +#include "misc.h" +#include "object.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + + +enum TaskTakeOrder +{ + TTO_TAKE = 1, // takes an object + TTO_DEPOSE = 2, // deposes the object +}; + +enum TaskTakeArm +{ + TTA_NEUTRAL = 1, // empty arm at rest + TTA_FFRONT = 2, // arm on the ground + TTA_FRIEND = 3, // arm behind a friend robot +}; + + + +class CTaskTake : public CTask +{ +public: + CTaskTake(CInstanceManager* iMan, CObject* object); + ~CTaskTake(); + + BOOL EventProcess(const Event &event); + + Error Start(); + Error IsEnded(); + BOOL Abort(); + +protected: + CObject* SearchTakeObject(float &angle, float dLimit, float aLimit); + CObject* SearchFriendObject(float &angle, float dLimit, float aLimit); + BOOL TruckTakeObject(); + BOOL TruckDeposeObject(); + BOOL IsFreeDeposeObject(D3DVECTOR pos); + +protected: + CTerrain* m_terrain; + + TaskTakeOrder m_order; + TaskTakeArm m_arm; + int m_step; + float m_speed; + float m_progress; + float m_height; + BOOL m_bError; + BOOL m_bTurn; + float m_angle; + ObjectType m_fretType; +}; + + +#endif //_TASKTAKE_H_ diff --git a/src/object/task/taskterraform.cpp b/src/object/task/taskterraform.cpp new file mode 100644 index 0000000..e2f75fc --- /dev/null +++ b/src/object/task/taskterraform.cpp @@ -0,0 +1,429 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskterraform.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "language.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "particule.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "pyro.h" +#include "brain.h" +#include "camera.h" +#include "sound.h" +#include "motion.h" +#include "motionant.h" +#include "motionspider.h" +#include "task.h" +#include "taskterraform.h" + + +#define ENERGY_TERRA 0.40f // energy consumed by blow +#define ACTION_RADIUS 400.0f + + + +// Object's constructor. + +CTaskTerraform::CTaskTerraform(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); + m_lastParticule = 0.0f; + m_soundChannel = -1; +} + +// Object's destructor. + +CTaskTerraform::~CTaskTerraform() +{ +} + + +// Management of an event. + +BOOL CTaskTerraform::EventProcess(const Event &event) +{ + CObject* power; + D3DMATRIX* mat; + D3DVECTOR pos, dir, speed; + FPOINT dim; + float energy; + + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + if ( m_bError ) return FALSE; + + m_progress += event.rTime*m_speed; // others advance + m_time += event.rTime; + + if ( m_phase == TTP_CHARGE ) + { + if ( m_soundChannel == -1 ) + { +#if _TEEN + m_soundChannel = m_sound->Play(SOUND_GGG, m_object->RetPosition(0), 1.0f, 0.5f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 2.0f, 1.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.5f, SOPER_STOP); +#else + m_soundChannel = m_sound->Play(SOUND_GGG, m_object->RetPosition(0), 1.0f, 0.5f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 2.0f, 4.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.5f, SOPER_STOP); +#endif + } + + dir.x = 0.0f; + dir.y = (Rand()-0.5f)*0.2f*m_progress; + dir.z = 0.0f; + m_object->SetCirVibration(dir); + + m_object->SetZoom(0, 1.0f+m_progress*0.2f); + + power = m_object->RetPower(); + if ( power != 0 ) + { + power->SetZoom(0, 1.0f+m_progress*1.0f); + + energy = power->RetEnergy(); + energy -= event.rTime*ENERGY_TERRA/power->RetCapacity()/4.0f; + if ( energy < 0.0f ) energy = 0.0f; + power->SetEnergy(energy); + } + } + + if ( m_phase == TTP_DOWN ) + { + pos.x = 9.0f; +#if _TEEN + pos.y = 4.0f-m_progress*4.0f; +#else + pos.y = 4.0f-m_progress*5.8f; +#endif + pos.z = 0.0f; + m_object->SetPosition(2, pos); + } + + if ( m_phase == TTP_UP ) + { + pos.x = 9.0f; +#if _TEEN + pos.y = 4.0f-(1.0f-m_progress)*4.0f; +#else + pos.y = 4.0f-(1.0f-m_progress)*5.8f; +#endif + pos.z = 0.0f; + m_object->SetPosition(2, pos); + } + + dir.x = 0.0f; + dir.y = 0.0f; + dir.z = 0.0f; + pos = m_object->RetPosition(2); + if ( pos.y < 0.0f ) + { + dir.z = -atanf((pos.y/2.0f)/9.0f); + } + m_object->SetInclinaison(dir); + + if ( m_time-m_lastParticule >= m_engine->ParticuleAdapt(0.05f) ) + { + m_lastParticule = m_time; + + mat = m_object->RetWorldMatrix(0); + + if ( m_phase == TTP_CHARGE ) + { + // Battery. + pos = D3DVECTOR(-6.0f, 5.5f+2.0f*m_progress, 0.0f); + pos.x += (Rand()-0.5f)*1.0f; + pos.z += (Rand()-0.5f)*1.0f; + pos = Transform(*mat, pos); + speed.x = (Rand()-0.5f)*6.0f*(1.0f+m_progress*4.0f); + speed.z = (Rand()-0.5f)*6.0f*(1.0f+m_progress*4.0f); + speed.y = 6.0f+Rand()*4.0f*(1.0f+m_progress*2.0f); + dim.x = 0.5f+1.5f*m_progress; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 2.0f, 20.0f); + } + + if ( m_phase != TTP_CHARGE ) + { + // Left grid. + pos = D3DVECTOR(-1.0f, 5.8f, 3.5f); + pos.x += (Rand()-0.5f)*1.0f; + pos.z += (Rand()-0.5f)*1.0f; + pos = Transform(*mat, pos); + speed.x = Rand()*4.0f; + speed.z = Rand()*2.0f; + speed.y = 2.5f+Rand()*1.0f; + speed = Transform(*mat, speed); + speed -= m_object->RetPosition(0); + dim.x = Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 3.0f); + + // Right grid. + pos = D3DVECTOR(-1.0f, 5.8f, -3.5f); + pos.x += (Rand()-0.5f)*1.0f; + pos.z += (Rand()-0.5f)*1.0f; + pos = Transform(*mat, pos); + speed.x = Rand()*4.0f; + speed.z = -Rand()*2.0f; + speed.y = 2.5f+Rand()*1.0f; + speed = Transform(*mat, speed); + speed -= m_object->RetPosition(0); + dim.x = Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 3.0f); + } + } + + return TRUE; +} + + +// Assigns the goal was achieved. + +Error CTaskTerraform::Start() +{ + CObject* power; + D3DMATRIX* mat; + D3DVECTOR pos, speed; + float energy; + + ObjectType type; + + m_bError = TRUE; // operation impossible + if ( !m_physics->RetLand() ) return ERR_TERRA_VEH; + + type = m_object->RetType(); + if ( type != OBJECT_MOBILErt ) return ERR_TERRA_VEH; + + power = m_object->RetPower(); + if ( power == 0 ) return ERR_TERRA_ENERGY; + energy = power->RetEnergy(); + if ( energy < ENERGY_TERRA/power->RetCapacity()+0.05f ) return ERR_TERRA_ENERGY; + + speed = m_physics->RetMotorSpeed(); + if ( speed.x != 0.0f || + speed.z != 0.0f ) return ERR_MANIP_MOTOR; + + mat = m_object->RetWorldMatrix(0); + pos = D3DVECTOR(9.0f, 0.0f, 0.0f); + pos = Transform(*mat, pos); // battery position + m_terraPos = pos; + + m_phase = TTP_CHARGE; + m_progress = 0.0f; +#if _TEEN + m_speed = 1.0f/1.5f; +#else + m_speed = 1.0f/4.0f; +#endif + m_time = 0.0f; + + m_bError = FALSE; // ok + + m_camera->StartCentering(m_object, PI*0.35f, 99.9f, 20.0f, 2.0f); + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskTerraform::IsEnded() +{ + CObject* power; + D3DVECTOR pos, speed; + FPOINT dim; + float dist, duration; + int i, max; + + if ( m_engine->RetPause() ) return ERR_CONTINUE; + if ( m_bError ) return ERR_STOP; + + if ( m_progress < 1.0f ) return ERR_CONTINUE; + m_progress = 0.0f; + + if ( m_phase == TTP_CHARGE ) + { +#if _TEEN + Terraform(); // changes the terrain. +#endif + + m_phase = TTP_DOWN; + m_speed = 1.0f/0.2f; + return ERR_CONTINUE; + } + + if ( m_phase == TTP_DOWN ) + { +#if !_TEEN + Terraform(); // changes the terrain. +#endif + + m_object->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); + m_object->SetZoom(0, 1.0f); + + power = m_object->RetPower(); + if ( power != 0 ) + { + power->SetZoom(0, 1.0f); + } + + max= (int)(50.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; iMoveOnFloor(pos); + dist = Length(pos, m_terraPos); + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 2.0f+(40.0f-dist)/(1.0f+Rand()*4.0f); + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + + pos = m_terraPos; + speed.x = (Rand()-0.5f)*40.0f; + speed.z = (Rand()-0.5f)*40.0f; + speed.y = Rand()*15.0f+15.0f; + dim.x = 0.6f; + dim.y = dim.x; + pos.y += dim.y; + duration = Rand()*3.0f+3.0f; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK5, + duration, Rand()*10.0f+15.0f, + duration*0.2f, 1.0f); + } + + m_phase = TTP_TERRA; + m_speed = 1.0f/2.0f; + return ERR_CONTINUE; + } + + if ( m_phase == TTP_TERRA ) + { + m_phase = TTP_UP; + m_speed = 1.0f/1.0f; + return ERR_CONTINUE; + } + + Abort(); + return ERR_STOP; +} + +// Suddenly ends the current action. + +BOOL CTaskTerraform::Abort() +{ + CObject* power; + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.3f, SOPER_STOP); + m_soundChannel = -1; + } + + m_object->SetPosition(2, D3DVECTOR(9.0f, 4.0f, 0.0f)); + m_object->SetInclinaison(D3DVECTOR(0.0f, 0.0f, 0.0f)); + m_object->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); + m_object->SetZoom(0, 1.0f); + + power = m_object->RetPower(); + if ( power != 0 ) + { + power->SetZoom(0, 1.0f); + } + + m_camera->StopCentering(m_object, 2.0f); + return TRUE; +} + + +// Returns all the close ants and spiders. + +BOOL CTaskTerraform::Terraform() +{ + CObject* pObj; + CBrain* brain; + CMotion* motion; + CPyro* pyro; + ObjectType type; + float dist; + int i; + + m_camera->StartEffect(CE_TERRAFORM, m_terraPos, 1.0f); + + m_sound->Play(SOUND_THUMP, m_terraPos); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type == OBJECT_NULL ) continue; + + if ( type == OBJECT_TEEN34 ) // stone? + { + dist = Length(m_terraPos, pObj->RetPosition(0)); + if ( dist > 20.0f ) continue; + + pyro = new CPyro(m_iMan); + pyro->Create(PT_FRAGT, pObj); + } + else + { + motion = pObj->RetMotion(); + if ( motion == 0 ) continue; + + dist = Length(m_terraPos, pObj->RetPosition(0)); + if ( dist > ACTION_RADIUS ) continue; + + if ( type == OBJECT_ANT ) + { + brain = pObj->RetBrain(); + if ( brain != 0 ) brain->StopTask(); + motion->SetAction(MAS_BACK1, 0.8f+Rand()*0.3f); + pObj->SetFixed(TRUE); // not moving + } + if ( type == OBJECT_SPIDER ) + { + brain = pObj->RetBrain(); + if ( brain != 0 ) brain->StopTask(); + motion->SetAction(MSS_BACK1, 0.8f+Rand()*0.3f); + pObj->SetFixed(TRUE); // not moving + } + } + } + + return TRUE; +} + diff --git a/src/object/task/taskterraform.h b/src/object/task/taskterraform.h new file mode 100644 index 0000000..254e363 --- /dev/null +++ b/src/object/task/taskterraform.h @@ -0,0 +1,72 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskterraform.h + +#ifndef _TASKSTERRAFORM_H_ +#define _TASKSTERRAFORM_H_ + + +#include "misc.h" +#include "d3dengine.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + + +enum TaskTerraPhase +{ + TTP_CHARGE = 1, // charge of energy + TTP_DOWN = 2, // down + TTP_TERRA = 3, // strike + TTP_UP = 4, // up +}; + + + +class CTaskTerraform : public CTask +{ +public: + CTaskTerraform(CInstanceManager* iMan, CObject* object); + ~CTaskTerraform(); + + BOOL EventProcess(const Event &event); + + Error Start(); + Error IsEnded(); + BOOL Abort(); + +protected: + BOOL Terraform(); + +protected: + TaskTerraPhase m_phase; + float m_progress; + float m_speed; + float m_time; + float m_lastParticule; + int m_soundChannel; + BOOL m_bError; + D3DVECTOR m_terraPos; +}; + + +#endif //_TASKSTERRAFORM_H_ diff --git a/src/object/task/taskturn.cpp b/src/object/task/taskturn.cpp new file mode 100644 index 0000000..832f523 --- /dev/null +++ b/src/object/task/taskturn.cpp @@ -0,0 +1,147 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskturn.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "task.h" +#include "taskturn.h" + + + + +// Object's constructor. + +CTaskTurn::CTaskTurn(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); +} + +// Object's destructor. + +CTaskTurn::~CTaskTurn() +{ +} + + +// Management of an event. + +BOOL CTaskTurn::EventProcess(const Event &event) +{ + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + // Momentarily stationary object (ant on the back)? + if ( m_object->RetFixed() ) + { + m_physics->SetMotorSpeedX(0.0f); // stops the advance + m_physics->SetMotorSpeedZ(0.0f); // stops the rotation + m_bError = TRUE; + return TRUE; + } + + return TRUE; +} + + +// Assigns the goal was achieved. +// A positive angle is turning right. + +Error CTaskTurn::Start(float angle) +{ + m_startAngle = m_object->RetAngleY(0); + m_finalAngle = m_startAngle+angle; + + if ( angle < 0.0f ) + { + m_angle = angle+m_physics->RetCirStopLength(); + m_physics->SetMotorSpeedZ(-1.0f); // turns left + m_bLeft = TRUE; + } + else + { + m_angle = angle-m_physics->RetCirStopLength(); + m_physics->SetMotorSpeedZ(1.0f); // turns right + m_bLeft = FALSE; + } + m_physics->SetMotorSpeedX(0.0f); + m_physics->SetMotorSpeedY(0.0f); + + m_bError = FALSE; + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskTurn::IsEnded() +{ + float angle; + + if ( m_engine->RetPause() ) return ERR_CONTINUE; + + if ( m_bError ) + { + return ERR_STOP; + } + + angle = m_object->RetAngleY(0); + + if ( m_bLeft ) + { + if ( angle <= m_startAngle+m_angle ) + { + m_physics->SetMotorSpeedZ(0.0f); +//? m_physics->SetCirMotionY(MO_MOTSPEED, 0.0f); + m_physics->SetCirMotionY(MO_CURSPEED, 0.0f); +//? m_physics->SetCirMotionY(MO_REASPEED, 0.0f); + m_object->SetAngleY(0, m_finalAngle); + return ERR_STOP; + } + } + else + { + if ( angle >= m_startAngle+m_angle ) + { + m_physics->SetMotorSpeedZ(0.0f); +//? m_physics->SetCirMotionY(MO_MOTSPEED, 0.0f); + m_physics->SetCirMotionY(MO_CURSPEED, 0.0f); +//? m_physics->SetCirMotionY(MO_REASPEED, 0.0f); + m_object->SetAngleY(0, m_finalAngle); + return ERR_STOP; + } + } + + return ERR_CONTINUE; +} + + diff --git a/src/object/task/taskturn.h b/src/object/task/taskturn.h new file mode 100644 index 0000000..abaef57 --- /dev/null +++ b/src/object/task/taskturn.h @@ -0,0 +1,55 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskturn.h + +#ifndef _TASKTURN_H_ +#define _TASKTURN_H_ + + +#include "misc.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + +class CTaskTurn : public CTask +{ +public: + CTaskTurn(CInstanceManager* iMan, CObject* object); + ~CTaskTurn(); + + BOOL EventProcess(const Event &event); + + Error Start(float angle); + Error IsEnded(); + +protected: + +protected: + float m_angle; + float m_startAngle; + float m_finalAngle; + BOOL m_bLeft; + BOOL m_bError; +}; + + +#endif //_TASKTURN_H_ diff --git a/src/object/task/taskwait.cpp b/src/object/task/taskwait.cpp new file mode 100644 index 0000000..af06383 --- /dev/null +++ b/src/object/task/taskwait.cpp @@ -0,0 +1,89 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskwait.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "terrain.h" +#include "object.h" +#include "physics.h" +#include "brain.h" +#include "task.h" +#include "taskwait.h" + + + + +// Object's constructor. + +CTaskWait::CTaskWait(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); +} + +// Object's destructor. + +CTaskWait::~CTaskWait() +{ +} + + +// Management of an event. + +BOOL CTaskWait::EventProcess(const Event &event) +{ + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_passTime += event.rTime; + m_bEnded = (m_passTime >= m_waitTime); + return TRUE; +} + + +// Assigns the goal was achieved. + +Error CTaskWait::Start(float time) +{ + m_waitTime = time; // duration to wait + m_passTime = 0.0f; // time elapsed + m_bEnded = FALSE; + return ERR_OK; +} + +// Indicates whether the action is finished. + +Error CTaskWait::IsEnded() +{ + if ( m_engine->RetPause() ) return ERR_CONTINUE; + if ( m_bEnded ) return ERR_STOP; + return ERR_CONTINUE; +} + + diff --git a/src/object/task/taskwait.h b/src/object/task/taskwait.h new file mode 100644 index 0000000..e8ba2b6 --- /dev/null +++ b/src/object/task/taskwait.h @@ -0,0 +1,53 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// taskwait.h + +#ifndef _TASKWAIT_H_ +#define _TASKWAIT_H_ + + +#include "misc.h" + + +class CInstanceManager; +class CTerrain; +class CBrain; +class CPhysics; +class CObject; + + +class CTaskWait : public CTask +{ +public: + CTaskWait(CInstanceManager* iMan, CObject* object); + ~CTaskWait(); + + BOOL EventProcess(const Event &event); + + Error Start(float time); + Error IsEnded(); + +protected: + +protected: + float m_waitTime; + float m_passTime; + BOOL m_bEnded; +}; + + +#endif //_TASKWAIT_H_ diff --git a/src/old/DirectX.ico b/src/old/DirectX.ico new file mode 100644 index 0000000..9752f54 Binary files /dev/null and b/src/old/DirectX.ico differ diff --git a/src/old/README.txt b/src/old/README.txt new file mode 100644 index 0000000..ec0443c --- /dev/null +++ b/src/old/README.txt @@ -0,0 +1,3 @@ +Contains files that are to be removed. + +The resources (cursors, etc.) cannot be included using windows rc files - they must be moved to .dat files. diff --git a/src/old/accents.txt b/src/old/accents.txt new file mode 100644 index 0000000..9473b1b --- /dev/null +++ b/src/old/accents.txt @@ -0,0 +1,5 @@ +!"#$%&'()*+,-./0123456789:;<=>? +@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^ +_abcdefghijklmnopqrstuvwxyz{|}~ +ÁÀÂÄÃÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜ +áàâäãçéèêëíìîïñóòôöõúùûü diff --git a/src/old/bug.txt b/src/old/bug.txt new file mode 100644 index 0000000..b598ad0 --- /dev/null +++ b/src/old/bug.txt @@ -0,0 +1,94 @@ +void CD3DApplication::StepSimul(float rTime) +{ + Event event; + + if ( m_pRobotMain == 0 ) return; + + if ( rTime > 0.5f ) rTime = 0.5f; // jamais plus de 0.5s ! + + ZeroMemory(&event, sizeof(Event)); + event.event = EVENT_FRAME; + event.rTime = rTime; + event.axeX = AxeLimit(m_axeKey.x + m_axeJoy.x); + event.axeY = AxeLimit(m_axeKey.y + m_axeJoy.y); + event.axeZ = AxeLimit(m_axeKey.z + m_axeJoy.z); + event.keyState = m_keyState; + +//?char s[100]; +//?sprintf(s, "StepSimul %.3f\n", event.rTime); +//?OutputDebugString(s); + m_pRobotMain->EventProcess(event); +} + + + +1347: void CD3DApplication::StepSimul(float rTime) +1348: { +0041E950 sub esp,24h +0041E953 push esi +0041E954 mov esi,ecx +1349: Event event; +1350: +1351: if ( m_pRobotMain == 0 ) return; +0041E956 mov eax,dword ptr [esi+0ECh] +0041E95C test eax,eax +0041E95E je CD3DApplication::StepSimul(0x0041ea08)+0B8h +1352: +1353: if ( rTime > 0.5f ) rTime = 0.5f; // jamais plus de 0.5s ! +0041E964 fld dword ptr [esp+2Ch] +0041E968 fcomp dword ptr [??_7CControl@@6B@(0x004b9ed4)+94h] +0041E96E push edi +0041E96F fnstsw ax +0041E971 test ah,41h +0041E974 jne CD3DApplication::StepSimul(0x0041e97e)+2Eh +0041E976 mov dword ptr [esp+30h],3F000000h +1354: +1355: ZeroMemory(&event, sizeof(Event)); +1356: event.event = EVENT_FRAME; +1357: event.rTime = rTime; +1358: event.axeX = AxeLimit(m_axeKey.x + m_axeJoy.x); +0041E97E fld dword ptr [esi+0F8h] +0041E984 fadd dword ptr [esi+104h] +0041E98A mov eax,dword ptr [esp+30h] +0041E98E mov ecx,9 +0041E993 mov dword ptr [esp+28h],eax +0041E997 push ecx +0041E998 xor eax,eax +0041E99A lea edi,dword ptr [esp+0Ch] +0041E99E fstp dword ptr [esp] +0041E9A1 rep stos dword ptr es:[edi] +0041E9A3 mov dword ptr [esp+0Ch],2 +0041E9AB call AxeLimit(0x0041cae0) +1359: event.axeY = AxeLimit(m_axeKey.y + m_axeJoy.y); +0041E9B0 fld dword ptr [esi+0FCh] +0041E9B6 fadd dword ptr [esi+108h] +0041E9BC fxch st(1) +0041E9BE fstp dword ptr [esp+1Ch] +0041E9C2 fstp dword ptr [esp] +0041E9C5 call AxeLimit(0x0041cae0) +1360: event.axeZ = AxeLimit(m_axeKey.z + m_axeJoy.z); +0041E9CA fld dword ptr [esi+100h] +0041E9D0 fadd dword ptr [esi+10Ch] +0041E9D6 fxch st(1) +0041E9D8 fstp dword ptr [esp+20h] +0041E9DC fstp dword ptr [esp] +0041E9DF call AxeLimit(0x0041cae0) +1361: event.keyState = m_keyState; +1362: +1363: //?char s[100]; +1364: //?sprintf(s, "StepSimul %.3f\n", event.rTime); +1365: //?OutputDebugString(s); +1366: m_pRobotMain->EventProcess(event); +0041E9E4 mov dx,word ptr [esi+0F4h] +0041E9EB mov ecx,dword ptr [esi+0ECh] +0041E9F1 fstp dword ptr [esp+24h] +0041E9F5 add esp,4 +0041E9F8 lea eax,dword ptr [esp+8] +0041E9FC mov word ptr [esp+24h],dx +0041EA01 push eax +0041EA02 call CRobotMain::EventProcess(0x0047fba0) +0041EA07 pop edi +1367: } +0041EA08 pop esi +0041EA09 add esp,24h +0041EA0C ret 4 diff --git a/src/old/bug1.txt b/src/old/bug1.txt new file mode 100644 index 0000000..59b0ca4 --- /dev/null +++ b/src/old/bug1.txt @@ -0,0 +1,68 @@ +extern void object::Solution( ) +{ + while ( true ) + { + object left, right; + + left = Radar(TypeMarkPath, -45, 120, 100); + right = Radar(TypeMarkPath, 45, 120, 100); + + if ( left == null && right == null ) + { + } + } +} + +CBotString::CBotString(const CBotString &) +CBotVar::GivName() +CBotStack::FindVar(CBotToken * &, int, int) +CBotStack::FindVar(CBotToken &, int, int) +CBotStack::CopyVar(CBotToken &, int) +CBotExpression::Execute(CBotStack * &) +CBotListInstr::Execute(CBotStack * &) +CBotWhile::Execute(CBotStack * &) +CBotListInstr::Execute(CBotStack * &) +CBotFunction::Execute(CBotVar * *, CBotStack * &) +CBotProgram::Run(void *) +CScript::Continue(const Event &) + + + +CBotString::CBotString(const CBotString &) : + m_token = 0xdddddddd + +CBotVar::GivName() : + return m_token->GivString(); + +CBotStack::FindVar(CBotToken * &, int, int) : + CBotStack* p = this; + CBotString name = pToken->GivString(); + + while (p != NULL) + { + CBotVar* pp = p->m_listVar; + while ( pp != NULL) + { + if (pp->GivName() == name) <- paf + + avec : + pp->__vfprt = 0xdddddddd + pp->m_token = 0xdddddddd + pp->m_next = 0xdddddddd + pp->m_type = -572662307 + pp->m_binit = -572662307 + pp->m_pMyThis = 0xdddddddd + pp->m_pUserPtr = 0xdddddddd + pp->m_InitExpr = 0xdddddddd + +CBotStack::FindVar(CBotToken &, int, int) : + CBotToken* pt = &Token; + pt->m_next = 0 + pt->m_prev = 0 + pt->m_type = 4 + pt->m_IdKeyWord = -1 + pt->m_Text = "right" + pt->m_Sep = " " + pt->m_start = 124 + pt->m_end = 129 + diff --git a/src/old/ceebot.ini b/src/old/ceebot.ini new file mode 100644 index 0000000..0de7a32 --- /dev/null +++ b/src/old/ceebot.ini @@ -0,0 +1,66 @@ +[Directory] +scene=scene +savegame=savegame +public=program +user=user +files=files +[Setup] +TotoMode=1 +Tooltips=1 +InterfaceGlint=1 +NiceMouse=0 +Movies=1 +NiceReset=1 +HimselfDamage=1 +CameraScroll=0 +CameraInvertX=0 +InterfaceEffect=1 +GroundShadow=1 +GroundSpot=1 +ObjectDirty=1 +FogMode=1 +LensMode=1 +SkyMode=1 +PlanetMode=1 +LightMode=1 +UseJoystick=0 +ParticuleDensity=1.00 +ClippingDistance=1.00 +ObjectDetail=2.00 +GadgetQuantity=1.00 +TextureQuality=1 +AudioVolume=4 +MidiVolume=15 +Sound3D=0 +EditIndentMode=1 +EditIndentValue=4 +KeyMap=37+0 39+0 38+0 40+0 16+0 17+0 32+258 96+262 13+257 107+261 109+260 9+259 36+263 27+0 112+0 113+0 110+0 115+0 116+0 117+0 +DeleteGamer=1 +Soluce4=1 +[Engine] +AlphaMode=1 +StateColor=-1 +BlackSrcBlend=0 +BlackDestBlend=0 +WhiteSrcBlend=0 +WhiteDestBlend=0 +DiffuseSrcBlend=0 +DiffuseDestBlend=0 +AlphaSrcBlend=0 +AlphaDestBlend=0 +[Gamer] +LastName=Linda +[Edit] +FontSize=9.00 +WindowPos.x=0.09 +WindowPos.y=0.08 +WindowDim.x=0.69 +WindowDim.y=0.84 +IOPos.x=0.36 +IOPos.y=0.15 +IODim.x=0.50 +IODim.y=0.55 +[Device] +Name=Direct3D HAL +Mode=1600 x 1200 x 32 +FullScreen=0 diff --git a/src/old/colobot.ini b/src/old/colobot.ini new file mode 100644 index 0000000..de547ec --- /dev/null +++ b/src/old/colobot.ini @@ -0,0 +1,75 @@ +[Gamer] +LastName=Joueur + +[Setup] +TotoMode=1 +Tooltips=1 +InterfaceGlint=1 +NiceMouse=0 +Movies=1 +NiceReset=1 +HimselfDamage=1 +CameraScroll=1 +CameraInvertX=0 +InterfaceEffect=1 +GroundShadow=1 +GroundSpot=1 +ObjectDirty=1 +FogMode=1 +LensMode=1 +SkyMode=1 +PlanetMode=1 +LightMode=1 +UseJoystick=0 +ParticuleDensity=1.00 +ClippingDistance=1.00 +ObjectDetail=2.00 +GadgetQuantity=1.00 +TextureQuality=1 +AudioVolume=15 +MidiVolume=20 +Sound3D=0 +EditIndentMode=1 +EditIndentValue=4 +KeyMap=37+0 39+0 38+0 40+0 16+0 17+0 32+258 96+262 13+257 107+261 109+260 9+259 36+263 27+0 112+0 113+0 110+0 115+0 116+0 117+0 +FullScreenActivateEnable=0 +AccessMission=1 +AccessUser=1 +DeleteGamer=1 +Soluce4=1 + +[Engine] +StateColor=-1 +BlackSrcBlend=0 +BlackDestBlend=0 +WhiteSrcBlend=0 +WhiteDestBlend=0 +DiffuseSrcBlend=0 +DiffuseDestBlend=0 +AlphaSrcBlend=0 +AlphaDestBlend=0 +AlphaMode=1 + +[Device] +Name=Direct3D HAL +Mode=1600 x 1200 x 32 +FullScreen=0 + +[Edit] +WindowPos.x=0.19 +WindowPos.y=0.15 +WindowDim.x=0.66 +WindowDim.y=0.69 +FontSize=9.00 +IOPos.x=0.29 +IOPos.y=0.34 +IODim.x=0.50 +IODim.y=0.55 +IOPublic=0 + +[Directory] +scene=scene +savegame=savegame +public=program +user=user +files=files diff --git a/src/old/cur00001.cur b/src/old/cur00001.cur new file mode 100644 index 0000000..e19873e Binary files /dev/null and b/src/old/cur00001.cur differ diff --git a/src/old/cur00002.cur b/src/old/cur00002.cur new file mode 100644 index 0000000..2376e8e Binary files /dev/null and b/src/old/cur00002.cur differ diff --git a/src/old/cur00003.cur b/src/old/cur00003.cur new file mode 100644 index 0000000..8a4745a Binary files /dev/null and b/src/old/cur00003.cur differ diff --git a/src/old/cursor1.cur b/src/old/cursor1.cur new file mode 100644 index 0000000..1f51251 Binary files /dev/null and b/src/old/cursor1.cur differ diff --git a/src/old/cursorha.cur b/src/old/cursorha.cur new file mode 100644 index 0000000..7b80435 Binary files /dev/null and b/src/old/cursorha.cur differ diff --git a/src/old/cursorsc.cur b/src/old/cursorsc.cur new file mode 100644 index 0000000..52004ac Binary files /dev/null and b/src/old/cursorsc.cur differ diff --git a/src/old/d3dres.h b/src/old/d3dres.h new file mode 100644 index 0000000..d3f8ba8 --- /dev/null +++ b/src/old/d3dres.h @@ -0,0 +1,59 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +//----------------------------------------------------------------------------- +// File: D3DRes.h +// +// Desc: Resource definitions required by the CD3DApplication class. +// Any application using the CD3DApplication class must include resources +// with the following identifiers. +// +// Copyright (c) 1999 Microsoft Corporation. All rights reserved. +//----------------------------------------------------------------------------- +#ifndef D3DRES_H +#define D3DRES_H + + +#define IDI_MAIN_ICON 101 // Application icon +#define IDR_MAIN_ACCEL 113 // Keyboard accelerator +#define IDR_MENU 141 // Application menu +#define IDR_POPUP 142 // Popup menu +#define IDD_ABOUT 143 // About dialog box +#define IDD_CHANGEDEVICE 144 // "Change Device" dialog box +#define IDC_CURSORHAND 149 +#define IDC_CURSORSCROLLL 150 +#define IDC_CURSORSCROLLR 151 +#define IDC_CURSORSCROLLU 152 +#define IDC_CURSORSCROLLD 153 +#define IDC_CURSORTARGET 154 + +#define IDC_DEVICE_COMBO 1000 // Device combobox for "Change Device" dlg +#define IDC_MODE_COMBO 1001 // Mode combobox for "Change Device" dlg +#define IDC_WINDOWED_CHECKBOX 1012 // Checkbox for windowed-mode +#define IDC_STEREO_CHECKBOX 1013 // Checkbox for stereo modes +#define IDC_FULLSCREEN_TEXT 1014 // Group box text label + +#define IDM_ABOUT 40001 // Command to invoke About dlg +#define IDM_CHANGEDEVICE 40002 // Command to invoke "Change Device" dlg +#define IDM_TOGGLEFULLSCREEN 40003 // Command to toggle fullscreen mode +#define IDM_TOGGLESTART 40004 // Command to toggle frame animation +#define IDM_SINGLESTEP 40005 // Command to single step frame animation +#define IDM_EXIT 40006 // Command to exit the application + + + + +#endif // D3DRES_H diff --git a/src/old/micent2.txt b/src/old/micent2.txt new file mode 100644 index 0000000..c77d91b --- /dev/null +++ b/src/old/micent2.txt @@ -0,0 +1,13 @@ +\b;Rapport du satellite +\c; +\s;-> SURFACE\c; +\tab;Température: 25.4 degrés +\tab;Atmosphère: oxygène, azote, ammoniaque +\tab;Vent: 0.7 m/s +\tab;Minerai titanium: aucun +\tab;Minerai uranium: aucun + +\s;-> SOUS-SOL\c; +\tab;Energie: aucune +\tab;Minerai titanium: aucun +\tab;Minerai uranium: aucun diff --git a/src/old/mixer.txt b/src/old/mixer.txt new file mode 100644 index 0000000..2009c2a --- /dev/null +++ b/src/old/mixer.txt @@ -0,0 +1,486 @@ +Several people have asked me for the sample code I use to program +the mixer in Windows. Since it's a fairly short sample and there's +clearly some interest, I thought I'd post it directly to the newsgroup. +Here it is ... enjoy! (?) + +Julian + +// Example routine that manipulates the mixer controls for Win32 +// This code is not a stand-alone application ... +// +// It's also not very pretty ... +// +// But then, neither is the API ... +// +// Julian Bunn, 1998, julianb@altavista.net + + +#include +#include + + +MIXERCONTROLDETAILS mixDetailsMic,mixDetailsSpk,mixDetailsLin; +LONG +lMaximumSpk,lMaximumMic,lMaximumLin,lMinimumMic,lMinimumSpk,lMinimumLin; + +int nMixerDevs; +int nMicMixID; + +LPHMIXER hMixer; +UINT IdMixer; + + +/**************************************************************************** + + Function: ProgramInitMixer() + + PURPOSE : Initialises the mixer +*****************************************************************************/ + +LONG WINAPI ProgramInitMixer() +{ + UINT iS,iD,iDC,iC, itype; + UINT volume; + MMRESULT mmres; + MIXERCAPS mixCaps; + MIXERLINE mixLine; + MIXERLINECONTROLS mixControls; + MIXERCONTROL mixClist[50]; + MIXERCONTROLDETAILS mixDetails; + MIXERCONTROLDETAILS_UNSIGNED mixValue; + MIXERCONTROLDETAILS_BOOLEAN mixMute; + MIXERCONTROLDETAILS_BOOLEAN mixBoolean[50]; + MIXERCONTROLDETAILS_LISTTEXT mixList[50]; + BOOL bDoneMike = FALSE; + BOOL bDoneSpkr = FALSE; + UINT LineID = 0; + + if(!bMixerOpened) { +// check first if we have a mixer + if((nMixerDevs = mixerGetNumDevs()) < 1) { + return (Program_ERROR); + } + +// really need to pop up a chooser for which mixer device, in +// cases where there is more than one. +// In the meantime, I select the last one listed + + IdMixer = nMixerDevs-1; + + mmres = mixerOpen((LPHMIXER) &hMixer, IdMixer, (DWORD) 0, (DWORD) +NULL, + MIXER_OBJECTF_MIXER); + if(mmres != MMSYSERR_NOERROR) { + return (Program_ERROR); + } + + bMixerOpened = TRUE; + } + + mmres = mixerGetDevCaps(IdMixer, (LPMIXERCAPS) &mixCaps, +sizeof(MIXERCAPS)); + if(mmres != MMSYSERR_NOERROR) { + return (Program_ERROR); + } +// Set the manufacturer's name for the mixer ... + SetDlgItemText(hWndDialogBox,IDC_MIXERNAME,mixCaps.szPname); + if(nMixerDevs>1) { + DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_INFOMESSAGE1), +hWndDialogBox, DialogBoxCallback); + } + + +// Loop over the destination mixer lines + for (iD=0;iD exercices + \scene\defixyy.txt -> défis + \scene\scenexyy.txt -> missions + \scene\freexyy.txt -> jeux libres + +Le numéro de 3 chiffres est composé de : + + x -> numéro du chapitre (1..9) + yy -> rang dans le chapitre (01..99) + +Par exemple, train102.txt est le deuxième exercice du premier +chapitre. +Lorsque le rang dans le chapitre est 00, c'est qu'il s'agit de +la description du chapitre. +Les fichiers doivent avoir des numéros sucessifs. Supposons par +exemple que les fichiers suivants existent : + + train600.txt + train601.txt + train602.txt + train605.txt + +Le chapitre 6 ne contiendra dans ce cas que 2 exercices, les +numéros 01 et 02. Le numéro 05 n'apparaît pas dans la liste, +car il manque les numéros 03 et 04. + +Description +----------- + +Un fichier de description d'exercice détermine le relief du +terrain, les textures utilisées, la position initiale des +différents robots, matières premières, plantes, etc. + + + +Couleur +------- + +Les couleurs sont spécifiées à l'aide de 4 composantes +rouge/vert/bleu/alpha. Les valeurs sont comprises entre +0 (noir) et 255 (blanc). La composante alpha est généralement +nulle. Par exemple : + + color=175;209;215;0 // bleu-sable + + + + +Title.E text="Power Cell 1" +Nom court de l'exercice, tel qu'il apparaît dans la liste de +gauche. + +Resume.E text="Instruct a bot to change the power cell of a nearby winged shooter." +Résumé de l'exercice, tel qu'il apparaît en dessous des deux +listes. + +ScriptName.E text="Spider2" +Nom par défaut donné à un nouveau programme créé. + +Instructions name="tcell1.txt" +Nom du fichier qui contient les instructions de l'exercice, +qui seront affichées dans le SatCom. +Le fichier ttit1.txt doit être placé dans le dossier help\. + +HelpFile name="cbot.txt" +Non du fichier qui contient les instructions sur la program- +mation, affichées lorsque l'on presse sur F2. +Le fichier cbot.txt doit être placé dans le dossier help\. +Normalement, tous les exercices font référence aux mêmes +instructions générales contenues dans cbot.txt. + +EndingFile win=2 lost=0 +Scène à utiliser lorsque l'exercice est réussi ou raté. +win=2 signifie qu'il faut utiliser scene\win002.txt. +lost=0 signifie qu'il faut utiliser scene\lost000.txt. + +Audio track=0 +Numéro de la piste audio du CD à jouer pendant l'exercice. +Normalement, les exercices restent silencieux, en donnant le +numéro de piste 0. Si nécessaire, il est possible de donner +les numéros suivants : + 2: Terre + 3: Tropica + 4: Crystalium + 5: Saari + 6: Volcano + 7: Centaury + 8: Orphéon + 9: Terranova + +AmbiantColor air=102;102;102;102 water=20;20;20;20 +Couleur ambiante utilisée lorsqu'on est à l'air libre ou +sous l'eau. + +FogColor air=180;222;255;0 water=10;20;100;0 +Couleur que prennent les objets lorsqu'ils sont au loin. + +VehicleColor color=175;209;215;0 +Couleur des robots et des bâtiments. + +DeepView air=100.00 water=25.00 +Distance en mètres jusqu'où porte la vue. Au delà de cette +distance, plus rien n'est affiché. + +FogStart air=0.1 water=0.1 +Plus on s'approche de la distance maximale de vue (DeepView) +et plus la couleur des objets fusionne avec la couleur du +brouillard (FogColor), ce qui simule du brouillard. Une valeur +de 0.1 indique un brouillard qui commence proche du point de +vue, donc un brouillard dense. Une valeur de 0.9 indique un +brouillard très peu dense. + +Par exemple : + DeepView air=100.00 + FogStart air=0.2 + +Distances à partir de l'observateur : +0 à 20 mètres -> affichage normal +20 à 100 mètres -> affichage de plus en plus brouillardeux +100 mètres et plus -> plus rien n'est affiché + +SecondTexture rank=3 +Texture utilisée pour salir les robots et les bâtiments. Vous +pouvez utiliser une valeur comprise entre 1 et 8. + +Background up=76;105;226;0 down=192;250;255;0 +Couleurs du fond d'écran, si aucune texture n'est utilisée. +Un dégradé de couleur passe de "up" tout en haut de l'écran +progressivement jusqu'à "down" en milieu d'écran. La moitié +inférieure de l'écran prend la couleur unie "down". Cette +moitié inférieure n'est en principe jamais visible, puisqu'il +y a toujours une partie de terrain qui la recouvre. + +FrontsizeName image="lens5.tga" +Nom de la texture d'avant-plan, qui contient un effet de +"lens flare", plus ou moins visible selon l'orientation. + + +TerrainRelief image="textures\relief41.bmp" factor=1.0 +Le relief du terrain est décrit dans une image BMP à 256 +niveaux de gris mesurant exactement 161 x 161 pixels. +La couleur blanche correspond à l'altitude la plus basse. +La couleur noire correspond à l'altitude la plus haute. +Normalement, on utilise "factor=1.0". Dans ce cas, les 256 +niveaux permettent de s'élever de 64 mètres. Une différence +d'intensité de gris de 1 correspond donc à une différence +d'altitude de 0.25 mètres. + +La coordonnée du pixel central 80;80 de l'image correspond +à la coordonnée 0;0 dans CoLoBoT. +La coordonnée 0;0 du pixel en haut à gauche dans l'image +correspond au point à l'extrème nord-ouest -400;400 dans CoLoBoT. +Un pixel dans l'image correspond à un carré au sol de 5x5 +mètres dans CoLoBoT. + +Vous pouvez dessiner de nouveaux reliefs avec un logiciel tel +que PaintShop, ou réutiliser les nombreux fichiers reliefxx.bmp +placés dans le dossier textures\. + +TerrainResource image="textures\res00.bmp" +Cette image détermine la présence des ressources dans le +sous-sol. Il s'agit d'une image BMP en 256 couleurs de +161 x 161 pixels. + +Rouge = 255;0;0 (index=5) -> titanium +Vert = 0;255;0 (index=30) -> énergie +Jaune = 255;255;0 (index=35) -> uranium + +Toutes les autres couleurs ou niveaux de gris sont ignorés. + +Généralement, un bon truc pour placer les zones de couleur au +bon endroit est de partir de l'image à niveaux de gris du +relief et de la convertir en 256 couleurs. + +TerrainWater level=7.5 ... +Cette commande contient plusieurs paramètres, dont seul "level" +nous intéresse ici. "level" indique donc le niveau de l'eau ou +de la lave, par-rapport au niveau zéro qui correspond à la +couleur blanche dans l'image du relief (TerrainResource). +L'altitude des robots est par la suite toujours calculée par- +rapport au niveau de la mer (level). Une altitude négative +indiquera donc que le robot est sous l'eau. + +BeginObject +Cette commande doit précéder le premier CreateObject. + +CreateObject pos=7;-10 dir=1.5 type=Me +Création d'un objet dans l'exercice. Il peut s'agir d'un robot, +d'un bâtiment, d'une matière première, d'une plante, etc. + +Pour déterminer la position d'un objet, un bon moyen consiste +à déplacer le cosmonaute à l'endroit souhaité, puis de taper +les commandes : + + Ctrl+Pause showstat Entrée + Ctrl+Pause showpos Entrée + +La partie inférieure de l'écran indique alors les coordonnées +de l'objet sélectionné, qu'il n'y a plus qu'à reporter dans le +fichier de description de l'exercice. + +La direction est un nombre compris entre 0 et 2. + 0.0 -> est + 0.5 -> sud + 1.0 -> ouest + 1.5 -> nord +Le sens de rotation est donc horaire. + +Les différents types possibles pour les objets sont : + +Base : + type=Me // cosmonaute + type=SpaceShip + +Robots : + type=PracticeBot // robot d'entraînement + type=TargetBot // robot cible + + type=WheeledGrabber + type=TrackedGrabber + type=WingedGrabber + type=LeggedGrabber + + type=WheeledShooter + type=TrackedShooter + type=WingedShooter + type=LeggedShooter + + type=WheeledOrgaShooter + type=TrackedOrgaShooter + type=WingedOrgaShooter + type=LeggedOrgaShooter + + type=WheeledSniffer + type=TrackedSniffer + type=WingedSniffer + type=LeggedSniffer + + type=Thumper + type=PhazerShooter + type=Recycler + type=Shielder + type=Subber + +Bâtiments : + type=Derrick + type=BotFactory + type=PowerStation + type=Converter + type=RepairCenter + type=DefenseTower + type=AlienNest + type=ResearchCenter + type=RadarStation + type=ExchangePost + type=PowerPlant + type=AutoLab + type=NuclearPlant + type=PowerCaptor + type=Vault + type=StartArea + type=GoalArea + type=Target1 // pour l'entraînement au vol + type=Target2 + type=Houston // centre de contrôle + +Objets transportables : + type=TitaniumOre + type=UraniumOre + type=Titanium + type=PowerCell + type=NuclearCell + type=OrgaMatter + type=BlackBox // boîte noire + type=KeyA..D + type=TNT // caisse d'explosif + +Plantes et décors : + type=Greenery0..4 // plante standard basse + type=Greenery5..7 // petit trèfle bas + type=Greenery10..14 // plante grasse montante + type=Greenery15..19 // fougère + type=Tree0..3 // arbre haut + type=Mushroom1 // champignon inoffensif + type=Mushroom2 // champignon corrosif + type=MegaStalk0..5 // plante étrange + + type=Quartz0..3 // quartz petit..grand + type=Barrier0 // barrière courte + type=Barrier1 // barrière longue + type=ApolloLEM // sur la lune uniquement : + type=ApolloJeep + type=ApolloFlag + type=ApolloModule + type=ApolloAntenna + +Epaves de robots recyclables : + type=WreckBotw1..2 // robot à roues + type=WreckBott1..2 // robot à petites chenilles + type=WreckBotr1..2 // robot à grosses chenilles + +Bâtiments en ruine : + type=RuinBotFactory + type=RuinDoor // porte de convertisseur + type=RuinSupport // support de radar + type=RuinRadar // socle de radar + type=RuinConvert + type=RuinBaseCamp // socle du vaisseau spatial + type=RuinHeadCamp // coiffe du vaisseau spatial + +Ennemis : + type=AlienQueen + type=AlienEgg + type=AlienAnt + type=AlienSpider + type=AlienWasp + type=AlienWorm + +Indicateurs : + type=PowerSpot // indique la présence d'énergie en sous-sol + type=TitaniumSpot // indique la présence de titanium en sous-sol + type=UraniumSpot // indique la présence d'uranium en sous-sol + type=KeyA..DSpot // indique la présence de clé en sous-sol + type=WayPoint // croix pour les exercices + type=BlueFlag + type=RedFlag + type=GreenFlag + type=YellowFlag + type=VioletFlag + +Divers : + type=Mine // bombe fixe à éviter + type=Portico // portique géant (sur la terre) + type=Bag // sac de survie + type=Home // petite maison sympa (sur terranova) + type=Tech // technicien de Houston + type=Firework // feu d'artifice + +La commande CreateObject peut contenir des paramètres +supplémentaires : + +CreateObject ... script1="ttit1.txt" +Nom du programme CBOT à charger à la position 1 dans le robot +ou l'insecte. Il est possible de charger jusqu'à 10 programmes +en utilisant les commandes script1 à script10. +Les fichiers .txt des programmes doivent être placés dans le +dossier script\. + +CreateObject ... run=1 +Numéro du programme à exécuter directement lorsque l'exercice +démarre. Cela peut être utile, par exemple, pour un robot +TargetBot que l'élève devra suivre. +Si plusieurs programmes sont chargés (avec script1, script2, +etc.), un seul pourra être exécuté, bien entendu. + +EnableResearch type=WINGER +Liste des recherches déjà effectuées. + +DoneResearch type=WINGER +Liste des recherches qu'il est autorisé de faire, en construisant +un centre de recherche (ResearchCenter) ou un laboratoire (AutoLab). + + + TRACKER Robots Tracked* + WINGER Robots Winged* + THUMPER Robots Thumper + SHOOTER Robots *Shooter + TOWER Bâtiment DefenseTower + PHAZER Robots PhazerShooter + SHIELDER Robots Shielder + ATOMIC Bâtiment NuclearPlant + + iPAW Robots Legged* + iGUN Robots *OrgaShooter + + RECYCLER Robots recycleurs + SUBBER Robots Subber + SNIFFER Robots *Sniffer + + +EndMissionTake pos=0.00;0.00 dist=25000.00 type=Me lost=0 +EndMissionTake pos=0.00;0.00 dist=25000.00 type=WheeledGrabber lost=0 +EndMissionTake pos=0.00;0.00 dist=1000.00 type=Titanium min=1 max=1 +Critères pour déterminer à quel moment l'exercice est terminé. + + + + +Dossiers et réseau +------------------ + +Dans une utilisation en réseau, COLOBOT doit être installé +sur chaque machine individuellement. Après cette opération, +les exercices et les missions sont chargés localement, +généralement dans le dossier : + + C:\Program Files\Colobot\scene\ + +Si vous avez créé des exercices spécifiques, il peut être +utile de les charger à partir d'un dossier central commun à +tous les ordinateurs. Pour cela, il faut modifier le fichier + + C:\Program Files\Colobot\colobot.ini + +sur chaque machine. La section suivante permet de donner le +chemin d'accès : + + [Directory] + scene=scene + +Ici, il s'agit d'un chemin d'accès relatif. Vous pouvez par +exemple le changer en un chemin absolu sur un serveur : + + [Directory] + scene=\\Serveur\c\colobot\scene\ + +De la même façon, vous pouvez changer le dossier dans lequel +sont placés les programmes lorsque vous utilisez la commande +ouvrir/enregistrer avec le mode "public", dans l'éditeur de +programmes : + + [Directory] + public=program + +En donnant un chemin d'accès commun à tous les ordinateurs, il +sera possible d'échanger des programmes : + + [Directory] + public=\\Serveur\c\colobot\program\ + + + +Réglages +-------- + +Pour afficher le nombre d'images par seconde, il faut appuyer +sur Ctrl+Pause puis taper la commande "showstat" et valider +avec la touche Entrée : + + Ctrl+Pause showstat Entrée + +La partie supérieure de l'écran affiche alors, par exemple : + + 32.46 fps T=11558 (640x480x16) + +Le premier chiffre correspond au nombre d'images par seconde +(fps = frame per second). +Le deuxième chiffre indique le nombre de triangles affiché dans +la scène. +Les 3 derniers chiffres entre parenthèses sont la résolution +(largeur x hauteur) et le nombre de bits pour les couleurs. + +Tous les réglages sont mémorisés dans le fichier colobot.ini, +présent dans le dossier principal où COLOBOT a été installé. +Ce fichier peut être modifié (avec prudence et après en avoir +fait une copie) avec un éditeur de texte, comme par exemple le +bloc-notes de Windows. + + +Problèmes +--------- + +Pour résoudre certains problèmes, il est possible de modifier +le fichier colobot.ini avec un éditeur de texte (par exemple +avec le bloc-notes de Windows). N'ajoutez pas de nouvelles +lignes, mais modifiez simplement les valeurs existantes. +Attention à ne pas insérer d'espace. Il faut quitter COLOBOT +avant de modifier le fichier. + +Si la végétation s'affiche mal, ou même pas du tout, vous +avez peut-être mis à zéro le nombre d'objets décoratifs dans +les options. Pour remettre 100% : + [Setup] + GadgetQuantity=1.00 +Si la végétation ne s'affiche toujours pas, essayez : + [Engine] + AlphaMode=0 +ou + [Engine] + AlphaMode=2 + +Si un carré apparaît autour des ombres, essayez : + [Engine] + WhiteSrcBlend=9 + WhiteDestBlend=6 +ou + [Engine] + WhiteSrcBlend=6 + WhiteDestBlend=3 +Si cela ne fonctionne pas, il faut supprimer les ombres : + [Engine] + WhiteSrcBlend=0 + WhiteDestBlend=0 + [Setup] + GroundShadow=0 + +Lorsque un objet s'interpose entre l'objet sélectionné et la +caméra, il devient transparent. Si l'objet n'est pas assez +transparent, essayez : + [Engine] + StateColor=0 +ou + [Engine] + StateColor=1 + + +Equipe de développement +----------------------- + +- Daniel Roux +- Denis Dumoulin +- Otto Kölbl +- Michael Walz +- Didier Gertsch + +Beta testeurs +------------- + +- Adrien Roux +- Didier Raboud +- Nicolas Beuchat +- Joël Roux +- Michael Jubin +- Daniel Sauthier +- Nicolas Stubi +- Patrick Thévoz + +Copyright +--------- + +La photo de la nébuleuse NGC3603 servant de fond pour la planète +Orphéon a été prise avec le télescope spatial Hubble. Elle est +utilisée avec l'autorisation des auteurs Wolfgang Brandner +(JPL/IPAC), Eva K. Grebel (Université de Washington), You-Hua Chu +(Université d'Illinois Urbana-Champaign) et de la NASA. + +Le son de tonnerre de la planète Orphéon est utilisé avec +l'autorisation limitée de CREATIVE moyennant la mention : +Material from products are used by limited permission from CREATIVE. + +Développeur +----------- + +EPSITEC SA +Mouette 5 +CH-1092 Belmont + +colobot@epsitec.ch +www.colobot.com + +Editeur de la version française +------------------------------- + +ALSYD +43, Ch. du vieux Chêne +F-38240 Meylan + +www.alsyd.com diff --git a/src/old/resource.h b/src/old/resource.h new file mode 100644 index 0000000..0f3be0a --- /dev/null +++ b/src/old/resource.h @@ -0,0 +1,55 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by winmain.rc +// +#define IDI_MAIN_ICON 101 +#define IDR_MAIN_ACCEL 113 +#define IDR_MENU 141 +#define IDR_POPUP 142 +#define IDD_ABOUT 143 +#define IDD_CHANGEDEVICE 144 +#define IDC_CURSORHAND 149 +#define IDC_CURSORSCROLLL 150 +#define IDC_CURSORSCROLLR 151 +#define IDC_CURSORSCROLLU 152 +#define IDC_CURSORSCROLLD 153 +#define IDC_CURSORTARGET 154 +#define IDC_DEVICE_COMBO 1000 +#define IDC_MODE_COMBO 1001 +#define IDC_WINDOWED_CHECKBOX 1012 +#define IDC_STEREO_CHECKBOX 1013 +#define IDC_FULLSCREEN_TEXT 1014 +#define IDM_ABOUT 40001 +#define IDM_CHANGEDEVICE 40002 +#define IDM_TOGGLEFULLSCREEN 40003 +#define IDM_TOGGLESTART 40004 +#define IDM_SINGLESTEP 40005 +#define IDM_EXIT 40006 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 159 +#define _APS_NEXT_COMMAND_VALUE 40011 +#define _APS_NEXT_CONTROL_VALUE 1015 +#define _APS_NEXT_SYMED_VALUE 102 +#endif +#endif diff --git a/src/old/t.txt b/src/old/t.txt new file mode 100644 index 0000000..9dd81fb --- /dev/null +++ b/src/old/t.txt @@ -0,0 +1,11 @@ +extern void object::Go() +{ +//float a = energyLevel; +//message(a); + +//object item=energyCell; +//float i = item.energyLevel; +//message(i); +float i = energyCell.energyLevel; + +} diff --git a/src/old/tracks.txt b/src/old/tracks.txt new file mode 100644 index 0000000..8d80872 --- /dev/null +++ b/src/old/tracks.txt @@ -0,0 +1,17 @@ +Utilisation des tracks + + 1: data + 2: terre Terre + 3: tropica Tropica + 4: crystalium Crystalium + 5: saari Saari + 6: volcano Volcano + 7: centaury Centaury + 8: orpheon Orphéon + 9: terranova Terranova +10: lost perdu +11: win gagné +12: fox fin du jeu +13: shuffle - + +DR 12.06.01 diff --git a/src/old/traduc.txt b/src/old/traduc.txt new file mode 100644 index 0000000..73bbf55 --- /dev/null +++ b/src/old/traduc.txt @@ -0,0 +1,151 @@ +Types des objets COLOBOT +------------------------ + + + ... // sac de survie + + BaseCamp // fusée principale + Derrick // derrick + BotFactory // fabrique de véhicules + PowerStation // station de recharge + Converter // conversion minerai en titanium + RepairCenter // centre de réparation + DefenceTower // tour de défense + AlienNest // nid + ResearchCenter // centre de recherches + RadarStation // radar + PowerPlant // fabrique de piles + AutoLab // analyseur de matières organiques + NuclearPlant // centrale nucléaire + StartArea // départ + GoalArea // arrivée + ExchangePost // borne d'information + + TitaniumOre // minerai de titanium + UraniumOre // minerai d'uranium + Titanium // titanium + PowerPack // pile normale + NuclearPack // pile nucléaire + OrgaStuff // matière organique + BlackBox // boîte noire + TNT // explosif + + PowerSpot // énergie en sous-sol + TitaniumSpot // titanium en sous-sol + UraniumSpot // uranium en sous-sol + PathSpot // chemin + + TrainingRollerBot // véhicule d'entraînement : + TrainingCrawlerBot + TrainingJetBot + TrainingSpiderBot + + GrabberRollerBot // véhicule manipulateur : + GrabberCrawlerBot + GrabberJetBot + GrabberSpiderBot + + FireballRollerBot // véhicule de défense : + FireballCrawlerBot + FireballJetBot + FireballSpiderBot + + OrgaballRollerBot // véhicule de défense : + OrgaballCrawlerBot + OrgaballJetBot + OrgaballSpiderBot + + SnifferRollerBot // véhicule sondeur : + SnifferCrawlerBot + SnifferJetBot + SnifferSpiderBot + + ThumperBot // véhicule de terrassement + FazerBot // véhicule de défense + RecyclerBot // véhicule de récupération + ShieldBot // véhicule de protection + SubBot // sous-marin + TargetBot // cible d'entraînement + + Me // homme + Wiz // toto + + AlienBigLady // mère pondeuse + AlienEgg // oeuf + AlienAnt // fourmi + AlienSpider // araignée + AlienWasp // guèpe + AlienWorm // ver + + Wreck // épave de véhicule + Ruin // bâtiment en ruine + Firework // feu d'artifice + Mine // mine + Barrier // barrière + Greenery // plante + Tree // arbre + Quartz // quartz + MegaStalk // racine + ... // gravi-plante + + +Fonction du langage CBOT : + + Move // avance d'une certaine distance + Turn // tourne d'un certain angle + Goto // va à une coordonnée donnée + Motor // commande directe des moteurs gauche & droite + Jet // commande directe du réacteur + + Radar // détecte un objet + Direction // calcule une direction + Distance // calcule la distance entre deux points + Wait // attend + Produce // crée un objet + Message // affiche un message + + Grab // prend un objet avec le bras manipulateur + Drop // dépose un objet avec le bras manipulateur + Sniff // sonde le sous-sol + Receive // reçoit une information + Send // envoie une information + Thump // terraforme le terrain + Recycle // récupère une épave + Shield // actionne le bouclier de protection + Fire // tir avec un canon + Aim // hausse du canon + + +Classes : + + point // point avec coordonnées x,y,z + object // descriptif d'un objet + + +Descripteur d'un objet : + + category // catégorie de l'objet + energyPack // object pile + load // objet transporté + position // position x,y,z + direction // orientation + energyLevel // niveau d'énergie + shieldLevel // niveau du bouclier + altitude // hauteur par rapport au sol + + +Argument de la commande Manip( ) : + + InFront // prend ou dépose devant + Behind // prend ou dépose derrière + EnergyPack // prend ou dépose sa propre pile + + +Filtre pour la commande Radar( ) ; + + FilterNone // pas de filtre + FilterOnlyLanding // seulement les robots qui roulent + FilterOnlyFliying // seulement les robots qui volent + + +DR 14.03.01 diff --git a/src/old/version.txt b/src/old/version.txt new file mode 100644 index 0000000..da31287 --- /dev/null +++ b/src/old/version.txt @@ -0,0 +1,108 @@ +1.18 (24.01.08) +- Ne vérifie plus la présence des pistes audio. + +1.17 (08.01.08) +- Sound.cpp:InitAudioTrackVolume:mixerGetLineControls ne devrait plus planter + sous Vista, grace à l'abandon de MIXER_GETLINECONTROLSF_ALL. +- CoLoBoT ne joue plus les pistes audio, et le réglage du volume a disparu +- CoLoBoT n'affiche plus Alsyd +- Texte "www.colobot.com" remplacé par "www.ceebot.com" + +1.16 (10.11.03) +- Options: si "accès aux solutions" décoché -> Lancer défi, + éditer programme, Esc, Abandonner: plus de bouton "accès à la solution" + +1.15 (02.09.03) +- EVENT_INTERFACE_KGUP: plus si CeeBot-Teen ! +- EVENT_INTERFACE_KGDOWN: plus si CeeBot-Teen ! +- EVENT_INTERFACE_KACTION: plus si CeeBot-Teen ! +- EVENT_INTERFACE_KVISIT: plus si CeeBot-Teen ! +- EVENT_INTERFACE_KNEXT: plus si CeeBot-Teen ! +- EVENT_INTERFACE_KHUMAN: plus si CeeBot-Teen ! +- EVENT_INTERFACE_KDESEL: plus si CeeBot-Teen ! +- EVENT_INTERFACE_KCBOT: plus si CeeBot-Teen ! + +1.14 (28.07.03) +- Switch -nosetup -> plus de bouton "Options" pendant jeu + +1.8 () +- instruction shield(1, radius) ok avec radius 10..25 +- instruction shield(1, radius) possible si bouclier déjà déployé + +1.8 BETA (05.10.01) +- CBOT: public, static, synchronized, private, protected +- CBOT: strlen, strleft, strright, strmid, strval, strfind, strupper, strlower +- CBOT: file, open, close, writeln, readln, eof, deletefile +- extern/public: aide en cliquant dans la ligne d'info de l'éditeur +- ExchangePost: UpdateList si infos reçues +- ok si lien d'un seul caractère: \l;x\u file; +- colobot.ini: [Setup] DeleteGamer=1 +- colobot.ini: [Directory] files=files +- studio: nb max de caractères: 10000 -> 20000 +- script antt41 (scene904): AlienMother -> AlienQueen +- load: recompilation ok si procédures "public" dans d'autres robots +- si le volume CD est nul, la piste n'est pas du tout jouée +- goto ResearchCenter toujours possible +- meilleure gestion des touches Ctrl et Shift dans l'éditeur +- object.temperature=12 impossible (PR_READ) +- studio: ne plante plus si on tape plus de 100 car. sans espace +- studio: "enregistrer" se rappelle du nom de fichier dans la mission +- studio: Ctrl+A sélectionne tout +- studio: run: si liste < 5 variables -> fond gris + +1.7 (13.09.01) +- object.lifeTime +- object.range Winged* idem si camera OnBoard/Back +- float flatground(center, rmax); +- float abstime(); +- float receive(name, power); +- void send(name, value, power); +- void deleteinfo(name, power); +- bool testinfo(name, power); +- Le cosmonaute peut construire une borne d'information + +1.6 (06.09.01) +- niveaux supplémentaires avec %user% +- fonction "send" plus coloriée +- english help: EnergyPack -> EnergyCell +- english help: energyPack -> energyCell +- english help: FinishArea -> GoalArea + +1.5 (24.08.01) +- first execute: prefered first non-T&L, second T&L +- fondus welcome: D3DSTATETTb/w -> D3DSTATETCb/w + +1.4 (02.08.01) +- n'importe quelle touche/clic passe les écrans welcome1, 2 et 3 +- icône associée au CD dans autorun.inf +- SatCom: icône "Aide à la programmation" présente dans exercices +- welcome: phase "Alsyd" plus longue (8s) +- SaveOneScript quand on quitte le studio par ok, cancel ou run + +1.3 (27.07.01) +- goto BotFactory toujours possible +- documentation errmode(0) +- petites corrections anglaises par MW +- enlever pile pendant recherche ne bloque plus +- si human porte qq chose et vaisseau décole -> ne reste plus sur place +- robot sur vaisseau puis sauvegarder-reprendre -> impossible gravir pentes + +GoldMaster 1.3 /e envoyé à CD PRESS pour 1000x + +1.2 +- bouton de fermeture (en haut à droite) supprimé en mode fenêtré +- suppression du réglage "nice reset" + +1.1 (20.07.01) +- volume du son non nul après installation +- images logo au démarrage du jeu +- image generic != si français ou anglais +- install: nouvelle clé pour uninstall depuis autorun + +GoldMaster 1.1 /f envoyé à Alsyd + +1.0 +- commande "reset" (exercices) tjrs ok (fichier rechargé) +- nom sauvegarde avec date/heure au format anglais +- ScriptName.F et .E + diff --git a/src/old/winmain.aps b/src/old/winmain.aps new file mode 100644 index 0000000..6a1e0df Binary files /dev/null and b/src/old/winmain.aps differ diff --git a/src/old/winmain.rc b/src/old/winmain.rc new file mode 100644 index 0000000..547d4c2 --- /dev/null +++ b/src/old/winmain.rc @@ -0,0 +1,265 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define IDC_STATIC -1 +#include + + + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_MAIN_ICON ICON DISCARDABLE "DirectX.ico" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#define IDC_STATIC -1\r\n" + "#include \r\n" + "\r\n" + "\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_MAIN_ACCEL ACCELERATORS DISCARDABLE +BEGIN + VK_F12, IDM_CHANGEDEVICE, VIRTKEY, SHIFT, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_ABOUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 165 + TOPMARGIN, 7 + BOTTOMMARGIN, 117 + END + + IDD_CHANGEDEVICE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 174 + TOPMARGIN, 7 + BOTTOMMARGIN, 83 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUT DIALOG DISCARDABLE 0, 0, 172, 124 +STYLE DS_SYSMODAL | DS_MODALFRAME | DS_NOIDLEMSG | DS_SETFOREGROUND | + DS_3DLOOK | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "About" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,115,103,50,14 + ICON IDI_MAIN_ICON,IDC_STATIC,5,5,20,20 + LTEXT "Robot Sample",IDC_STATIC,35,5,46,8 + LTEXT "Copyright (c) 1999-2000 EPSITEC SA",IDC_STATIC,35,15, + 120,8 + LTEXT "About",IDC_STATIC,62,52,20,8 + LTEXT "Select Driver / Device / Mode",IDC_STATIC,62,62,97,8 + CTEXT "",IDC_STATIC,12,72,45,8 + LTEXT "Toggle Fullscreen / Windowed",IDC_STATIC,62,72,98,8 + LTEXT "Exit",IDC_STATIC,62,82,12,8 + CTEXT "",IDC_STATIC,12,52,45,8 + CTEXT "",IDC_STATIC,12,62,45,8 + CTEXT "",IDC_STATIC,12,82,45,8 + GROUPBOX "Usage",IDC_STATIC,7,42,160,55 + LTEXT "Daniel Roux, version 0.1 Janvier 2000",IDC_STATIC,35,26, + 121,8 +END + +IDD_CHANGEDEVICE DIALOG DISCARDABLE 0, 0, 182, 90 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Change device" +FONT 8, "MS Sans Serif" +BEGIN + GROUPBOX "&Device selection",-1,5,5,115,40 + COMBOBOX IDC_DEVICE_COMBO,10,15,105,100,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + CONTROL "Use desktop &window",IDC_WINDOWED_CHECKBOX,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,30,85,10 + GROUPBOX "Fullscreen &modes",IDC_FULLSCREEN_TEXT,5,45,115,40 + COMBOBOX IDC_MODE_COMBO,10,55,105,100,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + CONTROL "&Stereoscopic viewing",IDC_STEREO_CHECKBOX,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,70,85,9 + DEFPUSHBUTTON "OK",IDOK,125,5,50,14 + PUSHBUTTON "Cancel",IDCANCEL,125,25,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Go/stop\tEnter", IDM_TOGGLESTART + MENUITEM "&Single step\tSpace", IDM_SINGLESTEP + MENUITEM SEPARATOR + MENUITEM "&About...\tF1", IDM_ABOUT + MENUITEM "&Change device...\tF2", IDM_CHANGEDEVICE + MENUITEM SEPARATOR + MENUITEM "E&xit\tESC", IDM_EXIT + END +END + +IDR_POPUP MENU DISCARDABLE +BEGIN + POPUP "Popup" + BEGIN + MENUITEM "&Go/stop", IDM_TOGGLESTART + MENUITEM "&Single step", IDM_SINGLESTEP + MENUITEM SEPARATOR + MENUITEM "&About...", IDM_ABOUT + MENUITEM "&Change device...", IDM_CHANGEDEVICE + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_EXIT + END +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// French (Switzerland) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRS) +#ifdef _WIN32 +LANGUAGE LANG_FRENCH, SUBLANG_FRENCH_SWISS +#pragma code_page(1252) +#endif //_WIN32 + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "100c04b0" + BEGIN + VALUE "CompanyName", "www.epsitec.com\0" + VALUE "FileDescription", "CeeBot\0" + VALUE "FileVersion", "Version 1.0\0" + VALUE "InternalName", "CeeBot\0" + VALUE "LegalCopyright", "Copyright © 2001 by EPSITEC SA\0" + VALUE "OriginalFilename", "ceebot.exe\0" + VALUE "ProductName", "EPSITEC CeeBot\0" + VALUE "ProductVersion", "Version 1.0\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x100c, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Cursor +// + +IDC_CURSORHAND CURSOR DISCARDABLE "cursor1.cur" +IDC_CURSORSCROLLL CURSOR DISCARDABLE "cursorha.cur" +IDC_CURSORSCROLLR CURSOR DISCARDABLE "cursorsc.cur" +IDC_CURSORSCROLLU CURSOR DISCARDABLE "cur00001.cur" +IDC_CURSORSCROLLD CURSOR DISCARDABLE "cur00002.cur" +IDC_CURSORTARGET CURSOR DISCARDABLE "cur00003.cur" +#endif // French (Switzerland) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/particule.cpp b/src/particule.cpp deleted file mode 100644 index 0a8c27d..0000000 --- a/src/particule.cpp +++ /dev/null @@ -1,4373 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// particule.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dmath.h" -#include "d3dtextr.h" -#include "d3dengine.h" -#include "d3dutil.h" -#include "language.h" -#include "iman.h" -#include "math3d.h" -#include "event.h" -#include "object.h" -#include "physics.h" -#include "auto.h" -#include "robotmain.h" -#include "terrain.h" -#include "sound.h" -#include "water.h" -#include "particule.h" - - - -#define FOG_HSUP 10.0f -#define FOG_HINF 100.0f - - - - -// Check if an object can be destroyed, but is not an enemy. - -BOOL IsSoft(ObjectType type) -{ - return ( type == OBJECT_HUMAN || - type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs || - type == OBJECT_MOBILEsa || - type == OBJECT_MOBILEft || - type == OBJECT_MOBILEtt || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEit || - type == OBJECT_MOBILEdr || // robot? - type == OBJECT_METAL || - type == OBJECT_POWER || - type == OBJECT_ATOMIC || // cargo? - type == OBJECT_DERRICK || - type == OBJECT_STATION || - type == OBJECT_FACTORY || - type == OBJECT_REPAIR || - type == OBJECT_DESTROYER|| - type == OBJECT_CONVERT || - type == OBJECT_TOWER || - type == OBJECT_RESEARCH || - type == OBJECT_RADAR || - type == OBJECT_INFO || - type == OBJECT_ENERGY || - type == OBJECT_LABO || - type == OBJECT_NUCLEAR || - type == OBJECT_PARA ); // building? -} - -// Check if an object is a destroyable enemy. - -BOOL IsAlien(ObjectType type) -{ - return ( type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_BEE || - type == OBJECT_WORM || - type == OBJECT_MOTHER || - type == OBJECT_NEST || - type == OBJECT_BULLET || - type == OBJECT_EGG || - type == OBJECT_MOBILEtg || - type == OBJECT_TEEN28 || - type == OBJECT_TEEN31 ); -} - -// Returns the damping factor for friendly fire. - -float RetDecay(ObjectType type) -{ - if ( IsSoft(type) ) return 0.2f; - return 1.0f; -} - - - -// Application constructor. - -CParticule::CParticule(CInstanceManager *iMan, CD3DEngine* engine) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_PARTICULE, this); - - m_pD3DDevice = 0; - m_engine = engine; - m_main = 0; - m_terrain = 0; - m_water = 0; - m_sound = 0; - m_uniqueStamp = 0; - m_exploGunCounter = 0; - m_lastTimeGunDel = 0.0f; - m_absTime = 0.0f; - - FlushParticule(); -} - -// Application destructor. Free memory. - -CParticule::~CParticule() -{ - m_iMan->DeleteInstance(CLASS_PARTICULE, this); -} - - -void CParticule::SetD3DDevice(LPDIRECT3DDEVICE7 device) -{ - m_pD3DDevice = device; -} - - -// Removes all particles. - -void CParticule::FlushParticule() -{ - int i, j; - - for ( i=0 ; iSearchInstance(CLASS_MAIN); - } - -#if 0 - if ( sheet == SH_WORLD && - type != PARTISELY && - type != PARTISELR && - type != PARTIGUN1 && - type != PARTIGUN2 && - type != PARTIGUN3 && - type != PARTIGUN4 && - type != PARTIQUARTZ && - !m_main->RetMovieLock() ) - { - dist = Length(pos, m_engine->RetEyePt()); - if ( dist > 300.0f ) return -1; - } -#endif - - t = -1; - if ( type == PARTIEXPLOT || - type == PARTIEXPLOO || - type == PARTIMOTOR || - type == PARTIBLITZ || - type == PARTICRASH || - type == PARTIVAPOR || - type == PARTIGAS || - type == PARTIBASE || - type == PARTIFIRE || - type == PARTIFIREZ || - type == PARTIBLUE || - type == PARTIROOT || - type == PARTIRECOVER || - type == PARTIEJECT || - type == PARTISCRAPS || - type == PARTIGUN2 || - type == PARTIGUN3 || - type == PARTIGUN4 || - type == PARTIQUEUE || - type == PARTIORGANIC1 || - type == PARTIORGANIC2 || - type == PARTIFLAME || - type == PARTIBUBBLE || - type == PARTIERROR || - type == PARTIWARNING || - type == PARTIINFO || - type == PARTISPHERE1 || - type == PARTISPHERE2 || - type == PARTISPHERE4 || - type == PARTISPHERE5 || - type == PARTISPHERE6 || - type == PARTIPLOUF0 || - type == PARTITRACK1 || - type == PARTITRACK2 || - type == PARTITRACK3 || - type == PARTITRACK4 || - type == PARTITRACK5 || - type == PARTITRACK6 || - type == PARTITRACK7 || - type == PARTITRACK8 || - type == PARTITRACK9 || - type == PARTITRACK10 || - type == PARTITRACK11 || - type == PARTITRACK12 || - type == PARTILENS1 || - type == PARTILENS2 || - type == PARTILENS3 || - type == PARTILENS4 || - type == PARTIGFLAT || - type == PARTIDROP || - type == PARTIWATER || - type == PARTILIMIT1 || - type == PARTILIMIT2 || - type == PARTILIMIT3 || - type == PARTILIMIT4 || - type == PARTIEXPLOG1 || - type == PARTIEXPLOG2 ) - { - t = 1; // effect00 - } - if ( type == PARTIGLINT || - type == PARTIGLINTb || - type == PARTIGLINTr || - type == PARTITOTO || - type == PARTISELY || - type == PARTISELR || - type == PARTIQUARTZ || - type == PARTIGUNDEL || - type == PARTICONTROL || - type == PARTISHOW || - type == PARTICHOC || - type == PARTIFOG4 || - type == PARTIFOG5 || - type == PARTIFOG6 || - type == PARTIFOG7 ) - { - t = 2; // effect01 - } - if ( type == PARTIGUN1 || - type == PARTIFLIC || - type == PARTISPHERE0 || - type == PARTISPHERE3 || - type == PARTIFOG0 || - type == PARTIFOG1 || - type == PARTIFOG2 || - type == PARTIFOG3 ) - { - t = 3; // effect02 - } - if ( type == PARTISMOKE1 || - type == PARTISMOKE2 || - type == PARTISMOKE3 || - type == PARTIBLOOD || - type == PARTIBLOODM || - type == PARTIVIRUS1 || - type == PARTIVIRUS2 || - type == PARTIVIRUS3 || - type == PARTIVIRUS4 || - type == PARTIVIRUS5 || - type == PARTIVIRUS6 || - type == PARTIVIRUS7 || - type == PARTIVIRUS8 || - type == PARTIVIRUS9 || - type == PARTIVIRUS10 ) - { - t = 4; // text (D3DSTATETTw) - } - if ( t >= MAXPARTITYPE ) return -1; - if ( t == -1 ) return -1; - - for ( j=0 ; j= PARTIFOG0 && - type <= PARTIFOG9 ) - { - if ( m_fogTotal < MAXPARTIFOG ) - m_fog[m_fogTotal++] = i; - } - - return i | ((m_particule[i].uniqueStamp&0xffff)<<16); - } - } - - return -1; -} - -// Creates a new triangular particle (debris). -// Returns the channel of the particle created or -1 on error. - -int CParticule::CreateFrag(D3DVECTOR pos, D3DVECTOR speed, - D3DTriangle *triangle, - ParticuleType type, - float duration, float mass, - float windSensitivity, int sheet) -{ - D3DVECTOR p1, p2, p3, n; - float l1, l2, l3, dx, dy; - int i, j, t; - - t = 0; - for ( j=0 ; j= MAXPARTITYPE ) return -1; - if ( t == -1 ) return -1; - - for ( j=0 ; jRetWheelTraceQuantity()*MAXWHEELTRACE); - max = MAXWHEELTRACE; - i = m_wheelTraceIndex++; - if ( m_wheelTraceIndex > max ) m_wheelTraceIndex = 0; - - m_wheelTrace[i].type = type; - m_wheelTrace[i].pos[0] = p1; // ul - m_wheelTrace[i].pos[1] = p2; // dl - m_wheelTrace[i].pos[2] = p3; // ur - m_wheelTrace[i].pos[3] = p4; // dr - m_wheelTrace[i].startTime = m_absTime; - - if ( m_terrain == 0 ) - { - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - } - - m_terrain->MoveOnFloor(m_wheelTrace[i].pos[0]); - m_wheelTrace[i].pos[0].y += 0.2f; // just above the ground - - m_terrain->MoveOnFloor(m_wheelTrace[i].pos[1]); - m_wheelTrace[i].pos[1].y += 0.2f; // just above the ground - - m_terrain->MoveOnFloor(m_wheelTrace[i].pos[2]); - m_wheelTrace[i].pos[2].y += 0.2f; // just above the ground - - m_terrain->MoveOnFloor(m_wheelTrace[i].pos[3]); - m_wheelTrace[i].pos[3].y += 0.2f; // just above the ground - - if ( m_wheelTraceTotal < max ) - { - m_wheelTraceTotal ++; - } - else - { - m_wheelTraceTotal = max; - } -} - - -// Check a channel number. -// Adapts the channel so it can be used as an offset in m_particule. - -BOOL CParticule::CheckChannel(int &channel) -{ - int uniqueStamp; - - uniqueStamp = (channel>>16)&0xffff; - channel &= 0xffff; - - if ( channel < 0 ) return FALSE; - if ( channel >= MAXPARTICULE*MAXPARTITYPE ) return FALSE; -#if 0 - if ( !m_particule[channel].bUsed ) return FALSE; - - if ( m_particule[channel].uniqueStamp != uniqueStamp ) return FALSE; -#else - if ( !m_particule[channel].bUsed ) - { - OutputDebugString("CheckChannel bUsed=FALSE !\n"); - return FALSE; - } - - if ( m_particule[channel].uniqueStamp != uniqueStamp ) - { - OutputDebugString("CheckChannel uniqueStamp !\n"); - return FALSE; - } -#endif - - return TRUE; -} - -// Removes a particle after his rank. - -void CParticule::DeleteRank(int rank) -{ - int i; - - if ( m_totalInterface[rank/MAXPARTICULE][m_particule[rank].sheet] > 0 ) - { - m_totalInterface[rank/MAXPARTICULE][m_particule[rank].sheet] --; - } - - i = m_particule[rank].trackRank; - if ( i != -1 ) // drag associated? - { - m_track[i].bUsed = FALSE; // frees the drag - } - - m_particule[rank].bUsed = FALSE; -} - -// Removes all particles of a given type. - -void CParticule::DeleteParticule(ParticuleType type) -{ - int i; - - for ( i=0 ; i 0 ) - { - m_totalInterface[channel/MAXPARTICULE][m_particule[channel].sheet] --; - } - - i = m_particule[channel].trackRank; - if ( i != -1 ) // drag associated? - { - m_track[i].bUsed = FALSE; // frees the drag - } - - m_particule[channel].bUsed = FALSE; -} - - -// Specifies the object to which the particle is bound. - -void CParticule::SetObjectLink(int channel, CObject *object) -{ - if ( !CheckChannel(channel) ) return; - m_particule[channel].objLink = object; -} - -// Specifies the parent object that created the particle. - -void CParticule::SetObjectFather(int channel, CObject *object) -{ - if ( !CheckChannel(channel) ) return; - m_particule[channel].objFather = object; -} - -void CParticule::SetPosition(int channel, D3DVECTOR pos) -{ - if ( !CheckChannel(channel) ) return; - m_particule[channel].pos = pos; -} - -void CParticule::SetDimension(int channel, FPOINT dim) -{ - if ( !CheckChannel(channel) ) return; - m_particule[channel].dim = dim; -} - -void CParticule::SetZoom(int channel, float zoom) -{ - if ( !CheckChannel(channel) ) return; - m_particule[channel].zoom = zoom; -} - -void CParticule::SetAngle(int channel, float angle) -{ - if ( !CheckChannel(channel) ) return; - m_particule[channel].angle = angle; -} - -void CParticule::SetIntensity(int channel, float intensity) -{ - if ( !CheckChannel(channel) ) return; - m_particule[channel].intensity = intensity; -} - -void CParticule::SetParam(int channel, D3DVECTOR pos, FPOINT dim, float zoom, - float angle, float intensity) -{ - if ( !CheckChannel(channel) ) return; - m_particule[channel].pos = pos; - m_particule[channel].dim = dim; - m_particule[channel].zoom = zoom; - m_particule[channel].angle = angle; - m_particule[channel].intensity = intensity; -} - -void CParticule::SetPhase(int channel, ParticulePhase phase, float duration) -{ - if ( !CheckChannel(channel) ) return; - m_particule[channel].phase = phase; - m_particule[channel].duration = duration; - m_particule[channel].phaseTime = m_particule[channel].time; -} - -// Returns the position of the particle. - -BOOL CParticule::GetPosition(int channel, D3DVECTOR &pos) -{ - if ( !CheckChannel(channel) ) return FALSE; - pos = m_particule[channel].pos; - return TRUE; -} - - -// Indicates whether a sheet evolves or not. - -void CParticule::SetFrameUpdate(int sheet, BOOL bUpdate) -{ - m_bFrameUpdate[sheet] = bUpdate; -} - -// Makes evolve all the particles. - -void CParticule::FrameParticule(float rTime) -{ - CObject* object; - D3DVECTOR eye, pos, speed, wind; - FPOINT ts, ti, dim; - BOOL bPause; - float progress, dp, h, duration, mass, amplitude; - int i, j, r, total; - - if ( m_main == 0 ) - { - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - } - - bPause = ( m_engine->RetPause() && !m_main->RetInfoLock() ); - - if ( m_terrain == 0 ) - { - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - } - if ( m_water == 0 ) - { - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - } - - if ( !bPause ) - { - m_lastTimeGunDel += rTime; - m_absTime += rTime; - } - - wind = m_terrain->RetWind(); - eye = m_engine->RetEyePt(); - - for ( i=0 ; iRetFloorLevel(m_particule[i].pos, TRUE); - } - h += m_particule[i].dim.y*0.75f; - if ( m_particule[i].pos.y < h ) // impact with the ground? - { - if ( m_particule[i].type == PARTIPART && - m_particule[i].weight > 3.0f && // heavy enough? - m_particule[i].bounce < 3 ) - { - amplitude = m_particule[i].weight*0.1f; - amplitude *= 1.0f-0.3f*m_particule[i].bounce; - if ( amplitude > 1.0f ) amplitude = 1.0f; - if ( amplitude > 0.0f ) - { - Play(SOUND_BOUM, m_particule[i].pos, amplitude); - } - } - - if ( m_particule[i].bounce < 3 ) - { - m_particule[i].pos.y = h; - m_particule[i].speed.y *= -0.4f; - m_particule[i].speed.x *= 0.4f; - m_particule[i].speed.z *= 0.4f; - m_particule[i].bounce ++; // more impact - } - else // disappears after 3 bounces? - { - if ( m_particule[i].pos.y < h-10.0f || - m_particule[i].time >= 20.0f ) - { - DeleteRank(i); - continue; - } - } - } - } - - // Manages drag associated. - r = m_particule[i].trackRank; - if ( r != -1 ) // drag exists? - { - if ( TrackMove(r, m_particule[i].pos, progress) ) - { - DeleteRank(i); - continue; - } - - m_track[r].bDrawParticule = (progress < 1.0f); - } - - if ( m_particule[i].type == PARTITRACK1 ) // explosion technique? - { - m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); - - ts.x = 0.375f; - ts.y = 0.000f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTITRACK2 ) // spray blue? - { - m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); - - ts.x = 0.500f; - ts.y = 0.000f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTITRACK3 ) // spider? - { - m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); - - ts.x = 0.500f; - ts.y = 0.750f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTITRACK4 ) // insect explosion? - { - m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); - - ts.x = 0.625f; - ts.y = 0.000f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTITRACK5 ) // derrick? - { - m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); - - ts.x = 0.750f; - ts.y = 0.000f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTITRACK6 ) // reset in/out? - { - ts.x = 0.0f; - ts.y = 0.0f; - ti.x = 0.0f; - ti.y = 0.0f; - } - - if ( m_particule[i].type == PARTITRACK7 || // win-1 ? - m_particule[i].type == PARTITRACK8 || // win-2 ? - m_particule[i].type == PARTITRACK9 || // win-3 ? - m_particule[i].type == PARTITRACK10 ) // win-4 ? - { - m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); - - ts.x = 0.25f*(m_particule[i].type-PARTITRACK7); - ts.y = 0.25f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTITRACK11 ) // phazer shot? - { - object = SearchObjectGun(m_particule[i].goal, m_particule[i].pos, m_particule[i].type, m_particule[i].objFather); - m_particule[i].goal = m_particule[i].pos; - if ( object != 0 ) - { - if ( object->RetType() == OBJECT_MOTHER ) - { - object->ExploObject(EXPLO_BOUM, 0.1f); - } - else - { - object->ExploObject(EXPLO_BOUM, 0.0f, RetDecay(object->RetType())); - } - } - - m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); - - ts.x = 0.375f; - ts.y = 0.000f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTITRACK12 ) // drag reactor? - { - m_particule[i].zoom = 1.0f; - - ts.x = 0.375f; - ts.y = 0.000f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIMOTOR ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f-progress; - m_particule[i].intensity = 1.0f-progress; - - ts.x = 0.000f; - ts.y = 0.750f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIBLITZ ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f-progress; - m_particule[i].angle = Rand()*PI*2.0f; - - ts.x = 0.125f; - ts.y = 0.750f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTICRASH ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - -//? m_particule[i].intensity = 1.0f-progress; - if ( progress < 0.25f ) - { - m_particule[i].zoom = progress/0.25f; - } - else - { - m_particule[i].intensity = 1.0f-(progress-0.25f)/0.75f; - } - -//? ts.x = 0.250f; - ts.x = 0.000f; -//? ts.x = 0.375f; - ts.y = 0.750f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIVAPOR ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].intensity = 1.0f-progress; - m_particule[i].zoom = 1.0f+progress*3.0f; - - ts.x = 0.000f; - ts.y = 0.750f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIGAS ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f-progress; - - ts.x = 0.375f; - ts.y = 0.750f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIBASE ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f+progress*7.0f; - m_particule[i].intensity = powf(1.0f-progress, 3.0f); - - ts.x = 0.375f; - ts.y = 0.750f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIFIRE || - m_particule[i].type == PARTIFIREZ ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( m_particule[i].type == PARTIFIRE ) - { - m_particule[i].zoom = 1.0f-progress; - } - else - { - m_particule[i].zoom = progress; - } - - ts.x = 0.500f; - ts.y = 0.750f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIGUN1 ) // fireball shot? - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( m_particule[i].testTime >= 0.1f ) - { - m_particule[i].testTime = 0.0f; - - if ( m_terrain->RetFloorHeight(m_particule[i].pos, TRUE) < -2.0f ) - { - m_exploGunCounter ++; - - if ( m_exploGunCounter%2 == 0 ) - { - pos = m_particule[i].goal; - m_terrain->MoveOnFloor(pos, TRUE); - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 0.0f; - dim.x = Rand()*6.0f+6.0f; - dim.y = dim.x; - duration = Rand()*1.0f+1.0f; - mass = 0.0f; - CreateParticule(pos, speed, dim, PARTIEXPLOG1, duration, mass, 1.0f); - - pos.y += 1.0f; - total = (int)(2.0f*m_engine->RetParticuleDensity()); - for ( j=0 ; jExploObject(EXPLO_BURN, 0.0f, RetDecay(object->RetType())); - - m_exploGunCounter ++; - - if ( m_exploGunCounter%2 == 0 ) - { - pos = m_particule[i].pos; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 0.0f; - dim.x = Rand()*6.0f+6.0f; - dim.y = dim.x; - duration = Rand()*1.0f+1.0f; - mass = 0.0f; - CreateParticule(pos, speed, dim, PARTIEXPLOG1, duration, mass, 1.0f); - - pos.y += 1.0f; - total = (int)(2.0f*m_engine->RetParticuleDensity()); - for ( j=0 ; j= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( m_particule[i].testTime >= 0.2f ) - { - m_particule[i].testTime = 0.0f; - object = SearchObjectGun(m_particule[i].goal, m_particule[i].pos, m_particule[i].type, m_particule[i].objFather); - m_particule[i].goal = m_particule[i].pos; - if ( object != 0 ) - { - if ( object->RetShieldRadius() > 0.0f ) // protected by shield? - { - CreateParticule(m_particule[i].pos, D3DVECTOR(0.0f, 0.0f, 0.0f), FPOINT(6.0f, 6.0f), PARTIGUNDEL, 2.0f); - if ( m_lastTimeGunDel > 0.2f ) - { - m_lastTimeGunDel = 0.0f; - Play(SOUND_GUNDEL, m_particule[i].pos, 1.0f); - } - DeleteRank(i); - continue; - } - else - { - if ( object->RetType() != OBJECT_HUMAN ) - { - Play(SOUND_TOUCH, m_particule[i].pos, 1.0f); - } - object->ExploObject(EXPLO_BOUM, 0.0f); // starts explosion - } - } - } - - m_particule[i].angle = Rand()*PI*2.0f; - m_particule[i].zoom = 1.0f-progress; - - ts.x = 0.125f; - ts.y = 0.875f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIGUN3 ) // spider suicides? - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( m_particule[i].testTime >= 0.2f ) - { - m_particule[i].testTime = 0.0f; - object = SearchObjectGun(m_particule[i].goal, m_particule[i].pos, m_particule[i].type, m_particule[i].objFather); - m_particule[i].goal = m_particule[i].pos; - if ( object != 0 ) - { - if ( object->RetShieldRadius() > 0.0f ) - { - CreateParticule(m_particule[i].pos, D3DVECTOR(0.0f, 0.0f, 0.0f), FPOINT(6.0f, 6.0f), PARTIGUNDEL, 2.0f); - if ( m_lastTimeGunDel > 0.2f ) - { - m_lastTimeGunDel = 0.0f; - Play(SOUND_GUNDEL, m_particule[i].pos, 1.0f); - } - DeleteRank(i); - continue; - } - else - { - object->ExploObject(EXPLO_BURN, 1.0f); // starts explosion - } - } - } - -//? ts.x = 0.875f; -//? ts.y = 0.750f; - ts.x = 0.500f; - ts.y = 0.750f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIGUN4 ) // orgaball shot? - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( m_particule[i].testTime >= 0.1f ) - { - m_particule[i].testTime = 0.0f; - - if ( m_terrain->RetFloorHeight(m_particule[i].pos, TRUE) < -2.0f ) - { - m_exploGunCounter ++; - - if ( m_exploGunCounter%2 == 0 ) - { - pos = m_particule[i].goal; - m_terrain->MoveOnFloor(pos, TRUE); - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 0.0f; - dim.x = Rand()*4.0f+2.0f; - dim.y = dim.x; - duration = Rand()*0.7f+0.7f; - mass = 0.0f; - CreateParticule(pos, speed, dim, PARTIEXPLOG2, duration, mass, 1.0f); - } - - if ( m_exploGunCounter%4 == 0 ) - { - Play(SOUND_EXPLOg2, pos, 0.5f); - } - - DeleteRank(i); - continue; - } - - object = SearchObjectGun(m_particule[i].goal, m_particule[i].pos, m_particule[i].type, m_particule[i].objFather); - m_particule[i].goal = m_particule[i].pos; - if ( object != 0 ) - { - object->ExploObject(EXPLO_BOUM, 0.0f, RetDecay(object->RetType())); - - m_exploGunCounter ++; - - if ( m_exploGunCounter%2 == 0 ) - { - pos = m_particule[i].pos; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 0.0f; - dim.x = Rand()*4.0f+2.0f; - dim.y = dim.x; - duration = Rand()*0.7f+0.7f; - mass = 0.0f; - CreateParticule(pos, speed, dim, PARTIEXPLOG2, duration, mass, 1.0f); - } - - if ( m_exploGunCounter%4 == 0 ) - { - Play(SOUND_EXPLOg2, pos, 0.5f); - } - - DeleteRank(i); - continue; - } - } - - m_particule[i].angle = Rand()*PI*2.0f; - m_particule[i].zoom = 1.0f-progress; - - ts.x = 0.125f; - ts.y = 0.875f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIFLIC ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 0.1f+progress; - m_particule[i].intensity = 1.0f-progress; - - ts.x = 0.00f; - ts.y = 0.75f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTISHOW ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( progress < 0.5f ) m_particule[i].intensity = progress/0.5f; - else m_particule[i].intensity = 2.0f-progress/0.5f; - m_particule[i].zoom = 1.0f-progress*0.8f; - m_particule[i].angle -= rTime*PI*0.5f; - - ts.x = 0.50f; - ts.y = 0.00f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTICHOC ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 0.1f+progress; - m_particule[i].intensity = 1.0f-progress; - - ts.x = 0.50f; - ts.y = 0.50f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTIGFLAT ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 0.1f+progress; - m_particule[i].intensity = 1.0f-progress; - m_particule[i].angle -= rTime*PI*2.0f; - - ts.x = 0.00f; - ts.y = 0.50f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTILIMIT1 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f; - m_particule[i].intensity = 1.0f; - - ts.x = 0.000f; - ts.y = 0.125f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - if ( m_particule[i].type == PARTILIMIT2 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f; - m_particule[i].intensity = 1.0f; - - ts.x = 0.375f; - ts.y = 0.125f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - if ( m_particule[i].type == PARTILIMIT3 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f; - m_particule[i].intensity = 1.0f; - - ts.x = 0.500f; - ts.y = 0.125f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIFOG0 ) - { - m_particule[i].zoom = progress; - m_particule[i].intensity = 0.3f+sinf(progress)*0.15f; - m_particule[i].angle += rTime*0.05f; - - ts.x = 0.25f; - ts.y = 0.75f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - if ( m_particule[i].type == PARTIFOG1 ) - { - m_particule[i].zoom = progress; - m_particule[i].intensity = 0.3f+sinf(progress)*0.15f; - m_particule[i].angle -= rTime*0.07f; - - ts.x = 0.25f; - ts.y = 0.75f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTIFOG2 ) - { - m_particule[i].zoom = progress; - m_particule[i].intensity = 0.6f+sinf(progress)*0.15f; - m_particule[i].angle += rTime*0.05f; - - ts.x = 0.75f; - ts.y = 0.75f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - if ( m_particule[i].type == PARTIFOG3 ) - { - m_particule[i].zoom = progress; - m_particule[i].intensity = 0.6f+sinf(progress)*0.15f; - m_particule[i].angle -= rTime*0.07f; - - ts.x = 0.75f; - ts.y = 0.75f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTIFOG4 ) - { - m_particule[i].zoom = progress; - m_particule[i].intensity = 0.5f+sinf(progress)*0.2f; - m_particule[i].angle += rTime*0.05f; - - ts.x = 0.00f; - ts.y = 0.25f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - if ( m_particule[i].type == PARTIFOG5 ) - { - m_particule[i].zoom = progress; - m_particule[i].intensity = 0.5f+sinf(progress)*0.2f; - m_particule[i].angle -= rTime*0.07f; - - ts.x = 0.00f; - ts.y = 0.25f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTIFOG6 ) - { - m_particule[i].zoom = progress; - m_particule[i].intensity = 0.5f+sinf(progress)*0.2f; - m_particule[i].angle += rTime*0.05f; - - ts.x = 0.50f; - ts.y = 0.25f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - if ( m_particule[i].type == PARTIFOG7 ) - { - m_particule[i].zoom = progress; - m_particule[i].intensity = 0.5f+sinf(progress)*0.2f; - m_particule[i].angle -= rTime*0.07f; - - ts.x = 0.50f; - ts.y = 0.25f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - // Decreases the intensity if the camera - // is almost at the same height (fog was eye level). - if ( m_particule[i].type >= PARTIFOG0 && - m_particule[i].type <= PARTIFOG9 ) - { - h = 10.0f; - - if ( m_particule[i].pos.y >= eye.y && - m_particule[i].pos.y < eye.y+h ) - { - m_particule[i].intensity *= (m_particule[i].pos.y-eye.y)/h; - } - if ( m_particule[i].pos.y > eye.y-h && - m_particule[i].pos.y < eye.y ) - { - m_particule[i].intensity *= (eye.y-m_particule[i].pos.y)/h; - } - } - - if ( m_particule[i].type == PARTIEXPLOT || - m_particule[i].type == PARTIEXPLOO ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f-progress/2.0f; - m_particule[i].intensity = 1.0f-progress; - - if ( m_particule[i].type == PARTIEXPLOT ) ts.x = 0.750f; - else ts.x = 0.875f; - ts.y = 0.750f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIEXPLOG1 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].intensity = 1.0f-progress; - - ts.x = 0.375f; - ts.y = 0.000f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - if ( m_particule[i].type == PARTIEXPLOG2 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].intensity = 1.0f-progress; - - ts.x = 0.625f; - ts.y = 0.000f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIFLAME ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f-progress/2.0f; - if ( progress < 0.5f ) - { - m_particule[i].intensity = progress/0.5f; - } - else - { - m_particule[i].intensity = 2.0f-progress/0.5f; - } - - ts.x = 0.750f; - ts.y = 0.750f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIBUBBLE ) - { - if ( progress >= 1.0f || - m_particule[i].pos.y >= m_water->RetLevel() ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f-progress/2.0f; - m_particule[i].intensity = 1.0f-progress; - - ts.x = 0.250f; - ts.y = 0.875f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTISMOKE1 || - m_particule[i].type == PARTISMOKE2 || - m_particule[i].type == PARTISMOKE3 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( progress < 0.25f ) - { - m_particule[i].zoom = progress/0.25f; - } - else - { - m_particule[i].intensity = 1.0f-(progress-0.25f)/0.75f; - } - - ts.x = 0.500f+0.125f*(m_particule[i].type-PARTISMOKE1); - ts.y = 0.750f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIBLOOD ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].intensity = 1.0f-progress; - - ts.x = 0.750f+(rand()%2)*0.125f; - ts.y = 0.875f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIBLOODM ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].intensity = 1.0f-progress; - - ts.x = 0.875f; - ts.y = 0.750f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIVIRUS1 || - m_particule[i].type == PARTIVIRUS2 || - m_particule[i].type == PARTIVIRUS3 || - m_particule[i].type == PARTIVIRUS4 || - m_particule[i].type == PARTIVIRUS5 || - m_particule[i].type == PARTIVIRUS6 || - m_particule[i].type == PARTIVIRUS7 || - m_particule[i].type == PARTIVIRUS8 || - m_particule[i].type == PARTIVIRUS9 || - m_particule[i].type == PARTIVIRUS10 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( progress < 0.25f ) - { - m_particule[i].zoom = progress/0.25f; - } - else - { - m_particule[i].intensity = 1.0f-(progress-0.25f)/0.75f; - } - m_particule[i].angle += rTime*PI*1.0f; - - if ( m_particule[i].type == PARTIVIRUS1 ) // A ? - { - ts.x = 0.0f/256.0f; ts.y = 19.0f/256.0f; - ti.x = 10.0f/256.0f; ti.y = 30.0f/256.0f; - } - if ( m_particule[i].type == PARTIVIRUS2 ) // C ? - { - ts.x = 19.0f/256.0f; ts.y = 19.0f/256.0f; - ti.x = 28.0f/256.0f; ti.y = 30.0f/256.0f; - } - if ( m_particule[i].type == PARTIVIRUS3 ) // E ? - { - ts.x = 36.0f/256.0f; ts.y = 19.0f/256.0f; - ti.x = 45.0f/256.0f; ti.y = 30.0f/256.0f; - } - if ( m_particule[i].type == PARTIVIRUS4 ) // N ? - { - ts.x = 110.0f/256.0f; ts.y = 19.0f/256.0f; - ti.x = 120.0f/256.0f; ti.y = 30.0f/256.0f; - } - if ( m_particule[i].type == PARTIVIRUS5 ) // R ? - { - ts.x = 148.0f/256.0f; ts.y = 19.0f/256.0f; - ti.x = 158.0f/256.0f; ti.y = 30.0f/256.0f; - } - if ( m_particule[i].type == PARTIVIRUS6 ) // T ? - { - ts.x = 166.0f/256.0f; ts.y = 19.0f/256.0f; - ti.x = 175.0f/256.0f; ti.y = 30.0f/256.0f; - } - if ( m_particule[i].type == PARTIVIRUS7 ) // 0 ? - { - ts.x = 90.0f/256.0f; ts.y = 2.0f/256.0f; - ti.x = 98.0f/256.0f; ti.y = 13.0f/256.0f; - } - if ( m_particule[i].type == PARTIVIRUS8 ) // 2 ? - { - ts.x = 103.0f/256.0f; ts.y = 2.0f/256.0f; - ti.x = 111.0f/256.0f; ti.y = 13.0f/256.0f; - } - if ( m_particule[i].type == PARTIVIRUS9 ) // 5 ? - { - ts.x = 125.0f/256.0f; ts.y = 2.0f/256.0f; - ti.x = 132.0f/256.0f; ti.y = 13.0f/256.0f; - } - if ( m_particule[i].type == PARTIVIRUS10 ) // 9 ? - { - ts.x = 153.0f/256.0f; ts.y = 2.0f/256.0f; - ti.x = 161.0f/256.0f; ti.y = 13.0f/256.0f; - } - } - - if ( m_particule[i].type == PARTIBLUE ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f-progress; - - ts.x = 0.625f; - ts.y = 0.750f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIROOT ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( progress < 0.25f ) - { - m_particule[i].zoom = progress/0.25f; - } - else - { - m_particule[i].intensity = 1.0f-(progress-0.25f)/0.75f; - } - - ts.x = 0.000f; - ts.y = 0.000f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIRECOVER ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( progress < 0.25f ) - { - m_particule[i].zoom = progress/0.25f; - } - else - { - m_particule[i].intensity = 1.0f-(progress-0.25f)/0.75f; - } - - ts.x = 0.875f; - ts.y = 0.000f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIEJECT ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f+powf(progress, 2.0f)*5.0f; - m_particule[i].intensity = 1.0f-progress; - - ts.x = 0.625f; - ts.y = 0.875f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTISCRAPS ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f-progress; - - ts.x = 0.625f; - ts.y = 0.875f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIFRAG ) - { - m_particule[i].angle += rTime*PI*0.5f; - - ts.x = 0.0f; - ts.y = 0.0f; - ti.x = 0.0f; - ti.y = 0.0f; - } - - if ( m_particule[i].type == PARTIPART ) - { - ts.x = 0.0f; - ts.y = 0.0f; - ti.x = 0.0f; - ti.y = 0.0f; - } - - if ( m_particule[i].type == PARTIQUEUE ) - { - if ( m_particule[i].testTime >= 0.05f ) - { - m_particule[i].testTime = 0.0f; - - D3DVECTOR pos, speed; - FPOINT dim; - - pos = m_particule[i].pos; -//? speed = -m_particule[i].speed*0.5f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 1.0f*(Rand()*0.8f+0.6f); - dim.y = dim.x; - CreateParticule(pos, speed, dim, PARTIGAS, 0.5f); - } - - ts.x = 0.375f; - ts.y = 0.750f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIORGANIC1 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - - pos = m_particule[i].pos; - dim.x = m_particule[i].dim.x/4.0f; - dim.y = dim.x; - duration = m_particule[i].duration; - mass = m_particule[i].mass; - total = (int)(10.0f*m_engine->RetParticuleDensity()); - for ( i=0 ; iRetParticuleDensity()); - for ( i=0 ; i= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration); - - ts.x = 0.125f; - ts.y = 0.875f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIGLINT ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( progress > 0.5f ) - { -//? m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration/2.0f); - m_particule[i].zoom = 1.0f-(progress-0.5f)*2.0f; - } - m_particule[i].angle = m_particule[i].time*PI; - - ts.x = 0.75f; - ts.y = 0.25f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTIGLINTb ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( progress > 0.5f ) - { - m_particule[i].zoom = 1.0f-(progress-0.5f)*2.0f; - } - m_particule[i].angle = m_particule[i].time*PI; - - ts.x = 0.75f; - ts.y = 0.50f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTIGLINTr ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( progress > 0.5f ) - { - m_particule[i].zoom = 1.0f-(progress-0.5f)*2.0f; - } - m_particule[i].angle = m_particule[i].time*PI; - - ts.x = 0.75f; - ts.y = 0.00f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type >= PARTILENS1 && - m_particule[i].type <= PARTILENS4 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( progress < 0.5f ) - { - m_particule[i].zoom = progress*2.0f; - } - else - { - m_particule[i].intensity = 1.0f-(progress-0.5f)*2.0f; - } -//? m_particule[i].angle = m_particule[i].time*PI; - - ts.x = 0.25f*(m_particule[i].type-PARTILENS1); - ts.y = 0.25f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTICONTROL ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( progress < 0.3f ) - { - m_particule[i].zoom = progress/0.3f; - } - else - { - m_particule[i].zoom = 1.0f; - m_particule[i].intensity = 1.0f-(progress-0.3f)/0.7f; - } - - ts.x = 0.00f; - ts.y = 0.00f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTIGUNDEL ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( progress > 0.5f ) - { - m_particule[i].zoom = 1.0f-(m_particule[i].time-m_particule[i].duration/2.0f); - } - m_particule[i].angle = m_particule[i].time*PI; - - ts.x = 0.75f; - ts.y = 0.50f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTIQUARTZ ) - { - if ( progress >= 1.0f ) - { - m_particule[i].time = 0.0f; - m_particule[i].duration = 0.5f+Rand()*2.0f; - m_particule[i].pos.x = m_particule[i].speed.x + (Rand()-0.5f)*m_particule[i].mass; - m_particule[i].pos.y = m_particule[i].speed.y + (Rand()-0.5f)*m_particule[i].mass; - m_particule[i].pos.z = m_particule[i].speed.z + (Rand()-0.5f)*m_particule[i].mass; - m_particule[i].dim.x = 0.5f+Rand()*1.5f; - m_particule[i].dim.y = m_particule[i].dim.x; - progress = 0.0f; - } - - if ( progress < 0.2f ) - { - m_particule[i].zoom = progress/0.2f; - m_particule[i].intensity = 1.0f; - } - else - { - m_particule[i].zoom = 1.0f; - m_particule[i].intensity = 1.0f-(progress-0.2f)/0.8f; - } - - ts.x = 0.25f; - ts.y = 0.25f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTITOTO ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f-progress; - if ( progress < 0.15f ) - { - m_particule[i].intensity = progress/0.15f; - } - else - { - m_particule[i].intensity = 1.0f-(progress-0.15f)/0.85f; - } - m_particule[i].intensity *= 0.5f; - - ts.x = 0.25f; - ts.y = 0.50f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTIERROR ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = progress*1.0f; - m_particule[i].intensity = 1.0f-progress; - - ts.x = 0.500f; - ts.y = 0.875f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIWARNING ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = progress*1.0f; - m_particule[i].intensity = 1.0f-progress; - - ts.x = 0.875f; - ts.y = 0.875f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIINFO ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = progress*1.0f; - m_particule[i].intensity = 1.0f-progress; - - ts.x = 0.750f; - ts.y = 0.875f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTISELY ) - { - ts.x = 0.75f; - ts.y = 0.25f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - if ( m_particule[i].type == PARTISELR ) - { - ts.x = 0.75f; - ts.y = 0.00f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTISPHERE0 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = progress*m_particule[i].dim.x; -//? m_particule[i].intensity = 1.0f-progress; - if ( progress < 0.65f ) - { - m_particule[i].intensity = progress/0.65f; - } - else - { - m_particule[i].intensity = 1.0f-(progress-0.65f)/0.35f; - } - m_particule[i].intensity *= 0.5f; - - ts.x = 0.50f; - ts.y = 0.75f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTISPHERE1 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( progress < 0.30f ) - { - m_particule[i].intensity = progress/0.30f; - } - else - { - m_particule[i].intensity = 1.0f-(progress-0.30f)/0.70f; - } - m_particule[i].zoom = progress*m_particule[i].dim.x; - m_particule[i].angle = m_particule[i].time*PI*2.0f; - - ts.x = 0.000f; - ts.y = 0.000f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTISPHERE2 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( progress < 0.20f ) - { - m_particule[i].intensity = 1.0f; - } - else - { - m_particule[i].intensity = 1.0f-(progress-0.20f)/0.80f; - } - m_particule[i].zoom = progress*m_particule[i].dim.x; - m_particule[i].angle = m_particule[i].time*PI*2.0f; - - ts.x = 0.125f; - ts.y = 0.000f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTISPHERE3 ) - { - if ( m_particule[i].phase == PARPHEND && - progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( m_particule[i].phase == PARPHSTART ) - { - m_particule[i].intensity = progress; - if ( m_particule[i].intensity > 1.0f ) - { - m_particule[i].intensity = 1.0f; - } - } - - if ( m_particule[i].phase == PARPHEND ) - { - m_particule[i].intensity = 1.0f-progress; - } - - m_particule[i].zoom = m_particule[i].dim.x; - m_particule[i].angle = m_particule[i].time*PI*0.2f; - - ts.x = 0.25f; - ts.y = 0.75f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTISPHERE4 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = progress*m_particule[i].dim.x; - if ( progress < 0.65f ) - { - m_particule[i].intensity = progress/0.65f; - } - else - { - m_particule[i].intensity = 1.0f-(progress-0.65f)/0.35f; - } - m_particule[i].intensity *= 0.5f; - - ts.x = 0.125f; - ts.y = 0.000f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTISPHERE5 ) - { - m_particule[i].intensity = 0.7f+sinf(progress)*0.3f; - m_particule[i].zoom = m_particule[i].dim.x*(1.0f+sinf(progress*0.7f)*0.01f); - m_particule[i].angle = m_particule[i].time*PI*0.2f; - - ts.x = 0.25f; - ts.y = 0.50f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTISPHERE6 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = (1.0f-progress)*m_particule[i].dim.x; - m_particule[i].intensity = progress*0.5f; - - ts.x = 0.125f; - ts.y = 0.000f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIPLOUF0 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = progress; -#if 0 - if ( progress <= 0.5f ) - { - m_particule[i].intensity = 1.0f; - } - else - { - m_particule[i].intensity = 1.0f-(progress-0.5f)/0.5f; - } -#else -//? m_particule[i].intensity = 1.0f; - m_particule[i].intensity = 1.0f-progress; -#endif - - ts.x = 0.50f; - ts.y = 0.50f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTIDROP ) - { - if ( progress >= 1.0f || - m_particule[i].pos.y < m_water->RetLevel() ) - { - DeleteRank(i); - continue; - } - - m_particule[i].zoom = 1.0f-progress; - m_particule[i].intensity = 1.0f-progress; - - ts.x = 0.750f; - ts.y = 0.500f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIWATER ) - { - if ( progress >= 1.0f || - m_particule[i].pos.y < m_water->RetLevel() ) - { - DeleteRank(i); - continue; - } - - m_particule[i].intensity = 1.0f-progress; - - ts.x = 0.125f; - ts.y = 0.125f; - ti.x = ts.x+0.125f; - ti.y = ts.y+0.125f; - } - - if ( m_particule[i].type == PARTIRAY1 ) // rayon tour ? - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - if ( m_particule[i].testTime >= 0.2f ) - { - m_particule[i].testTime = 0.0f; - object = SearchObjectRay(m_particule[i].pos, m_particule[i].goal, - m_particule[i].type, m_particule[i].objFather); - if ( object != 0 ) - { - object->ExploObject(EXPLO_BOUM, 0.0f); - } - } - - ts.x = 0.00f; - ts.y = 0.00f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - if ( m_particule[i].type == PARTIRAY2 || - m_particule[i].type == PARTIRAY3 ) - { - if ( progress >= 1.0f ) - { - DeleteRank(i); - continue; - } - - ts.x = 0.00f; - ts.y = 0.25f; - ti.x = ts.x+0.25f; - ti.y = ts.y+0.25f; - } - - dp = (1.0f/256.0f)/2.0f; - m_particule[i].texSup.x = ts.x+dp; - m_particule[i].texSup.y = ts.y+dp; - m_particule[i].texInf.x = ti.x-dp; - m_particule[i].texInf.y = ti.y-dp; - m_particule[i].time += rTime; - m_particule[i].testTime += rTime; - } -} - - -// Moves a drag. -// Returns true if the drag is finished. - -BOOL CParticule::TrackMove(int i, D3DVECTOR pos, float progress) -{ - D3DVECTOR last; - int h, hh; - - if ( i < 0 || i >= MAXTRACK ) return TRUE; - if ( m_track[i].bUsed == FALSE ) return TRUE; - - if ( progress < 1.0f ) // particle exists? - { - h = m_track[i].head; - - if ( m_track[i].used == 1 || - m_track[i].last+m_track[i].step <= progress ) - { - m_track[i].last = progress; - last = m_track[i].pos[h]; - h ++; - if ( h == MAXTRACKLEN ) h = 0; - if ( m_track[i].used < MAXTRACKLEN ) m_track[i].used ++; - } - else - { - hh = h-1; - if ( hh < 0 ) hh = MAXTRACKLEN-1; - last = m_track[i].pos[hh]; - } - m_track[i].pos[h] = pos; - m_track[i].len[h] = Length(pos, last); - - m_track[i].head = h; - -//? m_track[i].intensity = 1.0f; - m_track[i].intensity = 1.0f-progress; - } - else // mort lente de la tra�n�e ? - { -//? m_track[i].intensity = 1.0f-(progress-1.0f)/(m_track[i].step*MAXTRACKLEN); - m_track[i].intensity = 0.0f; - } - - return (m_track[i].intensity <= 0.0f); -} - -// Draws a drag. - -void CParticule::TrackDraw(int i, ParticuleType type) -{ - D3DVERTEX2 vertex[4]; // 2 triangles - D3DVECTOR corner[4], p1, p2, p, n, eye; - D3DMATRIX matrix; - FPOINT texInf, texSup, rot; - float lTotal, f1, f2, a; - int counter, h; - - // Calculates the total length memorized. - lTotal = 0.0f; - h = m_track[i].head; - for ( counter=0 ; counterSetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); - - if ( type == PARTITRACK1 ) // explosion technique? - { - texInf.x = 64.5f/256.0f; - texInf.y = 21.0f/256.0f; - texSup.x = 95.5f/256.0f; - texSup.y = 22.0f/256.0f; // orange - } - if ( type == PARTITRACK2 ) // blue spray? - { - texInf.x = 64.5f/256.0f; - texInf.y = 13.0f/256.0f; - texSup.x = 95.5f/256.0f; - texSup.y = 14.0f/256.0f; // blue - } - if ( type == PARTITRACK3 ) // spider? - { - texInf.x = 64.5f/256.0f; - texInf.y = 5.0f/256.0f; - texSup.x = 95.5f/256.0f; - texSup.y = 6.0f/256.0f; // brown - } - if ( type == PARTITRACK4 ) // insect explosion? - { - texInf.x = 64.5f/256.0f; - texInf.y = 9.0f/256.0f; - texSup.x = 95.5f/256.0f; - texSup.y = 10.0f/256.0f; // dark green - } - if ( type == PARTITRACK5 ) // derrick? - { - texInf.x = 64.5f/256.0f; - texInf.y = 29.0f/256.0f; - texSup.x = 95.5f/256.0f; - texSup.y = 30.0f/256.0f; // dark brown - } - if ( type == PARTITRACK6 ) // reset in/out? - { - texInf.x = 64.5f/256.0f; - texInf.y = 17.0f/256.0f; - texSup.x = 95.5f/256.0f; - texSup.y = 18.0f/256.0f; // cyan - } - if ( type == PARTITRACK7 ) // win-1? - { - texInf.x = 64.5f/256.0f; - texInf.y = 41.0f/256.0f; - texSup.x = 95.5f/256.0f; - texSup.y = 42.0f/256.0f; // orange - } - if ( type == PARTITRACK8 ) // win-2? - { - texInf.x = 64.5f/256.0f; - texInf.y = 45.0f/256.0f; - texSup.x = 95.5f/256.0f; - texSup.y = 46.0f/256.0f; // yellow - } - if ( type == PARTITRACK9 ) // win-3? - { - texInf.x = 64.5f/256.0f; - texInf.y = 49.0f/256.0f; - texSup.x = 95.5f/256.0f; - texSup.y = 50.0f/256.0f; // red - } - if ( type == PARTITRACK10 ) // win-4? - { - texInf.x = 64.5f/256.0f; - texInf.y = 53.0f/256.0f; - texSup.x = 95.5f/256.0f; - texSup.y = 54.0f/256.0f; // violet - } - if ( type == PARTITRACK11 ) // phazer shot? - { - texInf.x = 64.5f/256.0f; - texInf.y = 21.0f/256.0f; - texSup.x = 95.5f/256.0f; - texSup.y = 22.0f/256.0f; // orange - } - if ( type == PARTITRACK12 ) // drag reactor? - { - texInf.x = 64.5f/256.0f; - texInf.y = 21.0f/256.0f; - texSup.x = 95.5f/256.0f; - texSup.y = 22.0f/256.0f; // orange - } - - h = m_track[i].head; - p1 = m_track[i].pos[h]; - f1 = m_track[i].intensity; - - eye = m_engine->RetEyePt(); - a = RotateAngle(eye.x-p1.x, eye.z-p1.z); - - for ( counter=0 ; counterDrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); - - if ( f2 < 0.0f ) break; - f1 = f2; - p1 = p2; - } -} - -// Draws a triangular particle. - -void CParticule::DrawParticuleTriangle(int i) -{ - CObject* object; - D3DMATRIX matrix; - D3DVECTOR eye, pos, angle; - - if ( m_particule[i].zoom == 0.0f ) return; - - eye = m_engine->RetEyePt(); - pos = m_particule[i].pos; - - object = m_particule[i].objLink; - if ( object != 0 ) - { - pos += object->RetPosition(0); - } - - angle.x = -RotateAngle(Length2d(pos, eye), pos.y-eye.y); - angle.y = RotateAngle(pos.z-eye.z, pos.x-eye.x); - angle.z = m_particule[i].angle; - - MatRotateXZY(matrix, angle); - matrix._41 = pos.x; - matrix._42 = pos.y; - matrix._43 = pos.z; - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_VERTEX2, - m_triangle[i].triangle, 3, NULL); - m_engine->AddStatisticTriangle(1); -} - -// Draw a normal particle. - -void CParticule::DrawParticuleNorm(int i) -{ - CObject* object; - D3DVERTEX2 vertex[4]; // 2 triangles - D3DMATRIX matrix; - D3DVECTOR corner[4], eye, pos, n, angle; - FPOINT dim; - float zoom; - - zoom = m_particule[i].zoom; - if ( !m_engine->RetStateColor() && m_particule[i].intensity < 0.5f ) - { - zoom *= m_particule[i].intensity/0.5f; - } - - if ( zoom == 0.0f ) return; - if ( m_particule[i].intensity == 0.0f ) return; - - if ( m_particule[i].sheet == SH_INTERFACE ) - { - pos = m_particule[i].pos; - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); - - dim.x = m_particule[i].dim.x * zoom; - dim.y = m_particule[i].dim.y * zoom; - - corner[0].x = pos.x+dim.x; - corner[0].y = pos.y+dim.y; - corner[0].z = 0.0f; - - corner[1].x = pos.x-dim.x; - corner[1].y = pos.y+dim.y; - corner[1].z = 0.0f; - - corner[2].x = pos.x+dim.x; - corner[2].y = pos.y-dim.y; - corner[2].z = 0.0f; - - corner[3].x = pos.x-dim.x; - corner[3].y = pos.y-dim.y; - corner[3].z = 0.0f; - - vertex[0] = D3DVERTEX2(corner[1], n, m_particule[i].texSup.x, m_particule[i].texSup.y); - vertex[1] = D3DVERTEX2(corner[0], n, m_particule[i].texInf.x, m_particule[i].texSup.y); - vertex[2] = D3DVERTEX2(corner[3], n, m_particule[i].texSup.x, m_particule[i].texInf.y); - vertex[3] = D3DVERTEX2(corner[2], n, m_particule[i].texInf.x, m_particule[i].texInf.y); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); - } - else - { - eye = m_engine->RetEyePt(); - pos = m_particule[i].pos; - - object = m_particule[i].objLink; - if ( object != 0 ) - { - pos += object->RetPosition(0); - } - - angle.x = -RotateAngle(Length2d(pos, eye), pos.y-eye.y); - angle.y = RotateAngle(pos.z-eye.z, pos.x-eye.x); - angle.z = m_particule[i].angle; - - MatRotateXZY(matrix, angle); - matrix._41 = pos.x; - matrix._42 = pos.y; - matrix._43 = pos.z; - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); - - dim.x = m_particule[i].dim.x * zoom; - dim.y = m_particule[i].dim.y * zoom; - - corner[0].x = dim.x; - corner[0].y = dim.y; - corner[0].z = 0.0f; - - corner[1].x = -dim.x; - corner[1].y = dim.y; - corner[1].z = 0.0f; - - corner[2].x = dim.x; - corner[2].y = -dim.y; - corner[2].z = 0.0f; - - corner[3].x = -dim.x; - corner[3].y = -dim.y; - corner[3].z = 0.0f; - - vertex[0] = D3DVERTEX2(corner[1], n, m_particule[i].texSup.x, m_particule[i].texSup.y); - vertex[1] = D3DVERTEX2(corner[0], n, m_particule[i].texInf.x, m_particule[i].texSup.y); - vertex[2] = D3DVERTEX2(corner[3], n, m_particule[i].texSup.x, m_particule[i].texInf.y); - vertex[3] = D3DVERTEX2(corner[2], n, m_particule[i].texInf.x, m_particule[i].texInf.y); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); - } -} - -// Draw a particle flat (horizontal). - -void CParticule::DrawParticuleFlat(int i) -{ - CObject* object; - D3DVERTEX2 vertex[4]; // 2 triangles - D3DMATRIX matrix; - D3DVECTOR corner[4], pos, n, angle, eye; - FPOINT dim; - - if ( m_particule[i].zoom == 0.0f ) return; - if ( m_particule[i].intensity == 0.0f ) return; - - pos = m_particule[i].pos; - - object = m_particule[i].objLink; - if ( object != 0 ) - { - pos += object->RetPosition(0); - } - - angle.x = PI/2.0f; - angle.y = 0.0f; - angle.z = m_particule[i].angle; - -#if 0 - if ( m_engine->RetRankView() == 1 ) // underwater? - { - angle.x = -PI/2.0f; - pos.y -= 1.0f; - } -#else - if ( m_engine->RetRankView() == 1 ) // underwater? - { - pos.y -= 1.0f; - } - - eye = m_engine->RetEyePt(); - if ( pos.y > eye.y ) // seen from below? - { - angle.x = -PI/2.0f; - } -#endif - - MatRotateXZY(matrix, angle); - matrix._41 = pos.x; - matrix._42 = pos.y; - matrix._43 = pos.z; - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); - - dim.x = m_particule[i].dim.x * m_particule[i].zoom; - dim.y = m_particule[i].dim.y * m_particule[i].zoom; - - corner[0].x = dim.x; - corner[0].y = dim.y; - corner[0].z = 0.0f; - - corner[1].x = -dim.x; - corner[1].y = dim.y; - corner[1].z = 0.0f; - - corner[2].x = dim.x; - corner[2].y = -dim.y; - corner[2].z = 0.0f; - - corner[3].x = -dim.x; - corner[3].y = -dim.y; - corner[3].z = 0.0f; - - vertex[0] = D3DVERTEX2(corner[1], n, m_particule[i].texSup.x, m_particule[i].texSup.y); - vertex[1] = D3DVERTEX2(corner[0], n, m_particule[i].texInf.x, m_particule[i].texSup.y); - vertex[2] = D3DVERTEX2(corner[3], n, m_particule[i].texSup.x, m_particule[i].texInf.y); - vertex[3] = D3DVERTEX2(corner[2], n, m_particule[i].texInf.x, m_particule[i].texInf.y); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); -} - -// Draw a particle to a flat sheet of fog. - -void CParticule::DrawParticuleFog(int i) -{ - CObject* object; - D3DVERTEX2 vertex[4]; // 2 triangles - D3DMATRIX matrix; - D3DVECTOR corner[4], pos, n, angle, eye; - FPOINT dim, zoom; - - if ( !m_engine->RetFog() ) return; - if ( m_particule[i].intensity == 0.0f ) return; - - pos = m_particule[i].pos; - - dim.x = m_particule[i].dim.x; - dim.y = m_particule[i].dim.y; - - if ( m_particule[i].type == PARTIFOG0 || - m_particule[i].type == PARTIFOG2 || - m_particule[i].type == PARTIFOG4 || - m_particule[i].type == PARTIFOG6 ) - { -//? pos.x += sinf(m_particule[i].zoom*1.2f)*dim.x*0.1f; -//? pos.y += cosf(m_particule[i].zoom*1.5f)*dim.y*0.1f; - zoom.x = 1.0f+sinf(m_particule[i].zoom*2.0f)/6.0f; - zoom.y = 1.0f+cosf(m_particule[i].zoom*2.7f)/6.0f; - } - if ( m_particule[i].type == PARTIFOG1 || - m_particule[i].type == PARTIFOG3 || - m_particule[i].type == PARTIFOG5 || - m_particule[i].type == PARTIFOG7 ) - { -//? pos.x += sinf(m_particule[i].zoom*1.0f)*dim.x*0.1f; -//? pos.y += cosf(m_particule[i].zoom*1.3f)*dim.y*0.1f; - zoom.x = 1.0f+sinf(m_particule[i].zoom*3.0f)/6.0f; - zoom.y = 1.0f+cosf(m_particule[i].zoom*3.7f)/6.0f; - } - - dim.x *= zoom.x; - dim.y *= zoom.y; - - object = m_particule[i].objLink; - if ( object != 0 ) - { - pos += object->RetPosition(0); - } - - angle.x = PI/2.0f; - angle.y = 0.0f; - angle.z = m_particule[i].angle; - - if ( m_engine->RetRankView() == 1 ) // underwater? - { - pos.y -= 1.0f; - } - - eye = m_engine->RetEyePt(); - if ( pos.y > eye.y ) // seen from below? - { - angle.x = -PI/2.0f; - } - - MatRotateXZY(matrix, angle); - matrix._41 = pos.x; - matrix._42 = pos.y; - matrix._43 = pos.z; - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); - - corner[0].x = dim.x; - corner[0].y = dim.y; - corner[0].z = 0.0f; - - corner[1].x = -dim.x; - corner[1].y = dim.y; - corner[1].z = 0.0f; - - corner[2].x = dim.x; - corner[2].y = -dim.y; - corner[2].z = 0.0f; - - corner[3].x = -dim.x; - corner[3].y = -dim.y; - corner[3].z = 0.0f; - - vertex[0] = D3DVERTEX2(corner[1], n, m_particule[i].texSup.x, m_particule[i].texSup.y); - vertex[1] = D3DVERTEX2(corner[0], n, m_particule[i].texInf.x, m_particule[i].texSup.y); - vertex[2] = D3DVERTEX2(corner[3], n, m_particule[i].texSup.x, m_particule[i].texInf.y); - vertex[3] = D3DVERTEX2(corner[2], n, m_particule[i].texInf.x, m_particule[i].texInf.y); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); -} - -// Draw a particle in the form of radius. - -void CParticule::DrawParticuleRay(int i) -{ - CObject* object; - D3DVERTEX2 vertex[4]; // 2 triangles - D3DMATRIX matrix; - D3DVECTOR corner[4], eye, pos, goal, n, angle, proj; - FPOINT dim, texInf, texSup; - BOOL bLeft; - float a, len, adv, prop, vario1, vario2; - int r, rank, step, first, last; - - if ( m_particule[i].zoom == 0.0f ) return; - if ( m_particule[i].intensity == 0.0f ) return; - - eye = m_engine->RetEyePt(); - pos = m_particule[i].pos; - goal = m_particule[i].goal; - - object = m_particule[i].objLink; - if ( object != 0 ) - { - pos += object->RetPosition(0); - } - - a = RotateAngle(FPOINT(pos.x,pos.z), FPOINT(goal.x,goal.z), FPOINT(eye.x,eye.z)); - bLeft = (a < PI); - - proj = Projection(pos, goal, eye); - angle.x = -RotateAngle(Length2d(proj, eye), proj.y-eye.y); - angle.y = RotateAngle(pos.z-goal.z, pos.x-goal.x)+PI/2.0f; - angle.z = -RotateAngle(Length2d(pos, goal), pos.y-goal.y); - if ( bLeft ) angle.x = -angle.x; - - MatRotateZXY(matrix, angle); - matrix._41 = pos.x; - matrix._42 = pos.y; - matrix._43 = pos.z; - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); - - n = D3DVECTOR(0.0f, 0.0f, bLeft?1.0f:-1.0f); - - dim.x = m_particule[i].dim.x * m_particule[i].zoom; - dim.y = m_particule[i].dim.y * m_particule[i].zoom; - - if ( bLeft ) dim.y = -dim.y; - - len = Length(pos, goal); - adv = 0.0f; - - step = (int)(len/(dim.x*2.0f))+1; - - if ( step == 1 ) - { - vario1 = 1.0f; - vario2 = 1.0f; - } - else - { - vario1 = 0.0f; - vario2 = 2.0f; - } - - if ( m_particule[i].type == PARTIRAY2 ) - { - first = 0; - last = step; - vario1 = 0.0f; - vario2 = 0.0f; - } - else if ( m_particule[i].type == PARTIRAY3 ) - { - if ( m_particule[i].time < m_particule[i].duration*0.40f ) - { - prop = m_particule[i].time / (m_particule[i].duration*0.40f); - first = 0; - last = (int)(prop*step); - } - else if ( m_particule[i].time < m_particule[i].duration*0.60f ) - { - first = 0; - last = step; - } - else - { - prop = (m_particule[i].time-m_particule[i].duration*0.60f) / (m_particule[i].duration*0.40f); - first = (int)(prop*step); - last = step; - } - } - else - { - if ( m_particule[i].time < m_particule[i].duration*0.50f ) - { - prop = m_particule[i].time / (m_particule[i].duration*0.50f); - first = 0; - last = (int)(prop*step); - } - else if ( m_particule[i].time < m_particule[i].duration*0.75f ) - { - first = 0; - last = step; - } - else - { - prop = (m_particule[i].time-m_particule[i].duration*0.75f) / (m_particule[i].duration*0.25f); - first = (int)(prop*step); - last = step; - } - } - - corner[0].x = adv; - corner[2].x = adv; - corner[0].y = dim.y; - corner[2].y = -dim.y; - corner[0].z = (Rand()-0.5f)*vario1; - corner[1].z = (Rand()-0.5f)*vario1; - corner[2].z = (Rand()-0.5f)*vario1; - corner[3].z = (Rand()-0.5f)*vario1; - - for ( rank=0 ; rank= first && rank <= last ) - { -#if 1 - texInf = m_particule[i].texInf; - texSup = m_particule[i].texSup; - - r = rand()%16; - texInf.x += 0.25f*(r/4); - texSup.x += 0.25f*(r/4); - if ( r%2 < 1 && adv > 0.0f && m_particule[i].type != PARTIRAY1 ) - { - Swap(texInf.x, texSup.x); - } - if ( r%4 < 2 ) - { - Swap(texInf.y, texSup.y); - } -#else - texInf.x = Mod(texInf.x+0.25f, 1.0f); - texSup.x = Mod(texSup.x+0.25f, 1.0f); -#endif - - vertex[0] = D3DVERTEX2(corner[1], n, texSup.x, texSup.y); - vertex[1] = D3DVERTEX2(corner[0], n, texInf.x, texSup.y); - vertex[2] = D3DVERTEX2(corner[3], n, texSup.x, texInf.y); - vertex[3] = D3DVERTEX2(corner[2], n, texInf.x, texInf.y); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); - } - adv += dim.x*2.0f; - } -} - -// Draws a spherical particle. - -void CParticule::DrawParticuleSphere(int i) -{ - D3DVERTEX2 vertex[2*16*(16+1)]; // triangles - D3DMATRIX matrix, rot; - D3DVECTOR angle, v0, v1; - FPOINT ts, ti; - float zoom, deltaRingAngle, deltaSegAngle; - float r0,r1, tu0,tv0, tu1,tv1; - int j, ring, seg, numRings, numSegments; - - zoom = m_particule[i].zoom; -#if 0 - if ( !m_engine->RetStateColor() && m_particule[i].intensity < 0.5f ) - { - zoom *= m_particule[i].intensity/0.5f; - } -#endif - - if ( zoom == 0.0f ) return; - - m_engine->SetState(D3DSTATETTb|D3DSTATE2FACE|D3DSTATEWRAP, RetColor(m_particule[i].intensity)); - - D3DUtil_SetIdentityMatrix(matrix); - matrix._11 = zoom; - matrix._22 = zoom; - matrix._33 = zoom; - matrix._41 = m_particule[i].pos.x; - matrix._42 = m_particule[i].pos.y; - matrix._43 = m_particule[i].pos.z; - - if ( m_particule[i].angle != 0.0f ) - { - angle.x = m_particule[i].angle*0.4f; - angle.y = m_particule[i].angle*1.0f; - angle.z = m_particule[i].angle*0.7f; - MatRotateZXY(rot, angle); - matrix = rot*matrix; - } - - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); - - ts.x = m_particule[i].texSup.x; - ts.y = m_particule[i].texSup.y; - ti.x = m_particule[i].texInf.x; - ti.y = m_particule[i].texInf.y; - - // Choose a tesselation level. - if ( m_particule[i].type == PARTISPHERE3 || - m_particule[i].type == PARTISPHERE5 ) - { - numRings = 16; - numSegments = 16; - } - else - { - numRings = 8; - numSegments = 10; - } - - // Establish constants used in sphere generation. - deltaRingAngle = PI/numRings; - deltaSegAngle = 2.0f*PI/numSegments; - - // Generate the group of rings for the sphere. - j = 0; - for ( ring=0 ; ringDrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, j, NULL); - m_engine->AddStatisticTriangle(j); - - m_engine->SetState(D3DSTATETTb, RetColor(m_particule[i].intensity)); -} - -// Returns the height depending on the progress. - -float ProgressCylinder(float progress) -{ - if ( progress < 0.5f ) - { - return 1.0f - (powf(1.0f-progress*2.0f, 2.0f)); - } - else - { - return 1.0f - (powf(progress*2.0f-1.0f, 2.0f)); - } -} - -// Draws a cylindrical particle. - -void CParticule::DrawParticuleCylinder(int i) -{ - D3DVERTEX2 vertex[2*5*(10+1)]; // triangles - D3DMATRIX matrix, rot; - D3DVECTOR angle, v0, v1; - FPOINT ts, ti; - float progress, zoom, diam, deltaSegAngle, h[6], d[6]; - float r0,r1, tu0,tv0, tu1,tv1, p1, p2, pp; - int j, ring, seg, numRings, numSegments; - - progress = m_particule[i].zoom; - zoom = m_particule[i].dim.x; - diam = m_particule[i].dim.y; - if ( progress >= 1.0f || zoom == 0.0f ) return; - - m_engine->SetState(D3DSTATETTb|D3DSTATE2FACE|D3DSTATEWRAP, RetColor(m_particule[i].intensity)); - - D3DUtil_SetIdentityMatrix(matrix); - matrix._11 = zoom; - matrix._22 = zoom; - matrix._33 = zoom; - matrix._41 = m_particule[i].pos.x; - matrix._42 = m_particule[i].pos.y; - matrix._43 = m_particule[i].pos.z; - - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); - - ts.x = m_particule[i].texSup.x; - ts.y = m_particule[i].texSup.y; - ti.x = m_particule[i].texInf.x; - ti.y = m_particule[i].texInf.y; - - numRings = 5; - numSegments = 10; - deltaSegAngle = 2.0f*PI/numSegments; - - if ( m_particule[i].type == PARTIPLOUF0 ) - { -#if 0 - if ( progress <= 0.5f ) - { - p1 = progress/0.5f; // front - p2 = 0.0f; // back - } - else - { - p1 = 1.0f; // front - p2 = (progress-0.5f)/0.5f; // back - ts.y += (ti.y-ts.y)*p2; - } -#else - p1 = progress; // front - p2 = powf(progress, 5.0f); // back -#endif - - for ( ring=0 ; ring<=numRings ; ring++ ) - { - pp = p2+(p1-p2)*((float)ring/numRings); - d[ring] = diam/zoom+pp*2.0f; - h[ring] = ProgressCylinder(pp); - } - } - - j = 0; - for ( ring=0 ; ringDrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, j, NULL); - m_engine->AddStatisticTriangle(j); - - m_engine->SetState(D3DSTATETTb, RetColor(m_particule[i].intensity)); -} - -// Draws a tire mark. - -void CParticule::DrawParticuleWheel(int i) -{ - D3DVECTOR pos[4], center; - D3DVERTEX2 vertex[4]; // 2 triangles - D3DVECTOR n; - FPOINT ts, ti; - float dist, dp; - - dist = Length2d(m_engine->RetEyePt(), m_wheelTrace[i].pos[0]); - if ( dist > 300.0f ) return; - - pos[0] = m_wheelTrace[i].pos[0]; - pos[1] = m_wheelTrace[i].pos[1]; - pos[2] = m_wheelTrace[i].pos[2]; - pos[3] = m_wheelTrace[i].pos[3]; - - if ( m_wheelTrace[i].type == PARTITRACE0 ) // white ground track? - { - ts.x = 8.0f/256.0f; - ts.y = 224.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE1 ) // black ground track? - { - ts.x = 0.0f/256.0f; - ts.y = 224.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE2 ) // gray ground track? - { - ts.x = 0.0f/256.0f; - ts.y = 232.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE3 ) // light gray ground track? - { - ts.x = 8.0f/256.0f; - ts.y = 232.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE4 ) // red ground track? - { - ts.x = 32.0f/256.0f; - ts.y = 224.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE5 ) // pink ground track? - { - ts.x = 40.0f/256.0f; - ts.y = 224.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE6 ) // violet ground track? - { - ts.x = 32.0f/256.0f; - ts.y = 232.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE7 ) // orange ground track? - { - ts.x = 40.0f/256.0f; - ts.y = 232.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE8 ) // yellow ground track? - { - ts.x = 16.0f/256.0f; - ts.y = 224.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE9 ) // beige ground track? - { - ts.x = 24.0f/256.0f; - ts.y = 224.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE10 ) // brown ground track? - { - ts.x = 16.0f/256.0f; - ts.y = 232.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE11 ) // skin ground track? - { - ts.x = 24.0f/256.0f; - ts.y = 232.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE12 ) // green ground track? - { - ts.x = 48.0f/256.0f; - ts.y = 224.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE13 ) // light green ground track? - { - ts.x = 56.0f/256.0f; - ts.y = 224.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE14 ) // blue ground track? - { - ts.x = 48.0f/256.0f; - ts.y = 232.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE15 ) // light blue ground track? - { - ts.x = 56.0f/256.0f; - ts.y = 232.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE16 ) // black arrow ground track? - { - ts.x = 160.0f/256.0f; - ts.y = 224.0f/256.0f; - } - else if ( m_wheelTrace[i].type == PARTITRACE17 ) // red arrow ground track? - { - ts.x = 176.0f/256.0f; - ts.y = 224.0f/256.0f; - } - else - { - return; - } - - if ( m_wheelTrace[i].type == PARTITRACE16 || - m_wheelTrace[i].type == PARTITRACE17 ) - { - ti.x = ts.x+16.0f/256.0f; - ti.y = ts.y+16.0f/256.0f; - } - else - { - ti.x = ts.x+8.0f/256.0f; - ti.y = ts.y+8.0f/256.0f; - } - - dp = (1.0f/256.0f)/2.0f; - ts.x = ts.x+dp; - ts.y = ts.y+dp; - ti.x = ti.x-dp; - ti.y = ti.y-dp; - - n = D3DVECTOR(0.0f, 1.0f, 0.0f); - - vertex[0] = D3DVERTEX2(pos[0], n, ts.x, ts.y); - vertex[1] = D3DVERTEX2(pos[1], n, ti.x, ts.y); - vertex[2] = D3DVERTEX2(pos[2], n, ts.x, ti.y); - vertex[3] = D3DVERTEX2(pos[3], n, ti.x, ti.y); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); -} - -// Draws all the particles. - -void CParticule::DrawParticule(int sheet) -{ - D3DMATERIAL7 mat; - D3DMATRIX matrix; - BOOL bLoadTexture; - char name[20]; - int state, t, i, j, r; - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - - // Draw the basic particles of triangles. - if ( m_totalInterface[0][sheet] > 0 ) - { - for ( i=0 ; iSetTexture(m_triangle[i].texName1); - m_engine->SetMaterial(m_triangle[i].material); - m_engine->SetState(m_triangle[i].state); - DrawParticuleTriangle(i); - } - } - - // Draw the particles was calculated based on edge. - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE); - - ZeroMemory( &mat, sizeof(D3DMATERIAL7) ); - mat.diffuse.r = 1.0f; - mat.diffuse.g = 1.0f; - mat.diffuse.b = 1.0f; // white - mat.ambient.r = 0.5f; - mat.ambient.g = 0.5f; - mat.ambient.b = 0.5f; - m_engine->SetMaterial(mat); - - // Draw tire marks. - if ( m_wheelTraceTotal > 0 && sheet == SH_WORLD ) - { -#if _POLISH - m_engine->SetTexture("textp.tga"); -#else - m_engine->SetTexture("text.tga"); -#endif - m_engine->SetState(D3DSTATETTw); -//? m_engine->SetState(D3DSTATENORMAL); - D3DUtil_SetIdentityMatrix(matrix); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); - for ( i=0 ; i=1 ; t-- ) // black behind! - { - if ( m_totalInterface[t][sheet] == 0 ) continue; - - bLoadTexture = FALSE; - - if ( t == 4 ) state = D3DSTATETTw; // text.tga - else state = D3DSTATETTb; // effect[00..02].tga - m_engine->SetState(state); - - for ( j=0 ; jSetTexture(name); - bLoadTexture = TRUE; - } - - r = m_particule[i].trackRank; - if ( r != -1 ) - { - m_engine->SetState(state); - TrackDraw(r, m_particule[i].type); // draws the drag - if ( !m_track[r].bDrawParticule ) continue; - } - - m_engine->SetState(state, RetColor(m_particule[i].intensity)); - - if ( m_particule[i].bRay ) // ray? - { - DrawParticuleRay(i); - } - else if ( m_particule[i].type == PARTIFLIC || // circle in the water? - m_particule[i].type == PARTISHOW || - m_particule[i].type == PARTICHOC || - m_particule[i].type == PARTIGFLAT ) - { - DrawParticuleFlat(i); - } - else if ( m_particule[i].type >= PARTIFOG0 && - m_particule[i].type <= PARTIFOG9 ) - { - DrawParticuleFog(i); - } - else if ( m_particule[i].type >= PARTISPHERE0 && - m_particule[i].type <= PARTISPHERE9 ) // sphere? - { - DrawParticuleSphere(i); - } - else if ( m_particule[i].type >= PARTIPLOUF0 && - m_particule[i].type <= PARTIPLOUF4 ) // cylinder? - { - DrawParticuleCylinder(i); - } - else // normal? - { - DrawParticuleNorm(i); - } - } - } - -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE); -} - - -// Seeks if an object collided with a bullet. - -CObject* CParticule::SearchObjectGun(D3DVECTOR old, D3DVECTOR pos, - ParticuleType type, CObject *father) -{ - CObject *pObj, *pBest; - D3DVECTOR box1, box2, oPos, p; - ObjectType oType; - BOOL bShield; - float min, oRadius, dist, shieldRadius; - int i, j; - BOOL bHimself; - - if ( m_main->RetMovieLock() ) return 0; // current movie? - - bHimself = m_main->RetHimselfDamage(); - - min = 5.0f; - if ( type == PARTIGUN2 ) min = 2.0f; // shooting insect? - if ( type == PARTIGUN3 ) min = 3.0f; // suiciding spider? - - box1 = old; - box2 = pos; - if ( box1.x > box2.x ) Swap(box1.x, box2.x); // box1 < box2 - if ( box1.y > box2.y ) Swap(box1.y, box2.y); - if ( box1.z > box2.z ) Swap(box1.z, box2.z); - box1.x -= min; - box1.y -= min; - box1.z -= min; - box2.x += min; - box2.y += min; - box2.z += min; - - pBest = 0; - bShield = FALSE; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetActif() ) continue; // inactive? - if ( pObj == father ) continue; - - oType = pObj->RetType(); - - if ( oType == OBJECT_TOTO ) continue; - - if ( type == PARTIGUN1 ) // fireball shooting? - { - if ( oType == OBJECT_MOTHER ) continue; - if ( bHimself ) // damage is oneself? - { - if ( !IsAlien(oType) && - !IsSoft(oType) ) continue; - } - else // damage only to enemies? - { - if ( !IsAlien(oType) ) continue; - } - } - else if ( type == PARTIGUN2 ) // shooting insect? - { - if ( !IsSoft(oType) ) continue; - } - else if ( type == PARTIGUN3 ) // suiciding spider? - { - if ( !IsSoft(oType) ) continue; - } - else if ( type == PARTIGUN4 ) // orgaball shooting? - { - if ( oType == OBJECT_MOTHER ) continue; - if ( bHimself ) // damage is oneself? - { - if ( !IsAlien(oType) && - !IsSoft(oType) ) continue; - } - else // damage only to enemies? - { - if ( !IsAlien(oType) ) continue; - } - } - else if ( type == PARTITRACK11 ) // phazer shooting? - { - if ( bHimself ) // damage is oneself? - { - if ( !IsAlien(oType) && - !IsSoft(oType) ) continue; - } - else // damage only to enemies? - { - if ( !IsAlien(oType) ) continue; - } - } - else - { - continue; - } - - oPos = pObj->RetPosition(0); - - if ( type == PARTIGUN2 || // shooting insect? - type == PARTIGUN3 ) // suiciding spider? - { - // Test if the ball is entered into the sphere of a shield. - shieldRadius = pObj->RetShieldRadius(); - if ( shieldRadius > 0.0f ) - { - dist = Length(oPos, pos); - if ( dist <= shieldRadius ) - { - pBest = pObj; - bShield = TRUE; - } - } - } - if ( bShield ) continue; - - // Test the center of the object, which is necessary for objects - // that have no sphere in the center (station). - dist = Length(oPos, pos)-4.0f; - if ( dist < min ) - { - pBest = pObj; - } - - // Test with all spheres of the object. - j = 0; - while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) - { - if ( oPos.x+oRadius < box1.x || oPos.x-oRadius > box2.x || // outside the box? - oPos.y+oRadius < box1.y || oPos.y-oRadius > box2.y || - oPos.z+oRadius < box1.z || oPos.z-oRadius > box2.z ) continue; - - p = Projection(old, pos, oPos); - dist = Length(p, oPos)-oRadius; - if ( dist < min ) - { - pBest = pObj; - } - } - } - - return pBest; -} - -// Seeks if an object collided with a ray. - -CObject* CParticule::SearchObjectRay(D3DVECTOR pos, D3DVECTOR goal, - ParticuleType type, CObject *father) -{ - CObject* pObj; - D3DVECTOR box1, box2, oPos, p; - ObjectType oType; - float min, dist; - int i; - - if ( m_main->RetMovieLock() ) return 0; // current movie? - - min = 10.0f; - - box1 = pos; - box2 = goal; - if ( box1.x > box2.x ) Swap(box1.x, box2.x); // box1 < box2 - if ( box1.y > box2.y ) Swap(box1.y, box2.y); - if ( box1.z > box2.z ) Swap(box1.z, box2.z); - box1.x -= min; - box1.y -= min; - box1.z -= min; - box2.x += min; - box2.y += min; - box2.z += min; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetActif() ) continue; // inactive? - if ( pObj == father ) continue; - - oType = pObj->RetType(); - - if ( oType == OBJECT_TOTO ) continue; - - if ( type == PARTIRAY1 && - oType != OBJECT_MOBILEtg && - oType != OBJECT_TEEN28 && - oType != OBJECT_TEEN31 && - oType != OBJECT_ANT && - oType != OBJECT_SPIDER && - oType != OBJECT_BEE && - oType != OBJECT_WORM && - oType != OBJECT_MOTHER && - oType != OBJECT_NEST ) continue; - - oPos = pObj->RetPosition(0); - - if ( oPos.x < box1.x || oPos.x > box2.x || // outside the box? - oPos.y < box1.y || oPos.y > box2.y || - oPos.z < box1.z || oPos.z > box2.z ) continue; - - p = Projection(pos, goal, oPos); - dist = Length(p, oPos); - if ( dist < min ) return pObj; - } - - return 0; -} - - -// Sounded one. - -void CParticule::Play(Sound sound, D3DVECTOR pos, float amplitude) -{ - if ( m_sound == 0 ) - { - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - } - - m_sound->Play(sound, pos, amplitude); -} - - - -// Seeks the color if you're in the fog. -// Returns black if you're not in the fog. - -D3DCOLORVALUE CParticule::RetFogColor(D3DVECTOR pos) -{ - D3DCOLORVALUE result, color; - float dist, factor; - int fog, i; - - result.r = 0.0f; - result.g = 0.0f; - result.b = 0.0f; - result.a = 0.0f; - - for ( fog=0 ; fog= m_particule[i].pos.y+FOG_HSUP ) continue; - if ( pos.y <= m_particule[i].pos.y-FOG_HINF ) continue; - - dist = Length2d(pos, m_particule[i].pos); - if ( dist >= m_particule[i].dim.x*1.5f ) continue; - - // Calculates the horizontal distance. - factor = 1.0f-powf(dist/(m_particule[i].dim.x*1.5f), 4.0f); - - // Calculates the vertical distance. - if ( pos.y > m_particule[i].pos.y ) - { - factor *= 1.0f-(pos.y-m_particule[i].pos.y)/FOG_HSUP; - } - else - { - factor *= 1.0f-(m_particule[i].pos.y-pos.y)/FOG_HINF; - } - - factor *= 0.3f; - - if ( m_particule[i].type == PARTIFOG0 || - m_particule[i].type == PARTIFOG1 ) // blue? - { - color.r = 0.0f; - color.g = 0.5f; - color.b = 1.0f; - } - else if ( m_particule[i].type == PARTIFOG2 || - m_particule[i].type == PARTIFOG3 ) // red? - { - color.r = 2.0f; - color.g = 1.0f; - color.b = 0.0f; - } - else if ( m_particule[i].type == PARTIFOG4 || - m_particule[i].type == PARTIFOG5 ) // white? - { - color.r = 1.0f; - color.g = 1.0f; - color.b = 1.0f; - } - else if ( m_particule[i].type == PARTIFOG6 || - m_particule[i].type == PARTIFOG7 ) // yellow? - { - color.r = 0.8f; - color.g = 1.0f; - color.b = 0.4f; - } - else - { - color.r = 0.0f; - color.g = 0.0f; - color.b = 0.0f; - } - - result.r += color.r*factor; - result.g += color.g*factor; - result.b += color.b*factor; - } - - if ( result.r > 0.6f ) result.r = 0.6f; - if ( result.g > 0.6f ) result.g = 0.6f; - if ( result.b > 0.6f ) result.b = 0.6f; - - return result; -} - - -// Writes a file. BMP containing all the tire tracks. - -BOOL CParticule::WriteWheelTrace(char *filename, int width, int height, - D3DVECTOR dl, D3DVECTOR ur) -{ - HDC hDC; - HDC hDCImage; - HBITMAP hb; - PBITMAPINFO info; - HBRUSH hBrush; - HPEN hPen; - HGDIOBJ old; - RECT rect; - COLORREF color; - FPOINT pos[4]; - POINT list[4]; - int i; - - if ( !m_engine->GetRenderDC(hDC) ) return FALSE; - - hDCImage = CreateCompatibleDC(hDC); - if ( hDCImage == 0 ) - { - m_engine->ReleaseRenderDC(hDC); - return FALSE; - } - - hb = CreateCompatibleBitmap(hDC, width, height); - if ( hb == 0 ) - { - DeleteDC(hDCImage); - m_engine->ReleaseRenderDC(hDC); - return FALSE; - } - - SelectObject(hDCImage, hb); - - rect.left = 0; - rect.right = width; - rect.top = 0; - rect.bottom = height; - FillRect(hDCImage, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH)); - - hPen = CreatePen(PS_NULL, 1, 0); - SelectObject(hDCImage, hPen); - - for ( i=0 ; iCreateBitmapInfoStruct(hb); - if ( info == 0 ) - { - DeleteObject(hb); - DeleteDC(hDCImage); - m_engine->ReleaseRenderDC(hDC); - return FALSE; - } - - m_engine->CreateBMPFile(filename, info, hb, hDCImage); - - DeleteObject(hb); - DeleteDC(hDCImage); - m_engine->ReleaseRenderDC(hDC); - return TRUE; -} - diff --git a/src/particule.h b/src/particule.h deleted file mode 100644 index 67abad3..0000000 --- a/src/particule.h +++ /dev/null @@ -1,339 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// particule.h - -#ifndef _PARTICULE_H_ -#define _PARTICULE_H_ - - -#include "d3dengine.h" -#include "sound.h" - - -class CInstanceManager; -class CRobotMain; -class CTerrain; -class CWater; -class CObject; - - -#define MAXPARTICULE 500 -#define MAXPARTITYPE 5 -#define MAXTRACK 100 -#define MAXTRACKLEN 10 -#define MAXPARTIFOG 100 -#define MAXWHEELTRACE 1000 - -#define SH_WORLD 0 // particle in the world in the interface -#define SH_FRONT 1 // particle in the world on the interface -#define SH_INTERFACE 2 // particle in the interface -#define SH_MAX 3 - -// type == 0 -> triangles -// type == 1 -> effect00 (black background) -// type == 2 -> effect01 (black background) -// type == 3 -> effect02 (black background) -// type == 4 -> text (white background) - - -enum ParticuleType -{ - PARTIEXPLOT = 1, // technology explosion - PARTIEXPLOO = 2, // organic explosion - PARTIMOTOR = 3, // the engine exhaust gas - PARTIGLINT = 4, // reflection - PARTIBLITZ = 5, // lightning recharging battery - PARTICRASH = 6, // dust after fall - PARTIGAS = 7, // gas from the reactor - PARTIFIRE = 9, // fireball shrinks - PARTIFIREZ = 10, // fireball grows - PARTIBLUE = 11, // blue ball - PARTISELY = 12, // yellow selection - PARTISELR = 13, // red selection - PARTIGUN1 = 18, // a bullet (fireball) - PARTIGUN2 = 19, // bullet 2 (ant) - PARTIGUN3 = 20, // bullet 3 (spider) - PARTIGUN4 = 21, // bullet 4 (orgaball) - PARTIFRAG = 22, // triangular fragment - PARTIQUEUE = 23, // inflamed tail - PARTIORGANIC1 = 24, // organic ball mother - PARTIORGANIC2 = 25, // organic ball daughter - PARTISMOKE1 = 26, // black smoke - PARTISMOKE2 = 27, // black smoke - PARTISMOKE3 = 28, // black smoke - PARTISMOKE4 = 29, // black smoke - PARTIBLOOD = 30, // human blood - PARTIBLOODM = 31, // blood laying - PARTIVAPOR = 32, // steam - PARTIVIRUS1 = 33, // virus 1 - PARTIVIRUS2 = 34, // virus 2 - PARTIVIRUS3 = 35, // virus 3 - PARTIVIRUS4 = 36, // virus 4 - PARTIVIRUS5 = 37, // virus 5 - PARTIVIRUS6 = 38, // virus 6 - PARTIVIRUS7 = 39, // virus 7 - PARTIVIRUS8 = 40, // virus 8 - PARTIVIRUS9 = 41, // virus 9 - PARTIVIRUS10 = 42, // virus 10 - PARTIRAY1 = 43, // ray 1 (turn) - PARTIRAY2 = 44, // ray 2 (electric arc) - PARTIRAY3 = 45, // ray 3 - PARTIRAY4 = 46, // ray 4 - PARTIFLAME = 47, // flame - PARTIBUBBLE = 48, // bubble - PARTIFLIC = 49, // circles in the water - PARTIEJECT = 50, // ejection from the reactor - PARTISCRAPS = 51, // waste from the reactor - PARTITOTO = 52, // reactor of tot - PARTIERROR = 53, // toto says no - PARTIWARNING = 54, // foo says blah - PARTIINFO = 54, // toto says yes - PARTIQUARTZ = 55, // reflection crystal - PARTISPHERE0 = 56, // explosion sphere - PARTISPHERE1 = 57, // energy sphere - PARTISPHERE2 = 58, // analysis sphere - PARTISPHERE3 = 59, // shield sphere - PARTISPHERE4 = 60, // information sphere (emit) - PARTISPHERE5 = 61, // botanical sphere (gravity root) - PARTISPHERE6 = 62, // information sphere (receive) - PARTISPHERE7 = 63, // sphere - PARTISPHERE8 = 64, // sphere - PARTISPHERE9 = 65, // sphere - PARTIGUNDEL = 66, // bullet destroyed by shield - PARTIPART = 67, // object part - PARTITRACK1 = 68, // drag 1 - PARTITRACK2 = 69, // drag 2 - PARTITRACK3 = 70, // drag 3 - PARTITRACK4 = 71, // drag 4 - PARTITRACK5 = 72, // drag 5 - PARTITRACK6 = 73, // drag 6 - PARTITRACK7 = 74, // drag 7 - PARTITRACK8 = 75, // drag 8 - PARTITRACK9 = 76, // drag 9 - PARTITRACK10 = 77, // drag 10 - PARTITRACK11 = 78, // drag 11 - PARTITRACK12 = 79, // drag 12 - PARTITRACK13 = 80, // drag 13 - PARTITRACK14 = 81, // drag 14 - PARTITRACK15 = 82, // drag 15 - PARTITRACK16 = 83, // drag 16 - PARTITRACK17 = 84, // drag 17 - PARTITRACK18 = 85, // drag 18 - PARTITRACK19 = 86, // drag 19 - PARTITRACK20 = 87, // drag 20 - PARTIGLINTb = 88, // blue reflection - PARTIGLINTr = 89, // red reflection - PARTILENS1 = 90, // brilliance 1 (orange) - PARTILENS2 = 91, // brilliance 2 (yellow) - PARTILENS3 = 92, // brilliance 3 (red) - PARTILENS4 = 93, // brilliance 4 (violet) - PARTICONTROL = 94, // reflection on button - PARTISHOW = 95, // shows a place - PARTICHOC = 96, // shock wave - PARTIGFLAT = 97, // shows if the ground is flat - PARTIRECOVER = 98, // blue ball recycler - PARTIROOT = 100, // gravity root smoke - PARTIPLOUF0 = 101, // splash - PARTIPLOUF1 = 102, // splash - PARTIPLOUF2 = 103, // splash - PARTIPLOUF3 = 104, // splash - PARTIPLOUF4 = 105, // splash - PARTIDROP = 106, // drop - PARTIFOG0 = 107, // fog 0 - PARTIFOG1 = 108, // fog 1 - PARTIFOG2 = 109, // fog 2 - PARTIFOG3 = 110, // fog 3 - PARTIFOG4 = 111, // fog 4 - PARTIFOG5 = 112, // fog 5 - PARTIFOG6 = 113, // fog 6 - PARTIFOG7 = 114, // fog 7 - PARTIFOG8 = 115, // fog 8 - PARTIFOG9 = 116, // fog 9 - PARTILIMIT1 = 117, // shows the limits 1 - PARTILIMIT2 = 118, // shows the limits 2 - PARTILIMIT3 = 119, // shows the limits 3 - PARTILIMIT4 = 120, // shows the limits 4 - PARTIWATER = 121, // drop of water - PARTIEXPLOG1 = 122, // ball explosion 1 - PARTIEXPLOG2 = 123, // ball explosion 2 - PARTIBASE = 124, // gases of spaceship - PARTITRACE0 = 140, // trace - PARTITRACE1 = 141, // trace - PARTITRACE2 = 142, // trace - PARTITRACE3 = 143, // trace - PARTITRACE4 = 144, // trace - PARTITRACE5 = 145, // trace - PARTITRACE6 = 146, // trace - PARTITRACE7 = 147, // trace - PARTITRACE8 = 148, // trace - PARTITRACE9 = 149, // trace - PARTITRACE10 = 150, // trace - PARTITRACE11 = 151, // trace - PARTITRACE12 = 152, // trace - PARTITRACE13 = 153, // trace - PARTITRACE14 = 154, // trace - PARTITRACE15 = 155, // trace - PARTITRACE16 = 156, // trace - PARTITRACE17 = 157, // trace - PARTITRACE18 = 158, // trace - PARTITRACE19 = 159, // trace -}; - -enum ParticulePhase -{ - PARPHSTART = 0, - PARPHEND = 1, -}; - -typedef struct -{ - char bUsed; // TRUE -> particle used - char bRay; // TRUE -> ray with goal - unsigned short uniqueStamp; // unique mark - short sheet; // sheet (0..n) - ParticuleType type; // type PARTI* - ParticulePhase phase; // phase PARPH* - float mass; // mass of the particle (in rebounding) - float weight; // weight of the particle (for noise) - float duration; // length of life - D3DVECTOR pos; // absolute position (relative if object links) - D3DVECTOR goal; // goal position (if bRay) - D3DVECTOR speed; // speed of displacement - float windSensitivity; - short bounce; // number of rebounds - FPOINT dim; // dimensions of the rectangle - float zoom; // zoom (0..1) - float angle; // angle of rotation - float intensity; // intensity - FPOINT texSup; // coordinated upper texture - FPOINT texInf; // coordinated lower texture - float time; // age of the particle (0..n) - float phaseTime; // age at the beginning of phase - float testTime; // time since last test - CObject* objLink; // father object (for example reactor) - CObject* objFather; // father object (for example reactor) - short objRank; // rank of the object, or -1 - short trackRank; // rank of the drag -} -Particule; - -typedef struct -{ - char bUsed; // TRUE -> drag used - char bDrawParticule; - float step; // duration of not - float last; // increase last not memorized - float intensity; // intensity at starting (0..1) - float width; // tail width - int used; // number of positions in "pos" - int head; // head to write index - D3DVECTOR pos[MAXTRACKLEN]; - float len[MAXTRACKLEN]; -} -Track; - -typedef struct -{ - ParticuleType type; // type PARTI* - D3DVECTOR pos[4]; // rectangle positions - float startTime; // beginning of life -} -WheelTrace; - - - -class CParticule -{ -public: - CParticule(CInstanceManager* iMan, CD3DEngine* engine); - ~CParticule(); - - void SetD3DDevice(LPDIRECT3DDEVICE7 device); - - void FlushParticule(); - void FlushParticule(int sheet); - int CreateParticule(D3DVECTOR pos, D3DVECTOR speed, FPOINT dim, ParticuleType type, float duration=1.0f, float mass=0.0f, float windSensitivity=1.0f, int sheet=0); - int CreateFrag(D3DVECTOR pos, D3DVECTOR speed, D3DTriangle *triangle, ParticuleType type, float duration=1.0f, float mass=0.0f, float windSensitivity=1.0f, int sheet=0); - int CreatePart(D3DVECTOR pos, D3DVECTOR speed, ParticuleType type, float duration=1.0f, float mass=0.0f, float weight=0.0f, float windSensitivity=1.0f, int sheet=0); - int CreateRay(D3DVECTOR pos, D3DVECTOR goal, ParticuleType type, FPOINT dim, float duration=1.0f, int sheet=0); - int CreateTrack(D3DVECTOR pos, D3DVECTOR speed, FPOINT dim, ParticuleType type, float duration=1.0f, float mass=0.0f, float length=10.0f, float width=1.0f); - void CreateWheelTrace(const D3DVECTOR &p1, const D3DVECTOR &p2, const D3DVECTOR &p3, const D3DVECTOR &p4, ParticuleType type); - void DeleteParticule(ParticuleType type); - void DeleteParticule(int channel); - void SetObjectLink(int channel, CObject *object); - void SetObjectFather(int channel, CObject *object); - void SetPosition(int channel, D3DVECTOR pos); - void SetDimension(int channel, FPOINT dim); - void SetZoom(int channel, float zoom); - void SetAngle(int channel, float angle); - void SetIntensity(int channel, float intensity); - void SetParam(int channel, D3DVECTOR pos, FPOINT dim, float zoom, float angle, float intensity); - void SetPhase(int channel, ParticulePhase phase, float duration); - BOOL GetPosition(int channel, D3DVECTOR &pos); - - D3DCOLORVALUE RetFogColor(D3DVECTOR pos); - - void SetFrameUpdate(int sheet, BOOL bUpdate); - void FrameParticule(float rTime); - void DrawParticule(int sheet); - - BOOL WriteWheelTrace(char *filename, int width, int height, D3DVECTOR dl, D3DVECTOR ur); - -protected: - void DeleteRank(int rank); - BOOL CheckChannel(int &channel); - void DrawParticuleTriangle(int i); - void DrawParticuleNorm(int i); - void DrawParticuleFlat(int i); - void DrawParticuleFog(int i); - void DrawParticuleRay(int i); - void DrawParticuleSphere(int i); - void DrawParticuleCylinder(int i); - void DrawParticuleWheel(int i); - CObject* SearchObjectGun(D3DVECTOR old, D3DVECTOR pos, ParticuleType type, CObject *father); - CObject* SearchObjectRay(D3DVECTOR pos, D3DVECTOR goal, ParticuleType type, CObject *father); - void Play(Sound sound, D3DVECTOR pos, float amplitude); - BOOL TrackMove(int i, D3DVECTOR pos, float progress); - void TrackDraw(int i, ParticuleType type); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - LPDIRECT3DDEVICE7 m_pD3DDevice; - CRobotMain* m_main; - CTerrain* m_terrain; - CWater* m_water; - CSound* m_sound; - - Particule m_particule[MAXPARTICULE*MAXPARTITYPE]; - D3DTriangle m_triangle[MAXPARTICULE]; // triangle if PartiType == 0 - Track m_track[MAXTRACK]; - int m_wheelTraceTotal; - int m_wheelTraceIndex; - WheelTrace m_wheelTrace[MAXWHEELTRACE]; - int m_totalInterface[MAXPARTITYPE][SH_MAX]; - BOOL m_bFrameUpdate[SH_MAX]; - int m_fogTotal; - int m_fog[MAXPARTIFOG]; - int m_uniqueStamp; - int m_exploGunCounter; - float m_lastTimeGunDel; - float m_absTime; -}; - - -#endif //_PARTICULE_H_ diff --git a/src/patch16.txt b/src/patch16.txt deleted file mode 100644 index cfd3982..0000000 --- a/src/patch16.txt +++ /dev/null @@ -1,10 +0,0 @@ -Liste des fichiers pour le patch 1.6 - -help\cbot.txt (/f) -help\cbot\object.txt -help\cbot\grab.txt -help\cbot\drop.txt -help\cbot\category.txt -help\cbot\extern.txt (/f) -help\object\goal.txt -help\object\atomic.txt diff --git a/src/physics.cpp b/src/physics.cpp deleted file mode 100644 index beae37e..0000000 --- a/src/physics.cpp +++ /dev/null @@ -1,3885 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// physics.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "language.h" -#include "global.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "light.h" -#include "particule.h" -#include "terrain.h" -#include "water.h" -#include "camera.h" -#include "object.h" -#include "pyro.h" -#include "brain.h" -#include "motion.h" -#include "motionhuman.h" -#include "sound.h" -#include "task.h" -#include "cmdtoken.h" -#include "physics.h" - - - -#define LANDING_SPEED 3.0f -#define LANDING_ACCEL 5.0f -#define LANDING_ACCELh 1.5f - - - - -// Object's constructor. - -CPhysics::CPhysics(CInstanceManager* iMan, CObject* object) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_PHYSICS, this, 100); - - m_object = object; - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - m_brain = 0; - m_motion = 0; - - m_type = TYPE_ROLLING; - m_gravity = 9.81f; // default gravity - m_time = 0.0f; - m_timeUnderWater = 0.0f; - m_motorSpeed = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_bMotor = FALSE; - m_bLand = TRUE; // ground - m_bSwim = FALSE; // in air - m_bCollision = FALSE; - m_bObstacle = FALSE; - m_repeatCollision = 0; - m_linVibrationFactor = 1.0f; - m_cirVibrationFactor = 1.0f; - m_inclinaisonFactor = 1.0f; - m_lastPowerParticule = 0.0f; - m_lastSlideParticule = 0.0f; - m_lastMotorParticule = 0.0f; - m_lastWaterParticule = 0.0f; - m_lastUnderParticule = 0.0f; - m_lastPloufParticule = 0.0f; - m_lastFlameParticule = 0.0f; - m_bWheelParticuleBrake = FALSE; - m_absorbWater = 0.0f; - m_reactorTemperature = 0.0f; - m_reactorRange = 1.0f; - m_timeReactorFail = 0.0f; - m_lastEnergy = 0.0f; - m_lastSoundWater = 0.0f; - m_lastSoundInsect = 0.0f; - m_restBreakParticule = 0.0f; - m_floorHeight = 0.0f; - m_soundChannel = -1; - m_soundChannelSlide = -1; - m_soundTimePshhh = 0.0f; - m_soundTimeJostle = 0.0f; - m_soundTimeBoum = 0.0f; - m_bSoundSlow = TRUE; - m_bFreeze = FALSE; - m_bForceUpdate = TRUE; - m_bLowLevel = FALSE; - - ZeroMemory(&m_linMotion, sizeof(Motion)); - ZeroMemory(&m_cirMotion, sizeof(Motion)); -} - -// Object's destructor. - -CPhysics::~CPhysics() -{ - m_iMan->DeleteInstance(CLASS_PHYSICS, this); -} - - -// Destroys the object. - -void CPhysics::DeleteObject(BOOL bAll) -{ - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 0.3f, SOPER_STOP); - m_soundChannel = -1; - } - if ( m_soundChannelSlide != -1 ) - { - m_sound->FlushEnvelope(m_soundChannelSlide); - m_sound->AddEnvelope(m_soundChannelSlide, 0.0f, 1.0f, 0.3f, SOPER_STOP); - m_soundChannelSlide = -1; - } -} - - - -void CPhysics::SetBrain(CBrain* brain) -{ - m_brain = brain; -} - -void CPhysics::SetMotion(CMotion* motion) -{ - m_motion = motion; -} - -// Management of the type. - -void CPhysics::SetType(PhysicsType type) -{ - m_type = type; -} - -PhysicsType CPhysics::RetType() -{ - return m_type; -} - - - -// Saves all parameters of the object. - -BOOL CPhysics::Write(char *line) -{ - char name[100]; - - sprintf(name, " motor=%.2f;%.2f;%.2f", m_motorSpeed.x, m_motorSpeed.y, m_motorSpeed.z); - strcat(line, name); - - if ( m_type == TYPE_FLYING ) - { - sprintf(name, " reactorRange=%.2f", RetReactorRange()); - strcat(line, name); - - sprintf(name, " land=%d", RetLand()); - strcat(line, name); - } - - return TRUE; -} - -// Restores all parameters of the object. - -BOOL CPhysics::Read(char *line) -{ - m_motorSpeed = OpDir(line, "motor"); - - if ( m_type == TYPE_FLYING ) - { - SetReactorRange(OpFloat(line, "reactorRange", 0.0f)); - SetLand(OpInt(line, "land", 0)); - } - - return TRUE; -} - - - -// Management of the force of gravity. - -void CPhysics::SetGravity(float value) -{ - m_gravity = value; -} - -float CPhysics::RetGravity() -{ - return m_gravity; -} - - -// Returns the height above the ground. - -float CPhysics::RetFloorHeight() -{ - return m_floorHeight; -} - - -// Managing the state of the engine. - -void CPhysics::SetMotor(BOOL bState) -{ - int light; - - m_bMotor = bState; - - light = m_object->RetShadowLight(); - if ( light != -1 ) - { - m_light->SetLightIntensity(light, m_bMotor?1.0f:0.0f); - m_light->SetLightIntensitySpeed(light, 3.0f); - } -} - -BOOL CPhysics::RetMotor() -{ - return m_bMotor; -} - - -// Management of the state in flight/ground. - -void CPhysics::SetLand(BOOL bState) -{ - m_bLand = bState; - SetMotor(!bState); // lights if you leave the reactor in flight -} - -BOOL CPhysics::RetLand() -{ - return m_bLand; -} - - -// Management of the state in air/water. - -void CPhysics::SetSwim(BOOL bState) -{ - if ( !m_bSwim && bState ) // enters the water? - { - m_timeUnderWater = 0.0f; - } - m_bSwim = bState; -} - -BOOL CPhysics::RetSwim() -{ - return m_bSwim; -} - - -// Indicates whether a collision occurred. - -void CPhysics::SetCollision(BOOL bCollision) -{ - m_bCollision = bCollision; -} - -BOOL CPhysics::RetCollision() -{ - return m_bCollision; -} - - -// Indicates whether the influence of soil is activated or not. - -void CPhysics::SetFreeze(BOOL bFreeze) -{ - m_bFreeze = bFreeze; -} - -BOOL CPhysics::RetFreeze() -{ - return m_bFreeze; -} - - -// Returns the range of the reactor. - -void CPhysics::SetReactorRange(float range) -{ - m_reactorRange = range; -} - -float CPhysics::RetReactorRange() -{ - return m_reactorRange; -} - - -// Specifies the engine speed. -// x = forward/backward -// y = up/down -// z = turn - -void CPhysics::SetMotorSpeed(D3DVECTOR speed) -{ - m_motorSpeed = speed; -} - -// Specifies the engine speed for forward/backward. -// +1 = forward -// -1 = backward - -void CPhysics::SetMotorSpeedX(float speed) -{ - m_motorSpeed.x = speed; -} - -// Specifies the motor speed for up/down. -// +1 = up -// -1 = down - -void CPhysics::SetMotorSpeedY(float speed) -{ - m_motorSpeed.y = speed; -} - -// Specifies the speed of the motor to turn. -// +1 = turn right(CW) -// -1 = turn left(CCW) - -void CPhysics::SetMotorSpeedZ(float speed) -{ - m_motorSpeed.z = speed; -} - -D3DVECTOR CPhysics::RetMotorSpeed() -{ - return m_motorSpeed; -} - -float CPhysics::RetMotorSpeedX() -{ - return m_motorSpeed.x; -} - -float CPhysics::RetMotorSpeedY() -{ - return m_motorSpeed.y; -} - -float CPhysics::RetMotorSpeedZ() -{ - return m_motorSpeed.z; -} - - -// Management of linear and angular velocities. -// Specifies the speed parallel to the direction of travel. - -void CPhysics::SetLinMotion(PhysicsMode mode, D3DVECTOR value) -{ - if ( mode == MO_ADVACCEL ) m_linMotion.advanceAccel = value; - if ( mode == MO_RECACCEL ) m_linMotion.recedeAccel = value; - if ( mode == MO_STOACCEL ) m_linMotion.stopAccel = value; - if ( mode == MO_TERSPEED ) m_linMotion.terrainSpeed = value; - if ( mode == MO_TERSLIDE ) m_linMotion.terrainSlide = value; - if ( mode == MO_MOTACCEL ) m_linMotion.motorAccel = value; - if ( mode == MO_TERFORCE ) m_linMotion.terrainForce = value; - if ( mode == MO_ADVSPEED ) m_linMotion.advanceSpeed = value; - if ( mode == MO_RECSPEED ) m_linMotion.recedeSpeed = value; - if ( mode == MO_MOTSPEED ) m_linMotion.motorSpeed = value; - if ( mode == MO_CURSPEED ) m_linMotion.currentSpeed = value; - if ( mode == MO_REASPEED ) m_linMotion.realSpeed = value; -} - -D3DVECTOR CPhysics::RetLinMotion(PhysicsMode mode) -{ - if ( mode == MO_ADVACCEL ) return m_linMotion.advanceAccel; - if ( mode == MO_RECACCEL ) return m_linMotion.recedeAccel; - if ( mode == MO_STOACCEL ) return m_linMotion.stopAccel; - if ( mode == MO_TERSPEED ) return m_linMotion.terrainSpeed; - if ( mode == MO_TERSLIDE ) return m_linMotion.terrainSlide; - if ( mode == MO_MOTACCEL ) return m_linMotion.motorAccel; - if ( mode == MO_TERFORCE ) return m_linMotion.terrainForce; - if ( mode == MO_ADVSPEED ) return m_linMotion.advanceSpeed; - if ( mode == MO_RECSPEED ) return m_linMotion.recedeSpeed; - if ( mode == MO_MOTSPEED ) return m_linMotion.motorSpeed; - if ( mode == MO_CURSPEED ) return m_linMotion.currentSpeed; - if ( mode == MO_REASPEED ) return m_linMotion.realSpeed; - return D3DVECTOR(0.0f, 0.0f, 0.0f); -} - -void CPhysics::SetLinMotionX(PhysicsMode mode, float value) -{ - if ( mode == MO_ADVACCEL ) m_linMotion.advanceAccel.x = value; - if ( mode == MO_RECACCEL ) m_linMotion.recedeAccel.x = value; - if ( mode == MO_STOACCEL ) m_linMotion.stopAccel.x = value; - if ( mode == MO_TERSPEED ) m_linMotion.terrainSpeed.x = value; - if ( mode == MO_TERSLIDE ) m_linMotion.terrainSlide.x = value; - if ( mode == MO_MOTACCEL ) m_linMotion.motorAccel.x = value; - if ( mode == MO_TERFORCE ) m_linMotion.terrainForce.x = value; - if ( mode == MO_ADVSPEED ) m_linMotion.advanceSpeed.x = value; - if ( mode == MO_RECSPEED ) m_linMotion.recedeSpeed.x = value; - if ( mode == MO_MOTSPEED ) m_linMotion.motorSpeed.x = value; - if ( mode == MO_CURSPEED ) m_linMotion.currentSpeed.x = value; - if ( mode == MO_REASPEED ) m_linMotion.realSpeed.x = value; -} - -float CPhysics::RetLinMotionX(PhysicsMode mode) -{ - if ( mode == MO_ADVACCEL ) return m_linMotion.advanceAccel.x; - if ( mode == MO_RECACCEL ) return m_linMotion.recedeAccel.x; - if ( mode == MO_STOACCEL ) return m_linMotion.stopAccel.x; - if ( mode == MO_TERSPEED ) return m_linMotion.terrainSpeed.x; - if ( mode == MO_TERSLIDE ) return m_linMotion.terrainSlide.x; - if ( mode == MO_MOTACCEL ) return m_linMotion.motorAccel.x; - if ( mode == MO_TERFORCE ) return m_linMotion.terrainForce.x; - if ( mode == MO_ADVSPEED ) return m_linMotion.advanceSpeed.x; - if ( mode == MO_RECSPEED ) return m_linMotion.recedeSpeed.x; - if ( mode == MO_MOTSPEED ) return m_linMotion.motorSpeed.x; - if ( mode == MO_CURSPEED ) return m_linMotion.currentSpeed.x; - if ( mode == MO_REASPEED ) return m_linMotion.realSpeed.x; - return 0.0f; -} - -// Specifies the speed of elevation. - -void CPhysics::SetLinMotionY(PhysicsMode mode, float value) -{ - if ( mode == MO_ADVACCEL ) m_linMotion.advanceAccel.y = value; - if ( mode == MO_RECACCEL ) m_linMotion.recedeAccel.y = value; - if ( mode == MO_STOACCEL ) m_linMotion.stopAccel.y = value; - if ( mode == MO_TERSPEED ) m_linMotion.terrainSpeed.y = value; - if ( mode == MO_TERSLIDE ) m_linMotion.terrainSlide.y = value; - if ( mode == MO_MOTACCEL ) m_linMotion.motorAccel.y = value; - if ( mode == MO_TERFORCE ) m_linMotion.terrainForce.y = value; - if ( mode == MO_ADVSPEED ) m_linMotion.advanceSpeed.y = value; - if ( mode == MO_RECSPEED ) m_linMotion.recedeSpeed.y = value; - if ( mode == MO_MOTSPEED ) m_linMotion.motorSpeed.y = value; - if ( mode == MO_CURSPEED ) m_linMotion.currentSpeed.y = value; - if ( mode == MO_REASPEED ) m_linMotion.realSpeed.y = value; -} - -float CPhysics::RetLinMotionY(PhysicsMode mode) -{ - if ( mode == MO_ADVACCEL ) return m_linMotion.advanceAccel.y; - if ( mode == MO_RECACCEL ) return m_linMotion.recedeAccel.y; - if ( mode == MO_STOACCEL ) return m_linMotion.stopAccel.y; - if ( mode == MO_TERSPEED ) return m_linMotion.terrainSpeed.y; - if ( mode == MO_TERSLIDE ) return m_linMotion.terrainSlide.y; - if ( mode == MO_MOTACCEL ) return m_linMotion.motorAccel.y; - if ( mode == MO_TERFORCE ) return m_linMotion.terrainForce.y; - if ( mode == MO_ADVSPEED ) return m_linMotion.advanceSpeed.y; - if ( mode == MO_RECSPEED ) return m_linMotion.recedeSpeed.y; - if ( mode == MO_MOTSPEED ) return m_linMotion.motorSpeed.y; - if ( mode == MO_CURSPEED ) return m_linMotion.currentSpeed.y; - if ( mode == MO_REASPEED ) return m_linMotion.realSpeed.y; - return 0.0f; -} - -// Specifies the velocity perpendicular to the direction of travel. - -void CPhysics::SetLinMotionZ(PhysicsMode mode, float value) -{ - if ( mode == MO_ADVACCEL ) m_linMotion.advanceAccel.z = value; - if ( mode == MO_RECACCEL ) m_linMotion.recedeAccel.z = value; - if ( mode == MO_STOACCEL ) m_linMotion.stopAccel.z = value; - if ( mode == MO_TERSPEED ) m_linMotion.terrainSpeed.z = value; - if ( mode == MO_TERSLIDE ) m_linMotion.terrainSlide.z = value; - if ( mode == MO_MOTACCEL ) m_linMotion.motorAccel.z = value; - if ( mode == MO_TERFORCE ) m_linMotion.terrainForce.z = value; - if ( mode == MO_ADVSPEED ) m_linMotion.advanceSpeed.z = value; - if ( mode == MO_RECSPEED ) m_linMotion.recedeSpeed.z = value; - if ( mode == MO_MOTSPEED ) m_linMotion.motorSpeed.z = value; - if ( mode == MO_CURSPEED ) m_linMotion.currentSpeed.z = value; - if ( mode == MO_REASPEED ) m_linMotion.realSpeed.z = value; -} - -float CPhysics::RetLinMotionZ(PhysicsMode mode) -{ - if ( mode == MO_ADVACCEL ) return m_linMotion.advanceAccel.z; - if ( mode == MO_RECACCEL ) return m_linMotion.recedeAccel.z; - if ( mode == MO_STOACCEL ) return m_linMotion.stopAccel.z; - if ( mode == MO_TERSPEED ) return m_linMotion.terrainSpeed.z; - if ( mode == MO_TERSLIDE ) return m_linMotion.terrainSlide.z; - if ( mode == MO_MOTACCEL ) return m_linMotion.motorAccel.z; - if ( mode == MO_TERFORCE ) return m_linMotion.terrainForce.z; - if ( mode == MO_ADVSPEED ) return m_linMotion.advanceSpeed.z; - if ( mode == MO_RECSPEED ) return m_linMotion.recedeSpeed.z; - if ( mode == MO_MOTSPEED ) return m_linMotion.motorSpeed.z; - if ( mode == MO_CURSPEED ) return m_linMotion.currentSpeed.z; - if ( mode == MO_REASPEED ) return m_linMotion.realSpeed.z; - return 0.0f; -} - -// Specifies the rotation around the axis of walk. - -void CPhysics::SetCirMotion(PhysicsMode mode, D3DVECTOR value) -{ - if ( mode == MO_ADVACCEL ) m_cirMotion.advanceAccel = value; - if ( mode == MO_RECACCEL ) m_cirMotion.recedeAccel = value; - if ( mode == MO_STOACCEL ) m_cirMotion.stopAccel = value; - if ( mode == MO_TERSPEED ) m_cirMotion.terrainSpeed = value; - if ( mode == MO_TERSLIDE ) m_cirMotion.terrainSlide = value; - if ( mode == MO_MOTACCEL ) m_cirMotion.motorAccel = value; - if ( mode == MO_TERFORCE ) m_cirMotion.terrainForce = value; - if ( mode == MO_ADVSPEED ) m_cirMotion.advanceSpeed = value; - if ( mode == MO_RECSPEED ) m_cirMotion.recedeSpeed = value; - if ( mode == MO_MOTSPEED ) m_cirMotion.motorSpeed = value; - if ( mode == MO_CURSPEED ) m_cirMotion.currentSpeed = value; - if ( mode == MO_REASPEED ) m_cirMotion.realSpeed = value; -} - -D3DVECTOR CPhysics::RetCirMotion(PhysicsMode mode) -{ - if ( mode == MO_ADVACCEL ) return m_cirMotion.advanceAccel; - if ( mode == MO_RECACCEL ) return m_cirMotion.recedeAccel; - if ( mode == MO_STOACCEL ) return m_cirMotion.stopAccel; - if ( mode == MO_TERSPEED ) return m_cirMotion.terrainSpeed; - if ( mode == MO_TERSLIDE ) return m_cirMotion.terrainSlide; - if ( mode == MO_MOTACCEL ) return m_cirMotion.motorAccel; - if ( mode == MO_TERFORCE ) return m_cirMotion.terrainForce; - if ( mode == MO_ADVSPEED ) return m_cirMotion.advanceSpeed; - if ( mode == MO_RECSPEED ) return m_cirMotion.recedeSpeed; - if ( mode == MO_MOTSPEED ) return m_cirMotion.motorSpeed; - if ( mode == MO_CURSPEED ) return m_cirMotion.currentSpeed; - if ( mode == MO_REASPEED ) return m_cirMotion.realSpeed; - return D3DVECTOR(0.0f, 0.0f, 0.0f); -} - -void CPhysics::SetCirMotionX(PhysicsMode mode, float value) -{ - if ( mode == MO_ADVACCEL ) m_cirMotion.advanceAccel.x = value; - if ( mode == MO_RECACCEL ) m_cirMotion.recedeAccel.x = value; - if ( mode == MO_STOACCEL ) m_cirMotion.stopAccel.x = value; - if ( mode == MO_TERSPEED ) m_cirMotion.terrainSpeed.x = value; - if ( mode == MO_TERSLIDE ) m_cirMotion.terrainSlide.x = value; - if ( mode == MO_MOTACCEL ) m_cirMotion.motorAccel.x = value; - if ( mode == MO_TERFORCE ) m_cirMotion.terrainForce.x = value; - if ( mode == MO_ADVSPEED ) m_cirMotion.advanceSpeed.x = value; - if ( mode == MO_RECSPEED ) m_cirMotion.recedeSpeed.x = value; - if ( mode == MO_MOTSPEED ) m_cirMotion.motorSpeed.x = value; - if ( mode == MO_CURSPEED ) m_cirMotion.currentSpeed.x = value; - if ( mode == MO_REASPEED ) m_cirMotion.realSpeed.x = value; -} - -float CPhysics::RetCirMotionX(PhysicsMode mode) -{ - if ( mode == MO_ADVACCEL ) return m_cirMotion.advanceAccel.x; - if ( mode == MO_RECACCEL ) return m_cirMotion.recedeAccel.x; - if ( mode == MO_STOACCEL ) return m_cirMotion.stopAccel.x; - if ( mode == MO_TERSPEED ) return m_cirMotion.terrainSpeed.x; - if ( mode == MO_TERSLIDE ) return m_cirMotion.terrainSlide.x; - if ( mode == MO_MOTACCEL ) return m_cirMotion.motorAccel.x; - if ( mode == MO_TERFORCE ) return m_cirMotion.terrainForce.x; - if ( mode == MO_ADVSPEED ) return m_cirMotion.advanceSpeed.x; - if ( mode == MO_RECSPEED ) return m_cirMotion.recedeSpeed.x; - if ( mode == MO_MOTSPEED ) return m_cirMotion.motorSpeed.x; - if ( mode == MO_CURSPEED ) return m_cirMotion.currentSpeed.x; - if ( mode == MO_REASPEED ) return m_cirMotion.realSpeed.x; - return 0.0f; -} - -// Specifies the rotation direction. - -void CPhysics::SetCirMotionY(PhysicsMode mode, float value) -{ - if ( mode == MO_ADVACCEL ) m_cirMotion.advanceAccel.y = value; - if ( mode == MO_RECACCEL ) m_cirMotion.recedeAccel.y = value; - if ( mode == MO_STOACCEL ) m_cirMotion.stopAccel.y = value; - if ( mode == MO_TERSPEED ) m_cirMotion.terrainSpeed.y = value; - if ( mode == MO_TERSLIDE ) m_cirMotion.terrainSlide.y = value; - if ( mode == MO_MOTACCEL ) m_cirMotion.motorAccel.y = value; - if ( mode == MO_TERFORCE ) m_cirMotion.terrainForce.y = value; - if ( mode == MO_ADVSPEED ) m_cirMotion.advanceSpeed.y = value; - if ( mode == MO_RECSPEED ) m_cirMotion.recedeSpeed.y = value; - if ( mode == MO_MOTSPEED ) m_cirMotion.motorSpeed.y = value; - if ( mode == MO_CURSPEED ) m_cirMotion.currentSpeed.y = value; - if ( mode == MO_REASPEED ) m_cirMotion.realSpeed.y = value; -} - -float CPhysics::RetCirMotionY(PhysicsMode mode) -{ - if ( mode == MO_ADVACCEL ) return m_cirMotion.advanceAccel.y; - if ( mode == MO_RECACCEL ) return m_cirMotion.recedeAccel.y; - if ( mode == MO_STOACCEL ) return m_cirMotion.stopAccel.y; - if ( mode == MO_TERSPEED ) return m_cirMotion.terrainSpeed.y; - if ( mode == MO_TERSLIDE ) return m_cirMotion.terrainSlide.y; - if ( mode == MO_MOTACCEL ) return m_cirMotion.motorAccel.y; - if ( mode == MO_TERFORCE ) return m_cirMotion.terrainForce.y; - if ( mode == MO_ADVSPEED ) return m_cirMotion.advanceSpeed.y; - if ( mode == MO_RECSPEED ) return m_cirMotion.recedeSpeed.y; - if ( mode == MO_MOTSPEED ) return m_cirMotion.motorSpeed.y; - if ( mode == MO_CURSPEED ) return m_cirMotion.currentSpeed.y; - if ( mode == MO_REASPEED ) return m_cirMotion.realSpeed.y; - return 0.0f; -} - -// Specifies the rotation up/down. - -void CPhysics::SetCirMotionZ(PhysicsMode mode, float value) -{ - if ( mode == MO_ADVACCEL ) m_cirMotion.advanceAccel.z = value; - if ( mode == MO_RECACCEL ) m_cirMotion.recedeAccel.z = value; - if ( mode == MO_STOACCEL ) m_cirMotion.stopAccel.z = value; - if ( mode == MO_TERSPEED ) m_cirMotion.terrainSpeed.z = value; - if ( mode == MO_TERSLIDE ) m_cirMotion.terrainSlide.z = value; - if ( mode == MO_MOTACCEL ) m_cirMotion.motorAccel.z = value; - if ( mode == MO_TERFORCE ) m_cirMotion.terrainForce.z = value; - if ( mode == MO_ADVSPEED ) m_cirMotion.advanceSpeed.z = value; - if ( mode == MO_RECSPEED ) m_cirMotion.recedeSpeed.z = value; - if ( mode == MO_MOTSPEED ) m_cirMotion.motorSpeed.z = value; - if ( mode == MO_CURSPEED ) m_cirMotion.currentSpeed.z = value; - if ( mode == MO_REASPEED ) m_cirMotion.realSpeed.z = value; -} - -float CPhysics::RetCirMotionZ(PhysicsMode mode) -{ - if ( mode == MO_ADVACCEL ) return m_cirMotion.advanceAccel.z; - if ( mode == MO_RECACCEL ) return m_cirMotion.recedeAccel.z; - if ( mode == MO_STOACCEL ) return m_cirMotion.stopAccel.z; - if ( mode == MO_TERSPEED ) return m_cirMotion.terrainSpeed.z; - if ( mode == MO_TERSLIDE ) return m_cirMotion.terrainSlide.z; - if ( mode == MO_MOTACCEL ) return m_cirMotion.motorAccel.z; - if ( mode == MO_TERFORCE ) return m_cirMotion.terrainForce.z; - if ( mode == MO_ADVSPEED ) return m_cirMotion.advanceSpeed.z; - if ( mode == MO_RECSPEED ) return m_cirMotion.recedeSpeed.z; - if ( mode == MO_MOTSPEED ) return m_cirMotion.motorSpeed.z; - if ( mode == MO_CURSPEED ) return m_cirMotion.currentSpeed.z; - if ( mode == MO_REASPEED ) return m_cirMotion.realSpeed.z; - return 0.0f; -} - - -// Returns the linear distance braking. -// -// v*v -// d = ----- -// 2a - -float CPhysics::RetLinStopLength(PhysicsMode sMode, PhysicsMode aMode) -{ - float speed, accel; - - speed = RetLinMotionX(sMode); // MO_ADVSPEED/MO_RECSPEED - accel = RetLinMotionX(aMode); // MO_ADVACCEL/MO_RECACCEL/MO_STOACCEL - - if ( m_type == TYPE_FLYING && m_bLand ) // flying on the ground? - { - speed /= LANDING_SPEED; - accel *= LANDING_ACCEL; - } - - return (speed*speed) / (accel*2.0f); -} - -// Returns the angle of circular braking. - -float CPhysics::RetCirStopLength() -{ - return m_cirMotion.advanceSpeed.y * m_cirMotion.advanceSpeed.y / - m_cirMotion.stopAccel.y / 2.0f; -} - -// Returns the length advanced into a second, on the ground, maximum speed. - -float CPhysics::RetLinMaxLength(float dir) -{ - float dist; - - if ( dir > 0.0f ) dist = m_linMotion.advanceSpeed.x; - else dist = m_linMotion.recedeSpeed.x; - - if ( m_type == TYPE_FLYING ) - { - dist /= 5.0f; - } - - return dist; -} - -// Returns the time needed to travel some distance. - -float CPhysics::RetLinTimeLength(float dist, float dir) -{ - float accel, decel, dps; - - if ( dir > 0.0f ) - { - accel = RetLinStopLength(MO_ADVSPEED, MO_ADVACCEL); - decel = RetLinStopLength(MO_ADVSPEED, MO_STOACCEL); - } - else - { - accel = RetLinStopLength(MO_RECSPEED, MO_RECACCEL); - decel = RetLinStopLength(MO_RECSPEED, MO_STOACCEL); - } - - dps = RetLinMaxLength(dir); - - return (dist+accel+decel)/dps; -} - -// Returns the length for a forward travel some distance, taking into account the accelerations / decelerations. - -float CPhysics::RetLinLength(float dist) -{ - float accDist, desDist; - - if ( dist > 0.0f ) - { - accDist = RetLinStopLength(MO_ADVSPEED, MO_ADVACCEL); - desDist = RetLinStopLength(MO_ADVSPEED, MO_STOACCEL); - - if ( dist > accDist+desDist ) - { - return dist-desDist; - } - - return dist*m_linMotion.stopAccel.x / - (m_linMotion.advanceAccel.x+m_linMotion.stopAccel.x); - } - else - { - dist = -dist; - accDist = RetLinStopLength(MO_RECSPEED, MO_RECACCEL); - desDist = RetLinStopLength(MO_RECSPEED, MO_STOACCEL); - - if ( dist > accDist+desDist ) - { - return dist-desDist; - } - - return dist*m_linMotion.stopAccel.x / - (m_linMotion.recedeAccel.x+m_linMotion.stopAccel.x); - } -} - - -// Management of an event. -// Returns FALSE if the object is destroyed. - -BOOL CPhysics::EventProcess(const Event &event) -{ - if ( !m_object->RetEnable() ) return TRUE; - - if ( m_brain != 0 ) - { - m_brain->EventProcess(event); - } - - if ( event.event == EVENT_FRAME ) - { - return EventFrame(event); - } - return TRUE; -} - - -// Updates instructions for the motor speed. - -void CPhysics::MotorUpdate(float aTime, float rTime) -{ - ObjectType type; - CObject* power; - D3DVECTOR pos, motorSpeed; - float energy, speed, factor, h; - - type = m_object->RetType(); - - motorSpeed = m_motorSpeed; - - if ( type == OBJECT_MOTHER || - type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_BEE || - type == OBJECT_WORM || - type == OBJECT_APOLLO2 || - type == OBJECT_MOBILEdr ) - { - power = 0; - } - else if ( type == OBJECT_HUMAN || - type == OBJECT_TECH ) - { - power = 0; - if ( m_object->RetFret() != 0 && // carries something? - !m_object->RetCargo() ) - { - motorSpeed.x *= 0.7f; // forward more slowly - motorSpeed.z *= 0.5f; - motorSpeed.y = -1.0f; // grave - } - if ( m_bSwim ) - { - if ( m_bLand ) // deep in the water? - { - motorSpeed.x *= 0.4f; // forward more slowly - motorSpeed.z *= 0.5f; - motorSpeed.y *= 0.5f; - - if ( m_object->RetFret() != 0 ) // carries something? - { - motorSpeed.x *= 0.2f; - motorSpeed.z *= 0.9f; - motorSpeed.y *= 0.2f; - } - } - else // swimming? - { - motorSpeed.x *= 0.2f; // forward more slowly - motorSpeed.z *= 0.5f; - motorSpeed.y *= 0.2f; - } - } - } - else - { - power = m_object->RetPower(); // searches for the object battery uses - if ( power == 0 || power->RetEnergy() == 0.0f ) // no battery or flat? - { - motorSpeed.x = 0.0f; - motorSpeed.z = 0.0f; - if ( m_bFreeze || m_bLand ) - { - motorSpeed.y = 0.0f; // immobile - } - else - { - motorSpeed.y = -1.0f; // grave - } - SetMotor(FALSE); - } - } - - if ( m_object->RetDead() ) // dead man? - { - motorSpeed.x = 0.0f; - motorSpeed.z = 0.0f; - if ( m_motion->RetAction() == MHS_DEADw ) // drowned? - { - motorSpeed.y = 0.0f; // this is MHS_DEADw going back - } - else - { - motorSpeed.y = -1.0f; // grave - } - SetMotor(FALSE); - } - - if ( m_type == TYPE_FLYING && !m_bLand && motorSpeed.y > 0.0f ) - { - pos = m_object->RetPosition(0); - h = m_terrain->RetFlyingLimit(pos, type==OBJECT_BEE); - h += m_object->RetCharacter()->height; - if ( pos.y > h-40.0f ) // almost at the top? - { - factor = 1.0f-(pos.y-(h-40.0f))/40.0f; - if ( factor < -1.0f ) factor = -1.0f; - if ( factor > 1.0f ) factor = 1.0f; - motorSpeed.y *= factor; // limit the rate of rise - } - } - - if ( type != OBJECT_BEE && - m_object->RetRange() > 0.0f ) // limited flight range? - { - if ( m_bLand || m_bSwim || m_bObstacle ) // on the ground or in the water? - { - factor = 1.0f; - if ( m_bObstacle ) factor = 3.0f; // in order to leave! - if ( m_bSwim ) factor = 3.0f; // cools faster in water - m_reactorRange += rTime*(1.0f/5.0f)*factor; - if ( m_reactorRange > 1.0f ) - { - m_reactorRange = 1.0f; - if ( m_bLowLevel && m_object->RetSelect() ) // beep cool? - { - m_sound->Play(SOUND_INFO, m_object->RetPosition(0), 1.0f, 2.0f); - m_bLowLevel = FALSE; - } - } - m_bObstacle = FALSE; - } - else // in flight? - { - m_reactorRange -= rTime*(1.0f/m_object->RetRange()); - if ( m_reactorRange < 0.0f ) m_reactorRange = 0.0f; - if ( m_reactorRange < 0.5f ) m_bLowLevel = TRUE; - } - - if ( m_reactorRange == 0.0f ) // reactor tilt? - { - motorSpeed.y = -1.0f; // grave - } - } - -//? MotorParticule(aTime); - - // Forward/backward. - if ( motorSpeed.x > 0.0f ) - { - m_linMotion.motorAccel.x = m_linMotion.advanceAccel.x; - m_linMotion.motorSpeed.x = m_linMotion.advanceSpeed.x * motorSpeed.x; - } - if ( motorSpeed.x < 0.0f ) - { - m_linMotion.motorAccel.x = m_linMotion.recedeAccel.x; - m_linMotion.motorSpeed.x = m_linMotion.recedeSpeed.x * motorSpeed.x; - } - if ( motorSpeed.x == 0.0f ) - { - m_linMotion.motorAccel.x = m_linMotion.stopAccel.x; - m_linMotion.motorSpeed.x = 0.0f; - } - - // Up/down. - if ( motorSpeed.y > 0.0f ) - { - m_linMotion.motorAccel.y = m_linMotion.advanceAccel.y; - m_linMotion.motorSpeed.y = m_linMotion.advanceSpeed.y * motorSpeed.y; - } - if ( motorSpeed.y < 0.0f ) - { - m_linMotion.motorAccel.y = m_linMotion.recedeAccel.y; - m_linMotion.motorSpeed.y = m_linMotion.recedeSpeed.y * motorSpeed.y; - } - if ( motorSpeed.y == 0.0f ) - { - m_linMotion.motorAccel.y = m_linMotion.stopAccel.y; - m_linMotion.motorSpeed.y = 0.0f; - } - - // Turn left/right. - speed = motorSpeed.z; -//? if ( motorSpeed.x < 0.0f ) speed = -speed; // reverse if running back - - if ( motorSpeed.z > 0.0f ) - { - m_cirMotion.motorAccel.y = m_cirMotion.advanceAccel.y; - m_cirMotion.motorSpeed.y = m_cirMotion.advanceSpeed.y * speed; - } - if ( motorSpeed.z < 0.0f ) - { - m_cirMotion.motorAccel.y = m_cirMotion.recedeAccel.y; - m_cirMotion.motorSpeed.y = m_cirMotion.recedeSpeed.y * speed; - } - if ( motorSpeed.z == 0.0f ) - { - m_cirMotion.motorAccel.y = m_cirMotion.stopAccel.y; - m_cirMotion.motorSpeed.y = 0.0f; - } - - if ( m_type == TYPE_FLYING && m_bLand ) // flying on the ground? - { - if ( type == OBJECT_HUMAN || - type == OBJECT_TECH ) - { - factor = LANDING_ACCELh; - } - else - { - factor = LANDING_ACCEL; - } - m_linMotion.motorAccel.x = m_linMotion.stopAccel.x*factor; - m_cirMotion.motorAccel.y = m_cirMotion.stopAccel.y*factor; - - pos = m_object->RetPosition(0); - h = m_terrain->RetFlyingLimit(pos, type==OBJECT_BEE); - h += m_object->RetCharacter()->height; - if ( motorSpeed.y > 0.0f && m_reactorRange > 0.1f && pos.y < h ) - { - m_bLand = FALSE; // take off - SetMotor(TRUE); - pos.y += 0.05f; // small initial height (startup) - m_object->SetPosition(0, pos); - } - } - - if ( m_type == TYPE_ROLLING ) - { - if ( motorSpeed.x == 0.0f && - motorSpeed.z == 0.0f ) - { - SetMotor(FALSE); - } - else - { - SetMotor(TRUE); - } - } - - if ( power != 0 ) // battery transported? - { - factor = 1.0f; - if ( type == OBJECT_MOBILEia || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEii ) factor = 0.5f; - - factor /= power->RetCapacity(); - - energy = power->RetEnergy(); - energy -= Abs(motorSpeed.x)*rTime*factor*0.005f; - energy -= Abs(motorSpeed.z)*rTime*factor*0.005f; - - if ( m_type == TYPE_FLYING && motorSpeed.y > 0.0f ) - { - energy -= motorSpeed.y*rTime*factor*0.01f; - } - if ( energy < 0.0f ) energy = 0.0f; - power->SetEnergy(energy); - } -} - - -// Updates the effects of vibration and tilt. - -void CPhysics::EffectUpdate(float aTime, float rTime) -{ - Character* character; - D3DVECTOR vibLin, vibCir, incl; - float speedLin, speedCir, accel; - ObjectType type; - BOOL bOnBoard; - - if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return; - - type = m_object->RetType(); - character = m_object->RetCharacter(); - - bOnBoard = FALSE; - if ( m_object->RetSelect() && - m_camera->RetType() == CAMERA_ONBOARD ) - { - bOnBoard = TRUE; - } - - vibLin = m_motion->RetLinVibration(); - vibCir = m_motion->RetCirVibration(); - incl = m_motion->RetInclinaison(); - - if ( type == OBJECT_HUMAN || // human? - type == OBJECT_TECH ) - { - if ( !m_bLand && !m_bSwim ) // in flight? - { - vibLin.y = sinf(aTime*2.00f)*0.5f+ - sinf(aTime*2.11f)*0.3f; - - vibCir.z = sinf(aTime*PI* 2.01f)*(PI/150.0f)+ - sinf(aTime*PI* 2.51f)*(PI/200.0f)+ - sinf(aTime*PI*19.01f)*(PI/400.0f); - - vibCir.x = sinf(aTime*PI* 2.03f)*(PI/150.0f)+ - sinf(aTime*PI* 2.52f)*(PI/200.0f)+ - sinf(aTime*PI*19.53f)*(PI/400.0f); - - speedLin = m_linMotion.realSpeed.x / m_linMotion.advanceSpeed.x; - speedCir = m_cirMotion.realSpeed.y / m_cirMotion.advanceSpeed.y; - incl.x = -speedLin*speedCir*0.5f; // looks if turn - -//? speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.5f; - speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.2f; - speedLin /= m_linMotion.advanceSpeed.x; - m_linMotion.finalInclin.z = speedLin*1.4f; - if ( incl.z < m_linMotion.finalInclin.z ) - { - incl.z += rTime*0.4f; - if ( incl.z > m_linMotion.finalInclin.z ) - { - incl.z = m_linMotion.finalInclin.z; - } - } - else if ( incl.z > m_linMotion.finalInclin.z ) - { - incl.z -= rTime*0.4f; - if ( incl.z < m_linMotion.finalInclin.z ) - { - incl.z = m_linMotion.finalInclin.z; - } - } - - vibLin *= m_linVibrationFactor; - vibCir *= m_cirVibrationFactor; - incl *= m_inclinaisonFactor; - - m_motion->SetLinVibration(vibLin); - m_motion->SetCirVibration(vibCir); - m_motion->SetInclinaison(incl); - } - else if ( m_bSwim ) // swimming? - { - vibLin.y = sinf(aTime*2.00f)*0.5f+ - sinf(aTime*2.11f)*0.3f; - - vibCir.z = sinf(aTime*PI* 2.01f)*(PI/150.0f)+ - sinf(aTime*PI* 2.51f)*(PI/200.0f)+ -//? sinf(aTime*PI*19.01f)*(PI/400.0f)-PI/2.0f; - sinf(aTime*PI*19.01f)*(PI/400.0f); - - vibCir.x = sinf(aTime*PI* 2.03f)*(PI/150.0f)+ - sinf(aTime*PI* 2.52f)*(PI/200.0f)+ - sinf(aTime*PI*19.53f)*(PI/400.0f); - - speedLin = m_linMotion.realSpeed.x / m_linMotion.advanceSpeed.x; - speedCir = m_cirMotion.realSpeed.y / m_cirMotion.advanceSpeed.y; - incl.x = -speedLin*speedCir*5.0f; // looks if turn - -//? speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.5f; - speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.2f; - speedLin /= m_linMotion.advanceSpeed.x; - m_linMotion.finalInclin.z = speedLin*1.4f; - if ( incl.z < m_linMotion.finalInclin.z ) - { - incl.z += rTime*0.4f; - if ( incl.z > m_linMotion.finalInclin.z ) - { - incl.z = m_linMotion.finalInclin.z; - } - } - else if ( incl.z > m_linMotion.finalInclin.z ) - { - incl.z -= rTime*0.4f; - if ( incl.z < m_linMotion.finalInclin.z ) - { - incl.z = m_linMotion.finalInclin.z; - } - } - - if ( m_linMotion.realSpeed.y > 0.0f ) // up? - { - vibCir.z += m_linMotion.realSpeed.y*0.05f; - } - else // down? - { - vibCir.z += m_linMotion.realSpeed.y*0.12f; - } - vibCir.z -= PI*0.4f; - - vibLin *= m_linVibrationFactor; - vibCir *= m_cirVibrationFactor; - incl *= m_inclinaisonFactor; - - m_motion->SetLinVibration(vibLin); - m_motion->SetCirVibration(vibCir); - m_motion->SetInclinaison(incl); - } - else - { - m_motion->SetLinVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); -//? m_motion->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); -//? m_motion->SetInclinaison(D3DVECTOR(0.0f, 0.0f, 0.0f)); - } - } - - if ( type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEtg || - type == OBJECT_APOLLO2 ) // wheels? - { - speedLin = m_linMotion.realSpeed.x / m_linMotion.advanceSpeed.x; - speedCir = m_cirMotion.realSpeed.y / m_cirMotion.advanceSpeed.y; - incl.x = speedLin*speedCir*0.20f; // looks if turn - if ( type == OBJECT_APOLLO2 ) incl.x *= 0.25f; - - speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x; - speedLin /= m_linMotion.advanceSpeed.x; - if ( speedLin > 1.0f ) speedLin = 1.0f; - m_linMotion.finalInclin.z = -speedLin*0.30f; - accel = (0.40f-Abs(incl.z))*4.0f; - if ( incl.z < m_linMotion.finalInclin.z ) - { - incl.z += rTime*accel; - if ( incl.z > m_linMotion.finalInclin.z ) - { - incl.z = m_linMotion.finalInclin.z; - } - } - else if ( incl.z > m_linMotion.finalInclin.z ) - { - incl.z -= rTime*accel; - if ( incl.z < m_linMotion.finalInclin.z ) - { - incl.z = m_linMotion.finalInclin.z; - } - } - if ( bOnBoard ) incl.z *= 0.1f; - if ( type == OBJECT_APOLLO2 ) incl.z *= 0.25f; - m_object->SetInclinaison(incl); - - vibLin.x = 0.0f; - vibLin.z = 0.0f; - vibLin.y = Abs(character->wheelFront*sinf(incl.z))*0.8f + - Abs(character->wheelRight*sinf(incl.x))*0.5f; - m_motion->SetLinVibration(vibLin); - } - - if ( type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEft ) // fliyng? - { - if ( m_bLand ) // on the ground? - { - m_motion->SetLinVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); - m_motion->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); - m_motion->SetInclinaison(D3DVECTOR(0.0f, 0.0f, 0.0f)); - } - else // in flight? - { - vibLin.y = sinf(aTime*2.00f)*0.5f+ - sinf(aTime*2.11f)*0.3f; - - vibCir.z = sinf(aTime*PI* 2.01f)*(PI/150.0f)+ - sinf(aTime*PI* 2.51f)*(PI/200.0f)+ - sinf(aTime*PI*19.01f)*(PI/400.0f); - - vibCir.x = sinf(aTime*PI* 2.03f)*(PI/150.0f)+ - sinf(aTime*PI* 2.52f)*(PI/200.0f)+ - sinf(aTime*PI*19.53f)*(PI/400.0f); - - if ( bOnBoard ) vibCir *= 0.4f; - - speedLin = m_linMotion.realSpeed.x / m_linMotion.advanceSpeed.x; - speedCir = m_cirMotion.realSpeed.y / m_cirMotion.advanceSpeed.y; - incl.x = -speedLin*speedCir*0.5f; // looks if turn - -//? speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.5f; - speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.2f; - speedLin /= m_linMotion.advanceSpeed.x; - m_linMotion.finalInclin.z = speedLin*0.8f; - if ( incl.z < m_linMotion.finalInclin.z ) - { - incl.z += rTime*0.4f; - if ( incl.z > m_linMotion.finalInclin.z ) - { - incl.z = m_linMotion.finalInclin.z; - } - } - else if ( incl.z > m_linMotion.finalInclin.z ) - { - incl.z -= rTime*0.4f; - if ( incl.z < m_linMotion.finalInclin.z ) - { - incl.z = m_linMotion.finalInclin.z; - } - } -//? if ( bOnBoard ) incl.z *= 0.5f; - - vibLin *= m_linVibrationFactor; - vibCir *= m_cirVibrationFactor; - incl *= m_inclinaisonFactor; - - m_motion->SetLinVibration(vibLin); - m_motion->SetCirVibration(vibCir); - m_motion->SetInclinaison(incl); - } - } - - if ( type == OBJECT_BEE ) // bee? - { - if ( !m_bLand ) // in flight? - { - vibLin.y = sinf(aTime*2.00f)*0.5f+ - sinf(aTime*2.11f)*0.3f; - - vibCir.z = (Rand()-0.5f)*0.1f+ - sinf(aTime*PI* 2.01f)*(PI/150.0f)+ - sinf(aTime*PI* 2.51f)*(PI/200.0f)+ - sinf(aTime*PI*19.01f)*(PI/400.0f); - - vibCir.x = (Rand()-0.5f)*0.1f+ - sinf(aTime*PI* 2.03f)*(PI/150.0f)+ - sinf(aTime*PI* 2.52f)*(PI/200.0f)+ - sinf(aTime*PI*19.53f)*(PI/400.0f); - - speedLin = m_linMotion.realSpeed.x / m_linMotion.advanceSpeed.x; - speedCir = m_cirMotion.realSpeed.y / m_cirMotion.advanceSpeed.y; - incl.x = -speedLin*speedCir*1.5f; // looks if turn - -//? speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.5f; - speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.2f; - speedLin /= m_linMotion.advanceSpeed.x; - m_linMotion.finalInclin.z = speedLin*1.4f; - if ( incl.z < m_linMotion.finalInclin.z ) - { - incl.z += rTime*1.6f; - if ( incl.z > m_linMotion.finalInclin.z ) - { - incl.z = m_linMotion.finalInclin.z; - } - } - else if ( incl.z > m_linMotion.finalInclin.z ) - { - incl.z -= rTime*1.6f; - if ( incl.z < m_linMotion.finalInclin.z ) - { - incl.z = m_linMotion.finalInclin.z; - } - } - - vibLin *= m_linVibrationFactor; - vibCir *= m_cirVibrationFactor; - incl *= m_inclinaisonFactor; - - m_motion->SetLinVibration(vibLin); - m_motion->SetCirVibration(vibCir); - m_motion->SetInclinaison(incl); - } - } -} - - -// Updates structure Motion. - -void CPhysics::UpdateMotionStruct(float rTime, Motion &motion) -{ - float speed, motor; - - // Management for the coordinate x. - speed = motion.currentSpeed.x; - motor = motion.motorSpeed.x * m_inclinaisonFactor; - if ( speed < motor ) - { - speed += rTime*motion.motorAccel.x; // accelerates - if ( speed > motor ) - { - speed = motor; // does not exceed the speed - } - } - if ( speed > motor ) - { - speed -= rTime*motion.motorAccel.x; // decelerates - if ( speed < motor ) - { - speed = motor; // does not exceed the speed - } - } - motion.currentSpeed.x = speed; - motion.realSpeed.x = speed; - - if ( Abs(motion.terrainSpeed.x) > motion.terrainSlide.x ) - { - if ( motion.terrainSpeed.x > 0 ) - { - speed = motion.terrainSpeed.x - motion.terrainSlide.x; - } - else - { - speed = motion.terrainSpeed.x + motion.terrainSlide.x; - } - motion.realSpeed.x += speed; - } - - // Management for the coordinate y. - speed = motion.currentSpeed.y; - motor = motion.motorSpeed.y; // unlimited speed! - if ( speed < motor ) - { - speed += rTime*motion.motorAccel.y; // accelerates - if ( speed > motor ) - { - speed = motor; // does not exceed the speed - } - } - if ( speed > motor ) - { - speed -= rTime*motion.motorAccel.y; // decelerates - if ( speed < motor ) - { - speed = motor; // does not exceed the speed - } - } - motion.currentSpeed.y = speed; - motion.realSpeed.y = speed; - - if ( Abs(motion.terrainSpeed.y) > motion.terrainSlide.y ) - { - if ( motion.terrainSpeed.y > 0 ) - { - speed = motion.terrainSpeed.y - motion.terrainSlide.y; - } - else - { - speed = motion.terrainSpeed.y + motion.terrainSlide.y; - } - motion.realSpeed.y += speed; - } - - // Management for the coordinate z. - speed = motion.currentSpeed.z; - motor = motion.motorSpeed.z * m_inclinaisonFactor; - if ( speed < motor ) - { - speed += rTime*motion.motorAccel.z; // accelerates - if ( speed > motor ) - { - speed = motor; // does not exceed the speed - } - } - if ( speed > motor ) - { - speed -= rTime*motion.motorAccel.z; // decelerates - if ( speed < motor ) - { - speed = motor; // does not exceed the speed - } - } - motion.currentSpeed.z = speed; - motion.realSpeed.z = speed; - - if ( Abs(motion.terrainSpeed.z) > motion.terrainSlide.z ) - { - if ( motion.terrainSpeed.z > 0 ) - { - speed = motion.terrainSpeed.z - motion.terrainSlide.z; - } - else - { - speed = motion.terrainSpeed.z + motion.terrainSlide.z; - } - motion.realSpeed.z += speed; - } -} - - -// Makes physics evolve as time elapsed. -// Returns FALSE if the object is destroyed. -// -// a: acceleration -// v1: velocity at time t1 -// v2: velocity at time t2 -// dt: time elapsed since t1, then: dt = t2-t1 -// dd: difference in distance (advance) -// -// v2 = v1 + a*dt -// dd = v2*dt - -BOOL CPhysics::EventFrame(const Event &event) -{ - ObjectType type; - D3DMATRIX objRotate, matRotate; - D3DVECTOR iPos, iAngle, tAngle, pos, newpos, angle, newangle, n; - float h, w; - int i; - - if ( m_engine->RetPause() ) return TRUE; - - m_time += event.rTime; - m_timeUnderWater += event.rTime; - m_soundTimeJostle += event.rTime; - - type = m_object->RetType(); - - FrameParticule(m_time, event.rTime); - MotorUpdate(m_time, event.rTime); - EffectUpdate(m_time, event.rTime); - WaterFrame(m_time, event.rTime); - - iPos = pos = m_object->RetPosition(0); - iAngle = angle = m_object->RetAngle(0); - - // Accelerate is the descent, brake is the ascent. - if ( m_bFreeze || m_object->RetDead() ) - { - m_linMotion.terrainSpeed.x = 0.0f; - m_linMotion.terrainSpeed.z = 0.0f; - m_linMotion.terrainSpeed.y = 0.0f; - } - else - { - tAngle = angle; - h = m_terrain->RetBuildingFactor(pos); - if ( type == OBJECT_HUMAN || - type == OBJECT_TECH ) - { - if ( m_linMotion.currentSpeed.x == 0.0f ) - { - h *= 0.5f; // immobile man -> slippage - } - FloorAngle(pos, tAngle); // calculates the angle with the ground - } -#if 1 - if ( pos.y < m_water->RetLevel(m_object) ) // underwater? - { - h *= 0.5f; - } -#endif -//? m_linMotion.terrainSpeed.x = -tAngle.z*m_linMotion.terrainForce.x*h; -//? m_linMotion.terrainSpeed.z = tAngle.x*m_linMotion.terrainForce.z*h; -//? m_linMotion.terrainSpeed.x = -sinf(tAngle.z)*PI*0.5f*m_linMotion.terrainForce.x*h; -//? m_linMotion.terrainSpeed.z = sinf(tAngle.x)*PI*0.5f*m_linMotion.terrainForce.z*h; - m_linMotion.terrainSpeed.x = -tanf(tAngle.z)*0.9f*m_linMotion.terrainForce.x*h; - m_linMotion.terrainSpeed.z = tanf(tAngle.x)*0.9f*m_linMotion.terrainForce.z*h; - m_linMotion.terrainSpeed.y = 0.0f; - - // If the terrain is very steep, do not exaggerate! - if ( m_linMotion.terrainSpeed.x > 50.0f ) m_linMotion.terrainSpeed.x = 20.0f; - if ( m_linMotion.terrainSpeed.x < -50.0f ) m_linMotion.terrainSpeed.x = -20.0f; - if ( m_linMotion.terrainSpeed.z > 50.0f ) m_linMotion.terrainSpeed.z = 20.0f; - if ( m_linMotion.terrainSpeed.z < -50.0f ) m_linMotion.terrainSpeed.z = -20.0f; - } - - if ( type == OBJECT_BEE && !m_bLand ) - { - h = m_floorLevel; // ground level - w = m_water->RetLevel(m_object); - if ( h < w ) h = w; - h = pos.y-h-10.0f; // maximum height (*) - if ( h < 0.0f ) h = 0.0f; - m_linMotion.terrainSpeed.y = -h*2.5f; // is not above - } - - // (*) High enough to pass over the tower defense (OBJECT_TOWER), - // but not too much to pass under the cover of the ship (OBJECT_BASE)! - - UpdateMotionStruct(event.rTime, m_linMotion); - UpdateMotionStruct(event.rTime, m_cirMotion); - - newangle = angle + event.rTime*m_cirMotion.realSpeed; - MatRotateZXY(matRotate, newangle); - newpos = event.rTime*m_linMotion.realSpeed; - newpos = Transform(matRotate, newpos); - newpos += pos; - - m_terrain->LimitPos(newpos); - - if ( m_type == TYPE_FLYING && !m_bLand ) - { - h = m_terrain->RetFlyingLimit(newpos, type==OBJECT_BEE); - h += m_object->RetCharacter()->height; - if ( newpos.y > h ) newpos.y = h; - } - - if ( m_bForceUpdate || - newpos.x != pos.x || - newpos.y != pos.y || - newpos.z != pos.z || - newangle.x != angle.x || - newangle.y != angle.y || - newangle.z != angle.z ) - { - FloorAdapt(m_time, event.rTime, newpos, newangle); - } - - if ( m_bForceUpdate || - newpos.x != pos.x || - newpos.y != pos.y || - newpos.z != pos.z ) - { - i = ObjectAdapt(newpos, newangle); - if ( i == 2 ) // object destroyed? - { - return FALSE; - } - if ( i == 1 ) // immobile object? - { - newpos = iPos; // keeps the initial position, but accepts the rotation - } - } - - if ( newangle.x != angle.x || - newangle.y != angle.y || - newangle.z != angle.z ) - { - m_object->SetAngle(0, newangle); - } - - if ( newpos.x != pos.x || - newpos.y != pos.y || - newpos.z != pos.z ) - { - m_object->SetPosition(0, newpos); - } - - MotorParticule(m_time, event.rTime); - SoundMotor(event.rTime); - - m_bForceUpdate = FALSE; - - return TRUE; -} - -// Starts or stops the engine sounds. - -void CPhysics::SoundMotor(float rTime) -{ - CObject* power; - ObjectType type; - float energy; - - m_lastSoundInsect -= rTime; - type = m_object->RetType(); - - if ( type == OBJECT_MOTHER ) - { - if ( m_lastSoundInsect <= 0.0f && m_object->RetActif() ) - { - m_sound->Play(SOUND_INSECTm, m_object->RetPosition(0)); - if ( m_bMotor ) m_lastSoundInsect = 0.4f+Rand()*2.5f; - else m_lastSoundInsect = 1.5f+Rand()*4.0f; - } - } - else if ( type == OBJECT_ANT ) - { - if ( m_object->RetBurn() || - m_object->RetFixed() ) - { - if ( m_lastSoundInsect <= 0.0f ) - { - m_sound->Play(SOUND_INSECTa, m_object->RetPosition(0), 1.0f, 1.5f+Rand()*0.5f); - m_lastSoundInsect = 0.4f+Rand()*0.6f; - } - } - else if ( m_object->RetActif() ) - { - if ( m_lastSoundInsect <= 0.0f ) - { - m_sound->Play(SOUND_INSECTa, m_object->RetPosition(0)); - if ( m_bMotor ) m_lastSoundInsect = 0.4f+Rand()*2.5f; - else m_lastSoundInsect = 1.5f+Rand()*4.0f; - } - } - } - else if ( type == OBJECT_BEE ) - { - if ( m_object->RetActif() ) - { - if ( m_lastSoundInsect <= 0.0f ) - { - m_sound->Play(SOUND_INSECTb, m_object->RetPosition(0)); - if ( m_bMotor ) m_lastSoundInsect = 0.4f+Rand()*2.5f; - else m_lastSoundInsect = 1.5f+Rand()*4.0f; - } - } - else if ( m_object->RetBurn() ) - { - if ( m_lastSoundInsect <= 0.0f ) - { - m_sound->Play(SOUND_INSECTb, m_object->RetPosition(0), 1.0f, 1.5f+Rand()*0.5f); - m_lastSoundInsect = 0.3f+Rand()*0.5f; - } - } - } - else if ( type == OBJECT_WORM ) - { - if ( m_object->RetActif() ) - { - if ( m_lastSoundInsect <= 0.0f ) - { - m_sound->Play(SOUND_INSECTw, m_object->RetPosition(0)); - if ( m_bMotor ) m_lastSoundInsect = 0.4f+Rand()*2.5f; - else m_lastSoundInsect = 1.5f+Rand()*4.0f; - } - } - else if ( m_object->RetBurn() ) - { - if ( m_lastSoundInsect <= 0.0f ) - { - m_sound->Play(SOUND_INSECTw, m_object->RetPosition(0), 1.0f, 1.5f+Rand()*0.5f); - m_lastSoundInsect = 0.2f+Rand()*0.2f; - } - } - } - else if ( type == OBJECT_SPIDER ) - { - if ( m_object->RetBurn() || - m_object->RetFixed() ) - { - if ( m_lastSoundInsect <= 0.0f ) - { - m_sound->Play(SOUND_INSECTs, m_object->RetPosition(0), 1.0f, 1.5f+Rand()*0.5f); - m_lastSoundInsect = 0.4f+Rand()*0.6f; - } - } - else if ( m_object->RetActif() ) - { - if ( m_lastSoundInsect <= 0.0f ) - { - m_sound->Play(SOUND_INSECTs, m_object->RetPosition(0)); - if ( m_bMotor ) m_lastSoundInsect = 0.4f+Rand()*2.5f; - else m_lastSoundInsect = 1.5f+Rand()*4.0f; - } - } - } - else // vehicle? - { - if ( m_type == TYPE_ROLLING ) - { - if ( m_bMotor && m_object->RetActif() ) - { - SoundMotorFull(rTime, type); // full diet - } - else - { - energy = 0.0f; - power = m_object->RetPower(); - if ( power != 0 ) - { - energy = power->RetEnergy(); - } - - if ( m_object->RetSelect() && - energy != 0.0f ) - { - SoundMotorSlow(rTime, type); // in slow motion - } - else - { - SoundMotorStop(rTime, type); // to the stop - } - } - } - - if ( m_type == TYPE_FLYING ) - { - if ( m_bMotor && !m_bSwim && - m_object->RetActif() && !m_object->RetDead() ) - { - SoundReactorFull(rTime, type); // full diet - } - else - { - SoundReactorStop(rTime, type); // to the stop - } - } - } -} - -// Detonates the object if it is underwater. - -void CPhysics::WaterFrame(float aTime, float rTime) -{ - ObjectType type; - D3DVECTOR pos, speed; - FPOINT dim; - float level; - - level = m_water->RetLevel(); - if ( level == 0.0f ) return; // no water? - if ( m_object->RetTruck() != 0 ) return; // object transported? - - // Management of flames into the lava. - pos = m_object->RetPosition(0); - if ( m_water->RetLava() && - pos.y-m_object->RetCharacter()->height <= level ) - { - if ( m_lastFlameParticule+m_engine->ParticuleAdapt(0.05f) <= aTime ) - { - m_lastFlameParticule = aTime; - - pos = m_object->RetPosition(0); - pos.x += (Rand()-0.5f)*3.0f; - pos.z += (Rand()-0.5f)*3.0f; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = Rand()*5.0f+3.0f; - dim.x = Rand()*2.0f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFLAME, 2.0f, 0.0f, 0.2f); - - pos = m_object->RetPosition(0); - pos.y -= 2.0f; - pos.x += (Rand()-0.5f)*5.0f; - pos.z += (Rand()-0.5f)*5.0f; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 6.0f+Rand()*6.0f+6.0f; - dim.x = Rand()*1.5f+1.0f+3.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); - } - } - - pos = m_object->RetPosition(0); - if ( pos.y >= m_water->RetLevel(m_object) ) return; // out of water? - - type = m_object->RetType(); - if ( type == OBJECT_TOTO ) return; - if ( type == OBJECT_NULL ) return; - - if ( !m_object->RetActif() ) return; - if ( m_object->RetResetBusy() ) return; // reset in progress? - - if ( m_water->RetLava() || - (type == OBJECT_HUMAN && - m_object->RetOption() != 0 ) || // human without a helmet? - type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs || - type == OBJECT_MOBILEft || - type == OBJECT_MOBILEtt || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEit || - type == OBJECT_MOBILEdr || - type == OBJECT_APOLLO2 ) // vehicle not underwater? - { - m_object->ExploObject(EXPLO_WATER, 1.0f); // starts explosion - } -} - -// Sounds the engine at full power. - -void CPhysics::SoundMotorFull(float rTime, ObjectType type) -{ - Sound sound; - float amplitude, time, freq; - - if ( type == OBJECT_MOBILEia || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEis ) - { - if ( m_soundChannel == -1 ) - { - m_soundChannel = m_sound->Play(SOUND_MOTORi, m_object->RetPosition(0), 0.0f, 1.0f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 0.2f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 1.0f, SOPER_LOOP); - } - else - { - m_sound->Position(m_soundChannel, m_object->RetPosition(0)); - } - - freq = 1.0f+m_linMotion.terrainSpeed.x/50.0f; - if ( m_linMotion.realSpeed.x == 0.0f ) - { - freq -= Abs(m_cirMotion.realSpeed.y/3.0f); - } - else - { - freq -= Abs(m_cirMotion.realSpeed.y/4.0f); - } - m_sound->Frequency(m_soundChannel, freq); - - return; - } - - if ( type == OBJECT_MOBILEsa ) - { - sound = SOUND_MOTORs; - amplitude = 0.6f; - time = 0.5f; - } - else if ( type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs ) - { - sound = SOUND_MOTORr; - amplitude = 1.0f; - time = 0.7f; - } - else if ( type == OBJECT_MOBILEta || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEts ) - { - sound = SOUND_MOTORt; - amplitude = 1.0f; - time = 0.5f; - } - else if ( type == OBJECT_APOLLO2 ) - { - sound = SOUND_MANIP; - amplitude = 1.0f; - time = 0.5f; - } - else - { - sound = SOUND_MOTORw; - amplitude = 0.7f; - time = 0.3f; - } - - if ( m_object->RetToy() ) - { - sound = SOUND_MOTORd; - amplitude = 1.0f; - time = 0.1f; - } - - freq = 0.75f+(Abs(m_motorSpeed.x)+Abs(m_motorSpeed.z))*0.25f; - if ( freq > 1.0f ) freq = 1.0f; - if ( m_object->RetToy() ) freq = 1.0f; - - if ( m_soundChannel == -1 ) - { - m_soundChannel = m_sound->Play(sound, m_object->RetPosition(0), 0.0f, 0.5f, TRUE); - m_sound->AddEnvelope(m_soundChannel, amplitude, freq, time, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, amplitude, freq, 1.0f, SOPER_LOOP); - } - else - { - m_sound->Position(m_soundChannel, m_object->RetPosition(0)); - - if ( m_bSoundSlow ) // in slow motion? - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, amplitude, freq, time, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, amplitude, freq, 1.0f, SOPER_LOOP); - m_bSoundSlow = FALSE; - } - } - - freq *= 1.0f + m_linMotion.terrainSpeed.x/100.0f; - freq *= 1.0f + Abs(m_cirMotion.realSpeed.y/20.0f); - m_sound->Frequency(m_soundChannel, freq); - - m_soundTimePshhh -= rTime*2.0f; -} - -// Sounds the engine idling. - -void CPhysics::SoundMotorSlow(float rTime, ObjectType type) -{ - D3DMATRIX* mat; - D3DVECTOR pos, speed; - FPOINT dim; - Sound sound; - float amplitude; - int i, max; - - if ( type == OBJECT_MOBILEia || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEis ) - { - if ( m_soundChannel != -1 ) // engine is running? - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 0.3f, SOPER_STOP); - m_soundChannel = -1; - } - return; - } - - if ( type == OBJECT_MOBILEsa ) - { - sound = SOUND_MOTORs; - amplitude = 0.4f; - } - else if ( type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs ) - { - sound = SOUND_MOTORr; - amplitude = 0.9f; - } - else if ( type == OBJECT_MOBILEta || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEts ) - { - sound = SOUND_MOTORt; - amplitude = 0.7f; - } - else if ( type == OBJECT_APOLLO2 ) - { - if ( m_soundChannel != -1 ) // engine is running? - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.3f, SOPER_STOP); - m_soundChannel = -1; - } - return; - } - else - { - sound = SOUND_MOTORw; - amplitude = 0.3f; - } - - if ( m_object->RetToy() ) - { - sound = SOUND_MOTORd; - amplitude = 0.0f; - } - - if ( m_soundChannel == -1 ) - { - m_soundChannel = m_sound->Play(sound, m_object->RetPosition(0), 0.0f, 0.25f, TRUE); - m_sound->AddEnvelope(m_soundChannel, amplitude, 0.5f, 0.2f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, amplitude, 0.5f, 1.0f, SOPER_LOOP); - } - else - { - m_sound->Position(m_soundChannel, m_object->RetPosition(0)); - - if ( !m_bSoundSlow ) // full power? - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, amplitude, 0.5f, 0.3f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, amplitude, 0.5f, 1.0f, SOPER_LOOP); - m_bSoundSlow = TRUE; - } - } - - if ( type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs ) - { - m_soundTimePshhh -= rTime; - - if ( m_soundTimePshhh <= 0.0f ) - { - amplitude = 0.5f-m_soundTimePshhh*0.08f; - if ( amplitude > 1.0f ) amplitude = 1.0f; -//? m_sound->Play(SOUND_PSHHH, m_object->RetPosition(0), amplitude); - m_sound->Play(SOUND_PSHHH, m_object->RetPosition(0), 1.0f); - - m_soundTimePshhh = 4.0f+4.0f*Rand(); - - max = (int)(10.0f*m_engine->RetParticuleDensity()); - for ( i=0 ; iRetWorldMatrix(0); - pos = Transform(*mat, pos); - speed = Transform(*mat, speed)-pos; - - dim.x = Rand()*1.0f+1.0f; - dim.y = dim.x; - - m_particule->CreateParticule(pos, speed, dim, PARTIMOTOR, 2.0f); - } - } - } -} - -// Sounds the engine not running. - -void CPhysics::SoundMotorStop(float rTime, ObjectType type) -{ - if ( type == OBJECT_MOBILEia || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEis ) - { - if ( m_soundChannel != -1 ) // engine is running? - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 0.3f, SOPER_STOP); - m_soundChannel = -1; - } - return; - } - - if ( m_soundChannel != -1 ) // engine is running? - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.3f, SOPER_STOP); - m_soundChannel = -1; - } - - m_soundTimePshhh -= rTime*2.0f; -} - -// Sounds the reactor at full power. - -void CPhysics::SoundReactorFull(float rTime, ObjectType type) -{ - Sound sound; - D3DMATRIX* mat; - D3DVECTOR pos, speed; - FPOINT dim; - float freq; - int i; - - if ( m_soundChannelSlide != -1 ) // slides? - { - m_sound->FlushEnvelope(m_soundChannelSlide); - m_sound->AddEnvelope(m_soundChannelSlide, 0.0f, 1.0f, 0.3f, SOPER_STOP); - m_soundChannelSlide = -1; - } - - if ( m_reactorRange > 0.0f ) - { - if ( m_soundChannel == -1 ) - { - if ( type == OBJECT_HUMAN || - type == OBJECT_TECH ) - { - sound = SOUND_FLYh; - } - else - { - sound = SOUND_FLY; - } - - m_soundChannel = m_sound->Play(sound, m_object->RetPosition(0), 0.0f, 1.0f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 0.6f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 1.0f, SOPER_LOOP); - } - else - { - m_sound->Position(m_soundChannel, m_object->RetPosition(0)); - } - - freq = 1.0f + m_linMotion.realSpeed.y/100.0f; - freq *= 1.0f + Abs(m_cirMotion.realSpeed.y/5.0f); - m_sound->Frequency(m_soundChannel, freq); - } - else - { - if ( m_soundChannel != -1 ) // engine is running? - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } - - if ( m_timeReactorFail <= m_time ) - { - freq = 1.0f+Rand()*0.5f; - m_sound->Play(SOUND_FLYf, m_object->RetPosition(0), 1.0f, freq); - m_camera->StartEffect(CE_PET, m_object->RetPosition(0), 1.0f); - - for ( i=0 ; i<5 ; i++ ) - { - if ( m_object->RetType() == OBJECT_HUMAN || - m_object->RetType() == OBJECT_TECH ) - { - pos = D3DVECTOR(-1.6f, -0.5f, 0.0f); - } - else - { - pos = D3DVECTOR(0.0f, -1.0f, 0.0f); - } - pos.x += (Rand()-0.5f)*2.0f; - pos.z += (Rand()-0.5f)*2.0f; - mat = m_object->RetWorldMatrix(0); - pos = Transform(*mat, pos); - speed.x = (Rand()-0.5f)*5.0f; - speed.z = (Rand()-0.5f)*5.0f; - speed.y = -(4.0f+Rand()*4.0f); - dim.x = (2.0f+Rand()*1.0f); - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 2.0f, 0.0f, 0.1f); - } - - m_timeReactorFail = m_time+0.10f+Rand()*0.30f; - } - else - { - if ( m_object->RetType() == OBJECT_HUMAN || - m_object->RetType() == OBJECT_TECH ) - { - pos = D3DVECTOR(-1.6f, -0.5f, 0.0f); - } - else - { - pos = D3DVECTOR(0.0f, -1.0f, 0.0f); - } - pos.x += (Rand()-0.5f)*1.0f; - pos.z += (Rand()-0.5f)*1.0f; - mat = m_object->RetWorldMatrix(0); - pos = Transform(*mat, pos); - speed.x = (Rand()-0.5f)*2.0f; - speed.z = (Rand()-0.5f)*2.0f; - speed.y = -(4.0f+Rand()*4.0f); - dim.x = (0.7f+Rand()*0.4f); - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 2.0f, 0.0f, 0.1f); - } - } - -} - -// Sounds the reactor stopped. - -void CPhysics::SoundReactorStop(float rTime, ObjectType type) -{ - CObject* power; - float energy; - - energy = 0.0f; - power = m_object->RetPower(); - if ( power != 0 ) - { - energy = power->RetEnergy(); - } - - if ( m_soundChannel != -1 ) // engine is running? - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } - - if ( type == OBJECT_HUMAN || - type == OBJECT_TECH ) - { - if ( m_soundChannelSlide != -1 ) // slides? - { - m_sound->FlushEnvelope(m_soundChannelSlide); - m_sound->AddEnvelope(m_soundChannelSlide, 0.0f, 1.0f, 0.3f, SOPER_STOP); - m_soundChannelSlide = -1; - } - } - else - { - if ( energy != 0.0f && - (m_motorSpeed.x != 0.0f || // slides with small reactors in skates? - m_cirMotion.realSpeed.y != 0.0f) ) - { - if ( m_soundChannelSlide == -1 ) - { - m_soundChannelSlide = m_sound->Play(SOUND_SLIDE, m_object->RetPosition(0), 0.0f, 1.0f, TRUE); - m_sound->AddEnvelope(m_soundChannelSlide, 0.5f, 1.0f, 0.3f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannelSlide, 0.5f, 1.0f, 1.0f, SOPER_LOOP); - } - m_sound->Position(m_soundChannelSlide, m_object->RetPosition(0)); - } - else - { - if ( m_soundChannelSlide != -1 ) // slides? - { - m_sound->FlushEnvelope(m_soundChannelSlide); - m_sound->AddEnvelope(m_soundChannelSlide, 0.0f, 1.0f, 0.3f, SOPER_STOP); - m_soundChannelSlide = -1; - } - } - } -} - - -// Adapts the physics of the object based on the ground. - -void CPhysics::FloorAdapt(float aTime, float rTime, - D3DVECTOR &pos, D3DVECTOR &angle) -{ - Character* character; - ObjectType type; - D3DVECTOR norm; - D3DMATRIX matRotate; - float level, h, f, a1, volume, freq, force; - BOOL bOldSwim, bSlopingTerrain; - - type = m_object->RetType(); - character = m_object->RetCharacter(); - - level = m_water->RetLevel(m_object); - bOldSwim = m_bSwim; - SetSwim( pos.y < level ); - - m_floorLevel = m_terrain->RetFloorLevel(pos); // height above the ground - h = pos.y-m_floorLevel; - h -= character->height; - m_floorHeight = h; - - WaterParticule(aTime, pos, type, m_floorLevel, - Abs(m_linMotion.realSpeed.x), - Abs(m_cirMotion.realSpeed.y*15.0f)); - - if ( m_type == TYPE_ROLLING ) - { - pos.y -= h; // plate to the ground immediately - pos.y += character->height; - m_floorHeight = 0.0f; - } - - if ( m_type == TYPE_FLYING ) - { - bSlopingTerrain = FALSE; // ground as possible to land - - if ( !m_bLand ) // in flight? - { - m_terrain->GetNormal(norm, pos); - a1 = Abs(RotateAngle(Length(norm.x, norm.z), norm.y)); - if ( a1 < (90.0f-55.0f)*PI/180.0f ) // slope exceeds 55 degrees? - { - bSlopingTerrain = TRUE; // very sloped ground - - if ( h < 4.0f ) // collision with the ground? - { - force = 5.0f+Abs(m_linMotion.realSpeed.x*0.3f)+ - Abs(m_linMotion.realSpeed.y*0.3f); - m_linMotion.currentSpeed = norm*force; - MatRotateXZY(matRotate, -angle); - m_linMotion.currentSpeed = Transform(matRotate, m_linMotion.currentSpeed); - - if ( aTime-m_soundTimeBoum > 0.5f ) - { - volume = Abs(m_linMotion.realSpeed.x*0.02f)+ - Abs(m_linMotion.realSpeed.y*0.02f); - freq = 0.5f+m_terrain->RetHardness(pos)*2.5f; - m_sound->Play(SOUND_BOUM, pos, volume, freq); - - m_soundTimeBoum = aTime; - } - -//? pos = m_object->RetPosition(0); // gives position before collision - } - } - } - - if ( (h <= 0.0f || m_bLand) && !bSlopingTerrain ) // on the ground? - { - if ( !m_bLand ) // in flight? - { - volume = Abs(m_linMotion.realSpeed.y*0.02f); - freq = 0.5f+m_terrain->RetHardness(pos)*2.5f; - m_sound->Play(SOUND_BOUM, pos, volume, freq); - } - - m_bLand = TRUE; // on the ground? - SetMotor(FALSE); - pos.y -= h; // plate to the ground immediately - m_floorHeight = 0.0f; - - if ( h < 0.0f ) - { - f = Abs(m_linMotion.currentSpeed.y/m_linMotion.advanceSpeed.y); - CrashParticule(f); - } - m_linMotion.currentSpeed.y = 0.0f; - m_inclinaisonFactor = 1.0f/LANDING_SPEED; // slips a little to the ground - m_linVibrationFactor = 0.0f; - m_cirVibrationFactor = 0.0f; - - if ( type == OBJECT_HUMAN || - type == OBJECT_TECH ) return; // always right - } - - if ( h > 4.0f || bSlopingTerrain ) // meters above the ground? - { - if ( m_bSwim ) - { - m_linVibrationFactor = 1.0f; // vibrates a max - m_cirVibrationFactor = 1.0f; - } - else - { - m_linVibrationFactor = 2.0f; // vibrates a large max - m_cirVibrationFactor = 2.0f; - } - m_inclinaisonFactor = 1.0f; - - // Gives gently the horizontal. - if ( angle.x > 0.0f ) - { - angle.x -= rTime*0.5f; - if ( angle.x < 0.0f ) angle.x = 0.0f; - } - if ( angle.x < 0.0f ) - { - angle.x += rTime*0.5f; - if ( angle.x > 0.0f ) angle.x = 0.0f; - } - if ( angle.z > 0.0f ) - { - angle.z -= rTime*0.5f; - if ( angle.z < 0.0f ) angle.z = 0.0f; - } - if ( angle.z < 0.0f ) - { - angle.z += rTime*0.5f; - if ( angle.z > 0.0f ) angle.z = 0.0f; - } - return; - } - } - - if ( m_floorHeight == 0.0f ) // ground plate? - { - if ( m_object->RetTraceDown() ) - { - WheelParticule(m_object->RetTraceColor(), m_object->RetTraceWidth()*g_unit); - } - else - { - WheelParticule(-1, 0.0f); - } - } - - if ( type == OBJECT_HUMAN || - type == OBJECT_TECH || - type == OBJECT_WORM ) return; // always right - - FloorAngle(pos, angle); // adjusts the angle at the ground - - if ( m_type == TYPE_FLYING && !m_bLand ) // flying in the air? - { - f = h/1.0f; - if ( f < 0.0f ) f = 0.0f; - if ( f > 1.0f ) f = 1.0f; - m_linVibrationFactor = f; - m_cirVibrationFactor = f; - angle.z *= 1.0f-f; - angle.x *= 1.0f-f; - - f = h/1.0f; - if ( f < 0.0f ) f = 0.0f; - if ( f > 1.0f ) f = 1.0f; - m_inclinaisonFactor = f; - } -} - -// Calculates the angle of an object with the field. - -void CPhysics::FloorAngle(const D3DVECTOR &pos, D3DVECTOR &angle) -{ - Character* character; - D3DVECTOR pw, norm; - float a1, a2; - - character = m_object->RetCharacter(); - - pw.x = pos.x+character->wheelFront*cosf(angle.y+PI*0.0f); - pw.y = pos.y; - pw.z = pos.z-character->wheelFront*sinf(angle.y+PI*0.0f); - a1 = atanf(m_terrain->RetFloorHeight(pw)/character->wheelFront); - - pw.x = pos.x+character->wheelBack*cosf(angle.y+PI*1.0f); - pw.y = pos.y; - pw.z = pos.z-character->wheelBack*sinf(angle.y+PI*1.0f); - a2 = atanf(m_terrain->RetFloorHeight(pw)/character->wheelBack); - - angle.z = (a2-a1)/2.0f; - - pw.x = pos.x+character->wheelLeft*cosf(angle.y+PI*0.5f)*cosf(angle.z); - pw.y = pos.y; - pw.z = pos.z-character->wheelLeft*sinf(angle.y+PI*0.5f)*cosf(angle.z); - a1 = atanf(m_terrain->RetFloorHeight(pw)/character->wheelLeft); - - pw.x = pos.x+character->wheelRight*cosf(angle.y+PI*1.5f)*cosf(angle.z); - pw.y = pos.y; - pw.z = pos.z-character->wheelRight*sinf(angle.y+PI*1.5f)*cosf(angle.z); - a2 = atanf(m_terrain->RetFloorHeight(pw)/character->wheelRight); - - angle.x = (a2-a1)/2.0f; -} - - -// Adapts the physics of the object in relation to other objects. -// Returns 0 -> mobile object -// Returns 1 -> immobile object (because collision) -// Returns 2 -> destroyed object - -int CPhysics::ObjectAdapt(const D3DVECTOR &pos, const D3DVECTOR &angle) -{ - CObject* pObj; - CPyro* pyro; - CPhysics* ph; - D3DMATRIX matRotate; - D3DVECTOR iPos, oPos, iiPos, oAngle, oSpeed; - Sound sound; - float iRad, oRad, distance, force, volume; - int i, j, colType; - ObjectType iType, oType; - - if ( m_object->RetRuin() ) return 0; // is burning or exploding? - if ( !m_object->RetClip() ) return 0; - - // iiPos = sphere center is the old position. - // iPos = sphere center has the new position. - m_object->GetCrashSphere(0, iiPos, iRad); - iPos = iiPos + (pos - m_object->RetPosition(0)); - iType = m_object->RetType(); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj == m_object ) continue; // yourself? - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( !pObj->RetEnable() ) continue; // inactive? - if ( pObj->RetRuin() ) continue; // is burning or exploding? - if ( pObj->RetDead() ) continue; // dead man? - - oType = pObj->RetType(); - if ( oType == OBJECT_NULL ) continue; - if ( oType == OBJECT_TOTO ) continue; -//? if ( iType == OBJECT_BEE && oType == OBJECT_BEE ) continue; - if ( iType == OBJECT_WORM && oType != OBJECT_WORM ) continue; - if ( iType != OBJECT_WORM && oType == OBJECT_WORM ) continue; - if ( iType == OBJECT_MOTHER && oType == OBJECT_ANT ) continue; - if ( iType == OBJECT_ANT && oType == OBJECT_MOTHER ) continue; - if ( iType == OBJECT_MOTHER && oType == OBJECT_SPIDER ) continue; - if ( iType == OBJECT_SPIDER && oType == OBJECT_MOTHER ) continue; - if ( iType == OBJECT_MOTHER && oType == OBJECT_EGG ) continue; - if ( iType == OBJECT_EGG && oType == OBJECT_MOTHER ) continue; - - pObj->GetJotlerSphere(oPos, oRad); - if ( oRad > 0.0f ) - { - JostleObject(pObj, iPos, iRad, oPos, oRad); - } - - if ( iType == OBJECT_MOTHER || - iType == OBJECT_ANT || - iType == OBJECT_SPIDER || - iType == OBJECT_WORM || - iType == OBJECT_BEE ) // insect? - { - if ( oType == OBJECT_STONE || - oType == OBJECT_URANIUM || - oType == OBJECT_METAL || - oType == OBJECT_POWER || - oType == OBJECT_ATOMIC || - oType == OBJECT_BULLET || - oType == OBJECT_BBOX || - oType == OBJECT_KEYa || - oType == OBJECT_KEYb || - oType == OBJECT_KEYc || - oType == OBJECT_KEYd || - oType == OBJECT_TNT || - (oType >= OBJECT_PLANT0 && oType <= OBJECT_PLANT19 ) || - (oType >= OBJECT_MUSHROOM0 && oType <= OBJECT_MUSHROOM9) ) continue; - } - -#if _TEEN - if ( oType == OBJECT_WAYPOINT && - pObj->RetEnable() && - !m_object->RetResetBusy() ) // driving vehicle? -#else - if ( oType == OBJECT_WAYPOINT && - pObj->RetEnable() && - !m_object->RetResetBusy() && - m_object->RetTrainer() ) // driving vehicle? -#endif - { - oPos = pObj->RetPosition(0); - distance = Length2d(oPos, iPos); - if ( distance < 4.0f ) - { - m_sound->Play(SOUND_WAYPOINT, m_object->RetPosition(0)); - pyro = new CPyro(m_iMan); - pyro->Create(PT_WPCHECK, pObj); - } - } - - if ( oType == OBJECT_TARGET2 ) - { - oPos = pObj->RetPosition(0); - distance = Length(oPos, iPos); - if ( distance < 10.0f*1.5f ) - { - m_sound->Play(SOUND_WAYPOINT, m_object->RetPosition(0)); - pyro = new CPyro(m_iMan); - pyro->Create(PT_WPCHECK, pObj); - } - } - - j = 0; - while ( pObj->GetCrashSphere(j++, oPos, oRad) ) - { - if ( iType == OBJECT_MOTHER && oRad <= 1.2f ) continue; - if ( iType == OBJECT_ANT && oRad <= 1.2f ) continue; - if ( iType == OBJECT_SPIDER && oRad <= 1.2f ) continue; - if ( iType == OBJECT_BEE && oRad <= 1.2f ) continue; - if ( iType == OBJECT_WORM && oRad <= 1.2f ) continue; - - distance = Length(oPos, iPos); - if ( distance < iRad+oRad ) // collision? - { - distance = Length(oPos, iiPos); - if ( distance >= iRad+oRad ) // view (*) - { - m_bCollision = TRUE; - m_bObstacle = TRUE; - - sound = pObj->RetCrashSphereSound(j-1); - if ( sound != SOUND_CLICK ) - { - force = Abs(m_linMotion.realSpeed.x); - force *= pObj->RetCrashSphereHardness(j-1)*2.0f; - if ( ExploOther(iType, pObj, oType, force) ) continue; - colType = ExploHimself(iType, oType, force); - if ( colType == 2 ) return 2; // destroyed? - if ( colType == 0 ) continue; // ignores? - } - - force = Length(m_linMotion.realSpeed); - force *= pObj->RetCrashSphereHardness(j-1); - volume = Abs(force*0.05f); - if ( volume > 1.0f ) volume = 1.0f; - if ( sound != SOUND_CLICK ) - { - m_sound->Play(sound, m_object->RetPosition(0), volume); - } - if ( iType == OBJECT_HUMAN && volume > 0.5f ) - { - m_sound->Play(SOUND_AIE, m_object->RetPosition(0), volume); - } - - if ( m_repeatCollision > 0 ) - { - force *= 0.5f*m_repeatCollision; - if ( force > 20.0f ) force = 20.0f; - } - m_repeatCollision += 2; - if ( m_repeatCollision > 10 ) - { - m_repeatCollision = 10; - } - - m_linMotion.currentSpeed = Normalize(iPos-oPos)*force; - MatRotateXZY(matRotate, -angle); - m_linMotion.currentSpeed = Transform(matRotate, m_linMotion.currentSpeed); - if ( m_type == TYPE_ROLLING ) - { - m_linMotion.currentSpeed.y = 0.0f; - } - - ph = pObj->RetPhysics(); - if ( ph != 0 ) - { - oAngle = pObj->RetAngle(0); - oSpeed = Normalize(oPos-iPos)*force; - MatRotateXZY(matRotate, -oAngle); - oSpeed = Transform(matRotate, oSpeed); - if ( ph->RetType() == TYPE_ROLLING ) - { - oSpeed.y = 0.0f; - } - ph->SetLinMotion(MO_CURSPEED, oSpeed); - } - return 1; - } - } - } - } - - if ( m_repeatCollision > 0 ) - { - m_repeatCollision --; - } - return 0; -} - -// (*) Collision has the initial position (iiPos) and the new position (iPos), -// the obstacle is not known. We can therefore pass through. -// This is necessary when barriers found "in" a vehicle, not to block it definitely! - - -// Shakes an object. - -BOOL CPhysics::JostleObject(CObject* pObj, D3DVECTOR iPos, float iRad, - D3DVECTOR oPos, float oRad) -{ - D3DVECTOR speed; - float distance, force, d, f; - - distance = Length(oPos, iPos); - if ( distance >= iRad+oRad ) return FALSE; - - d = (iRad+oRad)/2.0f; - f = (distance-d)/d; // 0 = off, 1 = near - if ( f < 0.0f ) f = 0.0f; - if ( f > 1.0f ) f = 1.0f; - - speed = m_linMotion.realSpeed; - speed.y = 0.0f; - force = Length(speed)*f*0.05f; - if ( force > 1.0f ) force = 1.0f; - - if ( m_soundTimeJostle >= 0.20f ) - { - m_soundTimeJostle = 0.0f; - m_sound->Play(SOUND_JOSTLE, iPos, force); - } - - return pObj->JostleObject(force); -} - -// Shakes forcing an object. - -BOOL CPhysics::JostleObject(CObject* pObj, float force) -{ - D3DVECTOR oPos; - float oRad; - - pObj->GetJotlerSphere(oPos, oRad); - if ( oRad <= 0.0f ) return FALSE; - - if ( m_soundTimeJostle >= 0.20f ) - { - m_soundTimeJostle = 0.0f; - m_sound->Play(SOUND_JOSTLE, pObj->RetPosition(0), force); - } - - return pObj->JostleObject(force); -} - -// Effects of the explosion on the object buffers. -// Returns TRUE if we ignore this obstacle. - -BOOL CPhysics::ExploOther(ObjectType iType, - CObject *pObj, ObjectType oType, float force) -{ - CPyro* pyro; - - if ( !pObj->RetEnable() ) return TRUE; - - JostleObject(pObj, 1.0f); // shakes the object - - if ( force > 50.0f && - (oType == OBJECT_FRET || - oType == OBJECT_METAL ) ) - { - pyro = new CPyro(m_iMan); - pyro->Create(PT_EXPLOT, pObj); // total destruction - } - - if ( force > 50.0f && - (oType == OBJECT_POWER || - oType == OBJECT_ATOMIC ) ) - { - pyro = new CPyro(m_iMan); - pyro->Create(PT_FRAGT, pObj); // total destruction - } - - if ( force > 25.0f && - (oType == OBJECT_STONE || - oType == OBJECT_URANIUM ) ) - { - pyro = new CPyro(m_iMan); - pyro->Create(PT_FRAGT, pObj); // total destruction - } - - if ( force > 25.0f && - (oType == OBJECT_DERRICK || - oType == OBJECT_FACTORY || - oType == OBJECT_STATION || - oType == OBJECT_CONVERT || - oType == OBJECT_REPAIR || - oType == OBJECT_DESTROYER|| - oType == OBJECT_TOWER || - oType == OBJECT_RESEARCH || - oType == OBJECT_RADAR || - oType == OBJECT_INFO || - oType == OBJECT_ENERGY || - oType == OBJECT_LABO || - oType == OBJECT_NUCLEAR || - oType == OBJECT_PARA || - oType == OBJECT_SAFE || - oType == OBJECT_HUSTON ) ) // building? - { - pObj->ExploObject(EXPLO_BOUM, force/400.0f); - } - - if ( force > 25.0f && - (oType == OBJECT_MOBILEwa || - oType == OBJECT_MOBILEta || - oType == OBJECT_MOBILEfa || - oType == OBJECT_MOBILEia || - oType == OBJECT_MOBILEwc || - oType == OBJECT_MOBILEtc || - oType == OBJECT_MOBILEfc || - oType == OBJECT_MOBILEic || - oType == OBJECT_MOBILEwi || - oType == OBJECT_MOBILEti || - oType == OBJECT_MOBILEfi || - oType == OBJECT_MOBILEii || - oType == OBJECT_MOBILEws || - oType == OBJECT_MOBILEts || - oType == OBJECT_MOBILEfs || - oType == OBJECT_MOBILEis || - oType == OBJECT_MOBILErt || - oType == OBJECT_MOBILErc || - oType == OBJECT_MOBILErr || - oType == OBJECT_MOBILErs || - oType == OBJECT_MOBILEsa || - oType == OBJECT_MOBILEwt || - oType == OBJECT_MOBILEtt || - oType == OBJECT_MOBILEft || - oType == OBJECT_MOBILEit || - oType == OBJECT_MOBILEdr || - oType == OBJECT_APOLLO2 ) ) // vehicle? - { - pObj->ExploObject(EXPLO_BOUM, force/200.0f); - } - - if ( force > 10.0f && - (oType == OBJECT_MOBILEtg || - oType == OBJECT_TNT ) ) - { - pyro = new CPyro(m_iMan); - pyro->Create(PT_FRAGT, pObj); // total destruction - } - - if ( force > 0.0f && - oType == OBJECT_BOMB ) - { - pyro = new CPyro(m_iMan); - pyro->Create(PT_FRAGT, pObj); // total destruction - } - - return FALSE; -} - -// Effects of the explosion on the object itself. -// Returns 0 -> mobile object -// Returns 1 -> immobile object -// Returns 2 -> object destroyed - -int CPhysics::ExploHimself(ObjectType iType, ObjectType oType, float force) -{ - PyroType type; - CPyro* pyro; - - if ( force > 10.0f && - (oType == OBJECT_TNT || - oType == OBJECT_MOBILEtg ) ) - { - if ( iType == OBJECT_HUMAN ) type = PT_DEADG; - else type = PT_EXPLOT; - pyro = new CPyro(m_iMan); - pyro->Create(type, m_object); // total destruction - return 2; - } - - if ( force > 0.0f && - oType == OBJECT_BOMB ) - { - if ( iType == OBJECT_HUMAN ) - { - type = PT_DEADG; - } - else if ( iType == OBJECT_ANT || - iType == OBJECT_SPIDER || - iType == OBJECT_BEE ) - { - type = PT_EXPLOO; - } - else - { - type = PT_EXPLOT; - } - pyro = new CPyro(m_iMan); - pyro->Create(type, m_object); // total destruction - return 2; - } - - if ( force > 25.0f && - (iType == OBJECT_HUMAN || - iType == OBJECT_MOBILEwa || - iType == OBJECT_MOBILEta || - iType == OBJECT_MOBILEfa || - iType == OBJECT_MOBILEia || - iType == OBJECT_MOBILEwc || - iType == OBJECT_MOBILEtc || - iType == OBJECT_MOBILEfc || - iType == OBJECT_MOBILEic || - iType == OBJECT_MOBILEwi || - iType == OBJECT_MOBILEti || - iType == OBJECT_MOBILEfi || - iType == OBJECT_MOBILEii || - iType == OBJECT_MOBILEws || - iType == OBJECT_MOBILEts || - iType == OBJECT_MOBILEfs || - iType == OBJECT_MOBILEis || - iType == OBJECT_MOBILErt || - iType == OBJECT_MOBILErc || - iType == OBJECT_MOBILErr || - iType == OBJECT_MOBILErs || - iType == OBJECT_MOBILEsa || - iType == OBJECT_MOBILEwt || - iType == OBJECT_MOBILEtt || - iType == OBJECT_MOBILEft || - iType == OBJECT_MOBILEit || - iType == OBJECT_MOBILEdr || - iType == OBJECT_APOLLO2 ) ) // vehicle? - { - if ( oType == OBJECT_DERRICK || - oType == OBJECT_FACTORY || - oType == OBJECT_STATION || - oType == OBJECT_CONVERT || - oType == OBJECT_REPAIR || - oType == OBJECT_DESTROYER|| - oType == OBJECT_TOWER || - oType == OBJECT_RESEARCH || - oType == OBJECT_RADAR || - oType == OBJECT_INFO || - oType == OBJECT_ENERGY || - oType == OBJECT_LABO || - oType == OBJECT_NUCLEAR || - oType == OBJECT_PARA || - oType == OBJECT_SAFE || - oType == OBJECT_HUSTON ) // building? - { - force /= 200.0f; - } - else - if ( oType == OBJECT_MOTHER || - oType == OBJECT_ANT || - oType == OBJECT_SPIDER || - oType == OBJECT_BEE || - oType == OBJECT_WORM ) // insect? - { - force /= 400.0f; - } - else - if ( oType == OBJECT_FRET || - oType == OBJECT_STONE || - oType == OBJECT_METAL ) - { - force /= 500.0f; - } - else - if ( oType == OBJECT_URANIUM || - oType == OBJECT_POWER || - oType == OBJECT_ATOMIC ) - { - force /= 100.0f; - } - else - { - force /= 200.0f; - } - - if ( m_object->ExploObject(EXPLO_BOUM, force) ) return 2; - } - - return 1; -} - - - -// Makes the particles evolve. - -void CPhysics::FrameParticule(float aTime, float rTime) -{ - D3DVECTOR pos; - CObject* power; - float energy, intensity; - int effectLight; - BOOL bFlash; - - m_restBreakParticule -= rTime; - if ( aTime-m_lastPowerParticule < m_engine->ParticuleAdapt(0.05f) ) return; - m_lastPowerParticule = aTime; - - bFlash = FALSE; - - energy = 0.0f; - power = m_object->RetPower(); - if ( power != 0 ) - { - energy = power->RetEnergy(); - } - - if ( energy != m_lastEnergy ) // change the energy level? - { - if ( energy > m_lastEnergy ) // recharge? - { - PowerParticule(1.0f, FALSE); - bFlash = TRUE; - } - - if ( energy == 0.0f || m_lastEnergy == 0.0f ) - { - m_restBreakParticule = 2.5f; // particles for 2.5s - } - - m_lastEnergy = energy; - } - - if ( m_restBreakParticule > 0.0f ) - { - PowerParticule(m_restBreakParticule/2.5f, (energy == 0)); - bFlash = TRUE; - } - - effectLight = m_object->RetEffectLight(); - if ( effectLight != -1 ) - { - if ( bFlash ) - { - intensity = 0.0f; - if ( Rand() < 0.5f ) intensity = 1.0f; - m_light->SetLightIntensity(effectLight, intensity); - m_light->SetLightIntensitySpeed(effectLight, 10000.0f); - } - else - { - m_light->SetLightIntensity(effectLight, 0.0f); - } - } -} - -// Generates some particles after a recharge. - -void CPhysics::PowerParticule(float factor, BOOL bBreak) -{ - Character* character; - CObject* fret; - D3DMATRIX* mat; - D3DVECTOR pos, ppos, eye, speed; - FPOINT dim; - BOOL bCarryPower; - - bCarryPower = FALSE; - fret = m_object->RetFret(); - if ( fret != 0 && fret->RetType() == OBJECT_POWER && - m_object->RetAngleZ(1) == ARM_STOCK_ANGLE1 ) - { - bCarryPower = TRUE; // carries a battery - } - - mat = m_object->RetWorldMatrix(0); - character = m_object->RetCharacter(); - - pos = character->posPower; - pos.x -= 0.3f; - pos.y += 1.0f; // battery center position - pos = Transform(*mat, pos); - - speed.x = (Rand()-0.5f)*12.0f; - speed.y = (Rand()-0.5f)*12.0f; - speed.z = (Rand()-0.5f)*12.0f; - - ppos.x = pos.x; - ppos.y = pos.y+(Rand()-0.5f)*2.0f; - ppos.z = pos.z; - - dim.x = 1.0f*factor; - dim.y = 1.0f*factor; - - m_particule->CreateParticule(ppos, speed, dim, PARTIBLITZ, 0.5f, 0.0f, 0.0f); - - if ( bCarryPower ) // carry a battery? - { - pos = D3DVECTOR(3.0f, 5.6f, 0.0f); // position of battery holder - pos = Transform(*mat, pos); - - speed.x = (Rand()-0.5f)*12.0f; - speed.y = (Rand()-0.5f)*12.0f; - speed.z = (Rand()-0.5f)*12.0f; - - ppos.x = pos.x; - ppos.y = pos.y; - ppos.z = pos.z+(Rand()-0.5f)*2.0f; - - dim.x = 1.0f*factor; - dim.y = 1.0f*factor; - - m_particule->CreateParticule(ppos, speed, dim, PARTIBLITZ, 0.5f, 0.0f, 0.0f); - } -} - -// Generates some particles after a fall. -// crash: 0=super soft, 1=big crash - -void CPhysics::CrashParticule(float crash) -{ - D3DVECTOR pos, ppos, speed; - FPOINT dim; - float len; - int i, max; - - if ( crash < 0.2f ) return; - - pos = m_object->RetPosition(0); - m_camera->StartEffect(CE_CRASH, pos, crash); - -//? max = (int)(crash*50.0f); - max = (int)(crash*10.0f*m_engine->RetParticuleDensity()); - - for ( i=0 ; iCreateParticule(ppos, speed, dim, PARTICRASH, 2.0f); - } -} - -// Generates some exhaust gas particle. - -void CPhysics::MotorParticule(float aTime, float rTime) -{ - D3DMATRIX* mat; - D3DVECTOR pos, speed; - FPOINT dim; - ObjectType type; - FPOINT c, p; - float h, a, delay, level; - int r, i, nb; - - if ( m_object->RetToy() ) return; - - type = m_object->RetType(); - - if ( type == OBJECT_MOBILEia || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEis || // legs? - type == OBJECT_MOBILEdr || - type == OBJECT_MOTHER || - type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_BEE || - type == OBJECT_WORM || - type == OBJECT_APOLLO2 ) return; - - if ( type == OBJECT_HUMAN ) delay = 3.0f; - else delay = 8.0f; - if ( m_bSwim && m_timeUnderWater < delay ) // bubbles when entering water? - { - if ( aTime-m_lastUnderParticule >= m_engine->ParticuleAdapt(0.05f) ) - { - m_lastUnderParticule = aTime; - - nb = (int)(20.0f-(20.0f/delay)*m_timeUnderWater); - for ( i=0 ; iRetPosition(0); - pos.x += (Rand()-0.5f)*4.0f; - pos.y += (Rand()-0.5f)*4.0f; - pos.z += (Rand()-0.5f)*4.0f; - speed.y = (Rand()-0.5f)*8.0f+8.0f; - speed.x = (Rand()-0.5f)*0.2f; - speed.z = (Rand()-0.5f)*0.2f; - dim.x = 0.06f+Rand()*0.10f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBUBBLE, 3.0f, 0.0f, 0.0f); - } - } - } - - level = m_water->RetLevel(); - pos = m_object->RetPosition(0); - if ( type == OBJECT_HUMAN ) pos.y -= 2.0f; - if ( pos.y < level ) // underwater? - { - m_absorbWater += rTime*(1.0f/2.0f); // gets wet - if ( m_absorbWater > 1.0f ) m_absorbWater = 1.0f; - } - else // out of water? - { - m_absorbWater -= rTime*(1.0f/3.0f); // to dry - if ( m_absorbWater < 0.0f ) m_absorbWater = 0.0f; - } - - if ( pos.y >= level && - m_absorbWater > 0.0f && - !m_water->RetLava() ) // drops on leaving the water? - { - if ( aTime-m_lastUnderParticule >= m_engine->ParticuleAdapt(0.05f) ) - { - m_lastUnderParticule = aTime; - - nb = (int)(8.0f*m_absorbWater); - for ( i=0 ; iRetPosition(0); - if ( type == OBJECT_HUMAN ) pos.y -= Rand()*2.0f; - else pos.y += Rand()*2.0f; - pos.x += (Rand()-0.5f)*2.0f; - pos.z += (Rand()-0.5f)*2.0f; - speed.y = -((Rand()-0.5f)*8.0f+8.0f); - speed.x = 0.0f; - speed.z = 0.0f; - dim.x = 0.2f; - dim.y = 0.2f; - m_particule->CreateParticule(pos, speed, dim, PARTIWATER, 2.0f, 0.0f, 1.0f); - } - } - } - - if ( type == OBJECT_HUMAN || // human? - type == OBJECT_TECH ) - { - if ( m_bLand && - aTime-m_lastSlideParticule >= m_engine->ParticuleAdapt(0.05f) ) - { - h = Max(Abs(m_linMotion.terrainSpeed.x), - Abs(m_linMotion.terrainSpeed.z)); - if ( h > m_linMotion.terrainSlide.x+0.5f && - m_linMotion.motorSpeed.x == 0.0f ) // slides a stop? - { - m_lastSlideParticule = aTime; - - mat = m_object->RetWorldMatrix(0); - pos.x = (Rand()-0.5f)*1.0f; - pos.y = -m_object->RetCharacter()->height; - pos.z = Rand()*0.4f+1.0f; - if ( rand()%2 == 0 ) pos.z = -pos.z; - pos = Transform(*mat, pos); - speed = D3DVECTOR(0.0f, 1.0f, 0.0f); - dim.x = Rand()*(h-5.0f)/2.0f+1.0f; - if ( dim.x > 2.5f ) dim.x = 2.5f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.2f); - } - } - } - - if ( type == OBJECT_MOBILEta || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEts ) // caterpillars? - { - if ( aTime-m_lastSlideParticule >= m_engine->ParticuleAdapt(0.05f) ) - { - h = Abs(m_linMotion.motorSpeed.x-m_linMotion.realSpeed.x); - if ( h > 5.0f ) - { - m_lastSlideParticule = aTime; - - mat = m_object->RetWorldMatrix(0); - pos.x = (Rand()-0.5f)*8.0f; - pos.y = 0.0f; - pos.z = Rand()*2.0f+3.0f; - if ( rand()%2 == 0 ) pos.z = -pos.z; - pos = Transform(*mat, pos); - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = Rand()*(h-5.0f)/2.0f+1.0f; - if ( dim.x > 3.0f ) dim.x = 3.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.2f); - } - } - } - - if ( type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs ) // large caterpillars? - { - if ( aTime-m_lastSlideParticule >= m_engine->ParticuleAdapt(0.05f) ) - { - h = Abs(m_linMotion.motorSpeed.x-m_linMotion.realSpeed.x); - if ( h > 5.0f ) - { - m_lastSlideParticule = aTime; - - mat = m_object->RetWorldMatrix(0); - pos.x = (Rand()-0.5f)*9.0f; - pos.y = 0.0f; - pos.z = Rand()*3.0f+3.0f; - if ( rand()%2 == 0 ) pos.z = -pos.z; - pos = Transform(*mat, pos); - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = Rand()*(h-5.0f)/2.0f+1.0f; - if ( dim.x > 3.0f ) dim.x = 3.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.2f); - } - } - } - - if ( (type == OBJECT_HUMAN || type == OBJECT_TECH) && !m_bSwim ) - { - if ( m_bLand ) // on the ground? - { - if ( m_reactorTemperature > 0.0f ) - { - m_reactorTemperature -= rTime*(1.0f/10.0f); // cooling - if ( m_reactorTemperature < 0.0f ) - { - m_reactorTemperature = 0.0f; - } - } - - if ( m_reactorTemperature == 0.0f || - aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.05f) ) return; - m_lastMotorParticule = aTime; - - pos = D3DVECTOR(-1.6f, -0.5f, 0.0f); - mat = m_object->RetWorldMatrix(0); - pos = Transform(*mat, pos); - - speed.x = (Rand()-0.5f)*0.6f; - speed.z = (Rand()-0.5f)*0.6f; - speed.y = -(0.5f+Rand()*0.3f)*(1.0f-m_reactorTemperature); - - dim.x = (1.0f+Rand()*0.5f)*(0.2f+m_reactorTemperature*0.8f); - dim.y = dim.x; - - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE2, 3.0f, 0.0f, 0.1f); - } - else // in flight? - { - if ( !m_bMotor || m_reactorRange == 0.0f ) return; - - if ( m_reactorTemperature < 1.0f ) // not too hot? - { - m_reactorTemperature += rTime*(1.0f/4.0f); // heating - if ( m_reactorTemperature > 1.0f ) - { - m_reactorTemperature = 1.0f; // but not too much - } - } - - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.02f) ) return; - m_lastMotorParticule = aTime; - - pos = D3DVECTOR(-1.6f, -1.0f, 0.0f); - pos.x += (Rand()-0.5f)*3.0f; - pos.y += (Rand()-0.5f)*1.5f; - pos.z += (Rand()-0.5f)*3.0f; - mat = m_object->RetWorldMatrix(0); - pos = Transform(*mat, pos); - - h = m_floorHeight; - if ( h > 10.0f ) // high enough? - { - speed = D3DVECTOR(0.0f, -10.0f, 0.0f); // against the bottom - } - else - { - speed.y = 10.0f-2.0f*h - Rand()*(10.0f-h); //against the top - speed.x = (Rand()-0.5f)*(5.0f-h)*1.0f; // horizontal (xz) - speed.z = (Rand()-0.5f)*(5.0f-h)*1.0f; - } - - dim.x = 0.12f; - dim.y = 0.12f; - - m_particule->CreateParticule(pos, speed, dim, PARTISCRAPS, 2.0f, 10.0f); - -#if 1 - pos = D3DVECTOR(-1.6f, -0.5f, 0.0f); - pos = Transform(*mat, pos); - - speed.x = (Rand()-0.5f)*1.0f; - speed.z = (Rand()-0.5f)*1.0f; - speed.y = -(4.0f+Rand()*3.0f); - speed.x += m_linMotion.realSpeed.x*0.8f; - speed.z -= m_linMotion.realSpeed.x*m_cirMotion.realSpeed.y*0.05f; - if ( m_linMotion.realSpeed.y > 0.0f ) - { - speed.y += m_linMotion.realSpeed.y*0.5f; - } - else - { - speed.y += m_linMotion.realSpeed.y*1.2f; - } - a = m_object->RetAngleY(0); - p.x = speed.x; - p.y = speed.z; - p = RotatePoint(-a, p); - speed.x = p.x; - speed.z = p.y; - - dim.x = 0.4f+Rand()*0.2f; - dim.y = dim.x; - - m_particule->CreateParticule(pos, speed, dim, PARTIEJECT, 0.3f, 10.0f); -#endif - } - } - - if ( (type == OBJECT_HUMAN || type == OBJECT_TECH) && m_bSwim ) - { - m_reactorTemperature = 0.0f; // reactor cold - } - - if ( m_type == TYPE_FLYING && - type != OBJECT_HUMAN && - type != OBJECT_TECH && - !m_bSwim ) - { - if ( m_bLand ) // on the ground? - { - if ( m_motorSpeed.x == 0.0f && // glide slope due to ground? - m_cirMotion.realSpeed.y == 0.0f ) - { - h = Max(Abs(m_linMotion.realSpeed.x), - Abs(m_linMotion.realSpeed.z)); - - if ( h < 3.0f ) return; - - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.2f) ) return; - m_lastMotorParticule = aTime; - - r = rand()%3; - if ( r == 0 ) pos = D3DVECTOR(-3.0f, 0.0f, -4.0f); - if ( r == 1 ) pos = D3DVECTOR(-3.0f, 0.0f, 4.0f); - if ( r == 2 ) pos = D3DVECTOR( 4.0f, 0.0f, 0.0f); - - pos.x += (Rand()-0.5f)*2.0f; - pos.z += (Rand()-0.5f)*2.0f; - mat = m_object->RetWorldMatrix(0); - pos = Transform(*mat, pos); - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = Rand()*h/5.0f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); - } - else // glide with small reactors in skates? - { - if ( m_linMotion.realSpeed.x == 0.0f && - m_cirMotion.realSpeed.y == 0.0f ) return; - - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.02f) ) return; - m_lastMotorParticule = aTime; - - r = rand()%3; - if ( r == 0 ) pos = D3DVECTOR(-3.0f, 0.0f, -4.0f); - if ( r == 1 ) pos = D3DVECTOR(-3.0f, 0.0f, 4.0f); - if ( r == 2 ) pos = D3DVECTOR( 4.0f, 0.0f, 0.0f); - - pos.x += (Rand()-0.5f)*1.0f; - pos.z += (Rand()-0.5f)*1.0f; - mat = m_object->RetWorldMatrix(0); - pos = Transform(*mat, pos); - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIEJECT); - } - } - else // in flight? - { - if ( !m_bMotor || m_reactorRange == 0.0f ) return; - - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.02f) ) return; - m_lastMotorParticule = aTime; - - pos = D3DVECTOR(0.0f, -1.0f, 0.0f); - pos.x += (Rand()-0.5f)*6.0f; - pos.y += (Rand()-0.5f)*3.0f; - pos.z += (Rand()-0.5f)*6.0f; - mat = m_object->RetWorldMatrix(0); - pos = Transform(*mat, pos); - - h = m_floorHeight; - if ( h > 10.0f ) // high enough? - { - speed = D3DVECTOR(0.0f, -10.0f, 0.0f); // against the bottom - } - else - { - speed.y = 10.0f-2.0f*h - Rand()*(10.0f-h); // against the top - speed.x = (Rand()-0.5f)*(10.0f-h)*2.0f; // horizontal (xz) - speed.z = (Rand()-0.5f)*(10.0f-h)*2.0f; - } - - dim.x = 0.2f; - dim.y = 0.2f; - - m_particule->CreateParticule(pos, speed, dim, PARTISCRAPS, 2.0f, 10.0f); - -#if 1 - pos = D3DVECTOR(0.0f, 1.0f, 0.0f); - pos = Transform(*mat, pos); - - speed.x = (Rand()-0.5f)*1.0f; - speed.z = (Rand()-0.5f)*1.0f; - speed.y = -(6.0f+Rand()*4.5f); - speed.x += m_linMotion.realSpeed.x*0.8f; - speed.z -= m_linMotion.realSpeed.x*m_cirMotion.realSpeed.y*0.05f; - if ( m_linMotion.realSpeed.y > 0.0f ) - { - speed.y += m_linMotion.realSpeed.y*0.5f; - } - else - { - speed.y += m_linMotion.realSpeed.y*1.2f; - } - a = m_object->RetAngleY(0); - p.x = speed.x; - p.y = speed.z; - p = RotatePoint(-a, p); - speed.x = p.x; - speed.z = p.y; - - dim.x = 0.7f+Rand()*0.6f; - dim.y = dim.x; - - m_particule->CreateParticule(pos, speed, dim, PARTIEJECT, 0.5f, 10.0f); -#endif - } - } - - if ( (type == OBJECT_HUMAN || type == OBJECT_TECH) && m_bSwim ) - { - if ( !m_object->RetDead() ) - { - h = Mod(aTime, 5.0f); - if ( h < 3.5f && ( h < 1.5f || h > 1.6f ) ) return; - } - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.06f) ) return; - m_lastMotorParticule = aTime; - - pos = D3DVECTOR(0.0f, 3.0f, 0.0f); - mat = m_object->RetWorldMatrix(0); - pos = Transform(*mat, pos); - pos.x += (Rand()-0.5f)*1.0f; - pos.z += (Rand()-0.5f)*1.0f; - speed.y = (Rand()-0.5f)*8.0f+8.0f; - speed.x = (Rand()-0.5f)*0.2f; - speed.z = (Rand()-0.5f)*0.2f; - dim.x = 0.2f; - dim.y = 0.2f; - m_particule->CreateParticule(pos, speed, dim, PARTIBUBBLE, 3.0f, 0.0f, 0.0f); - - if ( aTime-m_lastSoundWater > 1.5f ) - { - m_lastSoundWater = aTime; - m_sound->Play(SOUND_BLUP, m_object->RetPosition(0), 0.5f+Rand()*0.5f); - } - } - - if ( type == OBJECT_MOBILEsa && m_bSwim ) - { - h = Mod(aTime, 3.0f); - if ( h < 1.5f && ( h < 0.5f || h > 0.9f ) ) return; - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.06f) ) return; - m_lastMotorParticule = aTime; - - pos = D3DVECTOR(0.0f, 3.0f, 0.0f); - mat = m_object->RetWorldMatrix(0); - pos = Transform(*mat, pos); - pos.x += (Rand()-0.5f)*1.0f; - pos.z += (Rand()-0.5f)*1.0f; - speed.y = (Rand()-0.5f)*8.0f+8.0f; - speed.x = (Rand()-0.5f)*0.2f; - speed.z = (Rand()-0.5f)*0.2f; - dim.x = 0.2f; - dim.y = 0.2f; - m_particule->CreateParticule(pos, speed, dim, PARTIBUBBLE, 3.0f, 0.0f, 0.0f); - - if ( aTime-m_lastSoundWater > 1.5f ) - { - m_lastSoundWater = aTime; - m_sound->Play(SOUND_BLUP, m_object->RetPosition(0), 0.5f+Rand()*0.5f); - } - } - - if ( m_type == TYPE_ROLLING ) - { - if ( type == OBJECT_APOLLO2 ) return; // electric motors! - - if ( type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs ) - { - if ( !m_bMotor ) return; - - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.1f) ) return; - m_lastMotorParticule = aTime; - - pos = D3DVECTOR(-2.5f, 10.3f, -1.3f); - pos.x += (Rand()-0.5f)*1.0f; - pos.z += (Rand()-0.5f)*1.0f; - mat = m_object->RetWorldMatrix(0); - pos = Transform(*mat, pos); - - speed.x = (Rand()-0.5f)*2.0f; - speed.z = (Rand()-0.5f)*2.0f; - speed.y = 1.5f+Rand()*1.0f; - - dim.x = Rand()*0.6f+0.4f; - dim.y = dim.x; - - m_particule->CreateParticule(pos, speed, dim, PARTIMOTOR, 2.0f); - } - else - { - if ( !m_bMotor ) return; - - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.05f) ) return; - m_lastMotorParticule = aTime; - - pos = D3DVECTOR(-3.4f, 1.8f, 0.5f); - - speed = pos; - if ( m_linMotion.currentSpeed.x < 0.0f ) - { - speed.x += m_linMotion.currentSpeed.x*1.2f; - } - else if ( m_linMotion.currentSpeed.x > 0.0f ) - { - speed.x += 0.0f; - } - else - { - speed.x -= 3.0f; - } - speed.y -= 0.5f+Rand()*2.0f; - speed.z += (Rand()-0.5f)*3.0f; - - mat = m_object->RetWorldMatrix(0); - pos = Transform(*mat, pos); - speed = Transform(*mat, speed)-pos; - - dim.x = Rand()*0.4f+0.3f; - dim.y = dim.x; - - m_particule->CreateParticule(pos, speed, dim, PARTIMOTOR, 2.0f); - } - } -} - -// Generates some particles after falling into the water. - -void CPhysics::WaterParticule(float aTime, D3DVECTOR pos, ObjectType type, - float floor, float advance, float turn) -{ - D3DVECTOR ppos, speed; - FPOINT dim; - float delay, level, min, max, force, volume, diam; - int i, nb; - - level = m_water->RetLevel(); - if ( floor >= level ) return; - - if ( type == OBJECT_HUMAN || - type == OBJECT_TECH ) - { - min = 3.0f; - max = 3.0f; - } - else - { - min = 0.0f; - max = 9.0f; - } - - if ( pos.y+max < level || pos.y-min > level ) return; - - // Management of the particle "splash". - if ( m_linMotion.realSpeed.y < -10.0f && - aTime-m_lastPloufParticule >= 1.0f ) - { - m_lastPloufParticule = aTime; - - force = -m_linMotion.realSpeed.y/20.0f; // power according to speed drops - if ( type == OBJECT_HUMAN || - type == OBJECT_TECH ) - { - diam = 2.5f; - } - else - { - diam = 5.0f; - force *= 1.3f; // a robot is heavier - } - - pos = m_object->RetPosition(0); - pos.y = m_water->RetLevel()-1.0f; - dim.x = 2.0f*force; // height - dim.y = diam; // diameter - m_particule->CreateParticule(pos, D3DVECTOR(0.0f, 0.0f, 0.0f), dim, PARTIPLOUF0, 1.4f, 0.0f, 0.0f); - - force = (0.5f+force*0.5f); - nb = (int)(force*50.0f*m_engine->RetParticuleDensity()); - for ( i=0 ; iCreateParticule(ppos, speed, dim, PARTIDROP, 2.0f, 20.0f, 0.2f); - } - - volume = Abs(m_linMotion.realSpeed.y*0.02f); - if ( volume > 1.0f ) volume = 1.0f; - m_sound->Play(SOUND_PLOUF, pos, volume); - } - - // Management particles "cop". - if ( m_water->RetLava() ) return; - - if ( advance == 0.0f && turn == 0.0f ) - { - turn = 10.0f; - delay = 0.50f; - } - else if ( advance == 0.0f ) - { - delay = 0.24f; - } - else - { - delay = 0.06f; - } - m_engine->ParticuleAdapt(delay); - - if ( aTime-m_lastWaterParticule < delay ) return; - m_lastWaterParticule = aTime; - - force = (advance+turn)*0.16f; - if ( force < 0.001f ) return; - - pos = m_object->RetPosition(0); - pos.y = level+0.1f; - if ( advance == 0 ) - { - pos.x += (Rand()-0.5f)*10.0f; - pos.z += (Rand()-0.5f)*10.0f; - } - else - { - pos.x += (Rand()-0.5f)*4.0f; - pos.z += (Rand()-0.5f)*4.0f; - } - speed.y = 0.0f; - speed.x = 0.0f; - speed.z = 0.0f; - dim.x = Min(Rand()*force+force+1.0f, 10.0f); - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFLIC, 3.0f, 0.0f, 0.0f); -} - -// Creates the trace under the robot. - -void CPhysics::WheelParticule(int color, float width) -{ - Character* character; - D3DMATRIX* mat; - D3DVECTOR goal1, goal2, wheel1, wheel2; - ParticuleType parti; - float dist1, dist2, step; - - character = m_object->RetCharacter(); - mat = m_object->RetWorldMatrix(0); - - // Draw a trace on the ground. - if ( color >= 0 && color <= 17 ) - { - parti = (ParticuleType)(PARTITRACE0+color); - step = 2.0f; - if ( color >= 16 ) step = 4.0f; // arrow? - step /= m_engine->RetTracePrecision(); - - goal1.x = step/2.0f; - goal1.y = 0.0f; - goal1.z = -width/2.0f; - goal1 = Transform(*mat, goal1); - - goal2.x = step/2.0f; - goal2.y = 0.0f; - goal2.z = width/2.0f; - goal2 = Transform(*mat, goal2); - - if ( !m_bWheelParticuleBrake ) - { - m_wheelParticulePos[0] = goal1; - m_wheelParticulePos[1] = goal2; - } - - while ( TRUE ) - { - dist1 = Length(m_wheelParticulePos[0], goal1); - if ( dist1 < step ) break; - dist2 = Length(m_wheelParticulePos[1], goal2); - wheel1 = SegmentDist(m_wheelParticulePos[0], goal1, step); - wheel2 = SegmentDist(m_wheelParticulePos[1], goal2, step*dist2/dist1); - if ( m_linMotion.realSpeed.x >= 0.0f ) - { - m_particule->CreateWheelTrace(m_wheelParticulePos[0], m_wheelParticulePos[1], wheel1, wheel2, parti); - } - else - { - m_particule->CreateWheelTrace(m_wheelParticulePos[1], m_wheelParticulePos[0], wheel2, wheel1, parti); - } - m_wheelParticulePos[0] = wheel1; - m_wheelParticulePos[1] = wheel2; - } - - m_bWheelParticuleBrake = TRUE; - } - else - { - m_bWheelParticuleBrake = FALSE; - } -} - - -// Creates the interface. - -void CPhysics::CreateInterface(BOOL bSelect) -{ - if ( m_brain != 0 ) - { - m_brain->CreateInterface(bSelect); - } -} - - -// Returns an error related to the general state. - -Error CPhysics::RetError() -{ - ObjectType type; - CObject* power; - - type = m_object->RetType(); - if ( type == OBJECT_HUMAN || - type == OBJECT_TECH || - type == OBJECT_MOTHER || - type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_BEE || - type == OBJECT_WORM || - type == OBJECT_APOLLO2 || - type == OBJECT_MOBILEdr ) return ERR_OK; - - if ( m_brain != 0 && m_brain->RetActiveVirus() ) - { - return ERR_VEH_VIRUS; - } - - power = m_object->RetPower(); // searches for the object battery used - if ( power == 0 ) - { - return ERR_VEH_POWER; - } - else - { - if ( power->RetEnergy() == 0.0f ) return ERR_VEH_ENERGY; - } - - return ERR_OK; -} - diff --git a/src/physics.h b/src/physics.h deleted file mode 100644 index 72f0c20..0000000 --- a/src/physics.h +++ /dev/null @@ -1,248 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// physics.h - -#ifndef _PHYSICS_H_ -#define _PHYSICS_H_ - - -#include "d3dengine.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CLight; -class CParticule; -class CTerrain; -class CWater; -class CCamera; -class CObject; -class CBrain; -class CMotion; -class CSound; - - -enum PhysicsType -{ - TYPE_ROLLING = 1, - TYPE_FLYING = 2, -}; - -enum PhysicsMode -{ - MO_ADVACCEL = 0, - MO_RECACCEL = 1, - MO_STOACCEL = 2, - MO_MOTACCEL = 3, - MO_ADVSPEED = 4, - MO_RECSPEED = 5, - MO_MOTSPEED = 6, - MO_CURSPEED = 7, - MO_TERFORCE = 8, - MO_TERSPEED = 9, - MO_TERSLIDE = 10, - MO_REASPEED = 11, -}; - - -typedef struct -{ - D3DVECTOR advanceAccel; // acceleration starting (+) - D3DVECTOR recedeAccel; // acceleration starting (+) - D3DVECTOR stopAccel; // acceleration stoping (+) - D3DVECTOR motorAccel; // current acceleration (+/-) - - D3DVECTOR advanceSpeed; // forward speed (+) - D3DVECTOR recedeSpeed; // reversing speed (+) - D3DVECTOR motorSpeed; // desired speed (+/-) - D3DVECTOR currentSpeed; // current speed (+/-) - - D3DVECTOR terrainForce; // power of resistance of the ground (+) - D3DVECTOR terrainSpeed; // speed of the ground (+/-) - D3DVECTOR terrainSlide; // limit sliding speed (+) - - D3DVECTOR realSpeed; // real speed(+/-) - - D3DVECTOR finalInclin; // final inclination -} -Motion; - - - - -class CPhysics -{ -public: - CPhysics(CInstanceManager* iMan, CObject* object); - ~CPhysics(); - - void DeleteObject(BOOL bAll=FALSE); - - BOOL EventProcess(const Event &event); - - void SetBrain(CBrain* brain); - void SetMotion(CMotion* motion); - - void SetType(PhysicsType type); - PhysicsType RetType(); - - BOOL Write(char *line); - BOOL Read(char *line); - - void SetGravity(float value); - float RetGravity(); - - float RetFloorHeight(); - - void SetLinMotion(PhysicsMode mode, D3DVECTOR value); - D3DVECTOR RetLinMotion(PhysicsMode mode); - void SetLinMotionX(PhysicsMode mode, float value); - void SetLinMotionY(PhysicsMode mode, float value); - void SetLinMotionZ(PhysicsMode mode, float value); - float RetLinMotionX(PhysicsMode mode); - float RetLinMotionY(PhysicsMode mode); - float RetLinMotionZ(PhysicsMode mode); - - void SetCirMotion(PhysicsMode mode, D3DVECTOR value); - D3DVECTOR RetCirMotion(PhysicsMode mode); - void SetCirMotionX(PhysicsMode mode, float value); - void SetCirMotionY(PhysicsMode mode, float value); - void SetCirMotionZ(PhysicsMode mode, float value); - float RetCirMotionX(PhysicsMode mode); - float RetCirMotionY(PhysicsMode mode); - float RetCirMotionZ(PhysicsMode mode); - - float RetLinStopLength(PhysicsMode sMode=MO_ADVSPEED, PhysicsMode aMode=MO_STOACCEL); - float RetCirStopLength(); - float RetLinMaxLength(float dir); - float RetLinTimeLength(float dist, float dir=1.0f); - float RetLinLength(float dist); - - void SetMotor(BOOL bState); - BOOL RetMotor(); - void SetLand(BOOL bState); - BOOL RetLand(); - void SetSwim(BOOL bState); - BOOL RetSwim(); - void SetCollision(BOOL bCollision); - BOOL RetCollision(); - void SetFreeze(BOOL bFreeze); - BOOL RetFreeze(); - void SetReactorRange(float range); - float RetReactorRange(); - - void SetMotorSpeed(D3DVECTOR speed); - void SetMotorSpeedX(float speed); - void SetMotorSpeedY(float speed); - void SetMotorSpeedZ(float speed); - D3DVECTOR RetMotorSpeed(); - float RetMotorSpeedX(); - float RetMotorSpeedY(); - float RetMotorSpeedZ(); - - void CreateInterface(BOOL bSelect); - Error RetError(); - -protected: - BOOL EventFrame(const Event &event); - void WaterFrame(float aTime, float rTime); - void SoundMotor(float rTime); - void SoundMotorFull(float rTime, ObjectType type); - void SoundMotorSlow(float rTime, ObjectType type); - void SoundMotorStop(float rTime, ObjectType type); - void SoundReactorFull(float rTime, ObjectType type); - void SoundReactorStop(float rTime, ObjectType type); - void FrameParticule(float aTime, float rTime); - void MotorUpdate(float aTime, float rTime); - void EffectUpdate(float aTime, float rTime); - void UpdateMotionStruct(float rTime, Motion &motion); - void FloorAdapt(float aTime, float rTime, D3DVECTOR &pos, D3DVECTOR &angle); - void FloorAngle(const D3DVECTOR &pos, D3DVECTOR &angle); - int ObjectAdapt(const D3DVECTOR &pos, const D3DVECTOR &angle); - BOOL JostleObject(CObject* pObj, D3DVECTOR iPos, float iRad, D3DVECTOR oPos, float oRad); - BOOL JostleObject(CObject* pObj, float force); - BOOL ExploOther(ObjectType iType, CObject *pObj, ObjectType oType, float force); - int ExploHimself(ObjectType iType, ObjectType oType, float force); - - void PowerParticule(float factor, BOOL bBreak); - void CrashParticule(float crash); - void MotorParticule(float aTime, float rTime); - void WaterParticule(float aTime, D3DVECTOR pos, ObjectType type, float floor, float advance, float turn); - void WheelParticule(int color, float width); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CLight* m_light; - CParticule* m_particule; - CTerrain* m_terrain; - CWater* m_water; - CCamera* m_camera; - CObject* m_object; - CBrain* m_brain; - CMotion* m_motion; - CSound* m_sound; - - PhysicsType m_type; // TYPE_* - float m_gravity; // force of gravity - float m_time; // absolute time - D3DVECTOR m_motorSpeed; // motor speed (-1..1) - Motion m_linMotion; // linear motion - Motion m_cirMotion; // circular motion - BOOL m_bMotor; - BOOL m_bLand; - BOOL m_bSwim; - BOOL m_bCollision; - BOOL m_bObstacle; - BOOL m_bFreeze; - int m_repeatCollision; - float m_linVibrationFactor; - float m_cirVibrationFactor; - float m_inclinaisonFactor; - float m_lastPowerParticule; - float m_lastSlideParticule; - float m_lastMotorParticule; - float m_lastWaterParticule; - float m_lastUnderParticule; - float m_lastPloufParticule; - float m_lastFlameParticule; - BOOL m_bWheelParticuleBrake; - D3DVECTOR m_wheelParticulePos[2]; - float m_absorbWater; - float m_reactorTemperature; - float m_reactorRange; - float m_timeReactorFail; - float m_timeUnderWater; - float m_lastEnergy; - float m_lastSoundWater; - float m_lastSoundInsect; - float m_restBreakParticule; - float m_floorLevel; // ground level - float m_floorHeight; // height above the ground - int m_soundChannel; - int m_soundChannelSlide; - float m_soundTimePshhh; - float m_soundTimeJostle; - float m_soundTimeBoum; - BOOL m_bSoundSlow; - BOOL m_bForceUpdate; - BOOL m_bLowLevel; -}; - - -#endif //_PHYSICS_H_ diff --git a/src/physics/README.txt b/src/physics/README.txt new file mode 100644 index 0000000..0003956 --- /dev/null +++ b/src/physics/README.txt @@ -0,0 +1,3 @@ +src/physics + +Contains the physics module. diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp new file mode 100644 index 0000000..beae37e --- /dev/null +++ b/src/physics/physics.cpp @@ -0,0 +1,3885 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// physics.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "language.h" +#include "global.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "math3d.h" +#include "light.h" +#include "particule.h" +#include "terrain.h" +#include "water.h" +#include "camera.h" +#include "object.h" +#include "pyro.h" +#include "brain.h" +#include "motion.h" +#include "motionhuman.h" +#include "sound.h" +#include "task.h" +#include "cmdtoken.h" +#include "physics.h" + + + +#define LANDING_SPEED 3.0f +#define LANDING_ACCEL 5.0f +#define LANDING_ACCELh 1.5f + + + + +// Object's constructor. + +CPhysics::CPhysics(CInstanceManager* iMan, CObject* object) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_PHYSICS, this, 100); + + m_object = object; + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); + m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); + m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + m_brain = 0; + m_motion = 0; + + m_type = TYPE_ROLLING; + m_gravity = 9.81f; // default gravity + m_time = 0.0f; + m_timeUnderWater = 0.0f; + m_motorSpeed = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_bMotor = FALSE; + m_bLand = TRUE; // ground + m_bSwim = FALSE; // in air + m_bCollision = FALSE; + m_bObstacle = FALSE; + m_repeatCollision = 0; + m_linVibrationFactor = 1.0f; + m_cirVibrationFactor = 1.0f; + m_inclinaisonFactor = 1.0f; + m_lastPowerParticule = 0.0f; + m_lastSlideParticule = 0.0f; + m_lastMotorParticule = 0.0f; + m_lastWaterParticule = 0.0f; + m_lastUnderParticule = 0.0f; + m_lastPloufParticule = 0.0f; + m_lastFlameParticule = 0.0f; + m_bWheelParticuleBrake = FALSE; + m_absorbWater = 0.0f; + m_reactorTemperature = 0.0f; + m_reactorRange = 1.0f; + m_timeReactorFail = 0.0f; + m_lastEnergy = 0.0f; + m_lastSoundWater = 0.0f; + m_lastSoundInsect = 0.0f; + m_restBreakParticule = 0.0f; + m_floorHeight = 0.0f; + m_soundChannel = -1; + m_soundChannelSlide = -1; + m_soundTimePshhh = 0.0f; + m_soundTimeJostle = 0.0f; + m_soundTimeBoum = 0.0f; + m_bSoundSlow = TRUE; + m_bFreeze = FALSE; + m_bForceUpdate = TRUE; + m_bLowLevel = FALSE; + + ZeroMemory(&m_linMotion, sizeof(Motion)); + ZeroMemory(&m_cirMotion, sizeof(Motion)); +} + +// Object's destructor. + +CPhysics::~CPhysics() +{ + m_iMan->DeleteInstance(CLASS_PHYSICS, this); +} + + +// Destroys the object. + +void CPhysics::DeleteObject(BOOL bAll) +{ + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 0.3f, SOPER_STOP); + m_soundChannel = -1; + } + if ( m_soundChannelSlide != -1 ) + { + m_sound->FlushEnvelope(m_soundChannelSlide); + m_sound->AddEnvelope(m_soundChannelSlide, 0.0f, 1.0f, 0.3f, SOPER_STOP); + m_soundChannelSlide = -1; + } +} + + + +void CPhysics::SetBrain(CBrain* brain) +{ + m_brain = brain; +} + +void CPhysics::SetMotion(CMotion* motion) +{ + m_motion = motion; +} + +// Management of the type. + +void CPhysics::SetType(PhysicsType type) +{ + m_type = type; +} + +PhysicsType CPhysics::RetType() +{ + return m_type; +} + + + +// Saves all parameters of the object. + +BOOL CPhysics::Write(char *line) +{ + char name[100]; + + sprintf(name, " motor=%.2f;%.2f;%.2f", m_motorSpeed.x, m_motorSpeed.y, m_motorSpeed.z); + strcat(line, name); + + if ( m_type == TYPE_FLYING ) + { + sprintf(name, " reactorRange=%.2f", RetReactorRange()); + strcat(line, name); + + sprintf(name, " land=%d", RetLand()); + strcat(line, name); + } + + return TRUE; +} + +// Restores all parameters of the object. + +BOOL CPhysics::Read(char *line) +{ + m_motorSpeed = OpDir(line, "motor"); + + if ( m_type == TYPE_FLYING ) + { + SetReactorRange(OpFloat(line, "reactorRange", 0.0f)); + SetLand(OpInt(line, "land", 0)); + } + + return TRUE; +} + + + +// Management of the force of gravity. + +void CPhysics::SetGravity(float value) +{ + m_gravity = value; +} + +float CPhysics::RetGravity() +{ + return m_gravity; +} + + +// Returns the height above the ground. + +float CPhysics::RetFloorHeight() +{ + return m_floorHeight; +} + + +// Managing the state of the engine. + +void CPhysics::SetMotor(BOOL bState) +{ + int light; + + m_bMotor = bState; + + light = m_object->RetShadowLight(); + if ( light != -1 ) + { + m_light->SetLightIntensity(light, m_bMotor?1.0f:0.0f); + m_light->SetLightIntensitySpeed(light, 3.0f); + } +} + +BOOL CPhysics::RetMotor() +{ + return m_bMotor; +} + + +// Management of the state in flight/ground. + +void CPhysics::SetLand(BOOL bState) +{ + m_bLand = bState; + SetMotor(!bState); // lights if you leave the reactor in flight +} + +BOOL CPhysics::RetLand() +{ + return m_bLand; +} + + +// Management of the state in air/water. + +void CPhysics::SetSwim(BOOL bState) +{ + if ( !m_bSwim && bState ) // enters the water? + { + m_timeUnderWater = 0.0f; + } + m_bSwim = bState; +} + +BOOL CPhysics::RetSwim() +{ + return m_bSwim; +} + + +// Indicates whether a collision occurred. + +void CPhysics::SetCollision(BOOL bCollision) +{ + m_bCollision = bCollision; +} + +BOOL CPhysics::RetCollision() +{ + return m_bCollision; +} + + +// Indicates whether the influence of soil is activated or not. + +void CPhysics::SetFreeze(BOOL bFreeze) +{ + m_bFreeze = bFreeze; +} + +BOOL CPhysics::RetFreeze() +{ + return m_bFreeze; +} + + +// Returns the range of the reactor. + +void CPhysics::SetReactorRange(float range) +{ + m_reactorRange = range; +} + +float CPhysics::RetReactorRange() +{ + return m_reactorRange; +} + + +// Specifies the engine speed. +// x = forward/backward +// y = up/down +// z = turn + +void CPhysics::SetMotorSpeed(D3DVECTOR speed) +{ + m_motorSpeed = speed; +} + +// Specifies the engine speed for forward/backward. +// +1 = forward +// -1 = backward + +void CPhysics::SetMotorSpeedX(float speed) +{ + m_motorSpeed.x = speed; +} + +// Specifies the motor speed for up/down. +// +1 = up +// -1 = down + +void CPhysics::SetMotorSpeedY(float speed) +{ + m_motorSpeed.y = speed; +} + +// Specifies the speed of the motor to turn. +// +1 = turn right(CW) +// -1 = turn left(CCW) + +void CPhysics::SetMotorSpeedZ(float speed) +{ + m_motorSpeed.z = speed; +} + +D3DVECTOR CPhysics::RetMotorSpeed() +{ + return m_motorSpeed; +} + +float CPhysics::RetMotorSpeedX() +{ + return m_motorSpeed.x; +} + +float CPhysics::RetMotorSpeedY() +{ + return m_motorSpeed.y; +} + +float CPhysics::RetMotorSpeedZ() +{ + return m_motorSpeed.z; +} + + +// Management of linear and angular velocities. +// Specifies the speed parallel to the direction of travel. + +void CPhysics::SetLinMotion(PhysicsMode mode, D3DVECTOR value) +{ + if ( mode == MO_ADVACCEL ) m_linMotion.advanceAccel = value; + if ( mode == MO_RECACCEL ) m_linMotion.recedeAccel = value; + if ( mode == MO_STOACCEL ) m_linMotion.stopAccel = value; + if ( mode == MO_TERSPEED ) m_linMotion.terrainSpeed = value; + if ( mode == MO_TERSLIDE ) m_linMotion.terrainSlide = value; + if ( mode == MO_MOTACCEL ) m_linMotion.motorAccel = value; + if ( mode == MO_TERFORCE ) m_linMotion.terrainForce = value; + if ( mode == MO_ADVSPEED ) m_linMotion.advanceSpeed = value; + if ( mode == MO_RECSPEED ) m_linMotion.recedeSpeed = value; + if ( mode == MO_MOTSPEED ) m_linMotion.motorSpeed = value; + if ( mode == MO_CURSPEED ) m_linMotion.currentSpeed = value; + if ( mode == MO_REASPEED ) m_linMotion.realSpeed = value; +} + +D3DVECTOR CPhysics::RetLinMotion(PhysicsMode mode) +{ + if ( mode == MO_ADVACCEL ) return m_linMotion.advanceAccel; + if ( mode == MO_RECACCEL ) return m_linMotion.recedeAccel; + if ( mode == MO_STOACCEL ) return m_linMotion.stopAccel; + if ( mode == MO_TERSPEED ) return m_linMotion.terrainSpeed; + if ( mode == MO_TERSLIDE ) return m_linMotion.terrainSlide; + if ( mode == MO_MOTACCEL ) return m_linMotion.motorAccel; + if ( mode == MO_TERFORCE ) return m_linMotion.terrainForce; + if ( mode == MO_ADVSPEED ) return m_linMotion.advanceSpeed; + if ( mode == MO_RECSPEED ) return m_linMotion.recedeSpeed; + if ( mode == MO_MOTSPEED ) return m_linMotion.motorSpeed; + if ( mode == MO_CURSPEED ) return m_linMotion.currentSpeed; + if ( mode == MO_REASPEED ) return m_linMotion.realSpeed; + return D3DVECTOR(0.0f, 0.0f, 0.0f); +} + +void CPhysics::SetLinMotionX(PhysicsMode mode, float value) +{ + if ( mode == MO_ADVACCEL ) m_linMotion.advanceAccel.x = value; + if ( mode == MO_RECACCEL ) m_linMotion.recedeAccel.x = value; + if ( mode == MO_STOACCEL ) m_linMotion.stopAccel.x = value; + if ( mode == MO_TERSPEED ) m_linMotion.terrainSpeed.x = value; + if ( mode == MO_TERSLIDE ) m_linMotion.terrainSlide.x = value; + if ( mode == MO_MOTACCEL ) m_linMotion.motorAccel.x = value; + if ( mode == MO_TERFORCE ) m_linMotion.terrainForce.x = value; + if ( mode == MO_ADVSPEED ) m_linMotion.advanceSpeed.x = value; + if ( mode == MO_RECSPEED ) m_linMotion.recedeSpeed.x = value; + if ( mode == MO_MOTSPEED ) m_linMotion.motorSpeed.x = value; + if ( mode == MO_CURSPEED ) m_linMotion.currentSpeed.x = value; + if ( mode == MO_REASPEED ) m_linMotion.realSpeed.x = value; +} + +float CPhysics::RetLinMotionX(PhysicsMode mode) +{ + if ( mode == MO_ADVACCEL ) return m_linMotion.advanceAccel.x; + if ( mode == MO_RECACCEL ) return m_linMotion.recedeAccel.x; + if ( mode == MO_STOACCEL ) return m_linMotion.stopAccel.x; + if ( mode == MO_TERSPEED ) return m_linMotion.terrainSpeed.x; + if ( mode == MO_TERSLIDE ) return m_linMotion.terrainSlide.x; + if ( mode == MO_MOTACCEL ) return m_linMotion.motorAccel.x; + if ( mode == MO_TERFORCE ) return m_linMotion.terrainForce.x; + if ( mode == MO_ADVSPEED ) return m_linMotion.advanceSpeed.x; + if ( mode == MO_RECSPEED ) return m_linMotion.recedeSpeed.x; + if ( mode == MO_MOTSPEED ) return m_linMotion.motorSpeed.x; + if ( mode == MO_CURSPEED ) return m_linMotion.currentSpeed.x; + if ( mode == MO_REASPEED ) return m_linMotion.realSpeed.x; + return 0.0f; +} + +// Specifies the speed of elevation. + +void CPhysics::SetLinMotionY(PhysicsMode mode, float value) +{ + if ( mode == MO_ADVACCEL ) m_linMotion.advanceAccel.y = value; + if ( mode == MO_RECACCEL ) m_linMotion.recedeAccel.y = value; + if ( mode == MO_STOACCEL ) m_linMotion.stopAccel.y = value; + if ( mode == MO_TERSPEED ) m_linMotion.terrainSpeed.y = value; + if ( mode == MO_TERSLIDE ) m_linMotion.terrainSlide.y = value; + if ( mode == MO_MOTACCEL ) m_linMotion.motorAccel.y = value; + if ( mode == MO_TERFORCE ) m_linMotion.terrainForce.y = value; + if ( mode == MO_ADVSPEED ) m_linMotion.advanceSpeed.y = value; + if ( mode == MO_RECSPEED ) m_linMotion.recedeSpeed.y = value; + if ( mode == MO_MOTSPEED ) m_linMotion.motorSpeed.y = value; + if ( mode == MO_CURSPEED ) m_linMotion.currentSpeed.y = value; + if ( mode == MO_REASPEED ) m_linMotion.realSpeed.y = value; +} + +float CPhysics::RetLinMotionY(PhysicsMode mode) +{ + if ( mode == MO_ADVACCEL ) return m_linMotion.advanceAccel.y; + if ( mode == MO_RECACCEL ) return m_linMotion.recedeAccel.y; + if ( mode == MO_STOACCEL ) return m_linMotion.stopAccel.y; + if ( mode == MO_TERSPEED ) return m_linMotion.terrainSpeed.y; + if ( mode == MO_TERSLIDE ) return m_linMotion.terrainSlide.y; + if ( mode == MO_MOTACCEL ) return m_linMotion.motorAccel.y; + if ( mode == MO_TERFORCE ) return m_linMotion.terrainForce.y; + if ( mode == MO_ADVSPEED ) return m_linMotion.advanceSpeed.y; + if ( mode == MO_RECSPEED ) return m_linMotion.recedeSpeed.y; + if ( mode == MO_MOTSPEED ) return m_linMotion.motorSpeed.y; + if ( mode == MO_CURSPEED ) return m_linMotion.currentSpeed.y; + if ( mode == MO_REASPEED ) return m_linMotion.realSpeed.y; + return 0.0f; +} + +// Specifies the velocity perpendicular to the direction of travel. + +void CPhysics::SetLinMotionZ(PhysicsMode mode, float value) +{ + if ( mode == MO_ADVACCEL ) m_linMotion.advanceAccel.z = value; + if ( mode == MO_RECACCEL ) m_linMotion.recedeAccel.z = value; + if ( mode == MO_STOACCEL ) m_linMotion.stopAccel.z = value; + if ( mode == MO_TERSPEED ) m_linMotion.terrainSpeed.z = value; + if ( mode == MO_TERSLIDE ) m_linMotion.terrainSlide.z = value; + if ( mode == MO_MOTACCEL ) m_linMotion.motorAccel.z = value; + if ( mode == MO_TERFORCE ) m_linMotion.terrainForce.z = value; + if ( mode == MO_ADVSPEED ) m_linMotion.advanceSpeed.z = value; + if ( mode == MO_RECSPEED ) m_linMotion.recedeSpeed.z = value; + if ( mode == MO_MOTSPEED ) m_linMotion.motorSpeed.z = value; + if ( mode == MO_CURSPEED ) m_linMotion.currentSpeed.z = value; + if ( mode == MO_REASPEED ) m_linMotion.realSpeed.z = value; +} + +float CPhysics::RetLinMotionZ(PhysicsMode mode) +{ + if ( mode == MO_ADVACCEL ) return m_linMotion.advanceAccel.z; + if ( mode == MO_RECACCEL ) return m_linMotion.recedeAccel.z; + if ( mode == MO_STOACCEL ) return m_linMotion.stopAccel.z; + if ( mode == MO_TERSPEED ) return m_linMotion.terrainSpeed.z; + if ( mode == MO_TERSLIDE ) return m_linMotion.terrainSlide.z; + if ( mode == MO_MOTACCEL ) return m_linMotion.motorAccel.z; + if ( mode == MO_TERFORCE ) return m_linMotion.terrainForce.z; + if ( mode == MO_ADVSPEED ) return m_linMotion.advanceSpeed.z; + if ( mode == MO_RECSPEED ) return m_linMotion.recedeSpeed.z; + if ( mode == MO_MOTSPEED ) return m_linMotion.motorSpeed.z; + if ( mode == MO_CURSPEED ) return m_linMotion.currentSpeed.z; + if ( mode == MO_REASPEED ) return m_linMotion.realSpeed.z; + return 0.0f; +} + +// Specifies the rotation around the axis of walk. + +void CPhysics::SetCirMotion(PhysicsMode mode, D3DVECTOR value) +{ + if ( mode == MO_ADVACCEL ) m_cirMotion.advanceAccel = value; + if ( mode == MO_RECACCEL ) m_cirMotion.recedeAccel = value; + if ( mode == MO_STOACCEL ) m_cirMotion.stopAccel = value; + if ( mode == MO_TERSPEED ) m_cirMotion.terrainSpeed = value; + if ( mode == MO_TERSLIDE ) m_cirMotion.terrainSlide = value; + if ( mode == MO_MOTACCEL ) m_cirMotion.motorAccel = value; + if ( mode == MO_TERFORCE ) m_cirMotion.terrainForce = value; + if ( mode == MO_ADVSPEED ) m_cirMotion.advanceSpeed = value; + if ( mode == MO_RECSPEED ) m_cirMotion.recedeSpeed = value; + if ( mode == MO_MOTSPEED ) m_cirMotion.motorSpeed = value; + if ( mode == MO_CURSPEED ) m_cirMotion.currentSpeed = value; + if ( mode == MO_REASPEED ) m_cirMotion.realSpeed = value; +} + +D3DVECTOR CPhysics::RetCirMotion(PhysicsMode mode) +{ + if ( mode == MO_ADVACCEL ) return m_cirMotion.advanceAccel; + if ( mode == MO_RECACCEL ) return m_cirMotion.recedeAccel; + if ( mode == MO_STOACCEL ) return m_cirMotion.stopAccel; + if ( mode == MO_TERSPEED ) return m_cirMotion.terrainSpeed; + if ( mode == MO_TERSLIDE ) return m_cirMotion.terrainSlide; + if ( mode == MO_MOTACCEL ) return m_cirMotion.motorAccel; + if ( mode == MO_TERFORCE ) return m_cirMotion.terrainForce; + if ( mode == MO_ADVSPEED ) return m_cirMotion.advanceSpeed; + if ( mode == MO_RECSPEED ) return m_cirMotion.recedeSpeed; + if ( mode == MO_MOTSPEED ) return m_cirMotion.motorSpeed; + if ( mode == MO_CURSPEED ) return m_cirMotion.currentSpeed; + if ( mode == MO_REASPEED ) return m_cirMotion.realSpeed; + return D3DVECTOR(0.0f, 0.0f, 0.0f); +} + +void CPhysics::SetCirMotionX(PhysicsMode mode, float value) +{ + if ( mode == MO_ADVACCEL ) m_cirMotion.advanceAccel.x = value; + if ( mode == MO_RECACCEL ) m_cirMotion.recedeAccel.x = value; + if ( mode == MO_STOACCEL ) m_cirMotion.stopAccel.x = value; + if ( mode == MO_TERSPEED ) m_cirMotion.terrainSpeed.x = value; + if ( mode == MO_TERSLIDE ) m_cirMotion.terrainSlide.x = value; + if ( mode == MO_MOTACCEL ) m_cirMotion.motorAccel.x = value; + if ( mode == MO_TERFORCE ) m_cirMotion.terrainForce.x = value; + if ( mode == MO_ADVSPEED ) m_cirMotion.advanceSpeed.x = value; + if ( mode == MO_RECSPEED ) m_cirMotion.recedeSpeed.x = value; + if ( mode == MO_MOTSPEED ) m_cirMotion.motorSpeed.x = value; + if ( mode == MO_CURSPEED ) m_cirMotion.currentSpeed.x = value; + if ( mode == MO_REASPEED ) m_cirMotion.realSpeed.x = value; +} + +float CPhysics::RetCirMotionX(PhysicsMode mode) +{ + if ( mode == MO_ADVACCEL ) return m_cirMotion.advanceAccel.x; + if ( mode == MO_RECACCEL ) return m_cirMotion.recedeAccel.x; + if ( mode == MO_STOACCEL ) return m_cirMotion.stopAccel.x; + if ( mode == MO_TERSPEED ) return m_cirMotion.terrainSpeed.x; + if ( mode == MO_TERSLIDE ) return m_cirMotion.terrainSlide.x; + if ( mode == MO_MOTACCEL ) return m_cirMotion.motorAccel.x; + if ( mode == MO_TERFORCE ) return m_cirMotion.terrainForce.x; + if ( mode == MO_ADVSPEED ) return m_cirMotion.advanceSpeed.x; + if ( mode == MO_RECSPEED ) return m_cirMotion.recedeSpeed.x; + if ( mode == MO_MOTSPEED ) return m_cirMotion.motorSpeed.x; + if ( mode == MO_CURSPEED ) return m_cirMotion.currentSpeed.x; + if ( mode == MO_REASPEED ) return m_cirMotion.realSpeed.x; + return 0.0f; +} + +// Specifies the rotation direction. + +void CPhysics::SetCirMotionY(PhysicsMode mode, float value) +{ + if ( mode == MO_ADVACCEL ) m_cirMotion.advanceAccel.y = value; + if ( mode == MO_RECACCEL ) m_cirMotion.recedeAccel.y = value; + if ( mode == MO_STOACCEL ) m_cirMotion.stopAccel.y = value; + if ( mode == MO_TERSPEED ) m_cirMotion.terrainSpeed.y = value; + if ( mode == MO_TERSLIDE ) m_cirMotion.terrainSlide.y = value; + if ( mode == MO_MOTACCEL ) m_cirMotion.motorAccel.y = value; + if ( mode == MO_TERFORCE ) m_cirMotion.terrainForce.y = value; + if ( mode == MO_ADVSPEED ) m_cirMotion.advanceSpeed.y = value; + if ( mode == MO_RECSPEED ) m_cirMotion.recedeSpeed.y = value; + if ( mode == MO_MOTSPEED ) m_cirMotion.motorSpeed.y = value; + if ( mode == MO_CURSPEED ) m_cirMotion.currentSpeed.y = value; + if ( mode == MO_REASPEED ) m_cirMotion.realSpeed.y = value; +} + +float CPhysics::RetCirMotionY(PhysicsMode mode) +{ + if ( mode == MO_ADVACCEL ) return m_cirMotion.advanceAccel.y; + if ( mode == MO_RECACCEL ) return m_cirMotion.recedeAccel.y; + if ( mode == MO_STOACCEL ) return m_cirMotion.stopAccel.y; + if ( mode == MO_TERSPEED ) return m_cirMotion.terrainSpeed.y; + if ( mode == MO_TERSLIDE ) return m_cirMotion.terrainSlide.y; + if ( mode == MO_MOTACCEL ) return m_cirMotion.motorAccel.y; + if ( mode == MO_TERFORCE ) return m_cirMotion.terrainForce.y; + if ( mode == MO_ADVSPEED ) return m_cirMotion.advanceSpeed.y; + if ( mode == MO_RECSPEED ) return m_cirMotion.recedeSpeed.y; + if ( mode == MO_MOTSPEED ) return m_cirMotion.motorSpeed.y; + if ( mode == MO_CURSPEED ) return m_cirMotion.currentSpeed.y; + if ( mode == MO_REASPEED ) return m_cirMotion.realSpeed.y; + return 0.0f; +} + +// Specifies the rotation up/down. + +void CPhysics::SetCirMotionZ(PhysicsMode mode, float value) +{ + if ( mode == MO_ADVACCEL ) m_cirMotion.advanceAccel.z = value; + if ( mode == MO_RECACCEL ) m_cirMotion.recedeAccel.z = value; + if ( mode == MO_STOACCEL ) m_cirMotion.stopAccel.z = value; + if ( mode == MO_TERSPEED ) m_cirMotion.terrainSpeed.z = value; + if ( mode == MO_TERSLIDE ) m_cirMotion.terrainSlide.z = value; + if ( mode == MO_MOTACCEL ) m_cirMotion.motorAccel.z = value; + if ( mode == MO_TERFORCE ) m_cirMotion.terrainForce.z = value; + if ( mode == MO_ADVSPEED ) m_cirMotion.advanceSpeed.z = value; + if ( mode == MO_RECSPEED ) m_cirMotion.recedeSpeed.z = value; + if ( mode == MO_MOTSPEED ) m_cirMotion.motorSpeed.z = value; + if ( mode == MO_CURSPEED ) m_cirMotion.currentSpeed.z = value; + if ( mode == MO_REASPEED ) m_cirMotion.realSpeed.z = value; +} + +float CPhysics::RetCirMotionZ(PhysicsMode mode) +{ + if ( mode == MO_ADVACCEL ) return m_cirMotion.advanceAccel.z; + if ( mode == MO_RECACCEL ) return m_cirMotion.recedeAccel.z; + if ( mode == MO_STOACCEL ) return m_cirMotion.stopAccel.z; + if ( mode == MO_TERSPEED ) return m_cirMotion.terrainSpeed.z; + if ( mode == MO_TERSLIDE ) return m_cirMotion.terrainSlide.z; + if ( mode == MO_MOTACCEL ) return m_cirMotion.motorAccel.z; + if ( mode == MO_TERFORCE ) return m_cirMotion.terrainForce.z; + if ( mode == MO_ADVSPEED ) return m_cirMotion.advanceSpeed.z; + if ( mode == MO_RECSPEED ) return m_cirMotion.recedeSpeed.z; + if ( mode == MO_MOTSPEED ) return m_cirMotion.motorSpeed.z; + if ( mode == MO_CURSPEED ) return m_cirMotion.currentSpeed.z; + if ( mode == MO_REASPEED ) return m_cirMotion.realSpeed.z; + return 0.0f; +} + + +// Returns the linear distance braking. +// +// v*v +// d = ----- +// 2a + +float CPhysics::RetLinStopLength(PhysicsMode sMode, PhysicsMode aMode) +{ + float speed, accel; + + speed = RetLinMotionX(sMode); // MO_ADVSPEED/MO_RECSPEED + accel = RetLinMotionX(aMode); // MO_ADVACCEL/MO_RECACCEL/MO_STOACCEL + + if ( m_type == TYPE_FLYING && m_bLand ) // flying on the ground? + { + speed /= LANDING_SPEED; + accel *= LANDING_ACCEL; + } + + return (speed*speed) / (accel*2.0f); +} + +// Returns the angle of circular braking. + +float CPhysics::RetCirStopLength() +{ + return m_cirMotion.advanceSpeed.y * m_cirMotion.advanceSpeed.y / + m_cirMotion.stopAccel.y / 2.0f; +} + +// Returns the length advanced into a second, on the ground, maximum speed. + +float CPhysics::RetLinMaxLength(float dir) +{ + float dist; + + if ( dir > 0.0f ) dist = m_linMotion.advanceSpeed.x; + else dist = m_linMotion.recedeSpeed.x; + + if ( m_type == TYPE_FLYING ) + { + dist /= 5.0f; + } + + return dist; +} + +// Returns the time needed to travel some distance. + +float CPhysics::RetLinTimeLength(float dist, float dir) +{ + float accel, decel, dps; + + if ( dir > 0.0f ) + { + accel = RetLinStopLength(MO_ADVSPEED, MO_ADVACCEL); + decel = RetLinStopLength(MO_ADVSPEED, MO_STOACCEL); + } + else + { + accel = RetLinStopLength(MO_RECSPEED, MO_RECACCEL); + decel = RetLinStopLength(MO_RECSPEED, MO_STOACCEL); + } + + dps = RetLinMaxLength(dir); + + return (dist+accel+decel)/dps; +} + +// Returns the length for a forward travel some distance, taking into account the accelerations / decelerations. + +float CPhysics::RetLinLength(float dist) +{ + float accDist, desDist; + + if ( dist > 0.0f ) + { + accDist = RetLinStopLength(MO_ADVSPEED, MO_ADVACCEL); + desDist = RetLinStopLength(MO_ADVSPEED, MO_STOACCEL); + + if ( dist > accDist+desDist ) + { + return dist-desDist; + } + + return dist*m_linMotion.stopAccel.x / + (m_linMotion.advanceAccel.x+m_linMotion.stopAccel.x); + } + else + { + dist = -dist; + accDist = RetLinStopLength(MO_RECSPEED, MO_RECACCEL); + desDist = RetLinStopLength(MO_RECSPEED, MO_STOACCEL); + + if ( dist > accDist+desDist ) + { + return dist-desDist; + } + + return dist*m_linMotion.stopAccel.x / + (m_linMotion.recedeAccel.x+m_linMotion.stopAccel.x); + } +} + + +// Management of an event. +// Returns FALSE if the object is destroyed. + +BOOL CPhysics::EventProcess(const Event &event) +{ + if ( !m_object->RetEnable() ) return TRUE; + + if ( m_brain != 0 ) + { + m_brain->EventProcess(event); + } + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + return TRUE; +} + + +// Updates instructions for the motor speed. + +void CPhysics::MotorUpdate(float aTime, float rTime) +{ + ObjectType type; + CObject* power; + D3DVECTOR pos, motorSpeed; + float energy, speed, factor, h; + + type = m_object->RetType(); + + motorSpeed = m_motorSpeed; + + if ( type == OBJECT_MOTHER || + type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_BEE || + type == OBJECT_WORM || + type == OBJECT_APOLLO2 || + type == OBJECT_MOBILEdr ) + { + power = 0; + } + else if ( type == OBJECT_HUMAN || + type == OBJECT_TECH ) + { + power = 0; + if ( m_object->RetFret() != 0 && // carries something? + !m_object->RetCargo() ) + { + motorSpeed.x *= 0.7f; // forward more slowly + motorSpeed.z *= 0.5f; + motorSpeed.y = -1.0f; // grave + } + if ( m_bSwim ) + { + if ( m_bLand ) // deep in the water? + { + motorSpeed.x *= 0.4f; // forward more slowly + motorSpeed.z *= 0.5f; + motorSpeed.y *= 0.5f; + + if ( m_object->RetFret() != 0 ) // carries something? + { + motorSpeed.x *= 0.2f; + motorSpeed.z *= 0.9f; + motorSpeed.y *= 0.2f; + } + } + else // swimming? + { + motorSpeed.x *= 0.2f; // forward more slowly + motorSpeed.z *= 0.5f; + motorSpeed.y *= 0.2f; + } + } + } + else + { + power = m_object->RetPower(); // searches for the object battery uses + if ( power == 0 || power->RetEnergy() == 0.0f ) // no battery or flat? + { + motorSpeed.x = 0.0f; + motorSpeed.z = 0.0f; + if ( m_bFreeze || m_bLand ) + { + motorSpeed.y = 0.0f; // immobile + } + else + { + motorSpeed.y = -1.0f; // grave + } + SetMotor(FALSE); + } + } + + if ( m_object->RetDead() ) // dead man? + { + motorSpeed.x = 0.0f; + motorSpeed.z = 0.0f; + if ( m_motion->RetAction() == MHS_DEADw ) // drowned? + { + motorSpeed.y = 0.0f; // this is MHS_DEADw going back + } + else + { + motorSpeed.y = -1.0f; // grave + } + SetMotor(FALSE); + } + + if ( m_type == TYPE_FLYING && !m_bLand && motorSpeed.y > 0.0f ) + { + pos = m_object->RetPosition(0); + h = m_terrain->RetFlyingLimit(pos, type==OBJECT_BEE); + h += m_object->RetCharacter()->height; + if ( pos.y > h-40.0f ) // almost at the top? + { + factor = 1.0f-(pos.y-(h-40.0f))/40.0f; + if ( factor < -1.0f ) factor = -1.0f; + if ( factor > 1.0f ) factor = 1.0f; + motorSpeed.y *= factor; // limit the rate of rise + } + } + + if ( type != OBJECT_BEE && + m_object->RetRange() > 0.0f ) // limited flight range? + { + if ( m_bLand || m_bSwim || m_bObstacle ) // on the ground or in the water? + { + factor = 1.0f; + if ( m_bObstacle ) factor = 3.0f; // in order to leave! + if ( m_bSwim ) factor = 3.0f; // cools faster in water + m_reactorRange += rTime*(1.0f/5.0f)*factor; + if ( m_reactorRange > 1.0f ) + { + m_reactorRange = 1.0f; + if ( m_bLowLevel && m_object->RetSelect() ) // beep cool? + { + m_sound->Play(SOUND_INFO, m_object->RetPosition(0), 1.0f, 2.0f); + m_bLowLevel = FALSE; + } + } + m_bObstacle = FALSE; + } + else // in flight? + { + m_reactorRange -= rTime*(1.0f/m_object->RetRange()); + if ( m_reactorRange < 0.0f ) m_reactorRange = 0.0f; + if ( m_reactorRange < 0.5f ) m_bLowLevel = TRUE; + } + + if ( m_reactorRange == 0.0f ) // reactor tilt? + { + motorSpeed.y = -1.0f; // grave + } + } + +//? MotorParticule(aTime); + + // Forward/backward. + if ( motorSpeed.x > 0.0f ) + { + m_linMotion.motorAccel.x = m_linMotion.advanceAccel.x; + m_linMotion.motorSpeed.x = m_linMotion.advanceSpeed.x * motorSpeed.x; + } + if ( motorSpeed.x < 0.0f ) + { + m_linMotion.motorAccel.x = m_linMotion.recedeAccel.x; + m_linMotion.motorSpeed.x = m_linMotion.recedeSpeed.x * motorSpeed.x; + } + if ( motorSpeed.x == 0.0f ) + { + m_linMotion.motorAccel.x = m_linMotion.stopAccel.x; + m_linMotion.motorSpeed.x = 0.0f; + } + + // Up/down. + if ( motorSpeed.y > 0.0f ) + { + m_linMotion.motorAccel.y = m_linMotion.advanceAccel.y; + m_linMotion.motorSpeed.y = m_linMotion.advanceSpeed.y * motorSpeed.y; + } + if ( motorSpeed.y < 0.0f ) + { + m_linMotion.motorAccel.y = m_linMotion.recedeAccel.y; + m_linMotion.motorSpeed.y = m_linMotion.recedeSpeed.y * motorSpeed.y; + } + if ( motorSpeed.y == 0.0f ) + { + m_linMotion.motorAccel.y = m_linMotion.stopAccel.y; + m_linMotion.motorSpeed.y = 0.0f; + } + + // Turn left/right. + speed = motorSpeed.z; +//? if ( motorSpeed.x < 0.0f ) speed = -speed; // reverse if running back + + if ( motorSpeed.z > 0.0f ) + { + m_cirMotion.motorAccel.y = m_cirMotion.advanceAccel.y; + m_cirMotion.motorSpeed.y = m_cirMotion.advanceSpeed.y * speed; + } + if ( motorSpeed.z < 0.0f ) + { + m_cirMotion.motorAccel.y = m_cirMotion.recedeAccel.y; + m_cirMotion.motorSpeed.y = m_cirMotion.recedeSpeed.y * speed; + } + if ( motorSpeed.z == 0.0f ) + { + m_cirMotion.motorAccel.y = m_cirMotion.stopAccel.y; + m_cirMotion.motorSpeed.y = 0.0f; + } + + if ( m_type == TYPE_FLYING && m_bLand ) // flying on the ground? + { + if ( type == OBJECT_HUMAN || + type == OBJECT_TECH ) + { + factor = LANDING_ACCELh; + } + else + { + factor = LANDING_ACCEL; + } + m_linMotion.motorAccel.x = m_linMotion.stopAccel.x*factor; + m_cirMotion.motorAccel.y = m_cirMotion.stopAccel.y*factor; + + pos = m_object->RetPosition(0); + h = m_terrain->RetFlyingLimit(pos, type==OBJECT_BEE); + h += m_object->RetCharacter()->height; + if ( motorSpeed.y > 0.0f && m_reactorRange > 0.1f && pos.y < h ) + { + m_bLand = FALSE; // take off + SetMotor(TRUE); + pos.y += 0.05f; // small initial height (startup) + m_object->SetPosition(0, pos); + } + } + + if ( m_type == TYPE_ROLLING ) + { + if ( motorSpeed.x == 0.0f && + motorSpeed.z == 0.0f ) + { + SetMotor(FALSE); + } + else + { + SetMotor(TRUE); + } + } + + if ( power != 0 ) // battery transported? + { + factor = 1.0f; + if ( type == OBJECT_MOBILEia || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEii ) factor = 0.5f; + + factor /= power->RetCapacity(); + + energy = power->RetEnergy(); + energy -= Abs(motorSpeed.x)*rTime*factor*0.005f; + energy -= Abs(motorSpeed.z)*rTime*factor*0.005f; + + if ( m_type == TYPE_FLYING && motorSpeed.y > 0.0f ) + { + energy -= motorSpeed.y*rTime*factor*0.01f; + } + if ( energy < 0.0f ) energy = 0.0f; + power->SetEnergy(energy); + } +} + + +// Updates the effects of vibration and tilt. + +void CPhysics::EffectUpdate(float aTime, float rTime) +{ + Character* character; + D3DVECTOR vibLin, vibCir, incl; + float speedLin, speedCir, accel; + ObjectType type; + BOOL bOnBoard; + + if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return; + + type = m_object->RetType(); + character = m_object->RetCharacter(); + + bOnBoard = FALSE; + if ( m_object->RetSelect() && + m_camera->RetType() == CAMERA_ONBOARD ) + { + bOnBoard = TRUE; + } + + vibLin = m_motion->RetLinVibration(); + vibCir = m_motion->RetCirVibration(); + incl = m_motion->RetInclinaison(); + + if ( type == OBJECT_HUMAN || // human? + type == OBJECT_TECH ) + { + if ( !m_bLand && !m_bSwim ) // in flight? + { + vibLin.y = sinf(aTime*2.00f)*0.5f+ + sinf(aTime*2.11f)*0.3f; + + vibCir.z = sinf(aTime*PI* 2.01f)*(PI/150.0f)+ + sinf(aTime*PI* 2.51f)*(PI/200.0f)+ + sinf(aTime*PI*19.01f)*(PI/400.0f); + + vibCir.x = sinf(aTime*PI* 2.03f)*(PI/150.0f)+ + sinf(aTime*PI* 2.52f)*(PI/200.0f)+ + sinf(aTime*PI*19.53f)*(PI/400.0f); + + speedLin = m_linMotion.realSpeed.x / m_linMotion.advanceSpeed.x; + speedCir = m_cirMotion.realSpeed.y / m_cirMotion.advanceSpeed.y; + incl.x = -speedLin*speedCir*0.5f; // looks if turn + +//? speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.5f; + speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.2f; + speedLin /= m_linMotion.advanceSpeed.x; + m_linMotion.finalInclin.z = speedLin*1.4f; + if ( incl.z < m_linMotion.finalInclin.z ) + { + incl.z += rTime*0.4f; + if ( incl.z > m_linMotion.finalInclin.z ) + { + incl.z = m_linMotion.finalInclin.z; + } + } + else if ( incl.z > m_linMotion.finalInclin.z ) + { + incl.z -= rTime*0.4f; + if ( incl.z < m_linMotion.finalInclin.z ) + { + incl.z = m_linMotion.finalInclin.z; + } + } + + vibLin *= m_linVibrationFactor; + vibCir *= m_cirVibrationFactor; + incl *= m_inclinaisonFactor; + + m_motion->SetLinVibration(vibLin); + m_motion->SetCirVibration(vibCir); + m_motion->SetInclinaison(incl); + } + else if ( m_bSwim ) // swimming? + { + vibLin.y = sinf(aTime*2.00f)*0.5f+ + sinf(aTime*2.11f)*0.3f; + + vibCir.z = sinf(aTime*PI* 2.01f)*(PI/150.0f)+ + sinf(aTime*PI* 2.51f)*(PI/200.0f)+ +//? sinf(aTime*PI*19.01f)*(PI/400.0f)-PI/2.0f; + sinf(aTime*PI*19.01f)*(PI/400.0f); + + vibCir.x = sinf(aTime*PI* 2.03f)*(PI/150.0f)+ + sinf(aTime*PI* 2.52f)*(PI/200.0f)+ + sinf(aTime*PI*19.53f)*(PI/400.0f); + + speedLin = m_linMotion.realSpeed.x / m_linMotion.advanceSpeed.x; + speedCir = m_cirMotion.realSpeed.y / m_cirMotion.advanceSpeed.y; + incl.x = -speedLin*speedCir*5.0f; // looks if turn + +//? speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.5f; + speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.2f; + speedLin /= m_linMotion.advanceSpeed.x; + m_linMotion.finalInclin.z = speedLin*1.4f; + if ( incl.z < m_linMotion.finalInclin.z ) + { + incl.z += rTime*0.4f; + if ( incl.z > m_linMotion.finalInclin.z ) + { + incl.z = m_linMotion.finalInclin.z; + } + } + else if ( incl.z > m_linMotion.finalInclin.z ) + { + incl.z -= rTime*0.4f; + if ( incl.z < m_linMotion.finalInclin.z ) + { + incl.z = m_linMotion.finalInclin.z; + } + } + + if ( m_linMotion.realSpeed.y > 0.0f ) // up? + { + vibCir.z += m_linMotion.realSpeed.y*0.05f; + } + else // down? + { + vibCir.z += m_linMotion.realSpeed.y*0.12f; + } + vibCir.z -= PI*0.4f; + + vibLin *= m_linVibrationFactor; + vibCir *= m_cirVibrationFactor; + incl *= m_inclinaisonFactor; + + m_motion->SetLinVibration(vibLin); + m_motion->SetCirVibration(vibCir); + m_motion->SetInclinaison(incl); + } + else + { + m_motion->SetLinVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); +//? m_motion->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); +//? m_motion->SetInclinaison(D3DVECTOR(0.0f, 0.0f, 0.0f)); + } + } + + if ( type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEtg || + type == OBJECT_APOLLO2 ) // wheels? + { + speedLin = m_linMotion.realSpeed.x / m_linMotion.advanceSpeed.x; + speedCir = m_cirMotion.realSpeed.y / m_cirMotion.advanceSpeed.y; + incl.x = speedLin*speedCir*0.20f; // looks if turn + if ( type == OBJECT_APOLLO2 ) incl.x *= 0.25f; + + speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x; + speedLin /= m_linMotion.advanceSpeed.x; + if ( speedLin > 1.0f ) speedLin = 1.0f; + m_linMotion.finalInclin.z = -speedLin*0.30f; + accel = (0.40f-Abs(incl.z))*4.0f; + if ( incl.z < m_linMotion.finalInclin.z ) + { + incl.z += rTime*accel; + if ( incl.z > m_linMotion.finalInclin.z ) + { + incl.z = m_linMotion.finalInclin.z; + } + } + else if ( incl.z > m_linMotion.finalInclin.z ) + { + incl.z -= rTime*accel; + if ( incl.z < m_linMotion.finalInclin.z ) + { + incl.z = m_linMotion.finalInclin.z; + } + } + if ( bOnBoard ) incl.z *= 0.1f; + if ( type == OBJECT_APOLLO2 ) incl.z *= 0.25f; + m_object->SetInclinaison(incl); + + vibLin.x = 0.0f; + vibLin.z = 0.0f; + vibLin.y = Abs(character->wheelFront*sinf(incl.z))*0.8f + + Abs(character->wheelRight*sinf(incl.x))*0.5f; + m_motion->SetLinVibration(vibLin); + } + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEft ) // fliyng? + { + if ( m_bLand ) // on the ground? + { + m_motion->SetLinVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); + m_motion->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); + m_motion->SetInclinaison(D3DVECTOR(0.0f, 0.0f, 0.0f)); + } + else // in flight? + { + vibLin.y = sinf(aTime*2.00f)*0.5f+ + sinf(aTime*2.11f)*0.3f; + + vibCir.z = sinf(aTime*PI* 2.01f)*(PI/150.0f)+ + sinf(aTime*PI* 2.51f)*(PI/200.0f)+ + sinf(aTime*PI*19.01f)*(PI/400.0f); + + vibCir.x = sinf(aTime*PI* 2.03f)*(PI/150.0f)+ + sinf(aTime*PI* 2.52f)*(PI/200.0f)+ + sinf(aTime*PI*19.53f)*(PI/400.0f); + + if ( bOnBoard ) vibCir *= 0.4f; + + speedLin = m_linMotion.realSpeed.x / m_linMotion.advanceSpeed.x; + speedCir = m_cirMotion.realSpeed.y / m_cirMotion.advanceSpeed.y; + incl.x = -speedLin*speedCir*0.5f; // looks if turn + +//? speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.5f; + speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.2f; + speedLin /= m_linMotion.advanceSpeed.x; + m_linMotion.finalInclin.z = speedLin*0.8f; + if ( incl.z < m_linMotion.finalInclin.z ) + { + incl.z += rTime*0.4f; + if ( incl.z > m_linMotion.finalInclin.z ) + { + incl.z = m_linMotion.finalInclin.z; + } + } + else if ( incl.z > m_linMotion.finalInclin.z ) + { + incl.z -= rTime*0.4f; + if ( incl.z < m_linMotion.finalInclin.z ) + { + incl.z = m_linMotion.finalInclin.z; + } + } +//? if ( bOnBoard ) incl.z *= 0.5f; + + vibLin *= m_linVibrationFactor; + vibCir *= m_cirVibrationFactor; + incl *= m_inclinaisonFactor; + + m_motion->SetLinVibration(vibLin); + m_motion->SetCirVibration(vibCir); + m_motion->SetInclinaison(incl); + } + } + + if ( type == OBJECT_BEE ) // bee? + { + if ( !m_bLand ) // in flight? + { + vibLin.y = sinf(aTime*2.00f)*0.5f+ + sinf(aTime*2.11f)*0.3f; + + vibCir.z = (Rand()-0.5f)*0.1f+ + sinf(aTime*PI* 2.01f)*(PI/150.0f)+ + sinf(aTime*PI* 2.51f)*(PI/200.0f)+ + sinf(aTime*PI*19.01f)*(PI/400.0f); + + vibCir.x = (Rand()-0.5f)*0.1f+ + sinf(aTime*PI* 2.03f)*(PI/150.0f)+ + sinf(aTime*PI* 2.52f)*(PI/200.0f)+ + sinf(aTime*PI*19.53f)*(PI/400.0f); + + speedLin = m_linMotion.realSpeed.x / m_linMotion.advanceSpeed.x; + speedCir = m_cirMotion.realSpeed.y / m_cirMotion.advanceSpeed.y; + incl.x = -speedLin*speedCir*1.5f; // looks if turn + +//? speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.5f; + speedLin = m_linMotion.currentSpeed.x - m_linMotion.motorSpeed.x*1.2f; + speedLin /= m_linMotion.advanceSpeed.x; + m_linMotion.finalInclin.z = speedLin*1.4f; + if ( incl.z < m_linMotion.finalInclin.z ) + { + incl.z += rTime*1.6f; + if ( incl.z > m_linMotion.finalInclin.z ) + { + incl.z = m_linMotion.finalInclin.z; + } + } + else if ( incl.z > m_linMotion.finalInclin.z ) + { + incl.z -= rTime*1.6f; + if ( incl.z < m_linMotion.finalInclin.z ) + { + incl.z = m_linMotion.finalInclin.z; + } + } + + vibLin *= m_linVibrationFactor; + vibCir *= m_cirVibrationFactor; + incl *= m_inclinaisonFactor; + + m_motion->SetLinVibration(vibLin); + m_motion->SetCirVibration(vibCir); + m_motion->SetInclinaison(incl); + } + } +} + + +// Updates structure Motion. + +void CPhysics::UpdateMotionStruct(float rTime, Motion &motion) +{ + float speed, motor; + + // Management for the coordinate x. + speed = motion.currentSpeed.x; + motor = motion.motorSpeed.x * m_inclinaisonFactor; + if ( speed < motor ) + { + speed += rTime*motion.motorAccel.x; // accelerates + if ( speed > motor ) + { + speed = motor; // does not exceed the speed + } + } + if ( speed > motor ) + { + speed -= rTime*motion.motorAccel.x; // decelerates + if ( speed < motor ) + { + speed = motor; // does not exceed the speed + } + } + motion.currentSpeed.x = speed; + motion.realSpeed.x = speed; + + if ( Abs(motion.terrainSpeed.x) > motion.terrainSlide.x ) + { + if ( motion.terrainSpeed.x > 0 ) + { + speed = motion.terrainSpeed.x - motion.terrainSlide.x; + } + else + { + speed = motion.terrainSpeed.x + motion.terrainSlide.x; + } + motion.realSpeed.x += speed; + } + + // Management for the coordinate y. + speed = motion.currentSpeed.y; + motor = motion.motorSpeed.y; // unlimited speed! + if ( speed < motor ) + { + speed += rTime*motion.motorAccel.y; // accelerates + if ( speed > motor ) + { + speed = motor; // does not exceed the speed + } + } + if ( speed > motor ) + { + speed -= rTime*motion.motorAccel.y; // decelerates + if ( speed < motor ) + { + speed = motor; // does not exceed the speed + } + } + motion.currentSpeed.y = speed; + motion.realSpeed.y = speed; + + if ( Abs(motion.terrainSpeed.y) > motion.terrainSlide.y ) + { + if ( motion.terrainSpeed.y > 0 ) + { + speed = motion.terrainSpeed.y - motion.terrainSlide.y; + } + else + { + speed = motion.terrainSpeed.y + motion.terrainSlide.y; + } + motion.realSpeed.y += speed; + } + + // Management for the coordinate z. + speed = motion.currentSpeed.z; + motor = motion.motorSpeed.z * m_inclinaisonFactor; + if ( speed < motor ) + { + speed += rTime*motion.motorAccel.z; // accelerates + if ( speed > motor ) + { + speed = motor; // does not exceed the speed + } + } + if ( speed > motor ) + { + speed -= rTime*motion.motorAccel.z; // decelerates + if ( speed < motor ) + { + speed = motor; // does not exceed the speed + } + } + motion.currentSpeed.z = speed; + motion.realSpeed.z = speed; + + if ( Abs(motion.terrainSpeed.z) > motion.terrainSlide.z ) + { + if ( motion.terrainSpeed.z > 0 ) + { + speed = motion.terrainSpeed.z - motion.terrainSlide.z; + } + else + { + speed = motion.terrainSpeed.z + motion.terrainSlide.z; + } + motion.realSpeed.z += speed; + } +} + + +// Makes physics evolve as time elapsed. +// Returns FALSE if the object is destroyed. +// +// a: acceleration +// v1: velocity at time t1 +// v2: velocity at time t2 +// dt: time elapsed since t1, then: dt = t2-t1 +// dd: difference in distance (advance) +// +// v2 = v1 + a*dt +// dd = v2*dt + +BOOL CPhysics::EventFrame(const Event &event) +{ + ObjectType type; + D3DMATRIX objRotate, matRotate; + D3DVECTOR iPos, iAngle, tAngle, pos, newpos, angle, newangle, n; + float h, w; + int i; + + if ( m_engine->RetPause() ) return TRUE; + + m_time += event.rTime; + m_timeUnderWater += event.rTime; + m_soundTimeJostle += event.rTime; + + type = m_object->RetType(); + + FrameParticule(m_time, event.rTime); + MotorUpdate(m_time, event.rTime); + EffectUpdate(m_time, event.rTime); + WaterFrame(m_time, event.rTime); + + iPos = pos = m_object->RetPosition(0); + iAngle = angle = m_object->RetAngle(0); + + // Accelerate is the descent, brake is the ascent. + if ( m_bFreeze || m_object->RetDead() ) + { + m_linMotion.terrainSpeed.x = 0.0f; + m_linMotion.terrainSpeed.z = 0.0f; + m_linMotion.terrainSpeed.y = 0.0f; + } + else + { + tAngle = angle; + h = m_terrain->RetBuildingFactor(pos); + if ( type == OBJECT_HUMAN || + type == OBJECT_TECH ) + { + if ( m_linMotion.currentSpeed.x == 0.0f ) + { + h *= 0.5f; // immobile man -> slippage + } + FloorAngle(pos, tAngle); // calculates the angle with the ground + } +#if 1 + if ( pos.y < m_water->RetLevel(m_object) ) // underwater? + { + h *= 0.5f; + } +#endif +//? m_linMotion.terrainSpeed.x = -tAngle.z*m_linMotion.terrainForce.x*h; +//? m_linMotion.terrainSpeed.z = tAngle.x*m_linMotion.terrainForce.z*h; +//? m_linMotion.terrainSpeed.x = -sinf(tAngle.z)*PI*0.5f*m_linMotion.terrainForce.x*h; +//? m_linMotion.terrainSpeed.z = sinf(tAngle.x)*PI*0.5f*m_linMotion.terrainForce.z*h; + m_linMotion.terrainSpeed.x = -tanf(tAngle.z)*0.9f*m_linMotion.terrainForce.x*h; + m_linMotion.terrainSpeed.z = tanf(tAngle.x)*0.9f*m_linMotion.terrainForce.z*h; + m_linMotion.terrainSpeed.y = 0.0f; + + // If the terrain is very steep, do not exaggerate! + if ( m_linMotion.terrainSpeed.x > 50.0f ) m_linMotion.terrainSpeed.x = 20.0f; + if ( m_linMotion.terrainSpeed.x < -50.0f ) m_linMotion.terrainSpeed.x = -20.0f; + if ( m_linMotion.terrainSpeed.z > 50.0f ) m_linMotion.terrainSpeed.z = 20.0f; + if ( m_linMotion.terrainSpeed.z < -50.0f ) m_linMotion.terrainSpeed.z = -20.0f; + } + + if ( type == OBJECT_BEE && !m_bLand ) + { + h = m_floorLevel; // ground level + w = m_water->RetLevel(m_object); + if ( h < w ) h = w; + h = pos.y-h-10.0f; // maximum height (*) + if ( h < 0.0f ) h = 0.0f; + m_linMotion.terrainSpeed.y = -h*2.5f; // is not above + } + + // (*) High enough to pass over the tower defense (OBJECT_TOWER), + // but not too much to pass under the cover of the ship (OBJECT_BASE)! + + UpdateMotionStruct(event.rTime, m_linMotion); + UpdateMotionStruct(event.rTime, m_cirMotion); + + newangle = angle + event.rTime*m_cirMotion.realSpeed; + MatRotateZXY(matRotate, newangle); + newpos = event.rTime*m_linMotion.realSpeed; + newpos = Transform(matRotate, newpos); + newpos += pos; + + m_terrain->LimitPos(newpos); + + if ( m_type == TYPE_FLYING && !m_bLand ) + { + h = m_terrain->RetFlyingLimit(newpos, type==OBJECT_BEE); + h += m_object->RetCharacter()->height; + if ( newpos.y > h ) newpos.y = h; + } + + if ( m_bForceUpdate || + newpos.x != pos.x || + newpos.y != pos.y || + newpos.z != pos.z || + newangle.x != angle.x || + newangle.y != angle.y || + newangle.z != angle.z ) + { + FloorAdapt(m_time, event.rTime, newpos, newangle); + } + + if ( m_bForceUpdate || + newpos.x != pos.x || + newpos.y != pos.y || + newpos.z != pos.z ) + { + i = ObjectAdapt(newpos, newangle); + if ( i == 2 ) // object destroyed? + { + return FALSE; + } + if ( i == 1 ) // immobile object? + { + newpos = iPos; // keeps the initial position, but accepts the rotation + } + } + + if ( newangle.x != angle.x || + newangle.y != angle.y || + newangle.z != angle.z ) + { + m_object->SetAngle(0, newangle); + } + + if ( newpos.x != pos.x || + newpos.y != pos.y || + newpos.z != pos.z ) + { + m_object->SetPosition(0, newpos); + } + + MotorParticule(m_time, event.rTime); + SoundMotor(event.rTime); + + m_bForceUpdate = FALSE; + + return TRUE; +} + +// Starts or stops the engine sounds. + +void CPhysics::SoundMotor(float rTime) +{ + CObject* power; + ObjectType type; + float energy; + + m_lastSoundInsect -= rTime; + type = m_object->RetType(); + + if ( type == OBJECT_MOTHER ) + { + if ( m_lastSoundInsect <= 0.0f && m_object->RetActif() ) + { + m_sound->Play(SOUND_INSECTm, m_object->RetPosition(0)); + if ( m_bMotor ) m_lastSoundInsect = 0.4f+Rand()*2.5f; + else m_lastSoundInsect = 1.5f+Rand()*4.0f; + } + } + else if ( type == OBJECT_ANT ) + { + if ( m_object->RetBurn() || + m_object->RetFixed() ) + { + if ( m_lastSoundInsect <= 0.0f ) + { + m_sound->Play(SOUND_INSECTa, m_object->RetPosition(0), 1.0f, 1.5f+Rand()*0.5f); + m_lastSoundInsect = 0.4f+Rand()*0.6f; + } + } + else if ( m_object->RetActif() ) + { + if ( m_lastSoundInsect <= 0.0f ) + { + m_sound->Play(SOUND_INSECTa, m_object->RetPosition(0)); + if ( m_bMotor ) m_lastSoundInsect = 0.4f+Rand()*2.5f; + else m_lastSoundInsect = 1.5f+Rand()*4.0f; + } + } + } + else if ( type == OBJECT_BEE ) + { + if ( m_object->RetActif() ) + { + if ( m_lastSoundInsect <= 0.0f ) + { + m_sound->Play(SOUND_INSECTb, m_object->RetPosition(0)); + if ( m_bMotor ) m_lastSoundInsect = 0.4f+Rand()*2.5f; + else m_lastSoundInsect = 1.5f+Rand()*4.0f; + } + } + else if ( m_object->RetBurn() ) + { + if ( m_lastSoundInsect <= 0.0f ) + { + m_sound->Play(SOUND_INSECTb, m_object->RetPosition(0), 1.0f, 1.5f+Rand()*0.5f); + m_lastSoundInsect = 0.3f+Rand()*0.5f; + } + } + } + else if ( type == OBJECT_WORM ) + { + if ( m_object->RetActif() ) + { + if ( m_lastSoundInsect <= 0.0f ) + { + m_sound->Play(SOUND_INSECTw, m_object->RetPosition(0)); + if ( m_bMotor ) m_lastSoundInsect = 0.4f+Rand()*2.5f; + else m_lastSoundInsect = 1.5f+Rand()*4.0f; + } + } + else if ( m_object->RetBurn() ) + { + if ( m_lastSoundInsect <= 0.0f ) + { + m_sound->Play(SOUND_INSECTw, m_object->RetPosition(0), 1.0f, 1.5f+Rand()*0.5f); + m_lastSoundInsect = 0.2f+Rand()*0.2f; + } + } + } + else if ( type == OBJECT_SPIDER ) + { + if ( m_object->RetBurn() || + m_object->RetFixed() ) + { + if ( m_lastSoundInsect <= 0.0f ) + { + m_sound->Play(SOUND_INSECTs, m_object->RetPosition(0), 1.0f, 1.5f+Rand()*0.5f); + m_lastSoundInsect = 0.4f+Rand()*0.6f; + } + } + else if ( m_object->RetActif() ) + { + if ( m_lastSoundInsect <= 0.0f ) + { + m_sound->Play(SOUND_INSECTs, m_object->RetPosition(0)); + if ( m_bMotor ) m_lastSoundInsect = 0.4f+Rand()*2.5f; + else m_lastSoundInsect = 1.5f+Rand()*4.0f; + } + } + } + else // vehicle? + { + if ( m_type == TYPE_ROLLING ) + { + if ( m_bMotor && m_object->RetActif() ) + { + SoundMotorFull(rTime, type); // full diet + } + else + { + energy = 0.0f; + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + } + + if ( m_object->RetSelect() && + energy != 0.0f ) + { + SoundMotorSlow(rTime, type); // in slow motion + } + else + { + SoundMotorStop(rTime, type); // to the stop + } + } + } + + if ( m_type == TYPE_FLYING ) + { + if ( m_bMotor && !m_bSwim && + m_object->RetActif() && !m_object->RetDead() ) + { + SoundReactorFull(rTime, type); // full diet + } + else + { + SoundReactorStop(rTime, type); // to the stop + } + } + } +} + +// Detonates the object if it is underwater. + +void CPhysics::WaterFrame(float aTime, float rTime) +{ + ObjectType type; + D3DVECTOR pos, speed; + FPOINT dim; + float level; + + level = m_water->RetLevel(); + if ( level == 0.0f ) return; // no water? + if ( m_object->RetTruck() != 0 ) return; // object transported? + + // Management of flames into the lava. + pos = m_object->RetPosition(0); + if ( m_water->RetLava() && + pos.y-m_object->RetCharacter()->height <= level ) + { + if ( m_lastFlameParticule+m_engine->ParticuleAdapt(0.05f) <= aTime ) + { + m_lastFlameParticule = aTime; + + pos = m_object->RetPosition(0); + pos.x += (Rand()-0.5f)*3.0f; + pos.z += (Rand()-0.5f)*3.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = Rand()*5.0f+3.0f; + dim.x = Rand()*2.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFLAME, 2.0f, 0.0f, 0.2f); + + pos = m_object->RetPosition(0); + pos.y -= 2.0f; + pos.x += (Rand()-0.5f)*5.0f; + pos.z += (Rand()-0.5f)*5.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 6.0f+Rand()*6.0f+6.0f; + dim.x = Rand()*1.5f+1.0f+3.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); + } + } + + pos = m_object->RetPosition(0); + if ( pos.y >= m_water->RetLevel(m_object) ) return; // out of water? + + type = m_object->RetType(); + if ( type == OBJECT_TOTO ) return; + if ( type == OBJECT_NULL ) return; + + if ( !m_object->RetActif() ) return; + if ( m_object->RetResetBusy() ) return; // reset in progress? + + if ( m_water->RetLava() || + (type == OBJECT_HUMAN && + m_object->RetOption() != 0 ) || // human without a helmet? + type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEft || + type == OBJECT_MOBILEtt || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEit || + type == OBJECT_MOBILEdr || + type == OBJECT_APOLLO2 ) // vehicle not underwater? + { + m_object->ExploObject(EXPLO_WATER, 1.0f); // starts explosion + } +} + +// Sounds the engine at full power. + +void CPhysics::SoundMotorFull(float rTime, ObjectType type) +{ + Sound sound; + float amplitude, time, freq; + + if ( type == OBJECT_MOBILEia || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEis ) + { + if ( m_soundChannel == -1 ) + { + m_soundChannel = m_sound->Play(SOUND_MOTORi, m_object->RetPosition(0), 0.0f, 1.0f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 0.2f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 1.0f, SOPER_LOOP); + } + else + { + m_sound->Position(m_soundChannel, m_object->RetPosition(0)); + } + + freq = 1.0f+m_linMotion.terrainSpeed.x/50.0f; + if ( m_linMotion.realSpeed.x == 0.0f ) + { + freq -= Abs(m_cirMotion.realSpeed.y/3.0f); + } + else + { + freq -= Abs(m_cirMotion.realSpeed.y/4.0f); + } + m_sound->Frequency(m_soundChannel, freq); + + return; + } + + if ( type == OBJECT_MOBILEsa ) + { + sound = SOUND_MOTORs; + amplitude = 0.6f; + time = 0.5f; + } + else if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) + { + sound = SOUND_MOTORr; + amplitude = 1.0f; + time = 0.7f; + } + else if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts ) + { + sound = SOUND_MOTORt; + amplitude = 1.0f; + time = 0.5f; + } + else if ( type == OBJECT_APOLLO2 ) + { + sound = SOUND_MANIP; + amplitude = 1.0f; + time = 0.5f; + } + else + { + sound = SOUND_MOTORw; + amplitude = 0.7f; + time = 0.3f; + } + + if ( m_object->RetToy() ) + { + sound = SOUND_MOTORd; + amplitude = 1.0f; + time = 0.1f; + } + + freq = 0.75f+(Abs(m_motorSpeed.x)+Abs(m_motorSpeed.z))*0.25f; + if ( freq > 1.0f ) freq = 1.0f; + if ( m_object->RetToy() ) freq = 1.0f; + + if ( m_soundChannel == -1 ) + { + m_soundChannel = m_sound->Play(sound, m_object->RetPosition(0), 0.0f, 0.5f, TRUE); + m_sound->AddEnvelope(m_soundChannel, amplitude, freq, time, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, amplitude, freq, 1.0f, SOPER_LOOP); + } + else + { + m_sound->Position(m_soundChannel, m_object->RetPosition(0)); + + if ( m_bSoundSlow ) // in slow motion? + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, amplitude, freq, time, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, amplitude, freq, 1.0f, SOPER_LOOP); + m_bSoundSlow = FALSE; + } + } + + freq *= 1.0f + m_linMotion.terrainSpeed.x/100.0f; + freq *= 1.0f + Abs(m_cirMotion.realSpeed.y/20.0f); + m_sound->Frequency(m_soundChannel, freq); + + m_soundTimePshhh -= rTime*2.0f; +} + +// Sounds the engine idling. + +void CPhysics::SoundMotorSlow(float rTime, ObjectType type) +{ + D3DMATRIX* mat; + D3DVECTOR pos, speed; + FPOINT dim; + Sound sound; + float amplitude; + int i, max; + + if ( type == OBJECT_MOBILEia || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEis ) + { + if ( m_soundChannel != -1 ) // engine is running? + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 0.3f, SOPER_STOP); + m_soundChannel = -1; + } + return; + } + + if ( type == OBJECT_MOBILEsa ) + { + sound = SOUND_MOTORs; + amplitude = 0.4f; + } + else if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) + { + sound = SOUND_MOTORr; + amplitude = 0.9f; + } + else if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts ) + { + sound = SOUND_MOTORt; + amplitude = 0.7f; + } + else if ( type == OBJECT_APOLLO2 ) + { + if ( m_soundChannel != -1 ) // engine is running? + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.3f, SOPER_STOP); + m_soundChannel = -1; + } + return; + } + else + { + sound = SOUND_MOTORw; + amplitude = 0.3f; + } + + if ( m_object->RetToy() ) + { + sound = SOUND_MOTORd; + amplitude = 0.0f; + } + + if ( m_soundChannel == -1 ) + { + m_soundChannel = m_sound->Play(sound, m_object->RetPosition(0), 0.0f, 0.25f, TRUE); + m_sound->AddEnvelope(m_soundChannel, amplitude, 0.5f, 0.2f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, amplitude, 0.5f, 1.0f, SOPER_LOOP); + } + else + { + m_sound->Position(m_soundChannel, m_object->RetPosition(0)); + + if ( !m_bSoundSlow ) // full power? + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, amplitude, 0.5f, 0.3f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, amplitude, 0.5f, 1.0f, SOPER_LOOP); + m_bSoundSlow = TRUE; + } + } + + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) + { + m_soundTimePshhh -= rTime; + + if ( m_soundTimePshhh <= 0.0f ) + { + amplitude = 0.5f-m_soundTimePshhh*0.08f; + if ( amplitude > 1.0f ) amplitude = 1.0f; +//? m_sound->Play(SOUND_PSHHH, m_object->RetPosition(0), amplitude); + m_sound->Play(SOUND_PSHHH, m_object->RetPosition(0), 1.0f); + + m_soundTimePshhh = 4.0f+4.0f*Rand(); + + max = (int)(10.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; iRetWorldMatrix(0); + pos = Transform(*mat, pos); + speed = Transform(*mat, speed)-pos; + + dim.x = Rand()*1.0f+1.0f; + dim.y = dim.x; + + m_particule->CreateParticule(pos, speed, dim, PARTIMOTOR, 2.0f); + } + } + } +} + +// Sounds the engine not running. + +void CPhysics::SoundMotorStop(float rTime, ObjectType type) +{ + if ( type == OBJECT_MOBILEia || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEis ) + { + if ( m_soundChannel != -1 ) // engine is running? + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 0.3f, SOPER_STOP); + m_soundChannel = -1; + } + return; + } + + if ( m_soundChannel != -1 ) // engine is running? + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.3f, SOPER_STOP); + m_soundChannel = -1; + } + + m_soundTimePshhh -= rTime*2.0f; +} + +// Sounds the reactor at full power. + +void CPhysics::SoundReactorFull(float rTime, ObjectType type) +{ + Sound sound; + D3DMATRIX* mat; + D3DVECTOR pos, speed; + FPOINT dim; + float freq; + int i; + + if ( m_soundChannelSlide != -1 ) // slides? + { + m_sound->FlushEnvelope(m_soundChannelSlide); + m_sound->AddEnvelope(m_soundChannelSlide, 0.0f, 1.0f, 0.3f, SOPER_STOP); + m_soundChannelSlide = -1; + } + + if ( m_reactorRange > 0.0f ) + { + if ( m_soundChannel == -1 ) + { + if ( type == OBJECT_HUMAN || + type == OBJECT_TECH ) + { + sound = SOUND_FLYh; + } + else + { + sound = SOUND_FLY; + } + + m_soundChannel = m_sound->Play(sound, m_object->RetPosition(0), 0.0f, 1.0f, TRUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 0.6f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 1.0f, SOPER_LOOP); + } + else + { + m_sound->Position(m_soundChannel, m_object->RetPosition(0)); + } + + freq = 1.0f + m_linMotion.realSpeed.y/100.0f; + freq *= 1.0f + Abs(m_cirMotion.realSpeed.y/5.0f); + m_sound->Frequency(m_soundChannel, freq); + } + else + { + if ( m_soundChannel != -1 ) // engine is running? + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + if ( m_timeReactorFail <= m_time ) + { + freq = 1.0f+Rand()*0.5f; + m_sound->Play(SOUND_FLYf, m_object->RetPosition(0), 1.0f, freq); + m_camera->StartEffect(CE_PET, m_object->RetPosition(0), 1.0f); + + for ( i=0 ; i<5 ; i++ ) + { + if ( m_object->RetType() == OBJECT_HUMAN || + m_object->RetType() == OBJECT_TECH ) + { + pos = D3DVECTOR(-1.6f, -0.5f, 0.0f); + } + else + { + pos = D3DVECTOR(0.0f, -1.0f, 0.0f); + } + pos.x += (Rand()-0.5f)*2.0f; + pos.z += (Rand()-0.5f)*2.0f; + mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, pos); + speed.x = (Rand()-0.5f)*5.0f; + speed.z = (Rand()-0.5f)*5.0f; + speed.y = -(4.0f+Rand()*4.0f); + dim.x = (2.0f+Rand()*1.0f); + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 2.0f, 0.0f, 0.1f); + } + + m_timeReactorFail = m_time+0.10f+Rand()*0.30f; + } + else + { + if ( m_object->RetType() == OBJECT_HUMAN || + m_object->RetType() == OBJECT_TECH ) + { + pos = D3DVECTOR(-1.6f, -0.5f, 0.0f); + } + else + { + pos = D3DVECTOR(0.0f, -1.0f, 0.0f); + } + pos.x += (Rand()-0.5f)*1.0f; + pos.z += (Rand()-0.5f)*1.0f; + mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, pos); + speed.x = (Rand()-0.5f)*2.0f; + speed.z = (Rand()-0.5f)*2.0f; + speed.y = -(4.0f+Rand()*4.0f); + dim.x = (0.7f+Rand()*0.4f); + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 2.0f, 0.0f, 0.1f); + } + } + +} + +// Sounds the reactor stopped. + +void CPhysics::SoundReactorStop(float rTime, ObjectType type) +{ + CObject* power; + float energy; + + energy = 0.0f; + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + } + + if ( m_soundChannel != -1 ) // engine is running? + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + if ( type == OBJECT_HUMAN || + type == OBJECT_TECH ) + { + if ( m_soundChannelSlide != -1 ) // slides? + { + m_sound->FlushEnvelope(m_soundChannelSlide); + m_sound->AddEnvelope(m_soundChannelSlide, 0.0f, 1.0f, 0.3f, SOPER_STOP); + m_soundChannelSlide = -1; + } + } + else + { + if ( energy != 0.0f && + (m_motorSpeed.x != 0.0f || // slides with small reactors in skates? + m_cirMotion.realSpeed.y != 0.0f) ) + { + if ( m_soundChannelSlide == -1 ) + { + m_soundChannelSlide = m_sound->Play(SOUND_SLIDE, m_object->RetPosition(0), 0.0f, 1.0f, TRUE); + m_sound->AddEnvelope(m_soundChannelSlide, 0.5f, 1.0f, 0.3f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannelSlide, 0.5f, 1.0f, 1.0f, SOPER_LOOP); + } + m_sound->Position(m_soundChannelSlide, m_object->RetPosition(0)); + } + else + { + if ( m_soundChannelSlide != -1 ) // slides? + { + m_sound->FlushEnvelope(m_soundChannelSlide); + m_sound->AddEnvelope(m_soundChannelSlide, 0.0f, 1.0f, 0.3f, SOPER_STOP); + m_soundChannelSlide = -1; + } + } + } +} + + +// Adapts the physics of the object based on the ground. + +void CPhysics::FloorAdapt(float aTime, float rTime, + D3DVECTOR &pos, D3DVECTOR &angle) +{ + Character* character; + ObjectType type; + D3DVECTOR norm; + D3DMATRIX matRotate; + float level, h, f, a1, volume, freq, force; + BOOL bOldSwim, bSlopingTerrain; + + type = m_object->RetType(); + character = m_object->RetCharacter(); + + level = m_water->RetLevel(m_object); + bOldSwim = m_bSwim; + SetSwim( pos.y < level ); + + m_floorLevel = m_terrain->RetFloorLevel(pos); // height above the ground + h = pos.y-m_floorLevel; + h -= character->height; + m_floorHeight = h; + + WaterParticule(aTime, pos, type, m_floorLevel, + Abs(m_linMotion.realSpeed.x), + Abs(m_cirMotion.realSpeed.y*15.0f)); + + if ( m_type == TYPE_ROLLING ) + { + pos.y -= h; // plate to the ground immediately + pos.y += character->height; + m_floorHeight = 0.0f; + } + + if ( m_type == TYPE_FLYING ) + { + bSlopingTerrain = FALSE; // ground as possible to land + + if ( !m_bLand ) // in flight? + { + m_terrain->GetNormal(norm, pos); + a1 = Abs(RotateAngle(Length(norm.x, norm.z), norm.y)); + if ( a1 < (90.0f-55.0f)*PI/180.0f ) // slope exceeds 55 degrees? + { + bSlopingTerrain = TRUE; // very sloped ground + + if ( h < 4.0f ) // collision with the ground? + { + force = 5.0f+Abs(m_linMotion.realSpeed.x*0.3f)+ + Abs(m_linMotion.realSpeed.y*0.3f); + m_linMotion.currentSpeed = norm*force; + MatRotateXZY(matRotate, -angle); + m_linMotion.currentSpeed = Transform(matRotate, m_linMotion.currentSpeed); + + if ( aTime-m_soundTimeBoum > 0.5f ) + { + volume = Abs(m_linMotion.realSpeed.x*0.02f)+ + Abs(m_linMotion.realSpeed.y*0.02f); + freq = 0.5f+m_terrain->RetHardness(pos)*2.5f; + m_sound->Play(SOUND_BOUM, pos, volume, freq); + + m_soundTimeBoum = aTime; + } + +//? pos = m_object->RetPosition(0); // gives position before collision + } + } + } + + if ( (h <= 0.0f || m_bLand) && !bSlopingTerrain ) // on the ground? + { + if ( !m_bLand ) // in flight? + { + volume = Abs(m_linMotion.realSpeed.y*0.02f); + freq = 0.5f+m_terrain->RetHardness(pos)*2.5f; + m_sound->Play(SOUND_BOUM, pos, volume, freq); + } + + m_bLand = TRUE; // on the ground? + SetMotor(FALSE); + pos.y -= h; // plate to the ground immediately + m_floorHeight = 0.0f; + + if ( h < 0.0f ) + { + f = Abs(m_linMotion.currentSpeed.y/m_linMotion.advanceSpeed.y); + CrashParticule(f); + } + m_linMotion.currentSpeed.y = 0.0f; + m_inclinaisonFactor = 1.0f/LANDING_SPEED; // slips a little to the ground + m_linVibrationFactor = 0.0f; + m_cirVibrationFactor = 0.0f; + + if ( type == OBJECT_HUMAN || + type == OBJECT_TECH ) return; // always right + } + + if ( h > 4.0f || bSlopingTerrain ) // meters above the ground? + { + if ( m_bSwim ) + { + m_linVibrationFactor = 1.0f; // vibrates a max + m_cirVibrationFactor = 1.0f; + } + else + { + m_linVibrationFactor = 2.0f; // vibrates a large max + m_cirVibrationFactor = 2.0f; + } + m_inclinaisonFactor = 1.0f; + + // Gives gently the horizontal. + if ( angle.x > 0.0f ) + { + angle.x -= rTime*0.5f; + if ( angle.x < 0.0f ) angle.x = 0.0f; + } + if ( angle.x < 0.0f ) + { + angle.x += rTime*0.5f; + if ( angle.x > 0.0f ) angle.x = 0.0f; + } + if ( angle.z > 0.0f ) + { + angle.z -= rTime*0.5f; + if ( angle.z < 0.0f ) angle.z = 0.0f; + } + if ( angle.z < 0.0f ) + { + angle.z += rTime*0.5f; + if ( angle.z > 0.0f ) angle.z = 0.0f; + } + return; + } + } + + if ( m_floorHeight == 0.0f ) // ground plate? + { + if ( m_object->RetTraceDown() ) + { + WheelParticule(m_object->RetTraceColor(), m_object->RetTraceWidth()*g_unit); + } + else + { + WheelParticule(-1, 0.0f); + } + } + + if ( type == OBJECT_HUMAN || + type == OBJECT_TECH || + type == OBJECT_WORM ) return; // always right + + FloorAngle(pos, angle); // adjusts the angle at the ground + + if ( m_type == TYPE_FLYING && !m_bLand ) // flying in the air? + { + f = h/1.0f; + if ( f < 0.0f ) f = 0.0f; + if ( f > 1.0f ) f = 1.0f; + m_linVibrationFactor = f; + m_cirVibrationFactor = f; + angle.z *= 1.0f-f; + angle.x *= 1.0f-f; + + f = h/1.0f; + if ( f < 0.0f ) f = 0.0f; + if ( f > 1.0f ) f = 1.0f; + m_inclinaisonFactor = f; + } +} + +// Calculates the angle of an object with the field. + +void CPhysics::FloorAngle(const D3DVECTOR &pos, D3DVECTOR &angle) +{ + Character* character; + D3DVECTOR pw, norm; + float a1, a2; + + character = m_object->RetCharacter(); + + pw.x = pos.x+character->wheelFront*cosf(angle.y+PI*0.0f); + pw.y = pos.y; + pw.z = pos.z-character->wheelFront*sinf(angle.y+PI*0.0f); + a1 = atanf(m_terrain->RetFloorHeight(pw)/character->wheelFront); + + pw.x = pos.x+character->wheelBack*cosf(angle.y+PI*1.0f); + pw.y = pos.y; + pw.z = pos.z-character->wheelBack*sinf(angle.y+PI*1.0f); + a2 = atanf(m_terrain->RetFloorHeight(pw)/character->wheelBack); + + angle.z = (a2-a1)/2.0f; + + pw.x = pos.x+character->wheelLeft*cosf(angle.y+PI*0.5f)*cosf(angle.z); + pw.y = pos.y; + pw.z = pos.z-character->wheelLeft*sinf(angle.y+PI*0.5f)*cosf(angle.z); + a1 = atanf(m_terrain->RetFloorHeight(pw)/character->wheelLeft); + + pw.x = pos.x+character->wheelRight*cosf(angle.y+PI*1.5f)*cosf(angle.z); + pw.y = pos.y; + pw.z = pos.z-character->wheelRight*sinf(angle.y+PI*1.5f)*cosf(angle.z); + a2 = atanf(m_terrain->RetFloorHeight(pw)/character->wheelRight); + + angle.x = (a2-a1)/2.0f; +} + + +// Adapts the physics of the object in relation to other objects. +// Returns 0 -> mobile object +// Returns 1 -> immobile object (because collision) +// Returns 2 -> destroyed object + +int CPhysics::ObjectAdapt(const D3DVECTOR &pos, const D3DVECTOR &angle) +{ + CObject* pObj; + CPyro* pyro; + CPhysics* ph; + D3DMATRIX matRotate; + D3DVECTOR iPos, oPos, iiPos, oAngle, oSpeed; + Sound sound; + float iRad, oRad, distance, force, volume; + int i, j, colType; + ObjectType iType, oType; + + if ( m_object->RetRuin() ) return 0; // is burning or exploding? + if ( !m_object->RetClip() ) return 0; + + // iiPos = sphere center is the old position. + // iPos = sphere center has the new position. + m_object->GetCrashSphere(0, iiPos, iRad); + iPos = iiPos + (pos - m_object->RetPosition(0)); + iType = m_object->RetType(); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj == m_object ) continue; // yourself? + if ( pObj->RetTruck() != 0 ) continue; // object transported? + if ( !pObj->RetEnable() ) continue; // inactive? + if ( pObj->RetRuin() ) continue; // is burning or exploding? + if ( pObj->RetDead() ) continue; // dead man? + + oType = pObj->RetType(); + if ( oType == OBJECT_NULL ) continue; + if ( oType == OBJECT_TOTO ) continue; +//? if ( iType == OBJECT_BEE && oType == OBJECT_BEE ) continue; + if ( iType == OBJECT_WORM && oType != OBJECT_WORM ) continue; + if ( iType != OBJECT_WORM && oType == OBJECT_WORM ) continue; + if ( iType == OBJECT_MOTHER && oType == OBJECT_ANT ) continue; + if ( iType == OBJECT_ANT && oType == OBJECT_MOTHER ) continue; + if ( iType == OBJECT_MOTHER && oType == OBJECT_SPIDER ) continue; + if ( iType == OBJECT_SPIDER && oType == OBJECT_MOTHER ) continue; + if ( iType == OBJECT_MOTHER && oType == OBJECT_EGG ) continue; + if ( iType == OBJECT_EGG && oType == OBJECT_MOTHER ) continue; + + pObj->GetJotlerSphere(oPos, oRad); + if ( oRad > 0.0f ) + { + JostleObject(pObj, iPos, iRad, oPos, oRad); + } + + if ( iType == OBJECT_MOTHER || + iType == OBJECT_ANT || + iType == OBJECT_SPIDER || + iType == OBJECT_WORM || + iType == OBJECT_BEE ) // insect? + { + if ( oType == OBJECT_STONE || + oType == OBJECT_URANIUM || + oType == OBJECT_METAL || + oType == OBJECT_POWER || + oType == OBJECT_ATOMIC || + oType == OBJECT_BULLET || + oType == OBJECT_BBOX || + oType == OBJECT_KEYa || + oType == OBJECT_KEYb || + oType == OBJECT_KEYc || + oType == OBJECT_KEYd || + oType == OBJECT_TNT || + (oType >= OBJECT_PLANT0 && oType <= OBJECT_PLANT19 ) || + (oType >= OBJECT_MUSHROOM0 && oType <= OBJECT_MUSHROOM9) ) continue; + } + +#if _TEEN + if ( oType == OBJECT_WAYPOINT && + pObj->RetEnable() && + !m_object->RetResetBusy() ) // driving vehicle? +#else + if ( oType == OBJECT_WAYPOINT && + pObj->RetEnable() && + !m_object->RetResetBusy() && + m_object->RetTrainer() ) // driving vehicle? +#endif + { + oPos = pObj->RetPosition(0); + distance = Length2d(oPos, iPos); + if ( distance < 4.0f ) + { + m_sound->Play(SOUND_WAYPOINT, m_object->RetPosition(0)); + pyro = new CPyro(m_iMan); + pyro->Create(PT_WPCHECK, pObj); + } + } + + if ( oType == OBJECT_TARGET2 ) + { + oPos = pObj->RetPosition(0); + distance = Length(oPos, iPos); + if ( distance < 10.0f*1.5f ) + { + m_sound->Play(SOUND_WAYPOINT, m_object->RetPosition(0)); + pyro = new CPyro(m_iMan); + pyro->Create(PT_WPCHECK, pObj); + } + } + + j = 0; + while ( pObj->GetCrashSphere(j++, oPos, oRad) ) + { + if ( iType == OBJECT_MOTHER && oRad <= 1.2f ) continue; + if ( iType == OBJECT_ANT && oRad <= 1.2f ) continue; + if ( iType == OBJECT_SPIDER && oRad <= 1.2f ) continue; + if ( iType == OBJECT_BEE && oRad <= 1.2f ) continue; + if ( iType == OBJECT_WORM && oRad <= 1.2f ) continue; + + distance = Length(oPos, iPos); + if ( distance < iRad+oRad ) // collision? + { + distance = Length(oPos, iiPos); + if ( distance >= iRad+oRad ) // view (*) + { + m_bCollision = TRUE; + m_bObstacle = TRUE; + + sound = pObj->RetCrashSphereSound(j-1); + if ( sound != SOUND_CLICK ) + { + force = Abs(m_linMotion.realSpeed.x); + force *= pObj->RetCrashSphereHardness(j-1)*2.0f; + if ( ExploOther(iType, pObj, oType, force) ) continue; + colType = ExploHimself(iType, oType, force); + if ( colType == 2 ) return 2; // destroyed? + if ( colType == 0 ) continue; // ignores? + } + + force = Length(m_linMotion.realSpeed); + force *= pObj->RetCrashSphereHardness(j-1); + volume = Abs(force*0.05f); + if ( volume > 1.0f ) volume = 1.0f; + if ( sound != SOUND_CLICK ) + { + m_sound->Play(sound, m_object->RetPosition(0), volume); + } + if ( iType == OBJECT_HUMAN && volume > 0.5f ) + { + m_sound->Play(SOUND_AIE, m_object->RetPosition(0), volume); + } + + if ( m_repeatCollision > 0 ) + { + force *= 0.5f*m_repeatCollision; + if ( force > 20.0f ) force = 20.0f; + } + m_repeatCollision += 2; + if ( m_repeatCollision > 10 ) + { + m_repeatCollision = 10; + } + + m_linMotion.currentSpeed = Normalize(iPos-oPos)*force; + MatRotateXZY(matRotate, -angle); + m_linMotion.currentSpeed = Transform(matRotate, m_linMotion.currentSpeed); + if ( m_type == TYPE_ROLLING ) + { + m_linMotion.currentSpeed.y = 0.0f; + } + + ph = pObj->RetPhysics(); + if ( ph != 0 ) + { + oAngle = pObj->RetAngle(0); + oSpeed = Normalize(oPos-iPos)*force; + MatRotateXZY(matRotate, -oAngle); + oSpeed = Transform(matRotate, oSpeed); + if ( ph->RetType() == TYPE_ROLLING ) + { + oSpeed.y = 0.0f; + } + ph->SetLinMotion(MO_CURSPEED, oSpeed); + } + return 1; + } + } + } + } + + if ( m_repeatCollision > 0 ) + { + m_repeatCollision --; + } + return 0; +} + +// (*) Collision has the initial position (iiPos) and the new position (iPos), +// the obstacle is not known. We can therefore pass through. +// This is necessary when barriers found "in" a vehicle, not to block it definitely! + + +// Shakes an object. + +BOOL CPhysics::JostleObject(CObject* pObj, D3DVECTOR iPos, float iRad, + D3DVECTOR oPos, float oRad) +{ + D3DVECTOR speed; + float distance, force, d, f; + + distance = Length(oPos, iPos); + if ( distance >= iRad+oRad ) return FALSE; + + d = (iRad+oRad)/2.0f; + f = (distance-d)/d; // 0 = off, 1 = near + if ( f < 0.0f ) f = 0.0f; + if ( f > 1.0f ) f = 1.0f; + + speed = m_linMotion.realSpeed; + speed.y = 0.0f; + force = Length(speed)*f*0.05f; + if ( force > 1.0f ) force = 1.0f; + + if ( m_soundTimeJostle >= 0.20f ) + { + m_soundTimeJostle = 0.0f; + m_sound->Play(SOUND_JOSTLE, iPos, force); + } + + return pObj->JostleObject(force); +} + +// Shakes forcing an object. + +BOOL CPhysics::JostleObject(CObject* pObj, float force) +{ + D3DVECTOR oPos; + float oRad; + + pObj->GetJotlerSphere(oPos, oRad); + if ( oRad <= 0.0f ) return FALSE; + + if ( m_soundTimeJostle >= 0.20f ) + { + m_soundTimeJostle = 0.0f; + m_sound->Play(SOUND_JOSTLE, pObj->RetPosition(0), force); + } + + return pObj->JostleObject(force); +} + +// Effects of the explosion on the object buffers. +// Returns TRUE if we ignore this obstacle. + +BOOL CPhysics::ExploOther(ObjectType iType, + CObject *pObj, ObjectType oType, float force) +{ + CPyro* pyro; + + if ( !pObj->RetEnable() ) return TRUE; + + JostleObject(pObj, 1.0f); // shakes the object + + if ( force > 50.0f && + (oType == OBJECT_FRET || + oType == OBJECT_METAL ) ) + { + pyro = new CPyro(m_iMan); + pyro->Create(PT_EXPLOT, pObj); // total destruction + } + + if ( force > 50.0f && + (oType == OBJECT_POWER || + oType == OBJECT_ATOMIC ) ) + { + pyro = new CPyro(m_iMan); + pyro->Create(PT_FRAGT, pObj); // total destruction + } + + if ( force > 25.0f && + (oType == OBJECT_STONE || + oType == OBJECT_URANIUM ) ) + { + pyro = new CPyro(m_iMan); + pyro->Create(PT_FRAGT, pObj); // total destruction + } + + if ( force > 25.0f && + (oType == OBJECT_DERRICK || + oType == OBJECT_FACTORY || + oType == OBJECT_STATION || + oType == OBJECT_CONVERT || + oType == OBJECT_REPAIR || + oType == OBJECT_DESTROYER|| + oType == OBJECT_TOWER || + oType == OBJECT_RESEARCH || + oType == OBJECT_RADAR || + oType == OBJECT_INFO || + oType == OBJECT_ENERGY || + oType == OBJECT_LABO || + oType == OBJECT_NUCLEAR || + oType == OBJECT_PARA || + oType == OBJECT_SAFE || + oType == OBJECT_HUSTON ) ) // building? + { + pObj->ExploObject(EXPLO_BOUM, force/400.0f); + } + + if ( force > 25.0f && + (oType == OBJECT_MOBILEwa || + oType == OBJECT_MOBILEta || + oType == OBJECT_MOBILEfa || + oType == OBJECT_MOBILEia || + oType == OBJECT_MOBILEwc || + oType == OBJECT_MOBILEtc || + oType == OBJECT_MOBILEfc || + oType == OBJECT_MOBILEic || + oType == OBJECT_MOBILEwi || + oType == OBJECT_MOBILEti || + oType == OBJECT_MOBILEfi || + oType == OBJECT_MOBILEii || + oType == OBJECT_MOBILEws || + oType == OBJECT_MOBILEts || + oType == OBJECT_MOBILEfs || + oType == OBJECT_MOBILEis || + oType == OBJECT_MOBILErt || + oType == OBJECT_MOBILErc || + oType == OBJECT_MOBILErr || + oType == OBJECT_MOBILErs || + oType == OBJECT_MOBILEsa || + oType == OBJECT_MOBILEwt || + oType == OBJECT_MOBILEtt || + oType == OBJECT_MOBILEft || + oType == OBJECT_MOBILEit || + oType == OBJECT_MOBILEdr || + oType == OBJECT_APOLLO2 ) ) // vehicle? + { + pObj->ExploObject(EXPLO_BOUM, force/200.0f); + } + + if ( force > 10.0f && + (oType == OBJECT_MOBILEtg || + oType == OBJECT_TNT ) ) + { + pyro = new CPyro(m_iMan); + pyro->Create(PT_FRAGT, pObj); // total destruction + } + + if ( force > 0.0f && + oType == OBJECT_BOMB ) + { + pyro = new CPyro(m_iMan); + pyro->Create(PT_FRAGT, pObj); // total destruction + } + + return FALSE; +} + +// Effects of the explosion on the object itself. +// Returns 0 -> mobile object +// Returns 1 -> immobile object +// Returns 2 -> object destroyed + +int CPhysics::ExploHimself(ObjectType iType, ObjectType oType, float force) +{ + PyroType type; + CPyro* pyro; + + if ( force > 10.0f && + (oType == OBJECT_TNT || + oType == OBJECT_MOBILEtg ) ) + { + if ( iType == OBJECT_HUMAN ) type = PT_DEADG; + else type = PT_EXPLOT; + pyro = new CPyro(m_iMan); + pyro->Create(type, m_object); // total destruction + return 2; + } + + if ( force > 0.0f && + oType == OBJECT_BOMB ) + { + if ( iType == OBJECT_HUMAN ) + { + type = PT_DEADG; + } + else if ( iType == OBJECT_ANT || + iType == OBJECT_SPIDER || + iType == OBJECT_BEE ) + { + type = PT_EXPLOO; + } + else + { + type = PT_EXPLOT; + } + pyro = new CPyro(m_iMan); + pyro->Create(type, m_object); // total destruction + return 2; + } + + if ( force > 25.0f && + (iType == OBJECT_HUMAN || + iType == OBJECT_MOBILEwa || + iType == OBJECT_MOBILEta || + iType == OBJECT_MOBILEfa || + iType == OBJECT_MOBILEia || + iType == OBJECT_MOBILEwc || + iType == OBJECT_MOBILEtc || + iType == OBJECT_MOBILEfc || + iType == OBJECT_MOBILEic || + iType == OBJECT_MOBILEwi || + iType == OBJECT_MOBILEti || + iType == OBJECT_MOBILEfi || + iType == OBJECT_MOBILEii || + iType == OBJECT_MOBILEws || + iType == OBJECT_MOBILEts || + iType == OBJECT_MOBILEfs || + iType == OBJECT_MOBILEis || + iType == OBJECT_MOBILErt || + iType == OBJECT_MOBILErc || + iType == OBJECT_MOBILErr || + iType == OBJECT_MOBILErs || + iType == OBJECT_MOBILEsa || + iType == OBJECT_MOBILEwt || + iType == OBJECT_MOBILEtt || + iType == OBJECT_MOBILEft || + iType == OBJECT_MOBILEit || + iType == OBJECT_MOBILEdr || + iType == OBJECT_APOLLO2 ) ) // vehicle? + { + if ( oType == OBJECT_DERRICK || + oType == OBJECT_FACTORY || + oType == OBJECT_STATION || + oType == OBJECT_CONVERT || + oType == OBJECT_REPAIR || + oType == OBJECT_DESTROYER|| + oType == OBJECT_TOWER || + oType == OBJECT_RESEARCH || + oType == OBJECT_RADAR || + oType == OBJECT_INFO || + oType == OBJECT_ENERGY || + oType == OBJECT_LABO || + oType == OBJECT_NUCLEAR || + oType == OBJECT_PARA || + oType == OBJECT_SAFE || + oType == OBJECT_HUSTON ) // building? + { + force /= 200.0f; + } + else + if ( oType == OBJECT_MOTHER || + oType == OBJECT_ANT || + oType == OBJECT_SPIDER || + oType == OBJECT_BEE || + oType == OBJECT_WORM ) // insect? + { + force /= 400.0f; + } + else + if ( oType == OBJECT_FRET || + oType == OBJECT_STONE || + oType == OBJECT_METAL ) + { + force /= 500.0f; + } + else + if ( oType == OBJECT_URANIUM || + oType == OBJECT_POWER || + oType == OBJECT_ATOMIC ) + { + force /= 100.0f; + } + else + { + force /= 200.0f; + } + + if ( m_object->ExploObject(EXPLO_BOUM, force) ) return 2; + } + + return 1; +} + + + +// Makes the particles evolve. + +void CPhysics::FrameParticule(float aTime, float rTime) +{ + D3DVECTOR pos; + CObject* power; + float energy, intensity; + int effectLight; + BOOL bFlash; + + m_restBreakParticule -= rTime; + if ( aTime-m_lastPowerParticule < m_engine->ParticuleAdapt(0.05f) ) return; + m_lastPowerParticule = aTime; + + bFlash = FALSE; + + energy = 0.0f; + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + } + + if ( energy != m_lastEnergy ) // change the energy level? + { + if ( energy > m_lastEnergy ) // recharge? + { + PowerParticule(1.0f, FALSE); + bFlash = TRUE; + } + + if ( energy == 0.0f || m_lastEnergy == 0.0f ) + { + m_restBreakParticule = 2.5f; // particles for 2.5s + } + + m_lastEnergy = energy; + } + + if ( m_restBreakParticule > 0.0f ) + { + PowerParticule(m_restBreakParticule/2.5f, (energy == 0)); + bFlash = TRUE; + } + + effectLight = m_object->RetEffectLight(); + if ( effectLight != -1 ) + { + if ( bFlash ) + { + intensity = 0.0f; + if ( Rand() < 0.5f ) intensity = 1.0f; + m_light->SetLightIntensity(effectLight, intensity); + m_light->SetLightIntensitySpeed(effectLight, 10000.0f); + } + else + { + m_light->SetLightIntensity(effectLight, 0.0f); + } + } +} + +// Generates some particles after a recharge. + +void CPhysics::PowerParticule(float factor, BOOL bBreak) +{ + Character* character; + CObject* fret; + D3DMATRIX* mat; + D3DVECTOR pos, ppos, eye, speed; + FPOINT dim; + BOOL bCarryPower; + + bCarryPower = FALSE; + fret = m_object->RetFret(); + if ( fret != 0 && fret->RetType() == OBJECT_POWER && + m_object->RetAngleZ(1) == ARM_STOCK_ANGLE1 ) + { + bCarryPower = TRUE; // carries a battery + } + + mat = m_object->RetWorldMatrix(0); + character = m_object->RetCharacter(); + + pos = character->posPower; + pos.x -= 0.3f; + pos.y += 1.0f; // battery center position + pos = Transform(*mat, pos); + + speed.x = (Rand()-0.5f)*12.0f; + speed.y = (Rand()-0.5f)*12.0f; + speed.z = (Rand()-0.5f)*12.0f; + + ppos.x = pos.x; + ppos.y = pos.y+(Rand()-0.5f)*2.0f; + ppos.z = pos.z; + + dim.x = 1.0f*factor; + dim.y = 1.0f*factor; + + m_particule->CreateParticule(ppos, speed, dim, PARTIBLITZ, 0.5f, 0.0f, 0.0f); + + if ( bCarryPower ) // carry a battery? + { + pos = D3DVECTOR(3.0f, 5.6f, 0.0f); // position of battery holder + pos = Transform(*mat, pos); + + speed.x = (Rand()-0.5f)*12.0f; + speed.y = (Rand()-0.5f)*12.0f; + speed.z = (Rand()-0.5f)*12.0f; + + ppos.x = pos.x; + ppos.y = pos.y; + ppos.z = pos.z+(Rand()-0.5f)*2.0f; + + dim.x = 1.0f*factor; + dim.y = 1.0f*factor; + + m_particule->CreateParticule(ppos, speed, dim, PARTIBLITZ, 0.5f, 0.0f, 0.0f); + } +} + +// Generates some particles after a fall. +// crash: 0=super soft, 1=big crash + +void CPhysics::CrashParticule(float crash) +{ + D3DVECTOR pos, ppos, speed; + FPOINT dim; + float len; + int i, max; + + if ( crash < 0.2f ) return; + + pos = m_object->RetPosition(0); + m_camera->StartEffect(CE_CRASH, pos, crash); + +//? max = (int)(crash*50.0f); + max = (int)(crash*10.0f*m_engine->RetParticuleDensity()); + + for ( i=0 ; iCreateParticule(ppos, speed, dim, PARTICRASH, 2.0f); + } +} + +// Generates some exhaust gas particle. + +void CPhysics::MotorParticule(float aTime, float rTime) +{ + D3DMATRIX* mat; + D3DVECTOR pos, speed; + FPOINT dim; + ObjectType type; + FPOINT c, p; + float h, a, delay, level; + int r, i, nb; + + if ( m_object->RetToy() ) return; + + type = m_object->RetType(); + + if ( type == OBJECT_MOBILEia || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEis || // legs? + type == OBJECT_MOBILEdr || + type == OBJECT_MOTHER || + type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_BEE || + type == OBJECT_WORM || + type == OBJECT_APOLLO2 ) return; + + if ( type == OBJECT_HUMAN ) delay = 3.0f; + else delay = 8.0f; + if ( m_bSwim && m_timeUnderWater < delay ) // bubbles when entering water? + { + if ( aTime-m_lastUnderParticule >= m_engine->ParticuleAdapt(0.05f) ) + { + m_lastUnderParticule = aTime; + + nb = (int)(20.0f-(20.0f/delay)*m_timeUnderWater); + for ( i=0 ; iRetPosition(0); + pos.x += (Rand()-0.5f)*4.0f; + pos.y += (Rand()-0.5f)*4.0f; + pos.z += (Rand()-0.5f)*4.0f; + speed.y = (Rand()-0.5f)*8.0f+8.0f; + speed.x = (Rand()-0.5f)*0.2f; + speed.z = (Rand()-0.5f)*0.2f; + dim.x = 0.06f+Rand()*0.10f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBUBBLE, 3.0f, 0.0f, 0.0f); + } + } + } + + level = m_water->RetLevel(); + pos = m_object->RetPosition(0); + if ( type == OBJECT_HUMAN ) pos.y -= 2.0f; + if ( pos.y < level ) // underwater? + { + m_absorbWater += rTime*(1.0f/2.0f); // gets wet + if ( m_absorbWater > 1.0f ) m_absorbWater = 1.0f; + } + else // out of water? + { + m_absorbWater -= rTime*(1.0f/3.0f); // to dry + if ( m_absorbWater < 0.0f ) m_absorbWater = 0.0f; + } + + if ( pos.y >= level && + m_absorbWater > 0.0f && + !m_water->RetLava() ) // drops on leaving the water? + { + if ( aTime-m_lastUnderParticule >= m_engine->ParticuleAdapt(0.05f) ) + { + m_lastUnderParticule = aTime; + + nb = (int)(8.0f*m_absorbWater); + for ( i=0 ; iRetPosition(0); + if ( type == OBJECT_HUMAN ) pos.y -= Rand()*2.0f; + else pos.y += Rand()*2.0f; + pos.x += (Rand()-0.5f)*2.0f; + pos.z += (Rand()-0.5f)*2.0f; + speed.y = -((Rand()-0.5f)*8.0f+8.0f); + speed.x = 0.0f; + speed.z = 0.0f; + dim.x = 0.2f; + dim.y = 0.2f; + m_particule->CreateParticule(pos, speed, dim, PARTIWATER, 2.0f, 0.0f, 1.0f); + } + } + } + + if ( type == OBJECT_HUMAN || // human? + type == OBJECT_TECH ) + { + if ( m_bLand && + aTime-m_lastSlideParticule >= m_engine->ParticuleAdapt(0.05f) ) + { + h = Max(Abs(m_linMotion.terrainSpeed.x), + Abs(m_linMotion.terrainSpeed.z)); + if ( h > m_linMotion.terrainSlide.x+0.5f && + m_linMotion.motorSpeed.x == 0.0f ) // slides a stop? + { + m_lastSlideParticule = aTime; + + mat = m_object->RetWorldMatrix(0); + pos.x = (Rand()-0.5f)*1.0f; + pos.y = -m_object->RetCharacter()->height; + pos.z = Rand()*0.4f+1.0f; + if ( rand()%2 == 0 ) pos.z = -pos.z; + pos = Transform(*mat, pos); + speed = D3DVECTOR(0.0f, 1.0f, 0.0f); + dim.x = Rand()*(h-5.0f)/2.0f+1.0f; + if ( dim.x > 2.5f ) dim.x = 2.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.2f); + } + } + } + + if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts ) // caterpillars? + { + if ( aTime-m_lastSlideParticule >= m_engine->ParticuleAdapt(0.05f) ) + { + h = Abs(m_linMotion.motorSpeed.x-m_linMotion.realSpeed.x); + if ( h > 5.0f ) + { + m_lastSlideParticule = aTime; + + mat = m_object->RetWorldMatrix(0); + pos.x = (Rand()-0.5f)*8.0f; + pos.y = 0.0f; + pos.z = Rand()*2.0f+3.0f; + if ( rand()%2 == 0 ) pos.z = -pos.z; + pos = Transform(*mat, pos); + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = Rand()*(h-5.0f)/2.0f+1.0f; + if ( dim.x > 3.0f ) dim.x = 3.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.2f); + } + } + } + + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) // large caterpillars? + { + if ( aTime-m_lastSlideParticule >= m_engine->ParticuleAdapt(0.05f) ) + { + h = Abs(m_linMotion.motorSpeed.x-m_linMotion.realSpeed.x); + if ( h > 5.0f ) + { + m_lastSlideParticule = aTime; + + mat = m_object->RetWorldMatrix(0); + pos.x = (Rand()-0.5f)*9.0f; + pos.y = 0.0f; + pos.z = Rand()*3.0f+3.0f; + if ( rand()%2 == 0 ) pos.z = -pos.z; + pos = Transform(*mat, pos); + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = Rand()*(h-5.0f)/2.0f+1.0f; + if ( dim.x > 3.0f ) dim.x = 3.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.2f); + } + } + } + + if ( (type == OBJECT_HUMAN || type == OBJECT_TECH) && !m_bSwim ) + { + if ( m_bLand ) // on the ground? + { + if ( m_reactorTemperature > 0.0f ) + { + m_reactorTemperature -= rTime*(1.0f/10.0f); // cooling + if ( m_reactorTemperature < 0.0f ) + { + m_reactorTemperature = 0.0f; + } + } + + if ( m_reactorTemperature == 0.0f || + aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.05f) ) return; + m_lastMotorParticule = aTime; + + pos = D3DVECTOR(-1.6f, -0.5f, 0.0f); + mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, pos); + + speed.x = (Rand()-0.5f)*0.6f; + speed.z = (Rand()-0.5f)*0.6f; + speed.y = -(0.5f+Rand()*0.3f)*(1.0f-m_reactorTemperature); + + dim.x = (1.0f+Rand()*0.5f)*(0.2f+m_reactorTemperature*0.8f); + dim.y = dim.x; + + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE2, 3.0f, 0.0f, 0.1f); + } + else // in flight? + { + if ( !m_bMotor || m_reactorRange == 0.0f ) return; + + if ( m_reactorTemperature < 1.0f ) // not too hot? + { + m_reactorTemperature += rTime*(1.0f/4.0f); // heating + if ( m_reactorTemperature > 1.0f ) + { + m_reactorTemperature = 1.0f; // but not too much + } + } + + if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.02f) ) return; + m_lastMotorParticule = aTime; + + pos = D3DVECTOR(-1.6f, -1.0f, 0.0f); + pos.x += (Rand()-0.5f)*3.0f; + pos.y += (Rand()-0.5f)*1.5f; + pos.z += (Rand()-0.5f)*3.0f; + mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, pos); + + h = m_floorHeight; + if ( h > 10.0f ) // high enough? + { + speed = D3DVECTOR(0.0f, -10.0f, 0.0f); // against the bottom + } + else + { + speed.y = 10.0f-2.0f*h - Rand()*(10.0f-h); //against the top + speed.x = (Rand()-0.5f)*(5.0f-h)*1.0f; // horizontal (xz) + speed.z = (Rand()-0.5f)*(5.0f-h)*1.0f; + } + + dim.x = 0.12f; + dim.y = 0.12f; + + m_particule->CreateParticule(pos, speed, dim, PARTISCRAPS, 2.0f, 10.0f); + +#if 1 + pos = D3DVECTOR(-1.6f, -0.5f, 0.0f); + pos = Transform(*mat, pos); + + speed.x = (Rand()-0.5f)*1.0f; + speed.z = (Rand()-0.5f)*1.0f; + speed.y = -(4.0f+Rand()*3.0f); + speed.x += m_linMotion.realSpeed.x*0.8f; + speed.z -= m_linMotion.realSpeed.x*m_cirMotion.realSpeed.y*0.05f; + if ( m_linMotion.realSpeed.y > 0.0f ) + { + speed.y += m_linMotion.realSpeed.y*0.5f; + } + else + { + speed.y += m_linMotion.realSpeed.y*1.2f; + } + a = m_object->RetAngleY(0); + p.x = speed.x; + p.y = speed.z; + p = RotatePoint(-a, p); + speed.x = p.x; + speed.z = p.y; + + dim.x = 0.4f+Rand()*0.2f; + dim.y = dim.x; + + m_particule->CreateParticule(pos, speed, dim, PARTIEJECT, 0.3f, 10.0f); +#endif + } + } + + if ( (type == OBJECT_HUMAN || type == OBJECT_TECH) && m_bSwim ) + { + m_reactorTemperature = 0.0f; // reactor cold + } + + if ( m_type == TYPE_FLYING && + type != OBJECT_HUMAN && + type != OBJECT_TECH && + !m_bSwim ) + { + if ( m_bLand ) // on the ground? + { + if ( m_motorSpeed.x == 0.0f && // glide slope due to ground? + m_cirMotion.realSpeed.y == 0.0f ) + { + h = Max(Abs(m_linMotion.realSpeed.x), + Abs(m_linMotion.realSpeed.z)); + + if ( h < 3.0f ) return; + + if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.2f) ) return; + m_lastMotorParticule = aTime; + + r = rand()%3; + if ( r == 0 ) pos = D3DVECTOR(-3.0f, 0.0f, -4.0f); + if ( r == 1 ) pos = D3DVECTOR(-3.0f, 0.0f, 4.0f); + if ( r == 2 ) pos = D3DVECTOR( 4.0f, 0.0f, 0.0f); + + pos.x += (Rand()-0.5f)*2.0f; + pos.z += (Rand()-0.5f)*2.0f; + mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, pos); + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = Rand()*h/5.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + else // glide with small reactors in skates? + { + if ( m_linMotion.realSpeed.x == 0.0f && + m_cirMotion.realSpeed.y == 0.0f ) return; + + if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.02f) ) return; + m_lastMotorParticule = aTime; + + r = rand()%3; + if ( r == 0 ) pos = D3DVECTOR(-3.0f, 0.0f, -4.0f); + if ( r == 1 ) pos = D3DVECTOR(-3.0f, 0.0f, 4.0f); + if ( r == 2 ) pos = D3DVECTOR( 4.0f, 0.0f, 0.0f); + + pos.x += (Rand()-0.5f)*1.0f; + pos.z += (Rand()-0.5f)*1.0f; + mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, pos); + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = 1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIEJECT); + } + } + else // in flight? + { + if ( !m_bMotor || m_reactorRange == 0.0f ) return; + + if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.02f) ) return; + m_lastMotorParticule = aTime; + + pos = D3DVECTOR(0.0f, -1.0f, 0.0f); + pos.x += (Rand()-0.5f)*6.0f; + pos.y += (Rand()-0.5f)*3.0f; + pos.z += (Rand()-0.5f)*6.0f; + mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, pos); + + h = m_floorHeight; + if ( h > 10.0f ) // high enough? + { + speed = D3DVECTOR(0.0f, -10.0f, 0.0f); // against the bottom + } + else + { + speed.y = 10.0f-2.0f*h - Rand()*(10.0f-h); // against the top + speed.x = (Rand()-0.5f)*(10.0f-h)*2.0f; // horizontal (xz) + speed.z = (Rand()-0.5f)*(10.0f-h)*2.0f; + } + + dim.x = 0.2f; + dim.y = 0.2f; + + m_particule->CreateParticule(pos, speed, dim, PARTISCRAPS, 2.0f, 10.0f); + +#if 1 + pos = D3DVECTOR(0.0f, 1.0f, 0.0f); + pos = Transform(*mat, pos); + + speed.x = (Rand()-0.5f)*1.0f; + speed.z = (Rand()-0.5f)*1.0f; + speed.y = -(6.0f+Rand()*4.5f); + speed.x += m_linMotion.realSpeed.x*0.8f; + speed.z -= m_linMotion.realSpeed.x*m_cirMotion.realSpeed.y*0.05f; + if ( m_linMotion.realSpeed.y > 0.0f ) + { + speed.y += m_linMotion.realSpeed.y*0.5f; + } + else + { + speed.y += m_linMotion.realSpeed.y*1.2f; + } + a = m_object->RetAngleY(0); + p.x = speed.x; + p.y = speed.z; + p = RotatePoint(-a, p); + speed.x = p.x; + speed.z = p.y; + + dim.x = 0.7f+Rand()*0.6f; + dim.y = dim.x; + + m_particule->CreateParticule(pos, speed, dim, PARTIEJECT, 0.5f, 10.0f); +#endif + } + } + + if ( (type == OBJECT_HUMAN || type == OBJECT_TECH) && m_bSwim ) + { + if ( !m_object->RetDead() ) + { + h = Mod(aTime, 5.0f); + if ( h < 3.5f && ( h < 1.5f || h > 1.6f ) ) return; + } + if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.06f) ) return; + m_lastMotorParticule = aTime; + + pos = D3DVECTOR(0.0f, 3.0f, 0.0f); + mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, pos); + pos.x += (Rand()-0.5f)*1.0f; + pos.z += (Rand()-0.5f)*1.0f; + speed.y = (Rand()-0.5f)*8.0f+8.0f; + speed.x = (Rand()-0.5f)*0.2f; + speed.z = (Rand()-0.5f)*0.2f; + dim.x = 0.2f; + dim.y = 0.2f; + m_particule->CreateParticule(pos, speed, dim, PARTIBUBBLE, 3.0f, 0.0f, 0.0f); + + if ( aTime-m_lastSoundWater > 1.5f ) + { + m_lastSoundWater = aTime; + m_sound->Play(SOUND_BLUP, m_object->RetPosition(0), 0.5f+Rand()*0.5f); + } + } + + if ( type == OBJECT_MOBILEsa && m_bSwim ) + { + h = Mod(aTime, 3.0f); + if ( h < 1.5f && ( h < 0.5f || h > 0.9f ) ) return; + if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.06f) ) return; + m_lastMotorParticule = aTime; + + pos = D3DVECTOR(0.0f, 3.0f, 0.0f); + mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, pos); + pos.x += (Rand()-0.5f)*1.0f; + pos.z += (Rand()-0.5f)*1.0f; + speed.y = (Rand()-0.5f)*8.0f+8.0f; + speed.x = (Rand()-0.5f)*0.2f; + speed.z = (Rand()-0.5f)*0.2f; + dim.x = 0.2f; + dim.y = 0.2f; + m_particule->CreateParticule(pos, speed, dim, PARTIBUBBLE, 3.0f, 0.0f, 0.0f); + + if ( aTime-m_lastSoundWater > 1.5f ) + { + m_lastSoundWater = aTime; + m_sound->Play(SOUND_BLUP, m_object->RetPosition(0), 0.5f+Rand()*0.5f); + } + } + + if ( m_type == TYPE_ROLLING ) + { + if ( type == OBJECT_APOLLO2 ) return; // electric motors! + + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) + { + if ( !m_bMotor ) return; + + if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.1f) ) return; + m_lastMotorParticule = aTime; + + pos = D3DVECTOR(-2.5f, 10.3f, -1.3f); + pos.x += (Rand()-0.5f)*1.0f; + pos.z += (Rand()-0.5f)*1.0f; + mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, pos); + + speed.x = (Rand()-0.5f)*2.0f; + speed.z = (Rand()-0.5f)*2.0f; + speed.y = 1.5f+Rand()*1.0f; + + dim.x = Rand()*0.6f+0.4f; + dim.y = dim.x; + + m_particule->CreateParticule(pos, speed, dim, PARTIMOTOR, 2.0f); + } + else + { + if ( !m_bMotor ) return; + + if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.05f) ) return; + m_lastMotorParticule = aTime; + + pos = D3DVECTOR(-3.4f, 1.8f, 0.5f); + + speed = pos; + if ( m_linMotion.currentSpeed.x < 0.0f ) + { + speed.x += m_linMotion.currentSpeed.x*1.2f; + } + else if ( m_linMotion.currentSpeed.x > 0.0f ) + { + speed.x += 0.0f; + } + else + { + speed.x -= 3.0f; + } + speed.y -= 0.5f+Rand()*2.0f; + speed.z += (Rand()-0.5f)*3.0f; + + mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, pos); + speed = Transform(*mat, speed)-pos; + + dim.x = Rand()*0.4f+0.3f; + dim.y = dim.x; + + m_particule->CreateParticule(pos, speed, dim, PARTIMOTOR, 2.0f); + } + } +} + +// Generates some particles after falling into the water. + +void CPhysics::WaterParticule(float aTime, D3DVECTOR pos, ObjectType type, + float floor, float advance, float turn) +{ + D3DVECTOR ppos, speed; + FPOINT dim; + float delay, level, min, max, force, volume, diam; + int i, nb; + + level = m_water->RetLevel(); + if ( floor >= level ) return; + + if ( type == OBJECT_HUMAN || + type == OBJECT_TECH ) + { + min = 3.0f; + max = 3.0f; + } + else + { + min = 0.0f; + max = 9.0f; + } + + if ( pos.y+max < level || pos.y-min > level ) return; + + // Management of the particle "splash". + if ( m_linMotion.realSpeed.y < -10.0f && + aTime-m_lastPloufParticule >= 1.0f ) + { + m_lastPloufParticule = aTime; + + force = -m_linMotion.realSpeed.y/20.0f; // power according to speed drops + if ( type == OBJECT_HUMAN || + type == OBJECT_TECH ) + { + diam = 2.5f; + } + else + { + diam = 5.0f; + force *= 1.3f; // a robot is heavier + } + + pos = m_object->RetPosition(0); + pos.y = m_water->RetLevel()-1.0f; + dim.x = 2.0f*force; // height + dim.y = diam; // diameter + m_particule->CreateParticule(pos, D3DVECTOR(0.0f, 0.0f, 0.0f), dim, PARTIPLOUF0, 1.4f, 0.0f, 0.0f); + + force = (0.5f+force*0.5f); + nb = (int)(force*50.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; iCreateParticule(ppos, speed, dim, PARTIDROP, 2.0f, 20.0f, 0.2f); + } + + volume = Abs(m_linMotion.realSpeed.y*0.02f); + if ( volume > 1.0f ) volume = 1.0f; + m_sound->Play(SOUND_PLOUF, pos, volume); + } + + // Management particles "cop". + if ( m_water->RetLava() ) return; + + if ( advance == 0.0f && turn == 0.0f ) + { + turn = 10.0f; + delay = 0.50f; + } + else if ( advance == 0.0f ) + { + delay = 0.24f; + } + else + { + delay = 0.06f; + } + m_engine->ParticuleAdapt(delay); + + if ( aTime-m_lastWaterParticule < delay ) return; + m_lastWaterParticule = aTime; + + force = (advance+turn)*0.16f; + if ( force < 0.001f ) return; + + pos = m_object->RetPosition(0); + pos.y = level+0.1f; + if ( advance == 0 ) + { + pos.x += (Rand()-0.5f)*10.0f; + pos.z += (Rand()-0.5f)*10.0f; + } + else + { + pos.x += (Rand()-0.5f)*4.0f; + pos.z += (Rand()-0.5f)*4.0f; + } + speed.y = 0.0f; + speed.x = 0.0f; + speed.z = 0.0f; + dim.x = Min(Rand()*force+force+1.0f, 10.0f); + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFLIC, 3.0f, 0.0f, 0.0f); +} + +// Creates the trace under the robot. + +void CPhysics::WheelParticule(int color, float width) +{ + Character* character; + D3DMATRIX* mat; + D3DVECTOR goal1, goal2, wheel1, wheel2; + ParticuleType parti; + float dist1, dist2, step; + + character = m_object->RetCharacter(); + mat = m_object->RetWorldMatrix(0); + + // Draw a trace on the ground. + if ( color >= 0 && color <= 17 ) + { + parti = (ParticuleType)(PARTITRACE0+color); + step = 2.0f; + if ( color >= 16 ) step = 4.0f; // arrow? + step /= m_engine->RetTracePrecision(); + + goal1.x = step/2.0f; + goal1.y = 0.0f; + goal1.z = -width/2.0f; + goal1 = Transform(*mat, goal1); + + goal2.x = step/2.0f; + goal2.y = 0.0f; + goal2.z = width/2.0f; + goal2 = Transform(*mat, goal2); + + if ( !m_bWheelParticuleBrake ) + { + m_wheelParticulePos[0] = goal1; + m_wheelParticulePos[1] = goal2; + } + + while ( TRUE ) + { + dist1 = Length(m_wheelParticulePos[0], goal1); + if ( dist1 < step ) break; + dist2 = Length(m_wheelParticulePos[1], goal2); + wheel1 = SegmentDist(m_wheelParticulePos[0], goal1, step); + wheel2 = SegmentDist(m_wheelParticulePos[1], goal2, step*dist2/dist1); + if ( m_linMotion.realSpeed.x >= 0.0f ) + { + m_particule->CreateWheelTrace(m_wheelParticulePos[0], m_wheelParticulePos[1], wheel1, wheel2, parti); + } + else + { + m_particule->CreateWheelTrace(m_wheelParticulePos[1], m_wheelParticulePos[0], wheel2, wheel1, parti); + } + m_wheelParticulePos[0] = wheel1; + m_wheelParticulePos[1] = wheel2; + } + + m_bWheelParticuleBrake = TRUE; + } + else + { + m_bWheelParticuleBrake = FALSE; + } +} + + +// Creates the interface. + +void CPhysics::CreateInterface(BOOL bSelect) +{ + if ( m_brain != 0 ) + { + m_brain->CreateInterface(bSelect); + } +} + + +// Returns an error related to the general state. + +Error CPhysics::RetError() +{ + ObjectType type; + CObject* power; + + type = m_object->RetType(); + if ( type == OBJECT_HUMAN || + type == OBJECT_TECH || + type == OBJECT_MOTHER || + type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_BEE || + type == OBJECT_WORM || + type == OBJECT_APOLLO2 || + type == OBJECT_MOBILEdr ) return ERR_OK; + + if ( m_brain != 0 && m_brain->RetActiveVirus() ) + { + return ERR_VEH_VIRUS; + } + + power = m_object->RetPower(); // searches for the object battery used + if ( power == 0 ) + { + return ERR_VEH_POWER; + } + else + { + if ( power->RetEnergy() == 0.0f ) return ERR_VEH_ENERGY; + } + + return ERR_OK; +} + diff --git a/src/physics/physics.h b/src/physics/physics.h new file mode 100644 index 0000000..72f0c20 --- /dev/null +++ b/src/physics/physics.h @@ -0,0 +1,248 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// physics.h + +#ifndef _PHYSICS_H_ +#define _PHYSICS_H_ + + +#include "d3dengine.h" +#include "misc.h" + + +class CInstanceManager; +class CD3DEngine; +class CLight; +class CParticule; +class CTerrain; +class CWater; +class CCamera; +class CObject; +class CBrain; +class CMotion; +class CSound; + + +enum PhysicsType +{ + TYPE_ROLLING = 1, + TYPE_FLYING = 2, +}; + +enum PhysicsMode +{ + MO_ADVACCEL = 0, + MO_RECACCEL = 1, + MO_STOACCEL = 2, + MO_MOTACCEL = 3, + MO_ADVSPEED = 4, + MO_RECSPEED = 5, + MO_MOTSPEED = 6, + MO_CURSPEED = 7, + MO_TERFORCE = 8, + MO_TERSPEED = 9, + MO_TERSLIDE = 10, + MO_REASPEED = 11, +}; + + +typedef struct +{ + D3DVECTOR advanceAccel; // acceleration starting (+) + D3DVECTOR recedeAccel; // acceleration starting (+) + D3DVECTOR stopAccel; // acceleration stoping (+) + D3DVECTOR motorAccel; // current acceleration (+/-) + + D3DVECTOR advanceSpeed; // forward speed (+) + D3DVECTOR recedeSpeed; // reversing speed (+) + D3DVECTOR motorSpeed; // desired speed (+/-) + D3DVECTOR currentSpeed; // current speed (+/-) + + D3DVECTOR terrainForce; // power of resistance of the ground (+) + D3DVECTOR terrainSpeed; // speed of the ground (+/-) + D3DVECTOR terrainSlide; // limit sliding speed (+) + + D3DVECTOR realSpeed; // real speed(+/-) + + D3DVECTOR finalInclin; // final inclination +} +Motion; + + + + +class CPhysics +{ +public: + CPhysics(CInstanceManager* iMan, CObject* object); + ~CPhysics(); + + void DeleteObject(BOOL bAll=FALSE); + + BOOL EventProcess(const Event &event); + + void SetBrain(CBrain* brain); + void SetMotion(CMotion* motion); + + void SetType(PhysicsType type); + PhysicsType RetType(); + + BOOL Write(char *line); + BOOL Read(char *line); + + void SetGravity(float value); + float RetGravity(); + + float RetFloorHeight(); + + void SetLinMotion(PhysicsMode mode, D3DVECTOR value); + D3DVECTOR RetLinMotion(PhysicsMode mode); + void SetLinMotionX(PhysicsMode mode, float value); + void SetLinMotionY(PhysicsMode mode, float value); + void SetLinMotionZ(PhysicsMode mode, float value); + float RetLinMotionX(PhysicsMode mode); + float RetLinMotionY(PhysicsMode mode); + float RetLinMotionZ(PhysicsMode mode); + + void SetCirMotion(PhysicsMode mode, D3DVECTOR value); + D3DVECTOR RetCirMotion(PhysicsMode mode); + void SetCirMotionX(PhysicsMode mode, float value); + void SetCirMotionY(PhysicsMode mode, float value); + void SetCirMotionZ(PhysicsMode mode, float value); + float RetCirMotionX(PhysicsMode mode); + float RetCirMotionY(PhysicsMode mode); + float RetCirMotionZ(PhysicsMode mode); + + float RetLinStopLength(PhysicsMode sMode=MO_ADVSPEED, PhysicsMode aMode=MO_STOACCEL); + float RetCirStopLength(); + float RetLinMaxLength(float dir); + float RetLinTimeLength(float dist, float dir=1.0f); + float RetLinLength(float dist); + + void SetMotor(BOOL bState); + BOOL RetMotor(); + void SetLand(BOOL bState); + BOOL RetLand(); + void SetSwim(BOOL bState); + BOOL RetSwim(); + void SetCollision(BOOL bCollision); + BOOL RetCollision(); + void SetFreeze(BOOL bFreeze); + BOOL RetFreeze(); + void SetReactorRange(float range); + float RetReactorRange(); + + void SetMotorSpeed(D3DVECTOR speed); + void SetMotorSpeedX(float speed); + void SetMotorSpeedY(float speed); + void SetMotorSpeedZ(float speed); + D3DVECTOR RetMotorSpeed(); + float RetMotorSpeedX(); + float RetMotorSpeedY(); + float RetMotorSpeedZ(); + + void CreateInterface(BOOL bSelect); + Error RetError(); + +protected: + BOOL EventFrame(const Event &event); + void WaterFrame(float aTime, float rTime); + void SoundMotor(float rTime); + void SoundMotorFull(float rTime, ObjectType type); + void SoundMotorSlow(float rTime, ObjectType type); + void SoundMotorStop(float rTime, ObjectType type); + void SoundReactorFull(float rTime, ObjectType type); + void SoundReactorStop(float rTime, ObjectType type); + void FrameParticule(float aTime, float rTime); + void MotorUpdate(float aTime, float rTime); + void EffectUpdate(float aTime, float rTime); + void UpdateMotionStruct(float rTime, Motion &motion); + void FloorAdapt(float aTime, float rTime, D3DVECTOR &pos, D3DVECTOR &angle); + void FloorAngle(const D3DVECTOR &pos, D3DVECTOR &angle); + int ObjectAdapt(const D3DVECTOR &pos, const D3DVECTOR &angle); + BOOL JostleObject(CObject* pObj, D3DVECTOR iPos, float iRad, D3DVECTOR oPos, float oRad); + BOOL JostleObject(CObject* pObj, float force); + BOOL ExploOther(ObjectType iType, CObject *pObj, ObjectType oType, float force); + int ExploHimself(ObjectType iType, ObjectType oType, float force); + + void PowerParticule(float factor, BOOL bBreak); + void CrashParticule(float crash); + void MotorParticule(float aTime, float rTime); + void WaterParticule(float aTime, D3DVECTOR pos, ObjectType type, float floor, float advance, float turn); + void WheelParticule(int color, float width); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CLight* m_light; + CParticule* m_particule; + CTerrain* m_terrain; + CWater* m_water; + CCamera* m_camera; + CObject* m_object; + CBrain* m_brain; + CMotion* m_motion; + CSound* m_sound; + + PhysicsType m_type; // TYPE_* + float m_gravity; // force of gravity + float m_time; // absolute time + D3DVECTOR m_motorSpeed; // motor speed (-1..1) + Motion m_linMotion; // linear motion + Motion m_cirMotion; // circular motion + BOOL m_bMotor; + BOOL m_bLand; + BOOL m_bSwim; + BOOL m_bCollision; + BOOL m_bObstacle; + BOOL m_bFreeze; + int m_repeatCollision; + float m_linVibrationFactor; + float m_cirVibrationFactor; + float m_inclinaisonFactor; + float m_lastPowerParticule; + float m_lastSlideParticule; + float m_lastMotorParticule; + float m_lastWaterParticule; + float m_lastUnderParticule; + float m_lastPloufParticule; + float m_lastFlameParticule; + BOOL m_bWheelParticuleBrake; + D3DVECTOR m_wheelParticulePos[2]; + float m_absorbWater; + float m_reactorTemperature; + float m_reactorRange; + float m_timeReactorFail; + float m_timeUnderWater; + float m_lastEnergy; + float m_lastSoundWater; + float m_lastSoundInsect; + float m_restBreakParticule; + float m_floorLevel; // ground level + float m_floorHeight; // height above the ground + int m_soundChannel; + int m_soundChannelSlide; + float m_soundTimePshhh; + float m_soundTimeJostle; + float m_soundTimeBoum; + BOOL m_bSoundSlow; + BOOL m_bForceUpdate; + BOOL m_bLowLevel; +}; + + +#endif //_PHYSICS_H_ diff --git a/src/planet.cpp b/src/planet.cpp deleted file mode 100644 index 925b2e9..0000000 --- a/src/planet.cpp +++ /dev/null @@ -1,248 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// planet.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "planet.h" - - - - -// Constructor of the terrain. - -CPlanet::CPlanet(CInstanceManager* iMan, CD3DEngine* engine) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_PLANET, this); - - m_engine = engine; - Flush(); - -} - -// Destructor of the terrain. - -CPlanet::~CPlanet() -{ -} - - -// Removes all the planets. - -void CPlanet::Flush() -{ - int i, j; - - for ( j=0 ; j<2 ; j++ ) - { - for ( i=0 ; iRetPause() ) return TRUE; - - m_time += event.rTime; - - for ( i=0 ; iLoadTexture(m_planet[j][i].name); - } - } -} - -// Draws all the planets. - -void CPlanet::Draw() -{ - LPDIRECT3DDEVICE7 device; - D3DVERTEX2 vertex[4]; // 2 triangles - D3DVECTOR n; - FPOINT p1, p2; - float eyeDirH, eyeDirV, dp, u1, u2, v1, v2, a; - int i; - - device = m_engine->RetD3DDevice(); - eyeDirH = m_engine->RetEyeDirH(); - eyeDirV = m_engine->RetEyeDirV(); - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal - dp = 0.5f/256.0f; - - for ( i=0 ; iSetTexture(m_planet[m_mode][i].name); - - if ( m_planet[m_mode][i].bTGA ) - { - m_engine->SetState(D3DSTATEWRAP|D3DSTATEALPHA); - } - else - { - m_engine->SetState(D3DSTATEWRAP|D3DSTATETTb); - } - - a = eyeDirH + m_planet[m_mode][i].angle.x; - p1.x = Mod(a, PI*2.0f)-0.5f; - - a = eyeDirV + m_planet[m_mode][i].angle.y; - p1.y = 0.4f+(Mod(a+PI, PI*2.0f)-PI)*(2.0f/PI); - - p1.x -= m_planet[m_mode][i].dim/2.0f*0.75f; - p1.y -= m_planet[m_mode][i].dim/2.0f; - p2.x = p1.x+m_planet[m_mode][i].dim*0.75f; - p2.y = p1.y+m_planet[m_mode][i].dim; - - u1 = m_planet[m_mode][i].uv1.x + dp; - v1 = m_planet[m_mode][i].uv1.y + dp; - u2 = m_planet[m_mode][i].uv2.x - dp; - v2 = m_planet[m_mode][i].uv2.y - dp; - - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); - vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); - vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); - - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); - } -} - - -// Creates a new planet. - -BOOL CPlanet::Create(int mode, FPOINT start, float dim, float speed, - float dir, char *name, FPOINT uv1, FPOINT uv2) -{ - int i; - - if ( mode < 0 ) mode = 0; - if ( mode > 1 ) mode = 1; - - for ( i=0 ; i 1 ) mode = 1; - m_mode = mode; -} - -int CPlanet::RetMode() -{ - return m_mode; -} - diff --git a/src/planet.h b/src/planet.h deleted file mode 100644 index 9a6ba52..0000000 --- a/src/planet.h +++ /dev/null @@ -1,79 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// planet.h - -#ifndef _PLANET_H_ -#define _PLANET_H_ - - -#include "struct.h" - - -class CInstanceManager; -class CD3DEngine; - - - -#define MAXPLANET 10 - -typedef struct -{ - char bUsed; // TRUE -> planet exists - FPOINT start; // initial position in degrees - FPOINT angle; // current position in degrees - float dim; // dimensions (0..1) - float speed; // speed - float dir; // direction in the sky - char name[20]; // name of the texture - FPOINT uv1, uv2; // texture mapping - char bTGA; // texture .TGA -} -Planet; - - - - -class CPlanet -{ -public: - CPlanet(CInstanceManager* iMan, CD3DEngine* engine); - ~CPlanet(); - - void Flush(); - BOOL EventProcess(const Event &event); - BOOL Create(int mode, FPOINT start, float dim, float speed, float dir, char *name, FPOINT uv1, FPOINT uv2); - BOOL PlanetExist(); - void LoadTexture(); - void Draw(); - void SetMode(int mode); - int RetMode(); - -protected: - BOOL EventFrame(const Event &event); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - - float m_time; - int m_mode; - Planet m_planet[2][MAXPLANET]; - BOOL m_bPlanetExist; -}; - - -#endif //_PLANET_H_ diff --git a/src/profile.cpp b/src/profile.cpp deleted file mode 100644 index 2baffb0..0000000 --- a/src/profile.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// profile.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "language.h" -#include "struct.h" -#include "profile.h" - - - -static char g_filename[100]; - - - -BOOL InitCurrentDirectory() -{ -#if _SCHOOL - _fullpath(g_filename, "ceebot.ini", 100); -#else - _fullpath(g_filename, "colobot.ini", 100); -#endif - return TRUE; -} - - -BOOL SetProfileString(char* section, char* key, char* string) -{ - WritePrivateProfileString(section, key, string, g_filename); - return TRUE; -} - -BOOL GetProfileString(char* section, char* key, char* buffer, int max) -{ - int nb; - - nb = GetPrivateProfileString(section, key, "", buffer, max, g_filename); - if ( nb == 0 ) - { - buffer[0] = 0; - return FALSE; - } - return TRUE; -} - - -BOOL SetProfileInt(char* section, char* key, int value) -{ - char s[20]; - - sprintf(s, "%d", value); - WritePrivateProfileString(section, key, s, g_filename); - return TRUE; -} - -BOOL GetProfileInt(char* section, char* key, int &value) -{ - char s[20]; - int nb; - - nb = GetPrivateProfileString(section, key, "", s, 20, g_filename); - if ( nb == 0 ) - { - value = 0; - return FALSE; - } - sscanf(s, "%d", &value); - return TRUE; -} - - -BOOL SetProfileFloat(char* section, char* key, float value) -{ - char s[20]; - - sprintf(s, "%.2f", value); - WritePrivateProfileString(section, key, s, g_filename); - return TRUE; -} - -BOOL GetProfileFloat(char* section, char* key, float &value) -{ - char s[20]; - int nb; - - nb = GetPrivateProfileString(section, key, "", s, 20, g_filename); - if ( nb == 0 ) - { - value = 0.0f; - return FALSE; - } - sscanf(s, "%f", &value); - return TRUE; -} - - diff --git a/src/profile.h b/src/profile.h deleted file mode 100644 index 969b764..0000000 --- a/src/profile.h +++ /dev/null @@ -1,36 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// profile.h - -#ifndef _PROFILE_H_ -#define _PROFILE_H_ - - -#define STRICT -#define D3D_OVERLOADS - - -extern BOOL InitCurrentDirectory(); -extern BOOL SetProfileString(char* section, char* key, char* string); -extern BOOL GetProfileString(char* section, char* key, char* buffer, int max); -extern BOOL SetProfileInt(char* section, char* key, int value); -extern BOOL GetProfileInt(char* section, char* key, int &value); -extern BOOL SetProfileFloat(char* section, char* key, float value); -extern BOOL GetProfileFloat(char* section, char* key, float &value); - - -#endif //_PROFILE_H_ diff --git a/src/pyro.cpp b/src/pyro.cpp deleted file mode 100644 index 3588585..0000000 --- a/src/pyro.cpp +++ /dev/null @@ -1,2486 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// pyro.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "D3DEngine.h" -#include "D3DMath.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "robotmain.h" -#include "terrain.h" -#include "camera.h" -#include "particule.h" -#include "light.h" -#include "object.h" -#include "motion.h" -#include "motionhuman.h" -#include "displaytext.h" -#include "sound.h" -#include "pyro.h" - - - - -// Object's constructor. - -CPyro::CPyro(CInstanceManager* iMan) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_PYRO, this, 100); - - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); - m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - m_object = 0; - - m_progress = 0.0f; - m_speed = 0.0f; - m_lightRank = -1; - m_soundChannel = -1; - LightOperFlush(); -} - -// Object's destructor. - -CPyro::~CPyro() -{ - m_iMan->DeleteInstance(CLASS_PYRO, this); -} - - -// Destroys the object. - -void CPyro::DeleteObject(BOOL bAll) -{ - if ( m_lightRank != -1 ) - { - m_light->DeleteLight(m_lightRank); - m_lightRank = -1; - } -} - - -// Creates pyrotechnic effect. - -BOOL CPyro::Create(PyroType type, CObject* pObj, float force) -{ - D3DMATRIX* mat; - CObject* power; - CMotion* motion; - D3DVECTOR min, max, pos, speed; - FPOINT dim; - ObjectType oType; - Sound sound; - float duration, mass, h, limit; - int part, objRank, total, i, channel; - - m_object = pObj; - m_force = force; - - oType = pObj->RetType(); - objRank = pObj->RetObjectRank(0); - if ( objRank == -1 ) return FALSE; - m_engine->GetBBox(objRank, min, max); - pos = pObj->RetPosition(0); - - DisplayError(type, pObj); // displays eventual messages - - // Copies all spheres of the object. - for ( i=0 ; i<50 ; i++ ) - { - if ( !pObj->GetCrashSphere(i, m_crashSpherePos[i], m_crashSphereRadius[i]) ) break; - } - m_crashSphereUsed = i; - - // Calculates the size of the effect. - if ( oType == OBJECT_ANT || - oType == OBJECT_BEE || - oType == OBJECT_WORM || - oType == OBJECT_SPIDER ) - { - m_size = 40.0f; - } - else - { - m_size = Length(min, max)*2.0f; - if ( m_size < 4.0f ) m_size = 4.0f; - if ( m_size > 80.0f ) m_size = 80.0f; - } - if ( oType == OBJECT_TNT || - oType == OBJECT_BOMB ) - { - m_size *= 2.0f; - } - - m_pos = pos+(min+max)/2.0f; - m_type = type; - m_progress = 0.0f; - m_speed = 1.0f/20.0f; - m_time = 0.0f; - m_lastParticule = 0.0f; - m_lastParticuleSmoke = 0.0f; - m_lightRank = -1; - - if ( oType == OBJECT_TEEN28 || - oType == OBJECT_TEEN31 ) - { - m_pos.y = pos.y+1.0f; - } - - // Seeking the position of the battery. - power = pObj->RetPower(); - if ( power == 0 ) - { - m_bPower = FALSE; - } - else - { - m_bPower = TRUE; - pos = power->RetPosition(0); - pos.y += 1.0f; - mat = pObj->RetWorldMatrix(0); - m_posPower = Transform(*mat, pos); - } - if ( oType == OBJECT_POWER || - oType == OBJECT_ATOMIC || - oType == OBJECT_URANIUM || - oType == OBJECT_TNT || - oType == OBJECT_BOMB ) - { - m_bPower = TRUE; - m_posPower = m_pos; - m_posPower.y += 1.0f; - m_pos = m_posPower; - } - if ( oType == OBJECT_STATION ) - { - m_bPower = TRUE; - mat = pObj->RetWorldMatrix(0); - m_posPower = Transform(*mat, D3DVECTOR(-15.0f, 7.0f, 0.0f)); - m_pos = m_posPower; - } - if ( oType == OBJECT_ENERGY ) - { - m_bPower = TRUE; - mat = pObj->RetWorldMatrix(0); - m_posPower = Transform(*mat, D3DVECTOR(-7.0f, 6.0f, 0.0f)); - m_pos = m_posPower; - } - if ( oType == OBJECT_NUCLEAR ) - { - m_bPower = TRUE; - m_posPower = m_pos; - } - if ( oType == OBJECT_PARA ) - { - m_bPower = TRUE; - m_posPower = m_pos; - } - if ( oType == OBJECT_SCRAP4 || - oType == OBJECT_SCRAP5 ) // plastic material? - { - m_bPower = TRUE; - m_posPower = m_pos; - } - - // Plays the sound of a pyrotechnic effect. - if ( type == PT_FRAGT || - type == PT_FRAGW || - type == PT_EXPLOT || - type == PT_EXPLOW ) - { - if ( m_bPower ) - { - sound = SOUND_EXPLOp; - } - else - { - sound = SOUND_EXPLO; - } - if ( oType == OBJECT_STONE || - oType == OBJECT_METAL || - oType == OBJECT_BULLET || - oType == OBJECT_BBOX || - oType == OBJECT_KEYa || - oType == OBJECT_KEYb || - oType == OBJECT_KEYc || - oType == OBJECT_KEYd ) - { - sound = SOUND_EXPLOl; - } - if ( oType == OBJECT_URANIUM || - oType == OBJECT_POWER || - oType == OBJECT_ATOMIC || - oType == OBJECT_TNT || - oType == OBJECT_BOMB ) - { - sound = SOUND_EXPLOlp; - } - m_sound->Play(sound, m_pos); - } - if ( type == PT_FRAGO || - type == PT_EXPLOO || - type == PT_SPIDER || - type == PT_SHOTM ) - { - m_sound->Play(SOUND_EXPLOi, m_pos); - } - if ( type == PT_BURNT || - type == PT_BURNO ) - { - m_soundChannel = m_sound->Play(SOUND_BURN, m_pos, 1.0f, 1.0f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 12.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 5.0f, SOPER_STOP); - } - if ( type == PT_BURNO ) - { - m_sound->Play(SOUND_DEADi, m_pos); - m_sound->Play(SOUND_DEADi, m_engine->RetEyePt()); - } - if ( type == PT_EGG ) - { - m_sound->Play(SOUND_EGG, m_pos); - } - if ( type == PT_WPCHECK || - type == PT_FLCREATE || - type == PT_FLDELETE ) - { - m_sound->Play(SOUND_WAYPOINT, m_pos); - } - if ( oType == OBJECT_HUMAN ) - { - if ( type == PT_DEADG ) - { - m_sound->Play(SOUND_DEADg, m_pos); - } - if ( type == PT_DEADW ) - { - m_sound->Play(SOUND_DEADw, m_pos); - } - if ( type == PT_SHOTH && m_object->RetSelect() ) - { - m_sound->Play(SOUND_AIE, m_pos); - m_sound->Play(SOUND_AIE, m_engine->RetEyePt()); - } - } - - if ( m_type == PT_FRAGT || - m_type == PT_FRAGO || - m_type == PT_FRAGW ) - { - m_engine->ShadowDelete(m_object->RetObjectRank(0)); - } - - if ( m_type == PT_DEADG ) - { - m_object->SetDead(TRUE); - - motion = m_object->RetMotion(); - if ( motion != 0 ) - { - motion->SetAction(MHS_DEADg, 1.0f); - } - m_camera->StartCentering(m_object, PI*0.5f, 99.9f, 0.0f, 1.5f); - m_camera->StartOver(OE_FADEOUTw, m_pos, 1.0f); - m_speed = 1.0f/10.0f; - return TRUE; - } - if ( m_type == PT_DEADW ) - { - m_object->SetDead(TRUE); - - motion = m_object->RetMotion(); - if ( motion != 0 ) - { - motion->SetAction(MHS_DEADw, 4.0f); - } - m_camera->StartCentering(m_object, PI*0.5f, 99.9f, 0.0f, 3.0f); - m_camera->StartOver(OE_FADEOUTb, m_pos, 1.0f); - m_speed = 1.0f/10.0f; - return TRUE; - } - - if ( m_type == PT_SHOTT || - m_type == PT_SHOTM ) - { - m_camera->StartEffect(CE_SHOT, m_pos, force); - m_speed = 1.0f/1.0f; - return TRUE; - } - if ( m_type == PT_SHOTH ) - { - if ( m_object->RetSelect() ) - { - m_camera->StartOver(OE_BLOOD, m_pos, force); - } - m_speed = 1.0f/0.2f; - return TRUE; - } - - if ( m_type == PT_SHOTW ) - { - m_speed = 1.0f/1.0f; - } - - if ( m_type == PT_BURNT ) - { - BurnStart(); - } - - if ( m_type == PT_WPCHECK ) - { - m_speed = 1.0f/8.0f; - m_object->SetEnable(FALSE); // object more functional - } - if ( m_type == PT_FLCREATE ) - { - m_speed = 1.0f/2.0f; - } - if ( m_type == PT_FLDELETE ) - { - m_speed = 1.0f/2.0f; - m_object->SetEnable(FALSE); // object more functional - } - if ( m_type == PT_RESET ) - { - m_speed = 1.0f/2.0f; - m_object->SetPosition(0, m_object->RetResetPosition()); - m_object->SetAngle(0, m_object->RetResetAngle()); - m_object->SetZoom(0, 0.0f); - } - if ( m_type == PT_FINDING ) - { - limit = (m_size-1.0f)/4.0f; - if ( limit > 8.0f ) limit = 8.0f; - if ( oType == OBJECT_APOLLO2 ) limit = 2.0f; - m_speed = 1.0f/limit; - } - - if ( m_type == PT_EXPLOT || - m_type == PT_EXPLOO || - m_type == PT_EXPLOW ) - { - CreateTriangle(pObj, oType, 0); - m_engine->ShadowDelete(m_object->RetObjectRank(0)); - ExploStart(); - } - - if ( m_type == PT_FALL ) - { - FallStart(); - return TRUE; - } - - if ( m_type == PT_BURNT || - m_type == PT_BURNO ) - { - m_speed = 1.0f/15.0f; - - LightOperAdd(0.00f, 0.0f, 2.0f, 1.0f, 0.0f); // red-orange - LightOperAdd(0.30f, 1.0f, -0.8f, -0.8f, -0.8f); // dark gray - LightOperAdd(0.80f, 1.0f, -0.8f, -0.8f, -0.8f); // dark gray - LightOperAdd(1.00f, 0.0f, -0.8f, -0.8f, -0.8f); // dark gray - CreateLight(m_pos, 40.0f); - return TRUE; - } - - if ( m_type == PT_SPIDER ) - { - m_speed = 1.0f/15.0f; - - pos = D3DVECTOR(-3.0f, 2.0f, 0.0f); - mat = pObj->RetWorldMatrix(0); - m_pos = Transform(*mat, pos); - - m_engine->ShadowDelete(m_object->RetObjectRank(0)); - } - - if ( m_type != PT_EGG && - m_type != PT_WIN && - m_type != PT_LOST ) - { - h = 40.0f; - if ( m_type == PT_FRAGO || - m_type == PT_EXPLOO ) - { - LightOperAdd(0.00f, 0.0f, -1.0f, -0.5f, -1.0f); // dark green - LightOperAdd(0.05f, 1.0f, -1.0f, -0.5f, -1.0f); // dark green - LightOperAdd(1.00f, 0.0f, -1.0f, -0.5f, -1.0f); // dark green - } - else if ( m_type == PT_FRAGT || - m_type == PT_EXPLOT ) - { - LightOperAdd(0.00f, 1.0f, 4.0f, 4.0f, 2.0f); // yellow - LightOperAdd(0.02f, 1.0f, 4.0f, 2.0f, 0.0f); // red-orange - LightOperAdd(0.16f, 1.0f, -0.8f, -0.8f, -0.8f); // dark gray - LightOperAdd(1.00f, 0.0f, -0.8f, -0.8f, -0.8f); // dark gray - h = m_size*2.0f; - } - else if ( m_type == PT_SPIDER ) - { - LightOperAdd(0.00f, 0.0f, -0.5f, -1.0f, -1.0f); // dark red - LightOperAdd(0.05f, 1.0f, -0.5f, -1.0f, -1.0f); // dark red - LightOperAdd(1.00f, 0.0f, -0.5f, -1.0f, -1.0f); // dark red - } - else if ( m_type == PT_FRAGW || - m_type == PT_EXPLOW || - m_type == PT_SHOTW ) - { - LightOperAdd(0.00f, 0.0f, -0.5f, -0.5f, -1.0f); // dark yellow - LightOperAdd(0.05f, 1.0f, -0.5f, -0.5f, -1.0f); // dark yellow - LightOperAdd(1.00f, 0.0f, -0.5f, -0.5f, -1.0f); // dark yellow - } - else if ( m_type == PT_WPCHECK || - m_type == PT_FLCREATE || - m_type == PT_FLDELETE || - m_type == PT_RESET || - m_type == PT_FINDING ) - { - LightOperAdd(0.00f, 1.0f, 4.0f, 4.0f, 2.0f); // yellow - LightOperAdd(1.00f, 0.0f, 4.0f, 4.0f, 2.0f); // yellow - } - else - { - LightOperAdd(0.00f, 0.0f, -0.8f, -0.8f, -0.8f); // dark gray - LightOperAdd(0.05f, 1.0f, -0.8f, -0.8f, -0.8f); // dark gray - LightOperAdd(1.00f, 0.0f, -0.8f, -0.8f, -0.8f); // dark gray - } - CreateLight(m_pos, h); - - if ( m_type != PT_SHOTW && - m_type != PT_WPCHECK && - m_type != PT_FLCREATE && - m_type != PT_FLDELETE && - m_type != PT_RESET && - m_type != PT_FINDING ) - { - m_camera->StartEffect(CE_EXPLO, m_pos, force); - } - } - - if ( m_type == PT_SHOTW ) return TRUE; - - // Generates the triangles of the explosion. - if ( m_type == PT_FRAGT || - m_type == PT_FRAGO || - m_type == PT_FRAGW || - m_type == PT_SPIDER || - m_type == PT_EGG || - (m_type == PT_EXPLOT && oType == OBJECT_MOBILEtg) || - (m_type == PT_EXPLOT && oType == OBJECT_TEEN28 ) || - (m_type == PT_EXPLOT && oType == OBJECT_TEEN31 ) ) - { - for ( part=0 ; partRetParticuleDensity()); - if ( oType == OBJECT_TNT || - oType == OBJECT_BOMB ) total *= 3; - for ( i=0 ; iCreateTrack(pos, speed, dim, PARTITRACK1, - duration, mass, Rand()+0.7f, 1.0f); - } - } - - if ( m_size > 10.0f ) // large enough (freight excluded)? - { - if ( m_bPower ) - { - pos = m_posPower; - } - else - { - pos = m_pos; - m_terrain->MoveOnFloor(pos); - pos.y += 1.0f; - } - dim.x = m_size*0.4f; - dim.y = dim.x; - m_particule->CreateParticule(pos, D3DVECTOR(0.0f,0.0f,0.0f), dim, PARTISPHERE0, 2.0f, 0.0f, 0.0f); - } - } - - if ( m_type == PT_FRAGO || - m_type == PT_EXPLOO ) - { - total = (int)(10.0f*m_engine->RetParticuleDensity()); - for ( i=0 ; iCreateParticule(pos, speed, dim, PARTIORGANIC1, - duration, mass); - } - total = (int)(5.0f*m_engine->RetParticuleDensity()); - for ( i=0 ; iCreateTrack(pos, speed, dim, PARTITRACK4, - duration, mass, duration*0.5f, dim.x*2.0f); - } - } - - if ( m_type == PT_SPIDER ) - { - for ( i=0 ; i<50 ; i++ ) - { - pos = m_pos; - pos.x += (Rand()-0.5f)*3.0f; - pos.z += (Rand()-0.5f)*3.0f; - pos.y += (Rand()-0.5f)*2.0f; - speed.x = (Rand()-0.5f)*24.0f; - speed.z = (Rand()-0.5f)*24.0f; - speed.y = 10.0f+Rand()*10.0f; - dim.x = 1.0f; - dim.y = dim.x; - channel = m_particule->CreateParticule(pos, speed, dim, PARTIGUN3, 2.0f+Rand()*2.0f, 10.0f); - m_particule->SetObjectFather(channel, pObj); - } - total = (int)(10.0f*m_engine->RetParticuleDensity()); - for ( i=0 ; iCreateTrack(pos, speed, dim, PARTITRACK3, - 2.0f+Rand()*2.0f, 10.0f, 2.0f, 0.6f); - } - } - - if ( type == PT_FRAGT || - type == PT_FRAGW || - type == PT_EXPLOT || - type == PT_EXPLOW ) - { - if ( m_size > 10.0f || m_bPower ) - { - pos = m_pos; -//? m_terrain->MoveOnFloor(pos); -//? pos.y += 2.0f; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = m_size; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICHOC, 2.0f); - } - } - - return TRUE; -} - -// Creates an explosion with triangular form of particles. - -void CPyro::CreateTriangle(CObject* pObj, ObjectType oType, int part) -{ - D3DTriangle buffer[100]; - D3DMATRIX* mat; - D3DVECTOR offset, pos, speed; - float percent, min, max, h, duration, mass; - int objRank, total, i; - - objRank = pObj->RetObjectRank(part); - if ( objRank == -1 ) return; - - min = 0.0f; - max = m_engine->RetLimitLOD(0); - total = m_engine->RetTotalTriangles(objRank); - percent = 0.10f; - if ( total < 50 ) percent = 0.25f; - if ( total < 20 ) percent = 0.50f; - if ( m_type == PT_EGG ) percent = 0.30f; - if ( oType == OBJECT_POWER || - oType == OBJECT_ATOMIC || - oType == OBJECT_URANIUM || - oType == OBJECT_TNT || - oType == OBJECT_BOMB ) percent = 0.75f; - if ( oType == OBJECT_MOBILEtg ) percent = 0.50f; - if ( oType == OBJECT_TEEN28 ) percent = 0.75f; - if ( oType == OBJECT_MOTHER ) max = 1000000.0f; - if ( oType == OBJECT_TEEN28 ) max = 1000000.0f; - if ( oType == OBJECT_TEEN31 ) max = 1000000.0f; - total = m_engine->GetTriangles(objRank, min, max, buffer, 100, percent); - - for ( i=0 ; i 5.0f ) - { - p2.x = p1.x+((p2.x-p1.x)*5.0f/h); - p2.y = p1.y+((p2.y-p1.y)*5.0f/h); - p2.z = p1.z+((p2.z-p1.z)*5.0f/h); - } - - h = Length(p2, p3); - if ( h > 5.0f ) - { - p3.x = p2.x+((p3.x-p2.x)*5.0f/h); - p3.y = p2.y+((p3.y-p2.y)*5.0f/h); - p3.z = p2.z+((p3.z-p2.z)*5.0f/h); - } - - h = Length(p3, p1); - if ( h > 5.0f ) - { - p1.x = p3.x+((p1.x-p3.x)*5.0f/h); - p1.y = p3.y+((p1.y-p3.y)*5.0f/h); - p1.z = p3.z+((p1.z-p3.z)*5.0f/h); - } - - buffer[i].triangle[0].x = p1.x; - buffer[i].triangle[0].y = p1.y; - buffer[i].triangle[0].z = p1.z; - buffer[i].triangle[1].x = p2.x; - buffer[i].triangle[1].y = p2.y; - buffer[i].triangle[1].z = p2.z; - buffer[i].triangle[2].x = p3.x; - buffer[i].triangle[2].y = p3.y; - buffer[i].triangle[2].z = p3.z; - - offset.x = (buffer[i].triangle[0].x+buffer[i].triangle[1].x+buffer[i].triangle[2].x)/3.0f; - offset.y = (buffer[i].triangle[0].y+buffer[i].triangle[1].y+buffer[i].triangle[2].y)/3.0f; - offset.z = (buffer[i].triangle[0].z+buffer[i].triangle[1].z+buffer[i].triangle[2].z)/3.0f; - - buffer[i].triangle[0].x -= offset.x; - buffer[i].triangle[1].x -= offset.x; - buffer[i].triangle[2].x -= offset.x; - - buffer[i].triangle[0].y -= offset.y; - buffer[i].triangle[1].y -= offset.y; - buffer[i].triangle[2].y -= offset.y; - - buffer[i].triangle[0].z -= offset.z; - buffer[i].triangle[1].z -= offset.z; - buffer[i].triangle[2].z -= offset.z; - - mat = pObj->RetWorldMatrix(part); - pos = Transform(*mat, offset); - if ( m_type == PT_EGG ) - { - speed.x = (Rand()-0.5f)*10.0f; - speed.z = (Rand()-0.5f)*10.0f; - speed.y = Rand()*15.0f; - mass = Rand()*20.0f+20.0f; - } - else if ( m_type == PT_SPIDER ) - { - speed.x = (Rand()-0.5f)*10.0f; - speed.z = (Rand()-0.5f)*10.0f; - speed.y = Rand()*20.0f; - mass = Rand()*10.0f+15.0f; - } - else - { - speed.x = (Rand()-0.5f)*30.0f; - speed.z = (Rand()-0.5f)*30.0f; - speed.y = Rand()*30.0f; - mass = Rand()*10.0f+15.0f; - } - if ( oType == OBJECT_STONE ) speed *= 0.5f; - if ( oType == OBJECT_URANIUM ) speed *= 0.4f; - duration = Rand()*3.0f+3.0f; - m_particule->CreateFrag(pos, speed, &buffer[i], PARTIFRAG, - duration, mass, 0.5f); - } -} - -// Displays the error or eventual information, -// linked to the destruction of an insect, a vehicle or building. - -void CPyro::DisplayError(PyroType type, CObject* pObj) -{ - ObjectType oType; - Error err; - - oType = pObj->RetType(); - - if ( type == PT_FRAGT || - type == PT_FRAGO || - type == PT_FRAGW || - type == PT_EXPLOT || - type == PT_EXPLOO || - type == PT_EXPLOW || - type == PT_BURNT || - type == PT_BURNO ) - { - err = ERR_OK; - if ( oType == OBJECT_MOTHER ) err = INFO_DELETEMOTHER; - if ( oType == OBJECT_ANT ) err = INFO_DELETEANT; - if ( oType == OBJECT_BEE ) err = INFO_DELETEBEE; - if ( oType == OBJECT_WORM ) err = INFO_DELETEWORM; - if ( oType == OBJECT_SPIDER ) err = INFO_DELETESPIDER; - - if ( oType == OBJECT_MOBILEwa || - oType == OBJECT_MOBILEta || - oType == OBJECT_MOBILEfa || - oType == OBJECT_MOBILEia || - oType == OBJECT_MOBILEwc || - oType == OBJECT_MOBILEtc || - oType == OBJECT_MOBILEfc || - oType == OBJECT_MOBILEic || - oType == OBJECT_MOBILEwi || - oType == OBJECT_MOBILEti || - oType == OBJECT_MOBILEfi || - oType == OBJECT_MOBILEii || - oType == OBJECT_MOBILEws || - oType == OBJECT_MOBILEts || - oType == OBJECT_MOBILEfs || - oType == OBJECT_MOBILEis || - oType == OBJECT_MOBILErt || - oType == OBJECT_MOBILErc || - oType == OBJECT_MOBILErr || - oType == OBJECT_MOBILErs || - oType == OBJECT_MOBILEsa || - oType == OBJECT_MOBILEwt || - oType == OBJECT_MOBILEtt || - oType == OBJECT_MOBILEft || - oType == OBJECT_MOBILEit || - oType == OBJECT_MOBILEdr ) - { - err = ERR_DELETEMOBILE; - } - - if ( oType == OBJECT_DERRICK || - oType == OBJECT_FACTORY || - oType == OBJECT_STATION || - oType == OBJECT_CONVERT || - oType == OBJECT_REPAIR || - oType == OBJECT_DESTROYER|| - oType == OBJECT_TOWER || - oType == OBJECT_RESEARCH || - oType == OBJECT_RADAR || - oType == OBJECT_INFO || - oType == OBJECT_ENERGY || - oType == OBJECT_LABO || - oType == OBJECT_NUCLEAR || - oType == OBJECT_PARA || - oType == OBJECT_SAFE || - oType == OBJECT_HUSTON || - oType == OBJECT_START || - oType == OBJECT_END ) - { - err = ERR_DELETEBUILDING; - m_displayText->DisplayError(err, pObj->RetPosition(0), 5.0f); - return; - } - - if ( err != ERR_OK ) - { - m_displayText->DisplayError(err, pObj); - } - } -} - - -// Management of an event. - -BOOL CPyro::EventProcess(const Event &event) -{ - ParticuleType type; - D3DVECTOR pos, speed, angle; - FPOINT dim; - float prog, factor, duration; - int i, r; - - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_engine->RetPause() ) return TRUE; - - m_time += event.rTime; - m_progress += event.rTime*m_speed; - - if ( m_soundChannel != -1 && m_object != 0 ) - { - pos = m_object->RetPosition(0); - m_sound->Position(m_soundChannel, pos); - - if ( m_lightRank != -1 ) - { - pos.y += m_lightHeight; - m_light->SetLightPos(m_lightRank, pos); - } - } - - if ( m_type == PT_SHOTT && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - if ( m_crashSphereUsed > 0 ) - { - i = rand()%m_crashSphereUsed; - pos = m_crashSpherePos[i]; - pos.x += (Rand()-0.5f)*m_crashSphereRadius[i]*2.0f; - pos.z += (Rand()-0.5f)*m_crashSphereRadius[i]*2.0f; - speed.x = (Rand()-0.5f)*m_crashSphereRadius[i]*0.5f; - speed.z = (Rand()-0.5f)*m_crashSphereRadius[i]*0.5f; - speed.y = Rand()*m_crashSphereRadius[i]*1.0f; - dim.x = Rand()*m_crashSphereRadius[i]*0.5f+m_crashSphereRadius[i]*0.75f*m_force; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 3.0f); - } - else - { - pos = m_pos; - pos.x += (Rand()-0.5f)*m_size*0.3f; - pos.z += (Rand()-0.5f)*m_size*0.3f; - speed.x = (Rand()-0.5f)*m_size*0.1f; - speed.z = (Rand()-0.5f)*m_size*0.1f; - speed.y = Rand()*m_size*0.2f; - dim.x = Rand()*m_size/10.0f+m_size/10.0f*m_force; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 3.0f); - } - } - - if ( m_type == PT_SHOTH && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - for ( i=0 ; i<10 ; i++ ) - { - pos = m_pos; - pos.x += (Rand()-0.5f)*m_size*0.2f; - pos.z += (Rand()-0.5f)*m_size*0.2f; - pos.y += (Rand()-0.5f)*m_size*0.5f; - speed.x = (Rand()-0.5f)*5.0f; - speed.z = (Rand()-0.5f)*5.0f; - speed.y = Rand()*1.0f; - dim.x = 1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLOOD, Rand()*3.0f+3.0f, Rand()*10.0f+15.0f, 0.5f); - } - } - - if ( m_type == PT_SHOTM && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - r = (int)(10.0f*m_engine->RetParticuleDensity()); - for ( i=0 ; iCreateParticule(pos, speed, dim, PARTIBLOODM, 2.0f, 50.0f, 0.0f); - } - } - - if ( m_type == PT_SHOTW && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - if ( m_crashSphereUsed > 0 ) - { - i = rand()%m_crashSphereUsed; - pos = m_crashSpherePos[i]; - pos.x += (Rand()-0.5f)*m_crashSphereRadius[i]*2.0f; - pos.z += (Rand()-0.5f)*m_crashSphereRadius[i]*2.0f; - speed.x = (Rand()-0.5f)*m_crashSphereRadius[i]*0.5f; - speed.z = (Rand()-0.5f)*m_crashSphereRadius[i]*0.5f; - speed.y = Rand()*m_crashSphereRadius[i]*1.0f; - dim.x = 1.0f*m_force; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 0.5f, 0.0f, 0.0f); - } - else - { - pos = m_pos; - pos.x += (Rand()-0.5f)*m_size*0.3f; - pos.z += (Rand()-0.5f)*m_size*0.3f; - speed.x = (Rand()-0.5f)*m_size*0.1f; - speed.z = (Rand()-0.5f)*m_size*0.1f; - speed.y = Rand()*m_size*0.2f; - dim.x = 1.0f*m_force; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 0.5f, 0.0f, 0.0f); - } - } - - if ( m_type == PT_SHOTW && - m_lastParticuleSmoke+m_engine->ParticuleAdapt(0.10f) <= m_time ) - { - m_lastParticuleSmoke = m_time; - - pos = m_pos; - pos.y -= 2.0f; - pos.x += (Rand()-0.5f)*4.0f; - pos.z += (Rand()-0.5f)*4.0f; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 10.0f+Rand()*10.0f; - dim.x = Rand()*2.5f+2.0f*m_force; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 4.0f); - } - - if ( (m_type == PT_FRAGT || m_type == PT_EXPLOT) && - m_progress < 0.05f && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_pos; - speed.x = (Rand()-0.5f)*m_size*1.0f; - speed.z = (Rand()-0.5f)*m_size*1.0f; - speed.y = Rand()*m_size*0.50f; - dim.x = Rand()*m_size/5.0f+m_size/5.0f; - dim.y = dim.x; - - m_particule->CreateParticule(pos, speed, dim, PARTIEXPLOT); - } - - if ( (m_type == PT_FRAGT || m_type == PT_EXPLOT) && - m_progress < 0.10f && - m_lastParticuleSmoke+m_engine->ParticuleAdapt(0.10f) <= m_time ) - { - m_lastParticuleSmoke = m_time; - - dim.x = Rand()*m_size/3.0f+m_size/3.0f; - dim.y = dim.x; - pos = m_pos; - pos.x += (Rand()-0.5f)*m_size*0.5f; - pos.z += (Rand()-0.5f)*m_size*0.5f; - m_terrain->MoveOnFloor(pos); - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = -dim.x/2.0f/4.0f; - pos.y += dim.x/2.0f; - - r = rand()%2; - if ( r == 0 ) type = PARTISMOKE1; - if ( r == 1 ) type = PARTISMOKE2; - m_particule->CreateParticule(pos, speed, dim, type, 6.0f); - } - - if ( (m_type == PT_FRAGO || m_type == PT_EXPLOO) && - m_progress < 0.03f && - m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_pos; - speed.x = (Rand()-0.5f)*m_size*2.0f; - speed.z = (Rand()-0.5f)*m_size*2.0f; - speed.y = Rand()*m_size*1.0f; - dim.x = Rand()*m_size/2.0f+m_size/2.0f; - dim.y = dim.x; - - m_particule->CreateParticule(pos, speed, dim, PARTIEXPLOO); - } - - if ( (m_type == PT_FRAGW || m_type == PT_EXPLOW) && - m_progress < 0.05f && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_pos; - speed.x = (Rand()-0.5f)*m_size*1.0f; - speed.z = (Rand()-0.5f)*m_size*1.0f; - speed.y = Rand()*m_size*0.50f; - dim.x = 1.0f; - dim.y = dim.x; - - m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 0.5f, 0.0f, 0.0f); - } - - if ( (m_type == PT_FRAGW || m_type == PT_EXPLOW) && - m_progress < 0.25f && - m_lastParticuleSmoke+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticuleSmoke = m_time; - - pos = m_pos; - pos.y -= 2.0f; - pos.x += (Rand()-0.5f)*4.0f; - pos.z += (Rand()-0.5f)*4.0f; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 4.0f+Rand()*4.0f; - dim.x = Rand()*2.5f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 4.0f); - } - - if ( m_type == PT_WPCHECK ) - { - if ( m_progress < 0.25f ) - { - factor = 0.0f; - } - else - { - factor = powf((m_progress-0.25f)/0.75f, 2.0f)*30.0f; - } - - if ( m_progress < 0.85f && - m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_pos; - pos.y += factor; - pos.x += (Rand()-0.5f)*3.0f; - pos.z += (Rand()-0.5f)*3.0f; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 5.0f+Rand()*5.0f; - dim.x = Rand()*1.5f+1.5f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f); -//? m_particule->CreateParticule(pos, speed, dim, (ParticuleType)(PARTILENS1+rand()%4), 2.0f); - } - - angle = m_object->RetAngle(0); - angle.y = m_progress*20.0f; - angle.x = sinf(m_progress*49.0f)*0.3f; - angle.z = sinf(m_progress*47.0f)*0.2f; - m_object->SetAngle(0, angle); - - pos = m_pos; - pos.y += factor; - m_object->SetPosition(0, pos); - - if ( m_progress > 0.85f ) - { - m_object->SetZoom(0, 1.0f-(m_progress-0.85f)/0.15f); - } - } - - if ( m_type == PT_FLCREATE ) - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_pos; - m_terrain->MoveOnFloor(pos); - pos.x += (Rand()-0.5f)*1.0f; - pos.z += (Rand()-0.5f)*1.0f; - speed.x = (Rand()-0.5f)*2.0f; - speed.z = (Rand()-0.5f)*2.0f; - speed.y = 2.0f+Rand()*2.0f; - dim.x = (Rand()*1.0f+1.0f)*(0.2f+m_progress*0.8f); - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f); - } - - angle = m_object->RetAngle(0); -//? angle.y = powf(m_progress, 0.2f)*20.0f; - angle.x = sinf(m_progress*49.0f)*0.3f*(1.0f-m_progress); - angle.z = sinf(m_progress*47.0f)*0.2f*(1.0f-m_progress); - m_object->SetAngle(0, angle); - - m_object->SetZoom(0, m_progress); - } - - if ( m_type == PT_FLDELETE ) - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_pos; - m_terrain->MoveOnFloor(pos); - pos.x += (Rand()-0.5f)*1.0f; - pos.z += (Rand()-0.5f)*1.0f; - speed.x = (Rand()-0.5f)*2.0f; - speed.z = (Rand()-0.5f)*2.0f; - speed.y = 2.0f+Rand()*2.0f; - dim.x = (Rand()*1.0f+1.0f)*(0.2f+m_progress*0.8f); - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.5f); - } - - angle = m_object->RetAngle(0); - angle.y = m_progress*20.0f; - angle.x = sinf(m_progress*49.0f)*0.3f; - angle.z = sinf(m_progress*47.0f)*0.2f; - m_object->SetAngle(0, angle); - - m_object->SetZoom(0, 1.0f-m_progress); - } - - if ( m_type == PT_RESET ) - { -#if 0 - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_pos; - speed.x = (Rand()-0.5f)*6.0f; - speed.z = (Rand()-0.5f)*6.0f; - speed.y = Rand()*12.0f; - dim.x = (Rand()*2.5f+2.5f)*(1.0f-m_progress*0.9f); - dim.y = dim.x; - pos.y += dim.y; - m_particule->CreateParticule(pos, speed, dim, - (ParticuleType)(PARTILENS1+rand()%4), - Rand()*2.5f+2.5f, - Rand()*5.0f+5.0f, 0.0f); - } -#else - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_pos; - pos.x += (Rand()-0.5f)*5.0f; - pos.z += (Rand()-0.5f)*5.0f; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 5.0f+Rand()*5.0f; - dim.x = Rand()*2.0f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINTb, 2.0f); - - pos = m_pos; - speed.x = (Rand()-0.5f)*20.0f; - speed.z = (Rand()-0.5f)*20.0f; - speed.y = Rand()*10.0f; - speed *= 0.5f+m_progress*0.5f; - dim.x = 0.6f; - dim.y = dim.x; - pos.y += dim.y; - duration = Rand()*1.5f+1.5f; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK6, - duration, 0.0f, - duration*0.9f, 0.7f); - } -#endif - - angle = m_object->RetResetAngle(); - m_object->SetAngleY(0, angle.y-powf((1.0f-m_progress)*5.0f, 2.0f)); - m_object->SetZoom(0, m_progress); - } - - if ( m_type == PT_FINDING ) - { - if ( m_object != 0 && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - factor = m_size*0.3f; - if ( m_object->RetType() == OBJECT_SAFE ) factor *= 1.3f; - if ( factor > 40.0f ) factor = 40.0f; - pos = m_pos; - m_terrain->MoveOnFloor(pos); - pos.x += (Rand()-0.5f)*factor; - pos.z += (Rand()-0.5f)*factor; - speed.x = (Rand()-0.5f)*2.0f; - speed.z = (Rand()-0.5f)*2.0f; - speed.y = 4.0f+Rand()*4.0f; - dim.x = (Rand()*3.0f+3.0f)*(1.0f-m_progress*0.9f); - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.5f); - } - } - - if ( (m_type == PT_BURNT || m_type == PT_BURNO) && - m_object != 0 ) - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - factor = m_size/25.0f; // 1 = standard size - - pos = m_object->RetPosition(0); - pos.y -= m_object->RetCharacter()->height; - pos.x += (Rand()-0.5f)*(4.0f+8.0f*m_progress)*factor; - pos.z += (Rand()-0.5f)*(4.0f+8.0f*m_progress)*factor; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 0.0f; - dim.x = (Rand()*2.5f+1.0f)*factor; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFLAME, 2.0f, 0.0f, 0.2f); - - pos = m_object->RetPosition(0); - pos.y -= m_object->RetCharacter()->height; - pos.x += (Rand()-0.5f)*(2.0f+4.0f*m_progress)*factor; - pos.z += (Rand()-0.5f)*(2.0f+4.0f*m_progress)*factor; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = (Rand()*5.0f*m_progress+3.0f)*factor; - dim.x = (Rand()*2.0f+1.0f)*factor; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFLAME, 2.0f, 0.0f, 0.2f); - - pos = m_object->RetPosition(0); - pos.y -= 2.0f; - pos.x += (Rand()-0.5f)*5.0f*factor; - pos.z += (Rand()-0.5f)*5.0f*factor; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = (6.0f+Rand()*6.0f+m_progress*6.0f)*factor; - dim.x = (Rand()*1.5f+1.0f+m_progress*3.0f)*factor; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); - } - - if ( m_type == PT_BURNT ) - { - BurnProgress(); - } - else - { - speed.y = 0.0f; - speed.x = (Rand()-0.5f)*m_progress*1.0f; - speed.z = (Rand()-0.5f)*m_progress*1.0f; - if ( m_progress > 0.8f ) - { - prog = (m_progress-0.8f)/0.2f; // 0..1 - speed.y = -prog*6.0f; // sinks into the ground - m_object->SetZoom(0, 1.0f-prog*0.5f); - } - m_object->SetLinVibration(speed); - } - } - - if ( m_type == PT_WIN ) - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_object->RetPosition(0); - pos.y += 1.5f; - speed.x = (Rand()-0.5f)*10.0f; - speed.z = (Rand()-0.5f)*10.0f; - speed.y = 8.0f+Rand()*8.0f; - dim.x = Rand()*0.2f+0.2f; - dim.y = dim.x; - m_particule->CreateTrack(pos, speed, dim, - (ParticuleType)(PARTITRACK7+rand()%4), - 3.0f, 20.0f, 1.0f, 0.4f); - } - } - - if ( m_type == PT_LOST ) - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_object->RetPosition(0); - pos.y -= 2.0f; - pos.x += (Rand()-0.5f)*10.0f; - pos.z += (Rand()-0.5f)*10.0f; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 1.0f+Rand()*1.0f; - dim.x = Rand()*1.0f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 8.0f, 0.0f, 0.0f); - } - } - - if ( m_type == PT_FALL ) - { - FallProgress(event.rTime); - } - - if ( m_lightRank != -1 ) - { - LightOperFrame(event.rTime); - } - - return TRUE; -} - -// Indicates that the object binds to the effect no longer exists, without deleting it. - -void CPyro::CutObjectLink(CObject* pObj) -{ - if ( m_object == pObj ) - { - m_object = 0; - } -} - -// Indicates whether the pyrotechnic effect is complete. - -Error CPyro::IsEnded() -{ - // Destroys the object that exploded. - //It should not be destroyed at the end of the Create, - //because it is sometimes the object itself that makes the Create: - // pyro->Create(PT_FRAGT, this); - if ( m_type == PT_FRAGT || - m_type == PT_FRAGO || - m_type == PT_FRAGW || - m_type == PT_SPIDER || - m_type == PT_EGG ) - { - DeleteObject(TRUE, TRUE); - } - - if ( m_type == PT_FALL ) // freight which grave? - { - return FallIsEnded(); - } - - if ( m_type == PT_WIN || - m_type == PT_LOST ) - { - return ERR_CONTINUE; - } - - // End of the pyrotechnic effect? - if ( m_progress < 1.0f ) return ERR_CONTINUE; - - if ( m_type == PT_EXPLOT || - m_type == PT_EXPLOO || - m_type == PT_EXPLOW ) // explosion? - { - ExploTerminate(); - } - - if ( m_type == PT_BURNT || - m_type == PT_BURNO ) // burning? - { - BurnTerminate(); - } - - if ( m_type == PT_WPCHECK || - m_type == PT_FLDELETE ) - { - DeleteObject(TRUE, TRUE); - } - - if ( m_type == PT_FLCREATE ) - { - m_object->SetAngleX(0, 0.0f); - m_object->SetAngleZ(0, 0.0f); - m_object->SetZoom(0, 1.0f); - } - - if ( m_type == PT_RESET ) - { - m_object->SetPosition(0, m_object->RetResetPosition()); - m_object->SetAngle(0, m_object->RetResetAngle()); - m_object->SetZoom(0, 1.0f); - } - - if ( m_lightRank != -1 ) - { - m_light->DeleteLight(m_lightRank); - m_lightRank = -1; - } - - return ERR_STOP; -} - -// Removes the binding to a pyrotechnic effect. - -void CPyro::DeleteObject(BOOL bPrimary, BOOL bSecondary) -{ - CObject *sub, *truck; - D3DVECTOR pos; - ObjectType type; - - if ( m_object == 0 ) return; - - if ( m_object->RetResetCap() == RESET_MOVE ) // resettable object? - { - m_object->SetEnable(FALSE); // object cache and inactive - pos = m_object->RetPosition(0); - pos.y = -100.0f; - m_object->SetPosition(0, pos); - return; - } - - type = m_object->RetType(); - if ( bSecondary && - type != OBJECT_FACTORY && - type != OBJECT_NUCLEAR && - type != OBJECT_ENERGY ) - { - sub = m_object->RetPower(); - if ( sub != 0 ) - { - sub->DeleteObject(); // removes the battery - delete sub; - m_object->SetPower(0); - } - - sub = m_object->RetFret(); - if ( sub != 0 ) - { - sub->DeleteObject(); // removes the object transported - delete sub; - m_object->SetFret(0); - } - } - - if ( bPrimary ) - { - truck = m_object->RetTruck(); - if ( truck != 0 ) // object carries? - { - if ( truck->RetPower() == m_object ) - { - truck->SetPower(0); - } - if ( truck->RetFret() == m_object ) - { - truck->SetFret(0); - } - } - - sub = m_object; - sub->DeleteObject(); // removes the object (*) - delete sub; - m_object = 0; - } -} - -// (*) CObject :: DeleteObject can reset m_object through CPyro :: CutObjectLink! - - -// Empty the table of operations of animation of light. - -void CPyro::LightOperFlush() -{ - m_lightOperTotal = 0; -} - -// Adds an animation operation of the light. - -void CPyro::LightOperAdd(float progress, float intensity, - float r, float g, float b) -{ - int i; - - i = m_lightOperTotal; - - m_lightOper[i].progress = progress; - m_lightOper[i].intensity = intensity; - m_lightOper[i].color.r = r; - m_lightOper[i].color.g = g; - m_lightOper[i].color.b = b; - - m_lightOperTotal ++; -} - -// Makes evolve the associated light. - -void CPyro::LightOperFrame(float rTime) -{ - D3DCOLORVALUE color; - float progress, intensity; - int i; - - for ( i=0 ; iSetLightIntensity(m_lightRank, intensity); - m_light->SetLightColor(m_lightRank, color); - break; - } - } -} - - -// Creates light to accompany a pyrotechnic effect. - -BOOL CPyro::CreateLight(D3DVECTOR pos, float height) -{ - D3DLIGHT7 light; - - if ( !m_engine->RetLightMode() ) return TRUE; - - m_lightHeight = height; - - ZeroMemory( &light, sizeof(light) ); - light.dltType = D3DLIGHT_SPOT; - light.dvPosition.x = pos.x; - light.dvPosition.y = pos.y+height; - light.dvPosition.z = pos.z; - light.dvDirection.x = 0.0f; - light.dvDirection.y = -1.0f; // against the bottom - light.dvDirection.z = 0.0f; - light.dvRange = D3DLIGHT_RANGE_MAX; - light.dvFalloff = 1.0f; - light.dvAttenuation0 = 1.0f; - light.dvAttenuation1 = 0.0f; - light.dvAttenuation2 = 0.0f; - light.dvTheta = 0.0f; - light.dvPhi = PI/4.0f; - - m_lightRank = m_light->CreateLight(); - if ( m_lightRank == -1 ) return FALSE; - - m_light->SetLight(m_lightRank, light); - m_light->SetLightIntensity(m_lightRank, 0.0f); - - // Only illuminates the objects on the ground. - m_light->SetLightIncluType(m_lightRank, TYPETERRAIN); - - return TRUE; -} - - -// Starts the explosion of a vehicle. - -void CPyro::ExploStart() -{ - D3DVECTOR pos, angle, speed, min, max; - float weight; - int i, objRank, channel; - - m_burnType = m_object->RetType(); - - pos = m_object->RetPosition(0); - m_burnFall = m_terrain->RetFloorHeight(pos, TRUE); - - m_object->Simplify(); - m_object->SetLock(TRUE); // ruin not usable yet - m_object->SetExplo(TRUE); // being destroyed - m_object->FlatParent(); - - if ( m_object->RetSelect() ) - { - m_object->SetSelect(FALSE); // deselects the object - m_camera->SetType(CAMERA_EXPLO); - m_main->DeselectAll(); - } - m_object->DeleteDeselList(m_object); - - for ( i=0 ; iRetObjectRank(i); - if ( objRank == -1 ) continue; - m_engine->ChangeSecondTexture(objRank, "dirty04.tga"); - - pos = m_object->RetPosition(i); - - if ( i == 0 ) // main part? - { - weight = 0.0f; - - speed.y = -1.0f; - speed.x = 0.0f; - speed.z = 0.0f; - } - else - { - m_engine->GetBBox(objRank, min, max); - weight = Length(min, max); // weight according to size! - - speed.y = 10.0f+Rand()*20.0f; - speed.x = (Rand()-0.5f)*20.0f; - speed.z = (Rand()-0.5f)*20.0f; - } - - channel = m_particule->CreatePart(pos, speed, PARTIPART, 10.0f, 20.0f, weight, 0.5f); - if ( channel != -1 ) - { - m_object->SetMasterParticule(i, channel); - } - } - m_engine->LoadTexture("dirty04.tga", 1); - - DeleteObject(FALSE, TRUE); // destroys the object transported + the battery -} - -// Ends the explosion of a vehicle. - -void CPyro::ExploTerminate() -{ - DeleteObject(TRUE, FALSE); // removes the main object -} - - -// Starts a vehicle fire. - -void CPyro::BurnStart() -{ - D3DVECTOR pos, angle; - int i, objRank; - - m_burnType = m_object->RetType(); - - pos = m_object->RetPosition(0); - m_burnFall = m_terrain->RetFloorHeight(pos, TRUE); - - m_object->Simplify(); - m_object->SetLock(TRUE); // ruin not usable yet - - if ( m_object->RetSelect() ) - { - m_object->SetSelect(FALSE); // deselects the object - m_camera->SetType(CAMERA_EXPLO); - m_main->DeselectAll(); - } - m_object->DeleteDeselList(m_object); - - for ( i=0 ; iRetObjectRank(i); - if ( objRank == -1 ) continue; - m_engine->ChangeSecondTexture(objRank, "dirty04.tga"); - } - m_engine->LoadTexture("dirty04.tga", 1); - - m_burnPartTotal = 0; - - if ( m_burnType == OBJECT_DERRICK || - m_burnType == OBJECT_FACTORY || - m_burnType == OBJECT_REPAIR || - m_burnType == OBJECT_DESTROYER|| - m_burnType == OBJECT_CONVERT || - m_burnType == OBJECT_TOWER || - m_burnType == OBJECT_RESEARCH || - m_burnType == OBJECT_ENERGY || - m_burnType == OBJECT_LABO ) - { - pos.x = 0.0f; - pos.y = -(4.0f+Rand()*4.0f); - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.4f; - angle.y = 0.0f; - angle.z = (Rand()-0.5f)*0.4f; - } - else if ( m_burnType == OBJECT_STATION || - m_burnType == OBJECT_RADAR || - m_burnType == OBJECT_INFO ) - { - pos.x = 0.0f; - pos.y = -(1.0f+Rand()*1.0f); - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.2f; - angle.y = 0.0f; - angle.z = (Rand()-0.5f)*0.2f; - } - else if ( m_burnType == OBJECT_NUCLEAR ) - { - pos.x = 0.0f; - pos.y = -(10.0f+Rand()*10.0f); - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.4f; - angle.y = 0.0f; - angle.z = (Rand()-0.5f)*0.4f; - } - else if ( m_burnType == OBJECT_PARA ) - { - pos.x = 0.0f; - pos.y = -(10.0f+Rand()*10.0f); - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.4f; - angle.y = 0.0f; - angle.z = (Rand()-0.5f)*0.4f; - } - else if ( m_burnType == OBJECT_SAFE ) - { - pos.x = 0.0f; - pos.y = -(10.0f+Rand()*10.0f); - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.4f; - angle.y = 0.0f; - angle.z = (Rand()-0.5f)*0.4f; - } - else if ( m_burnType == OBJECT_HUSTON ) - { - pos.x = 0.0f; - pos.y = -(10.0f+Rand()*10.0f); - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.4f; - angle.y = 0.0f; - angle.z = (Rand()-0.5f)*0.4f; - } - else if ( m_burnType == OBJECT_MOBILEwa || - m_burnType == OBJECT_MOBILEwc || - m_burnType == OBJECT_MOBILEwi || - m_burnType == OBJECT_MOBILEws || - m_burnType == OBJECT_MOBILEwt ) - { - pos.x = 0.0f; - pos.y = -(0.5f+Rand()*1.0f); - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.8f; - angle.y = 0.0f; - angle.z = (Rand()-0.5f)*0.4f; - } - else if ( m_burnType == OBJECT_TEEN31 ) // basket? - { - pos.x = 0.0f; - pos.y = 0.0f; - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.8f; - angle.y = 0.0f; - angle.z = (Rand()-0.5f)*0.2f; - } - else - { - pos.x = 0.0f; - pos.y = -(2.0f+Rand()*2.0f); - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.8f; - angle.y = 0.0f; - angle.z = (Rand()-0.5f)*0.8f; - } - BurnAddPart(0, pos, angle); // movement of the main part - - m_burnKeepPart[0] = -1; // nothing to keep - - if ( m_burnType == OBJECT_DERRICK ) - { - pos.x = 0.0f; - pos.y = -40.0f; - pos.z = 0.0f; - angle.x = 0.0f; - angle.y = 0.0f; - angle.z = 0.0f; - BurnAddPart(1, pos, angle); // down the drill - } - - if ( m_burnType == OBJECT_REPAIR ) - { - pos.x = 0.0f; - pos.y = -12.0f; - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.2f; - angle.y = (Rand()-0.5f)*0.2f; - angle.z = -90.0f*PI/180.0f; - BurnAddPart(1, pos, angle); // down the sensor - } - - if ( m_burnType == OBJECT_DESTROYER ) - { - pos.x = 0.0f; - pos.y = -12.0f; - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.2f; - angle.y = (Rand()-0.5f)*0.2f; - angle.z = -90.0f*PI/180.0f; - BurnAddPart(1, pos, angle); // down the sensor - } - - if ( m_burnType == OBJECT_CONVERT ) - { - pos.x = 0.0f; - pos.y = -200.0f; - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.5f; - angle.y = (Rand()-0.5f)*0.5f; - angle.z = 0.0f; - BurnAddPart(1, pos, angle); // down the cover - BurnAddPart(2, pos, angle); - BurnAddPart(3, pos, angle); - } - - if ( m_burnType == OBJECT_TOWER ) - { - pos.x = 0.0f; - pos.y = -7.0f; - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.4f; - angle.y = (Rand()-0.5f)*0.4f; - angle.z = 0.0f; - BurnAddPart(1, pos, angle); // down the cannon - } - - if ( m_burnType == OBJECT_RESEARCH ) - { - pos.x = 0.0f; - pos.y = -7.0f; - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.2f; - angle.y = (Rand()-0.5f)*0.2f; - angle.z = 0.0f; - BurnAddPart(1, pos, angle); // down the anemometer - } - - if ( m_burnType == OBJECT_RADAR ) - { - pos.x = 0.0f; - pos.y = -14.0f; - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.4f; - angle.y = (Rand()-0.5f)*0.4f; - angle.z = 0.0f; - BurnAddPart(1, pos, angle); // down the radar - BurnAddPart(2, pos, angle); - } - - if ( m_burnType == OBJECT_INFO ) - { - pos.x = 0.0f; - pos.y = -14.0f; - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.4f; - angle.y = (Rand()-0.5f)*0.4f; - angle.z = 0.0f; - BurnAddPart(1, pos, angle); // down the information terminal - BurnAddPart(2, pos, angle); - } - - if ( m_burnType == OBJECT_LABO ) - { - pos.x = 0.0f; - pos.y = -12.0f; - pos.z = 0.0f; - angle.x = 0.0f; - angle.y = 0.0f; - angle.z = 0.0f; - BurnAddPart(1, pos, angle); // down the arm - } - - if ( m_burnType == OBJECT_NUCLEAR ) - { - pos.x = 0.0f; - pos.y = 0.0f; - pos.z = 0.0f; - angle.x = 0.0f; - angle.y = 0.0f; - angle.z = -135.0f*PI/180.0f; - BurnAddPart(1, pos, angle); // down the cover - } - - if ( m_burnType == OBJECT_MOBILEfa || - m_burnType == OBJECT_MOBILEta || - m_burnType == OBJECT_MOBILEwa || - m_burnType == OBJECT_MOBILEia ) - { - pos.x = 2.0f; - pos.y = -5.0f; - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.2f; - angle.y = (Rand()-0.5f)*0.2f; - angle.z = 40.0f*PI/180.0f; - BurnAddPart(1, pos, angle); // down the arm - } - - if ( m_burnType == OBJECT_MOBILEfs || - m_burnType == OBJECT_MOBILEts || - m_burnType == OBJECT_MOBILEws || - m_burnType == OBJECT_MOBILEis ) - { - pos.x = 0.0f; - pos.y = -7.0f; - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.2f; - angle.y = (Rand()-0.5f)*0.2f; - angle.z = 50.0f*PI/180.0f; - BurnAddPart(1, pos, angle); // down the sensor - } - - if ( m_burnType == OBJECT_MOBILEfc || - m_burnType == OBJECT_MOBILEtc || - m_burnType == OBJECT_MOBILEwc || - m_burnType == OBJECT_MOBILEic ) - { - pos.x = -1.5f; - pos.y = -5.0f; - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.2f; - angle.y = (Rand()-0.5f)*0.2f; - angle.z = -25.0f*PI/180.0f; - BurnAddPart(1, pos, angle); // down the cannon - } - - if ( m_burnType == OBJECT_MOBILEfi || - m_burnType == OBJECT_MOBILEti || - m_burnType == OBJECT_MOBILEwi || - m_burnType == OBJECT_MOBILEii ) - { - pos.x = -1.5f; - pos.y = -5.0f; - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*0.2f; - angle.y = (Rand()-0.5f)*0.2f; - angle.z = -25.0f*PI/180.0f; - BurnAddPart(1, pos, angle); // down the insect-cannon - } - - if ( m_burnType == OBJECT_MOBILErt || - m_burnType == OBJECT_MOBILErc ) - { - pos.x = 0.0f; - pos.y = -10.0f; - pos.z = 0.0f; - angle.x = 0.0f; - angle.y = 0.0f; - angle.z = 0.0f; - BurnAddPart(1, pos, angle); // down the holder - - pos.x = 0.0f; - pos.y = -10.0f; - pos.z = 0.0f; - angle.x = 0.0f; - angle.y = 0.0f; - angle.z = 0.0f; - BurnAddPart(2, pos, angle); // down the pestle/cannon - } - - if ( m_burnType == OBJECT_MOBILErr ) - { - pos.x = 0.0f; - pos.y = -10.0f; - pos.z = 0.0f; - angle.x = 0.0f; - angle.y = 0.0f; - angle.z = 0.0f; - BurnAddPart(1, pos, angle); // down the holder - - pos.x = 0.0f; - pos.y = 0.0f; - pos.z = 0.0f; - angle.x = 0.0f; - angle.y = 0.0f; - angle.z = -PI/2.0f; - BurnAddPart(4, pos, angle); - - pos.x = 0.0f; - pos.y = 0.0f; - pos.z = 0.0f; - angle.x = 0.0f; - angle.y = 0.0f; - angle.z = PI/2.5f; - BurnAddPart(2, pos, angle); - } - - if ( m_burnType == OBJECT_MOBILErs ) - { - pos.x = 0.0f; - pos.y = -10.0f; - pos.z = 0.0f; - angle.x = 0.0f; - angle.y = 0.0f; - angle.z = 0.0f; - BurnAddPart(1, pos, angle); // down the holder - - pos.x = 0.0f; - pos.y = -5.0f; - pos.z = 0.0f; - angle.x = 0.0f; - angle.y = 0.0f; - angle.z = 0.0f; - BurnAddPart(2, pos, angle); - - pos.x = 0.0f; - pos.y = -5.0f; - pos.z = 0.0f; - angle.x = 0.0f; - angle.y = 0.0f; - angle.z = 0.0f; - BurnAddPart(3, pos, angle); - } - - if ( m_burnType == OBJECT_MOBILEsa ) - { - pos.x = 0.0f; - pos.y = -10.0f; - pos.z = 0.0f; - angle.x = 0.0f; - angle.y = 0.0f; - angle.z = 0.0f; - BurnAddPart(1, pos, angle); // down the holder - } - - if ( m_burnType == OBJECT_MOBILEwa || - m_burnType == OBJECT_MOBILEwc || - m_burnType == OBJECT_MOBILEwi || - m_burnType == OBJECT_MOBILEws || - m_burnType == OBJECT_MOBILEwt ) // wheels? - { - for ( i=0 ; i<4 ; i++ ) - { - pos.x = 0.0f; - pos.y = Rand()*0.5f; - pos.z = 0.0f; - angle.x = (Rand()-0.5f)*PI/2.0f; - angle.y = (Rand()-0.5f)*PI/2.0f; - angle.z = 0.0f; - BurnAddPart(6+i, pos, angle); // wheel - - m_burnKeepPart[i] = 6+i; // we keep the wheels - } - m_burnKeepPart[i] = -1; - } - - if ( m_burnType == OBJECT_MOBILEta || - m_burnType == OBJECT_MOBILEtc || - m_burnType == OBJECT_MOBILEti || - m_burnType == OBJECT_MOBILEts || - m_burnType == OBJECT_MOBILErt || - m_burnType == OBJECT_MOBILErc || - m_burnType == OBJECT_MOBILErr || - m_burnType == OBJECT_MOBILErs || - m_burnType == OBJECT_MOBILEsa || - m_burnType == OBJECT_MOBILEdr ) // caterpillars? - { - pos.x = 0.0f; - pos.y = -4.0f; - pos.z = 2.0f; - angle.x = (Rand()-0.5f)*20.0f*PI/180.0f; - angle.y = (Rand()-0.5f)*10.0f*PI/180.0f; - angle.z = (Rand()-0.5f)*30.0f*PI/180.0f; - BurnAddPart(6, pos, angle); // down the right caterpillar - - pos.x = 0.0f; - pos.y = -4.0f; - pos.z = -2.0f; - angle.x = (Rand()-0.5f)*20.0f*PI/180.0f; - angle.y = (Rand()-0.5f)*10.0f*PI/180.0f; - angle.z = (Rand()-0.5f)*30.0f*PI/180.0f; - BurnAddPart(7, pos, angle); // down the left caterpillar - } - - if ( m_burnType == OBJECT_MOBILEfa || - m_burnType == OBJECT_MOBILEfc || - m_burnType == OBJECT_MOBILEfi || - m_burnType == OBJECT_MOBILEfs || - m_burnType == OBJECT_MOBILEft ) // flying? - { - for ( i=0 ; i<3 ; i++ ) - { - pos.x = 0.0f; - pos.y = -3.0f; - pos.z = 0.0f; - angle.x = 0.0f; - angle.y = 0.0f; - angle.z = (Rand()-0.5f)*PI/2.0f; - BurnAddPart(6+i, pos, angle); // foot - } - m_burnKeepPart[i] = -1; - } - - if ( m_burnType == OBJECT_MOBILEia || - m_burnType == OBJECT_MOBILEic || - m_burnType == OBJECT_MOBILEii || - m_burnType == OBJECT_MOBILEis ) // legs? - { - for ( i=0 ; i<6; i++ ) - { - pos.x = 0.0f; - pos.y = -3.0f; - pos.z = 0.0f; - angle.x = 0.0f; - angle.y = (Rand()-0.5f)*PI/4.0f; - angle.z = (Rand()-0.5f)*PI/4.0f; - BurnAddPart(6+i, pos, angle); // leg - } - } -} - -// Adds a part move. - -void CPyro::BurnAddPart(int part, D3DVECTOR pos, D3DVECTOR angle) -{ - int i; - - i = m_burnPartTotal; - m_burnPart[i].part = part; - m_burnPart[i].initialPos = m_object->RetPosition(part); - m_burnPart[i].finalPos = m_burnPart[i].initialPos+pos; - m_burnPart[i].initialAngle = m_object->RetAngle(part); - m_burnPart[i].finalAngle = m_burnPart[i].initialAngle+angle; - - m_burnPartTotal ++; -} - -// Advances of a vehicle fire. - -void CPyro::BurnProgress() -{ - CObject* sub; - D3DVECTOR pos; - float h; - int i; - - if ( m_burnType == OBJECT_TEEN31 ) // basket? - { - m_object->SetZoomY(0, 1.0f-m_progress*0.5f); // slight flattening - } - - for ( i=0 ; i 0.0f ) - { - h = powf(m_progress, 2.0f)*1000.0f; - if ( h > m_burnFall ) h = m_burnFall; - pos.y -= h; - } - m_object->SetPosition(m_burnPart[i].part, pos); - - pos = m_burnPart[i].initialAngle + m_progress*(m_burnPart[i].finalAngle-m_burnPart[i].initialAngle); - m_object->SetAngle(m_burnPart[i].part, pos); - } - - sub = m_object->RetPower(); - if ( sub != 0 ) // is there a battery? - { - sub->SetZoomY(0, 1.0f-m_progress); // complete flattening - } -} - -// Indicates whether a part should be retained. - -BOOL CPyro::BurnIsKeepPart(int part) -{ - int i; - - i = 0; - while ( m_burnKeepPart[i] != -1 ) - { - if ( part == m_burnKeepPart[i++] ) return TRUE; // must keep - } - return FALSE; // must destroy -} - -// Ends the fire of an insect or a vehicle. - -void CPyro::BurnTerminate() -{ - int i, objRank; - - if ( m_type == PT_BURNO ) // organic object is burning? - { - DeleteObject(TRUE, TRUE); // removes the insect - return; - } - - for ( i=1 ; iRetObjectRank(i); - if ( objRank == -1 ) continue; - if ( BurnIsKeepPart(i) ) continue; - - m_object->DeletePart(i); - } - - DeleteObject(FALSE, TRUE); // destroys the object transported + the battery - - if ( m_burnType == OBJECT_DERRICK || - m_burnType == OBJECT_STATION || - m_burnType == OBJECT_FACTORY || - m_burnType == OBJECT_REPAIR || - m_burnType == OBJECT_DESTROYER|| - m_burnType == OBJECT_CONVERT || - m_burnType == OBJECT_TOWER || - m_burnType == OBJECT_RESEARCH || - m_burnType == OBJECT_RADAR || - m_burnType == OBJECT_INFO || - m_burnType == OBJECT_ENERGY || - m_burnType == OBJECT_LABO || - m_burnType == OBJECT_NUCLEAR || - m_burnType == OBJECT_PARA || - m_burnType == OBJECT_SAFE || - m_burnType == OBJECT_HUSTON || - m_burnType == OBJECT_START || - m_burnType == OBJECT_END ) - { - m_object->SetType(OBJECT_RUINfactory); // others become a ruin - m_object->SetLock(FALSE); - } - else - { - m_object->SetType(OBJECT_RUINmobilew1); // others become a ruin - m_object->SetLock(FALSE); - } - - m_object->SetBurn(FALSE); // ruin usable (c-e-d. recoverable) -} - - -// Start of an object freight falling. - -void CPyro::FallStart() -{ - D3DVECTOR pos; - - m_object->SetBurn(TRUE); // usable - - pos = m_object->RetPosition(0); - m_fallFloor = m_terrain->RetFloorLevel(pos); - m_fallSpeed = 0.0f; - m_fallBulletTime = 0.0f; - m_bFallEnding = FALSE; -} - -// Seeking an object explode by the falling ball of bees. - -CObject* CPyro::FallSearchBeeExplo() -{ - CObject* pObj; - D3DVECTOR iPos, oPos; - ObjectType oType; - float iRadius, oRadius, distance, shieldRadius; - int i, j; - - m_object->GetCrashSphere(0, iPos, iRadius); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - oType = pObj->RetType(); - if ( oType != OBJECT_HUMAN && - oType != OBJECT_MOBILEfa && - oType != OBJECT_MOBILEta && - oType != OBJECT_MOBILEwa && - oType != OBJECT_MOBILEia && - oType != OBJECT_MOBILEfc && - oType != OBJECT_MOBILEtc && - oType != OBJECT_MOBILEwc && - oType != OBJECT_MOBILEic && - oType != OBJECT_MOBILEfi && - oType != OBJECT_MOBILEti && - oType != OBJECT_MOBILEwi && - oType != OBJECT_MOBILEii && - oType != OBJECT_MOBILEfs && - oType != OBJECT_MOBILEts && - oType != OBJECT_MOBILEws && - oType != OBJECT_MOBILEis && - oType != OBJECT_MOBILErt && - oType != OBJECT_MOBILErc && - oType != OBJECT_MOBILErr && - oType != OBJECT_MOBILErs && - oType != OBJECT_MOBILEsa && - oType != OBJECT_MOBILEtg && - oType != OBJECT_MOBILEft && - oType != OBJECT_MOBILEtt && - oType != OBJECT_MOBILEwt && - oType != OBJECT_MOBILEit && - oType != OBJECT_MOBILEdr && - oType != OBJECT_BASE && - oType != OBJECT_DERRICK && - oType != OBJECT_STATION && - oType != OBJECT_FACTORY && - oType != OBJECT_REPAIR && - oType != OBJECT_DESTROYER&& - oType != OBJECT_CONVERT && - oType != OBJECT_TOWER && - oType != OBJECT_RESEARCH && - oType != OBJECT_RADAR && - oType != OBJECT_INFO && - oType != OBJECT_ENERGY && - oType != OBJECT_LABO && - oType != OBJECT_NUCLEAR && - oType != OBJECT_PARA && - oType != OBJECT_SAFE && - oType != OBJECT_HUSTON && - oType != OBJECT_METAL && - oType != OBJECT_POWER && - oType != OBJECT_ATOMIC ) continue; - - if ( pObj->RetTruck() != 0 ) continue; // object transported? - - oPos = pObj->RetPosition(0); - - shieldRadius = pObj->RetShieldRadius(); - if ( shieldRadius > 0.0f ) - { - distance = Length(oPos, iPos); - if ( distance <= shieldRadius ) return pObj; - } - - if ( oType == OBJECT_BASE ) - { - distance = Length(oPos, iPos); - if ( distance < 25.0f ) return pObj; - } - - // Test the center of the object, which is necessary for objects - // that have no sphere in the center (station). - distance = Length(oPos, iPos)-4.0f; - if ( distance < 5.0f ) return pObj; - - // Test with all spheres of the object. - j = 0; - while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) - { - distance = Length(oPos, iPos); - if ( distance <= iRadius+oRadius ) - { - return pObj; - } - } - } - return 0; -} - -// Fall of an object's freight. - -void CPyro::FallProgress(float rTime) -{ - CObject* pObj; - D3DVECTOR pos; - BOOL bFloor = FALSE; - - if ( m_object == 0 ) return; - - m_fallSpeed += rTime*50.0f; // v2 = v1 + a*dt - pos = m_object->RetPosition(0); - pos.y -= m_fallSpeed*rTime; // dd -= v2*dt - - if ( pos.y <= m_fallFloor ) // below the ground level? - { - pos.y = m_fallFloor; - bFloor = TRUE; - } - m_object->SetPosition(0, pos); - - if ( m_object->RetType() == OBJECT_BULLET ) - { - m_fallBulletTime += rTime; - - if ( m_fallBulletTime > 0.2f || bFloor ) - { - m_fallBulletTime = 0.0f; - - pObj = FallSearchBeeExplo(); - if ( pObj == 0 ) - { - if ( bFloor ) // reaches the ground? - { - m_object->ExploObject(EXPLO_BOUM, 0.0f); // start explosion - } - } - else - { - if ( pObj->RetShieldRadius() > 0.0f ) // protected by shield? - { - m_particule->CreateParticule(pos, D3DVECTOR(0.0f, 0.0f, 0.0f), FPOINT(6.0f, 6.0f), PARTIGUNDEL, 2.0f, 0.0f, 0.0f); - m_sound->Play(SOUND_GUNDEL); - - DeleteObject(TRUE, TRUE); // removes the ball - } - else - { - if ( pObj->ExploObject(EXPLO_BOUM, 1.0f) ) // start explosion - { - DeleteObject(TRUE, TRUE); // removes the ball - } - else - { - m_object->ExploObject(EXPLO_BOUM, 0.0f); // start explosion - } - } - } - - if ( bFloor || pObj != 0 ) - { - m_bFallEnding = TRUE; - } - } - } -} - -// Indicates whether the fall is over. - -Error CPyro::FallIsEnded() -{ - D3DVECTOR pos; - - if ( m_bFallEnding || m_object == 0 ) return ERR_STOP; - - pos = m_object->RetPosition(0); - if ( pos.y > m_fallFloor ) return ERR_CONTINUE; - - m_sound->Play(SOUND_BOUM, pos); - m_object->SetBurn(FALSE); // usable again - - return ERR_STOP; -} - diff --git a/src/pyro.h b/src/pyro.h deleted file mode 100644 index 5eac0c9..0000000 --- a/src/pyro.h +++ /dev/null @@ -1,175 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// pyro.h - -#ifndef _PYRO_H_ -#define _PYRO_H_ - - -#include "d3dengine.h" -#include "object.h" -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CTerrain; -class CCamera; -class CParticule; -class CLight; -class CObject; -class CDisplayText; -class CRobotMain; -class CSound; - - - -enum PyroType -{ - PT_NULL = 0, - PT_FRAGT = 1, // fragmentation of technical object - PT_FRAGO = 2, // fragmentation of organic object - PT_FRAGW = 4, // fragmentation of object under water - PT_EXPLOT = 5, // explosion of technical object - PT_EXPLOO = 6, // explosion of organic object - PT_EXPLOW = 8, // explosion of object under water - PT_SHOTT = 9, // hit technical object - PT_SHOTH = 10, // hit human - PT_SHOTM = 11, // hit queen - PT_SHOTW = 12, // hit under water - PT_EGG = 13, // break the egg - PT_BURNT = 14, // burning of technical object - PT_BURNO = 15, // burning of organic object - PT_SPIDER = 16, // spider explosion - PT_FALL = 17, // cargo falling - PT_WPCHECK = 18, // indicator reaches - PT_FLCREATE = 19, // flag create - PT_FLDELETE = 20, // flag destroy - PT_RESET = 21, // reset position of the object - PT_WIN = 22, // fireworks - PT_LOST = 23, // black smoke - PT_DEADG = 24, // shooting death - PT_DEADW = 25, // drowning death - PT_FINDING = 26, // object discovered -}; - - -typedef struct -{ - int part; - D3DVECTOR initialPos; - D3DVECTOR finalPos; - D3DVECTOR initialAngle; - D3DVECTOR finalAngle; -} -PyroBurnPart; - -typedef struct -{ - float progress; - float intensity; - D3DCOLORVALUE color; -} -PyroLightOper; - - - -class CPyro -{ -public: - CPyro(CInstanceManager* iMan); - ~CPyro(); - - void DeleteObject(BOOL bAll=FALSE); - BOOL Create(PyroType type, CObject* pObj, float force=1.0f); - BOOL EventProcess(const Event &event); - Error IsEnded(); - void CutObjectLink(CObject* pObj); - -protected: - void DisplayError(PyroType type, CObject* pObj); - BOOL CreateLight(D3DVECTOR pos, float height); - void DeleteObject(BOOL bPrimary, BOOL bSecondary); - - void CreateTriangle(CObject* pObj, ObjectType oType, int part); - - void ExploStart(); - void ExploTerminate(); - - void BurnStart(); - void BurnAddPart(int part, D3DVECTOR pos, D3DVECTOR angle); - void BurnProgress(); - BOOL BurnIsKeepPart(int part); - void BurnTerminate(); - - void FallStart(); - CObject* FallSearchBeeExplo(); - void FallProgress(float rTime); - Error FallIsEnded(); - - void LightOperFlush(); - void LightOperAdd(float progress, float intensity, float r, float g, float b); - void LightOperFrame(float rTime); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CTerrain* m_terrain; - CCamera* m_camera; - CParticule* m_particule; - CLight* m_light; - CObject* m_object; - CDisplayText* m_displayText; - CRobotMain* m_main; - CSound* m_sound; - - D3DVECTOR m_pos; // center of the effect - D3DVECTOR m_posPower; // center of the battery - BOOL m_bPower; // battery exists? - PyroType m_type; - float m_force; - float m_size; - float m_progress; - float m_speed; - float m_time; - float m_lastParticule; - float m_lastParticuleSmoke; - int m_soundChannel; - - int m_lightRank; - int m_lightOperTotal; - PyroLightOper m_lightOper[10]; - float m_lightHeight; - - ObjectType m_burnType; - int m_burnPartTotal; - PyroBurnPart m_burnPart[10]; - int m_burnKeepPart[10]; - float m_burnFall; - - float m_fallFloor; - float m_fallSpeed; - float m_fallBulletTime; - BOOL m_bFallEnding; - - int m_crashSphereUsed; // number of spheres used - D3DVECTOR m_crashSpherePos[50]; - float m_crashSphereRadius[50]; -}; - - -#endif //_PYRO_H_ diff --git a/src/readme.txt b/src/readme.txt deleted file mode 100644 index 55bdeeb..0000000 --- a/src/readme.txt +++ /dev/null @@ -1,872 +0,0 @@ -COLOBOT version 1.4 /f ----------------------- - -COLOBOT est un mélange d'un jeu de stratégie en temps réel et -d'une initiation à la programmation. Le scénario vous place à -la tête d'une expédition spatiale, composée d'un seul humain -(vous) et de quelques robots. Vous devrez explorer et coloniser -différentes planètes, tout en cherchant des matières premières -nécessaires à votre survie. - -Petit à petit, vous pourrez construire et programmer de nouveaux -robots, qui vous aideront dans vos tâches. Certaines planètes -sont habitées par des créatures primitives et hostiles qu'il -vous faudra combattre. - - -Configuration minimale ----------------------- - -Processeur 300 MHz -64 Mb RAM -Carte graphique 3D avec 16 Mb RAM -100 Mb d'espace libre sur le disque dur - -Si ce n'est pas déjà fait, DirectX 8a est installé. -La présence du CD est nécessaire pour jouer. - - -Missions --------- - -Les missions contiennent la partie "aventure" de COLOBOT. Elles -sont au nombre de 36, réparties sur 9 planètes différentes. -Elles doivent être faites dans l'ordre imposé. - -Jeu libre ---------- - -Le mode "jeu libre" vous permet d'agir librement sur une -planète, sans but déterminé. Seuls les planètes déjà visitées et -les recherches effectuées sont disponibles. - -Programmation -------------- - -Cette partie de COLOBOT permet d'apprendre à programmer, même si -vous n'avez aucune notion dans ce domaine. Différents chapitres -présentent des sujets de plus en plus compliqués. Vous pouvez -effectuer n'importe quel exercice, bien qu'il soit conseillé de -commencer par les plus simples. - -Défis ------ - -Les défis vous demandent une bonne connaissance de la -programmation. Ils permettent de vérifier si les notions -apprises sous "programmation" sont effectivement comprises. - - -Autre joueur ------------- - -Après avoir installé COLOBOT sur un ordinateur, plusieurs -personnes peuvent y jouer. Pour chaque joueur, COLOBOT -enregistre automatiquement la progression dans les missions, -les programmes écrits, etc. - - -Options -------- - -Réglages du jeu, répartis dans 5 pages. - - -Options - Affichage -------------------- - -- Pilotes -Il faut choisir un pilote qui porte la mention HAL (Hardware -Abstraction Layer). Evitez les pilotes ayant la mention -"Emulation" ou "T&L". Il arrive fréquemment que des pilotes -avec des noms différents aient des comportements identiques. - -- Résolutions -Les premier et deuxième chiffres indiquent le nombre de pixels -en largeur et en hauteur dans l'écran. Le troisième chiffre -indique le nombre de couleurs affichables (16 pour 65'000 -couleurs et 32 pour 4 millions de couleurs). -Plus la résolution est grande et plus le jeu est beau. -Mais il risque de devenir lent. Commencez par mettre -640 x 480 x 16. La plupart des cartes graphiques modernes -supportent 1024 x 768 x 16. A vous d'essayer le meilleur -compromis. - -- Plein écran -Normalement, COLOBOT occupe tout l'écran, quelle que soit la -résolution. Si vous enlevez la coche, COLOBOT tournera dans -une fenêtre fixe ayant approximativement 640 x 480 pixels. - -- Appliquer les changements -Il faut cliquer ce bouton pour que les changements effectués -dans cette page prennent effet. - - -Options - Graphique -------------------- - -- Ombres -Normalement, tous les objets (robots, bâtiments, titanium, -etc.) projettent une ombre sur le sol. Avec certaines cartes -graphiques anciennes, un carré gris peut apparaître, en plus -de l'ombre. Si cela vous semble inesthétique, supprimez cette -option. - -- Marques sur le sol -Les marques accentuent les berges. Elles donnent aussi des -teintes différentes à certains endroits du terrain. Si cette -option est déclenchée, il n'est pas possible de montrer les -zones plates avec le cosmonaute. - -- Salissures -Les salissures donnent un effet vieux et sale aux robots et aux -bâtiments. - -- Ciel -Avec cette option, le ciel de certaines planètes contient des -nuages poussés par le vent. Sans cela, le ciel est généralement -rempli par un simple dégradé de couleurs. - -- Rayons du soleil -Lorsque vous vous tournez en direction du soleil, un reflet -apparaît. - -- Planètes et étoiles -Sur certaines planètes, vous voyez dans le ciel des planètes -proches qui bougent lentement. - -- Brouillard -Cette option correspond aux nappes de brouillard horizontales -qui sont généralement très proches du sol. - -- Lumières dynamiques -Les lumières dynamiques apparaissent lors d'explosions, ou -lorsqu'un robot refait le plein d'énergie. - -- Quantité de particules (0% à 200%) -Les particules servent à simuler la poussière, la fumée, les -éclats, les bulles sous l'eau, etc. - -- Profondeur de champ (50% à 200%) -La profondeur de champ détermine jusqu'où porte votre regard. -Cette profondeur est de toute façon très différente selon -l'atmosphère de la planète. Une grande valeur (par exemple -200%) permet de voir loin, mais nécessite une bonne carte -graphique 3D. - -- Détails des objets (0% à 200%) -Lorsqu'un objet est au loin, il est représenté avec moins de -détails. Une grande valeur éloigne la distance à laquelle le -changement est effectué. - -- Nombre d'objets décoratifs (0% à 100%) -Ce nombre détermine la quantité d'objets décoratifs présents, -tels que les plantes, les arbres, les cristaux, etc. - - -Options - Jeu -------------- - -- Séquences cinématiques -Certaines missions commencent ou finissent par un petit film -montrant l'atterrissage ou le décollage du vaisseau. La touche -Esc permet toujours de stopper ces séquences. Si cette option -est supprimée, ces films sont complètement sautés. - -- Défilement dans les bords -Lorsque la caméra est derrière le cosmonaute ou derrière un -robot, une rotation est effectuée si la souris s'approche du -bord de l'écran. - -- Inversion souris X -Inverse le sens de la rotation lorsque la souris touche le bord -gauche ou le bord droite de l'écran. - -- Inversion souris Y -Inverse le sens du mouvement lorsque la souris touche le bord -supérieur ou le bord inférieur de l'écran, dans l'éditeur de -programmes. - -- Secousses lors d'explosions -Lors d'une explosion, ou lorsque vous effectuez un atterrissage -brusque, la caméra subit un choc qui se manifeste par une -secousse plus on moins prononcée. Supprimez cette option pour -que la caméra soit toujours parfaitement stable. - -- Retour animé -Indique comment la situation est réinitialisée dans les exercices -de programmation et dans les défis. - -- Bulles d'aide -Les bulles d'aide vous donnent un petit texte explicatif lorsque -la souris s'arrête sur un bouton ou un objet. - -- Reflets sur les boutons -Les reflets sont visibles lorsque la souris survole un bouton. - -- Particules dans l'interface -Pluie de particules lorsque la souris bouge dans les écrans -d'interface. - -- Souris ombrée -La souris ombrée est gérée par COLOBOT. La souris normale est -dessinée par Windows. Lorsque COLOBOT ne fonctionne pas en mode -"plein écran", la souris est forcément normale. - -- Indentation automatique -L'indentation déplace automatiquement le curseur vers la droite -lors de l'édition d'un programme, en fonction des accolades -{ et }. - -- Grande indentation -Une grande indentation décale vers la droite d'une distance -égale à 4 espaces. Sinon, le décalage est de 2 espaces. - - -Options - Commandes -------------------- - -- Flèches gauche, droite, haut et bas -Pour faire tourner, avancer ou reculer le cosmonaute ou un -robot. Dans les exercices de programmation, notez que les robots -ne peuvent pas être déplacés ainsi. - -- Shirt et Ctrl -Pour faire monter ou descendre le cosmonaute ou un robot volant. -Sur certaines planètes, le vol est impossible. - -- Entrée -Cette touche effectue l'action principale du robot sélectionné, -qui correspond au bouton avec un cadre rouge. - -- Espace -Change le point de vue de la caméra. Pour la plupart des robots, -la caméra passe alternativement d'une vue arrière à une vue -intérieure. - -- . (pavé numérique) -Met le jeu en pause et montre l'endroit correspondant au dernier -message affiché en haut de l'écran. Si plusieurs messages sont -affichés, une nouvelle pression montre le message précédent, -chronologiquement parlant. Esc enlève la pause et le jeu reprend -son cours. - -- Tab -Sélectionne l'objet suivant, selon l'ordre des petites icônes -tout en haut de l'écran. - -- Home -Sélectionne toujours rapidement le cosmonaute. - -- 0 (pavé numérique) -Sélectionne le robot ou le bâtiment qui était sélectionné -précédemment. - -- + et - (pavé numérique) -Approche ou éloigne la caméra de l'objet sélectionné. - -- F1 -Affiche les instructions sur la mission ou l'exercice à l'aide -du SatCom. - -- F2 -Affiche le glossaire sur la programmation à l'aide du SatCom. - -- F3 -Pendant l'édition d'un programme, cette touche affiche des -informations complémentaires sur l'instruction en cours de -frappe. - -- F4, F5 et F6 -Choix de la vitesse du jeu. Le mode normal x1 correspond à la -touche F4. Les modes rapides x1.5 et x2 doivent être utilisés -avec prudence, car les ennemis vont également plus vite ! - -- Esc -Quitte la mission en cours. - - -Options - Son -------------- - -- Bruitages -Les bruitages sont générés par l'action en cours. Il s'agit de -bruits de moteur, de pas, d'explosions, etc. - -- Fond sonore -Le fond sonore dépend de la planète. Il donne une ambiance -générale, indépendamment de l'action en cours. Chaque fond -sonore correspond à une piste audio sur le CD. Dans les -exercices, les défis ainsi que sur la lune, il n'y a pas de -fond sonore. - -- Bruitages 3D -Certaines cartes son permettent de localiser un son dans -l'espace à l'aide de 4 haut-parleurs. Le réalisme est alors -superbe. Si votre carte son ne le permet pas, le bouton est -grisé. - - -Créér des exercices -------------------- - -Tous les exercices sont dans le sous-dossier \scene\ : - - \scene\trainxyy.txt -> exercices - \scene\defixyy.txt -> défis - \scene\scenexyy.txt -> missions - \scene\freexyy.txt -> jeux libres - -Le numéro de 3 chiffres est composé de : - - x -> numéro du chapitre (1..9) - yy -> rang dans le chapitre (01..99) - -Par exemple, train102.txt est le deuxième exercice du premier -chapitre. -Lorsque le rang dans le chapitre est 00, c'est qu'il s'agit de -la description du chapitre. -Les fichiers doivent avoir des numéros sucessifs. Supposons par -exemple que les fichiers suivants existent : - - train600.txt - train601.txt - train602.txt - train605.txt - -Le chapitre 6 ne contiendra dans ce cas que 2 exercices, les -numéros 01 et 02. Le numéro 05 n'apparaît pas dans la liste, -car il manque les numéros 03 et 04. - -Description ------------ - -Un fichier de description d'exercice détermine le relief du -terrain, les textures utilisées, la position initiale des -différents robots, matières premières, plantes, etc. - - - -Couleur -------- - -Les couleurs sont spécifiées à l'aide de 4 composantes -rouge/vert/bleu/alpha. Les valeurs sont comprises entre -0 (noir) et 255 (blanc). La composante alpha est généralement -nulle. Par exemple : - - color=175;209;215;0 // bleu-sable - - - - -Title.E text="Power Cell 1" -Nom court de l'exercice, tel qu'il apparaît dans la liste de -gauche. - -Resume.E text="Instruct a bot to change the power cell of a nearby winged shooter." -Résumé de l'exercice, tel qu'il apparaît en dessous des deux -listes. - -ScriptName.E text="Spider2" -Nom par défaut donné à un nouveau programme créé. - -Instructions name="tcell1.txt" -Nom du fichier qui contient les instructions de l'exercice, -qui seront affichées dans le SatCom. -Le fichier ttit1.txt doit être placé dans le dossier help\. - -HelpFile name="cbot.txt" -Non du fichier qui contient les instructions sur la program- -mation, affichées lorsque l'on presse sur F2. -Le fichier cbot.txt doit être placé dans le dossier help\. -Normalement, tous les exercices font référence aux mêmes -instructions générales contenues dans cbot.txt. - -EndingFile win=2 lost=0 -Scène à utiliser lorsque l'exercice est réussi ou raté. -win=2 signifie qu'il faut utiliser scene\win002.txt. -lost=0 signifie qu'il faut utiliser scene\lost000.txt. - -Audio track=0 -Numéro de la piste audio du CD à jouer pendant l'exercice. -Normalement, les exercices restent silencieux, en donnant le -numéro de piste 0. Si nécessaire, il est possible de donner -les numéros suivants : - 2: Terre - 3: Tropica - 4: Crystalium - 5: Saari - 6: Volcano - 7: Centaury - 8: Orphéon - 9: Terranova - -AmbiantColor air=102;102;102;102 water=20;20;20;20 -Couleur ambiante utilisée lorsqu'on est à l'air libre ou -sous l'eau. - -FogColor air=180;222;255;0 water=10;20;100;0 -Couleur que prennent les objets lorsqu'ils sont au loin. - -VehicleColor color=175;209;215;0 -Couleur des robots et des bâtiments. - -DeepView air=100.00 water=25.00 -Distance en mètres jusqu'où porte la vue. Au delà de cette -distance, plus rien n'est affiché. - -FogStart air=0.1 water=0.1 -Plus on s'approche de la distance maximale de vue (DeepView) -et plus la couleur des objets fusionne avec la couleur du -brouillard (FogColor), ce qui simule du brouillard. Une valeur -de 0.1 indique un brouillard qui commence proche du point de -vue, donc un brouillard dense. Une valeur de 0.9 indique un -brouillard très peu dense. - -Par exemple : - DeepView air=100.00 - FogStart air=0.2 - -Distances à partir de l'observateur : -0 à 20 mètres -> affichage normal -20 à 100 mètres -> affichage de plus en plus brouillardeux -100 mètres et plus -> plus rien n'est affiché - -SecondTexture rank=3 -Texture utilisée pour salir les robots et les bâtiments. Vous -pouvez utiliser une valeur comprise entre 1 et 8. - -Background up=76;105;226;0 down=192;250;255;0 -Couleurs du fond d'écran, si aucune texture n'est utilisée. -Un dégradé de couleur passe de "up" tout en haut de l'écran -progressivement jusqu'à "down" en milieu d'écran. La moitié -inférieure de l'écran prend la couleur unie "down". Cette -moitié inférieure n'est en principe jamais visible, puisqu'il -y a toujours une partie de terrain qui la recouvre. - -FrontsizeName image="lens5.tga" -Nom de la texture d'avant-plan, qui contient un effet de -"lens flare", plus ou moins visible selon l'orientation. - - -TerrainRelief image="textures\relief41.bmp" factor=1.0 -Le relief du terrain est décrit dans une image BMP à 256 -niveaux de gris mesurant exactement 161 x 161 pixels. -La couleur blanche correspond à l'altitude la plus basse. -La couleur noire correspond à l'altitude la plus haute. -Normalement, on utilise "factor=1.0". Dans ce cas, les 256 -niveaux permettent de s'élever de 64 mètres. Une différence -d'intensité de gris de 1 correspond donc à une différence -d'altitude de 0.25 mètres. - -La coordonnée du pixel central 80;80 de l'image correspond -à la coordonnée 0;0 dans CoLoBoT. -La coordonnée 0;0 du pixel en haut à gauche dans l'image -correspond au point à l'extrème nord-ouest -400;400 dans CoLoBoT. -Un pixel dans l'image correspond à un carré au sol de 5x5 -mètres dans CoLoBoT. - -Vous pouvez dessiner de nouveaux reliefs avec un logiciel tel -que PaintShop, ou réutiliser les nombreux fichiers reliefxx.bmp -placés dans le dossier textures\. - -TerrainResource image="textures\res00.bmp" -Cette image détermine la présence des ressources dans le -sous-sol. Il s'agit d'une image BMP en 256 couleurs de -161 x 161 pixels. - -Rouge = 255;0;0 (index=5) -> titanium -Vert = 0;255;0 (index=30) -> énergie -Jaune = 255;255;0 (index=35) -> uranium - -Toutes les autres couleurs ou niveaux de gris sont ignorés. - -Généralement, un bon truc pour placer les zones de couleur au -bon endroit est de partir de l'image à niveaux de gris du -relief et de la convertir en 256 couleurs. - -TerrainWater level=7.5 ... -Cette commande contient plusieurs paramètres, dont seul "level" -nous intéresse ici. "level" indique donc le niveau de l'eau ou -de la lave, par-rapport au niveau zéro qui correspond à la -couleur blanche dans l'image du relief (TerrainResource). -L'altitude des robots est par la suite toujours calculée par- -rapport au niveau de la mer (level). Une altitude négative -indiquera donc que le robot est sous l'eau. - -BeginObject -Cette commande doit précéder le premier CreateObject. - -CreateObject pos=7;-10 dir=1.5 type=Me -Création d'un objet dans l'exercice. Il peut s'agir d'un robot, -d'un bâtiment, d'une matière première, d'une plante, etc. - -Pour déterminer la position d'un objet, un bon moyen consiste -à déplacer le cosmonaute à l'endroit souhaité, puis de taper -les commandes : - - Ctrl+Pause showstat Entrée - Ctrl+Pause showpos Entrée - -La partie inférieure de l'écran indique alors les coordonnées -de l'objet sélectionné, qu'il n'y a plus qu'à reporter dans le -fichier de description de l'exercice. - -La direction est un nombre compris entre 0 et 2. - 0.0 -> est - 0.5 -> sud - 1.0 -> ouest - 1.5 -> nord -Le sens de rotation est donc horaire. - -Les différents types possibles pour les objets sont : - -Base : - type=Me // cosmonaute - type=SpaceShip - -Robots : - type=PracticeBot // robot d'entraînement - type=TargetBot // robot cible - - type=WheeledGrabber - type=TrackedGrabber - type=WingedGrabber - type=LeggedGrabber - - type=WheeledShooter - type=TrackedShooter - type=WingedShooter - type=LeggedShooter - - type=WheeledOrgaShooter - type=TrackedOrgaShooter - type=WingedOrgaShooter - type=LeggedOrgaShooter - - type=WheeledSniffer - type=TrackedSniffer - type=WingedSniffer - type=LeggedSniffer - - type=Thumper - type=PhazerShooter - type=Recycler - type=Shielder - type=Subber - -Bâtiments : - type=Derrick - type=BotFactory - type=PowerStation - type=Converter - type=RepairCenter - type=DefenseTower - type=AlienNest - type=ResearchCenter - type=RadarStation - type=ExchangePost - type=PowerPlant - type=AutoLab - type=NuclearPlant - type=PowerCaptor - type=Vault - type=StartArea - type=GoalArea - type=Target1 // pour l'entraînement au vol - type=Target2 - type=Houston // centre de contrôle - -Objets transportables : - type=TitaniumOre - type=UraniumOre - type=Titanium - type=PowerCell - type=NuclearCell - type=OrgaMatter - type=BlackBox // boîte noire - type=KeyA..D - type=TNT // caisse d'explosif - -Plantes et décors : - type=Greenery0..4 // plante standard basse - type=Greenery5..7 // petit trèfle bas - type=Greenery10..14 // plante grasse montante - type=Greenery15..19 // fougère - type=Tree0..3 // arbre haut - type=Mushroom1 // champignon inoffensif - type=Mushroom2 // champignon corrosif - type=MegaStalk0..5 // plante étrange - - type=Quartz0..3 // quartz petit..grand - type=Barrier0 // barrière courte - type=Barrier1 // barrière longue - type=ApolloLEM // sur la lune uniquement : - type=ApolloJeep - type=ApolloFlag - type=ApolloModule - type=ApolloAntenna - -Epaves de robots recyclables : - type=WreckBotw1..2 // robot à roues - type=WreckBott1..2 // robot à petites chenilles - type=WreckBotr1..2 // robot à grosses chenilles - -Bâtiments en ruine : - type=RuinBotFactory - type=RuinDoor // porte de convertisseur - type=RuinSupport // support de radar - type=RuinRadar // socle de radar - type=RuinConvert - type=RuinBaseCamp // socle du vaisseau spatial - type=RuinHeadCamp // coiffe du vaisseau spatial - -Ennemis : - type=AlienQueen - type=AlienEgg - type=AlienAnt - type=AlienSpider - type=AlienWasp - type=AlienWorm - -Indicateurs : - type=PowerSpot // indique la présence d'énergie en sous-sol - type=TitaniumSpot // indique la présence de titanium en sous-sol - type=UraniumSpot // indique la présence d'uranium en sous-sol - type=KeyA..DSpot // indique la présence de clé en sous-sol - type=WayPoint // croix pour les exercices - type=BlueFlag - type=RedFlag - type=GreenFlag - type=YellowFlag - type=VioletFlag - -Divers : - type=Mine // bombe fixe à éviter - type=Portico // portique géant (sur la terre) - type=Bag // sac de survie - type=Home // petite maison sympa (sur terranova) - type=Tech // technicien de Houston - type=Firework // feu d'artifice - -La commande CreateObject peut contenir des paramètres -supplémentaires : - -CreateObject ... script1="ttit1.txt" -Nom du programme CBOT à charger à la position 1 dans le robot -ou l'insecte. Il est possible de charger jusqu'à 10 programmes -en utilisant les commandes script1 à script10. -Les fichiers .txt des programmes doivent être placés dans le -dossier script\. - -CreateObject ... run=1 -Numéro du programme à exécuter directement lorsque l'exercice -démarre. Cela peut être utile, par exemple, pour un robot -TargetBot que l'élève devra suivre. -Si plusieurs programmes sont chargés (avec script1, script2, -etc.), un seul pourra être exécuté, bien entendu. - -EnableResearch type=WINGER -Liste des recherches déjà effectuées. - -DoneResearch type=WINGER -Liste des recherches qu'il est autorisé de faire, en construisant -un centre de recherche (ResearchCenter) ou un laboratoire (AutoLab). - - - TRACKER Robots Tracked* - WINGER Robots Winged* - THUMPER Robots Thumper - SHOOTER Robots *Shooter - TOWER Bâtiment DefenseTower - PHAZER Robots PhazerShooter - SHIELDER Robots Shielder - ATOMIC Bâtiment NuclearPlant - - iPAW Robots Legged* - iGUN Robots *OrgaShooter - - RECYCLER Robots recycleurs - SUBBER Robots Subber - SNIFFER Robots *Sniffer - - -EndMissionTake pos=0.00;0.00 dist=25000.00 type=Me lost=0 -EndMissionTake pos=0.00;0.00 dist=25000.00 type=WheeledGrabber lost=0 -EndMissionTake pos=0.00;0.00 dist=1000.00 type=Titanium min=1 max=1 -Critères pour déterminer à quel moment l'exercice est terminé. - - - - -Dossiers et réseau ------------------- - -Dans une utilisation en réseau, COLOBOT doit être installé -sur chaque machine individuellement. Après cette opération, -les exercices et les missions sont chargés localement, -généralement dans le dossier : - - C:\Program Files\Colobot\scene\ - -Si vous avez créé des exercices spécifiques, il peut être -utile de les charger à partir d'un dossier central commun à -tous les ordinateurs. Pour cela, il faut modifier le fichier - - C:\Program Files\Colobot\colobot.ini - -sur chaque machine. La section suivante permet de donner le -chemin d'accès : - - [Directory] - scene=scene - -Ici, il s'agit d'un chemin d'accès relatif. Vous pouvez par -exemple le changer en un chemin absolu sur un serveur : - - [Directory] - scene=\\Serveur\c\colobot\scene\ - -De la même façon, vous pouvez changer le dossier dans lequel -sont placés les programmes lorsque vous utilisez la commande -ouvrir/enregistrer avec le mode "public", dans l'éditeur de -programmes : - - [Directory] - public=program - -En donnant un chemin d'accès commun à tous les ordinateurs, il -sera possible d'échanger des programmes : - - [Directory] - public=\\Serveur\c\colobot\program\ - - - -Réglages --------- - -Pour afficher le nombre d'images par seconde, il faut appuyer -sur Ctrl+Pause puis taper la commande "showstat" et valider -avec la touche Entrée : - - Ctrl+Pause showstat Entrée - -La partie supérieure de l'écran affiche alors, par exemple : - - 32.46 fps T=11558 (640x480x16) - -Le premier chiffre correspond au nombre d'images par seconde -(fps = frame per second). -Le deuxième chiffre indique le nombre de triangles affiché dans -la scène. -Les 3 derniers chiffres entre parenthèses sont la résolution -(largeur x hauteur) et le nombre de bits pour les couleurs. - -Tous les réglages sont mémorisés dans le fichier colobot.ini, -présent dans le dossier principal où COLOBOT a été installé. -Ce fichier peut être modifié (avec prudence et après en avoir -fait une copie) avec un éditeur de texte, comme par exemple le -bloc-notes de Windows. - - -Problèmes ---------- - -Pour résoudre certains problèmes, il est possible de modifier -le fichier colobot.ini avec un éditeur de texte (par exemple -avec le bloc-notes de Windows). N'ajoutez pas de nouvelles -lignes, mais modifiez simplement les valeurs existantes. -Attention à ne pas insérer d'espace. Il faut quitter COLOBOT -avant de modifier le fichier. - -Si la végétation s'affiche mal, ou même pas du tout, vous -avez peut-être mis à zéro le nombre d'objets décoratifs dans -les options. Pour remettre 100% : - [Setup] - GadgetQuantity=1.00 -Si la végétation ne s'affiche toujours pas, essayez : - [Engine] - AlphaMode=0 -ou - [Engine] - AlphaMode=2 - -Si un carré apparaît autour des ombres, essayez : - [Engine] - WhiteSrcBlend=9 - WhiteDestBlend=6 -ou - [Engine] - WhiteSrcBlend=6 - WhiteDestBlend=3 -Si cela ne fonctionne pas, il faut supprimer les ombres : - [Engine] - WhiteSrcBlend=0 - WhiteDestBlend=0 - [Setup] - GroundShadow=0 - -Lorsque un objet s'interpose entre l'objet sélectionné et la -caméra, il devient transparent. Si l'objet n'est pas assez -transparent, essayez : - [Engine] - StateColor=0 -ou - [Engine] - StateColor=1 - - -Equipe de développement ------------------------ - -- Daniel Roux -- Denis Dumoulin -- Otto Kölbl -- Michael Walz -- Didier Gertsch - -Beta testeurs -------------- - -- Adrien Roux -- Didier Raboud -- Nicolas Beuchat -- Joël Roux -- Michael Jubin -- Daniel Sauthier -- Nicolas Stubi -- Patrick Thévoz - -Copyright ---------- - -La photo de la nébuleuse NGC3603 servant de fond pour la planète -Orphéon a été prise avec le télescope spatial Hubble. Elle est -utilisée avec l'autorisation des auteurs Wolfgang Brandner -(JPL/IPAC), Eva K. Grebel (Université de Washington), You-Hua Chu -(Université d'Illinois Urbana-Champaign) et de la NASA. - -Le son de tonnerre de la planète Orphéon est utilisé avec -l'autorisation limitée de CREATIVE moyennant la mention : -Material from products are used by limited permission from CREATIVE. - -Développeur ------------ - -EPSITEC SA -Mouette 5 -CH-1092 Belmont - -colobot@epsitec.ch -www.colobot.com - -Editeur de la version française -------------------------------- - -ALSYD -43, Ch. du vieux Chêne -F-38240 Meylan - -www.alsyd.com diff --git a/src/resource.h b/src/resource.h deleted file mode 100644 index 0f3be0a..0000000 --- a/src/resource.h +++ /dev/null @@ -1,55 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by winmain.rc -// -#define IDI_MAIN_ICON 101 -#define IDR_MAIN_ACCEL 113 -#define IDR_MENU 141 -#define IDR_POPUP 142 -#define IDD_ABOUT 143 -#define IDD_CHANGEDEVICE 144 -#define IDC_CURSORHAND 149 -#define IDC_CURSORSCROLLL 150 -#define IDC_CURSORSCROLLR 151 -#define IDC_CURSORSCROLLU 152 -#define IDC_CURSORSCROLLD 153 -#define IDC_CURSORTARGET 154 -#define IDC_DEVICE_COMBO 1000 -#define IDC_MODE_COMBO 1001 -#define IDC_WINDOWED_CHECKBOX 1012 -#define IDC_STEREO_CHECKBOX 1013 -#define IDC_FULLSCREEN_TEXT 1014 -#define IDM_ABOUT 40001 -#define IDM_CHANGEDEVICE 40002 -#define IDM_TOGGLEFULLSCREEN 40003 -#define IDM_TOGGLESTART 40004 -#define IDM_SINGLESTEP 40005 -#define IDM_EXIT 40006 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 159 -#define _APS_NEXT_COMMAND_VALUE 40011 -#define _APS_NEXT_CONTROL_VALUE 1015 -#define _APS_NEXT_SYMED_VALUE 102 -#endif -#endif diff --git a/src/restext.cpp b/src/restext.cpp deleted file mode 100644 index 7422990..0000000 --- a/src/restext.cpp +++ /dev/null @@ -1,3663 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/.// restext.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include "struct.h" -#include "d3dengine.h" -#include "language.h" -#include "misc.h" -#include "event.h" -#include "object.h" -#include "CBot/resource.h" -#include "restext.h" - - - -//** -> text to translate! - - - -// Gives the pointer to the engine. - -void SetEngine(CD3DEngine *engine) -{ - g_engine = engine; -} - -// Give the player's name. - -void SetGlobalGamerName(char *name) -{ - strcpy(g_gamerName, name); -} - - - -typedef struct -{ - KeyRank key; - char name[20]; -} -KeyDesc; - -static KeyDesc keyTable[22] = -{ - { KEYRANK_LEFT, "left;" }, - { KEYRANK_RIGHT, "right;" }, - { KEYRANK_UP, "up;" }, - { KEYRANK_DOWN, "down;" }, - { KEYRANK_GUP, "gup;" }, - { KEYRANK_GDOWN, "gdown;" }, - { KEYRANK_CAMERA, "camera;" }, - { KEYRANK_DESEL, "desel;" }, - { KEYRANK_ACTION, "action;" }, - { KEYRANK_NEAR, "near;" }, - { KEYRANK_AWAY, "away;" }, - { KEYRANK_NEXT, "next;" }, - { KEYRANK_HUMAN, "human;" }, - { KEYRANK_QUIT, "quit;" }, - { KEYRANK_HELP, "help;" }, - { KEYRANK_PROG, "prog;" }, - { KEYRANK_CBOT, "cbot;" }, - { KEYRANK_VISIT, "visit;" }, - { KEYRANK_SPEED10, "speed10;" }, - { KEYRANK_SPEED15, "speed15;" }, - { KEYRANK_SPEED20, "speed20;" }, - { KEYRANK_SPEED30, "speed30;" }, -}; - -// Seeks a key. - -BOOL SearchKey(char *cmd, KeyRank &key) -{ - int i; - - for ( i=0 ; i<22 ; i++ ) - { - if ( strstr(cmd, keyTable[i].name) == cmd ) - { - key = keyTable[i].key; - return TRUE; - } - } - return FALSE; -} - -// Replaces the commands "\key name;" in a text. - -void PutKeyName(char* dst, char* src) -{ - KeyRank key; - char name[50]; - int s, d, n, res; - - s = d = 0; - while ( src[s] != 0 ) - { - if ( src[s+0] == '\\' && - src[s+1] == 'k' && - src[s+2] == 'e' && - src[s+3] == 'y' && - src[s+4] == ' ' ) - { - if ( SearchKey(src+s+5, key) ) - { - res = g_engine->RetKey(key, 0); - if ( res != 0 ) - { - if ( GetResource(RES_KEY, res, name) ) - { - n = 0; - while ( name[n] != 0 ) - { - dst[d++] = name[n++]; - } - while ( src[s++] != ';' ); - continue; - } - } - } - } - - dst[d++] = src[s++]; - } - dst[d++] = 0; -} - - -// Returns the text of a resource. - -BOOL GetResource(ResType type, int num, char* text) -{ - char buffer[100]; - - if ( !GetResourceBase(type, num, buffer) ) - { - text[0] = 0; - return FALSE; - } - - PutKeyName(text, buffer); - return TRUE; -} - - -// Returns the text of a resource. - -BOOL GetResourceBase(ResType type, int num, char* text) -{ - text[0] = 0; - -#if _ENGLISH - if ( type == RES_TEXT ) - { - #if _FULL - if ( num == RT_VERSION_ID ) strcpy(text, "1.18 /e"); - #endif - #if _NET - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A 1.18"); - #endif - #if _SCHOOL & _EDU - #if _TEEN - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen EDU 1.18"); - #else - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A EDU 1.18"); - #endif - #endif - #if _SCHOOL & _PERSO - #if _TEEN - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen PERSO 1.18"); - #else - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A PERSO 1.18"); - #endif - #endif - #if _SCHOOL & _CEEBOTDEMO - #if _TEEN - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen DEMO 1.18"); - #else - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A DEMO 1.18"); - #endif - #endif - #if _DEMO - if ( num == RT_VERSION_ID ) strcpy(text, "Demo 1.18 /e"); - #endif - if ( num == RT_DISINFO_TITLE ) strcpy(text, "SatCom"); - if ( num == RT_WINDOW_MAXIMIZED ) strcpy(text, "Maximize"); - if ( num == RT_WINDOW_MINIMIZED ) strcpy(text, "Minimize"); - if ( num == RT_WINDOW_STANDARD ) strcpy(text, "Normal size"); - if ( num == RT_WINDOW_CLOSE ) strcpy(text, "Close"); - - if ( num == RT_STUDIO_TITLE ) strcpy(text, "Program editor"); - if ( num == RT_SCRIPT_NEW ) strcpy(text, "New"); - if ( num == RT_NAME_DEFAULT ) strcpy(text, "Player"); - if ( num == RT_IO_NEW ) strcpy(text, "New ..."); - if ( num == RT_KEY_OR ) strcpy(text, " or "); - -#if _NEWLOOK - if ( num == RT_TITLE_BASE ) strcpy(text, "CeeBot"); - if ( num == RT_TITLE_INIT ) strcpy(text, "CeeBot"); -#else - if ( num == RT_TITLE_BASE ) strcpy(text, "COLOBOT"); - if ( num == RT_TITLE_INIT ) strcpy(text, "COLOBOT"); -#endif - if ( num == RT_TITLE_TRAINER ) strcpy(text, "Programming exercises"); - if ( num == RT_TITLE_DEFI ) strcpy(text, "Challenges"); - if ( num == RT_TITLE_MISSION ) strcpy(text, "Missions"); - if ( num == RT_TITLE_FREE ) strcpy(text, "Free game"); - if ( num == RT_TITLE_TEEN ) strcpy(text, "Free game"); - if ( num == RT_TITLE_USER ) strcpy(text, "User levels"); - if ( num == RT_TITLE_PROTO ) strcpy(text, "Prototypes"); - if ( num == RT_TITLE_SETUP ) strcpy(text, "Options"); - if ( num == RT_TITLE_NAME ) strcpy(text, "Player's name"); - if ( num == RT_TITLE_PERSO ) strcpy(text, "Customize your appearance"); - if ( num == RT_TITLE_WRITE ) strcpy(text, "Save the current mission"); - if ( num == RT_TITLE_READ ) strcpy(text, "Load a saved mission"); - - if ( num == RT_PLAY_CHAPt ) strcpy(text, " Chapters:"); - if ( num == RT_PLAY_CHAPd ) strcpy(text, " Chapters:"); - if ( num == RT_PLAY_CHAPm ) strcpy(text, " Planets:"); - if ( num == RT_PLAY_CHAPf ) strcpy(text, " Planets:"); - if ( num == RT_PLAY_CHAPu ) strcpy(text, " User levels:"); - if ( num == RT_PLAY_CHAPp ) strcpy(text, " Planets:"); - if ( num == RT_PLAY_CHAPte ) strcpy(text, " Chapters:"); - if ( num == RT_PLAY_LISTt ) strcpy(text, " Exercises in the chapter:"); - if ( num == RT_PLAY_LISTd ) strcpy(text, " Challenges in the chapter:"); - if ( num == RT_PLAY_LISTm ) strcpy(text, " Missions on this planet:"); - if ( num == RT_PLAY_LISTf ) strcpy(text, " Free game on this planet:"); - if ( num == RT_PLAY_LISTu ) strcpy(text, " Missions on this level:"); - if ( num == RT_PLAY_LISTp ) strcpy(text, " Prototypes on this planet:"); - if ( num == RT_PLAY_LISTk ) strcpy(text, " Free game on this chapter:"); - if ( num == RT_PLAY_RESUME ) strcpy(text, " Summary:"); - - if ( num == RT_SETUP_DEVICE ) strcpy(text, " Drivers:"); - if ( num == RT_SETUP_MODE ) strcpy(text, " Resolution:"); - if ( num == RT_SETUP_KEY1 ) strcpy(text, "1) First click on the key you want to redefine."); - if ( num == RT_SETUP_KEY2 ) strcpy(text, "2) Then press the key you want to use instead."); - - if ( num == RT_PERSO_FACE ) strcpy(text, "Face type:"); - if ( num == RT_PERSO_GLASSES ) strcpy(text, "Eyeglasses:"); - if ( num == RT_PERSO_HAIR ) strcpy(text, "Hair color:"); - if ( num == RT_PERSO_COMBI ) strcpy(text, "Suit color:"); - if ( num == RT_PERSO_BAND ) strcpy(text, "Strip color:"); - -#if _NEWLOOK - if ( num == RT_DIALOG_QUIT ) strcpy(text, "Do you want to quit CeeBot ?"); - if ( num == RT_DIALOG_TITLE ) strcpy(text, "CeeBot"); - if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Quit\\Quit CeeBot"); -#else - if ( num == RT_DIALOG_QUIT ) strcpy(text, "Do you want to quit COLOBOT ?"); - if ( num == RT_DIALOG_TITLE ) strcpy(text, "COLOBOT"); - if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Quit\\Quit COLOBOT"); -#endif - if ( num == RT_DIALOG_ABORT ) strcpy(text, "Quit the mission?"); - if ( num == RT_DIALOG_YES ) strcpy(text, "Abort\\Abort the current mission"); - if ( num == RT_DIALOG_NO ) strcpy(text, "Continue\\Continue the current mission"); - if ( num == RT_DIALOG_NOQUIT ) strcpy(text, "Continue\\Continue the game"); - if ( num == RT_DIALOG_DELOBJ ) strcpy(text, "Do you really want to destroy the selected building?"); - if ( num == RT_DIALOG_DELGAME ) strcpy(text, "Do you want to delete %s's saved games? "); - if ( num == RT_DIALOG_YESDEL ) strcpy(text, "Delete"); - if ( num == RT_DIALOG_NODEL ) strcpy(text, "Cancel"); - if ( num == RT_DIALOG_LOADING ) strcpy(text, "LOADING"); - - if ( num == RT_STUDIO_LISTTT ) strcpy(text, "Keyword help(\\key cbot;)"); - if ( num == RT_STUDIO_COMPOK ) strcpy(text, "Compilation ok (0 errors)"); - if ( num == RT_STUDIO_PROGSTOP ) strcpy(text, "Program finished"); - - if ( num == RT_SATCOM_LIST ) strcpy(text, "\\b;List of objects\n"); - if ( num == RT_SATCOM_BOT ) strcpy(text, "\\b;Robots\n"); - if ( num == RT_SATCOM_BUILDING ) strcpy(text, "\\b;Buildings\n"); - if ( num == RT_SATCOM_FRET ) strcpy(text, "\\b;Moveable objects\n"); - if ( num == RT_SATCOM_ALIEN ) strcpy(text, "\\b;Aliens\n"); - if ( num == RT_SATCOM_NULL ) strcpy(text, "\\c; (none)\\n;\n"); - if ( num == RT_SATCOM_ERROR1 ) strcpy(text, "\\b;Error\n"); - if ( num == RT_SATCOM_ERROR2 ) strcpy(text, "The list is only available if a \\l;radar station\\u object\\radar; is working.\n"); - - if ( num == RT_IO_OPEN ) strcpy(text, "Open"); - if ( num == RT_IO_SAVE ) strcpy(text, "Save"); - if ( num == RT_IO_LIST ) strcpy(text, "Folder: %s"); - if ( num == RT_IO_NAME ) strcpy(text, "Name:"); - if ( num == RT_IO_DIR ) strcpy(text, "Folder:"); - if ( num == RT_IO_PRIVATE ) strcpy(text, "Private\\Private folder"); - if ( num == RT_IO_PUBLIC ) strcpy(text, "Public\\Common folder"); - - if ( num == RT_GENERIC_DEV1 ) strcpy(text, "Developed by :"); - if ( num == RT_GENERIC_DEV2 ) strcpy(text, "www.epsitec.com"); -//? if ( num == RT_GENERIC_EDIT1 ) strcpy(text, "English version published by:"); -//? if ( num == RT_GENERIC_EDIT2 ) strcpy(text, "www.?.com"); - if ( num == RT_GENERIC_EDIT1 ) strcpy(text, " "); - if ( num == RT_GENERIC_EDIT2 ) strcpy(text, " "); - - if ( num == RT_INTERFACE_REC ) strcpy(text, "Recorder"); - } - - if ( type == RES_EVENT ) - { - if ( num == EVENT_BUTTON_OK ) strcpy(text, "OK"); - if ( num == EVENT_BUTTON_CANCEL ) strcpy(text, "Cancel"); - if ( num == EVENT_BUTTON_NEXT ) strcpy(text, "Next"); - if ( num == EVENT_BUTTON_PREV ) strcpy(text, "Previous"); - if ( num == EVENT_BUTTON_QUIT ) strcpy(text, "Menu (\\key quit;)"); - - if ( num == EVENT_DIALOG_OK ) strcpy(text, "OK"); - if ( num == EVENT_DIALOG_CANCEL ) strcpy(text, "Cancel"); - - if ( num == EVENT_INTERFACE_TRAINER) strcpy(text, "Exercises\\Programming exercises"); - if ( num == EVENT_INTERFACE_DEFI ) strcpy(text, "Challenges\\Programming challenges"); - if ( num == EVENT_INTERFACE_MISSION) strcpy(text, "Missions\\Select mission"); - if ( num == EVENT_INTERFACE_FREE ) strcpy(text, "Free game\\Free game without a specific goal"); - if ( num == EVENT_INTERFACE_TEEN ) strcpy(text, "Free game\\Free game without a specific goal"); - if ( num == EVENT_INTERFACE_USER ) strcpy(text, "User\\User levels"); - if ( num == EVENT_INTERFACE_PROTO ) strcpy(text, "Proto\\Prototypes under development"); - if ( num == EVENT_INTERFACE_NAME ) strcpy(text, "New player\\Choose player's name"); - if ( num == EVENT_INTERFACE_SETUP ) strcpy(text, "Options\\Preferences"); - if ( num == EVENT_INTERFACE_AGAIN ) strcpy(text, "Restart\\Restart the mission from the beginning"); - if ( num == EVENT_INTERFACE_WRITE ) strcpy(text, "Save\\Save the current mission "); - if ( num == EVENT_INTERFACE_READ ) strcpy(text, "Load\\Load a saved mission"); -#if _NEWLOOK - if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Return to CeeBot"); - if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Quit\\Quit CeeBot"); -#else - if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Return to COLOBOT"); - if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Quit\\Quit COLOBOT"); -#endif - if ( num == EVENT_INTERFACE_BACK ) strcpy(text, "<< Back \\Back to the previous screen"); - if ( num == EVENT_INTERFACE_PLAY ) strcpy(text, "Play\\Start mission!"); - if ( num == EVENT_INTERFACE_SETUPd ) strcpy(text, "Device\\Driver and resolution settings"); - if ( num == EVENT_INTERFACE_SETUPg ) strcpy(text, "Graphics\\Graphics settings"); - if ( num == EVENT_INTERFACE_SETUPp ) strcpy(text, "Game\\Game settings"); - if ( num == EVENT_INTERFACE_SETUPc ) strcpy(text, "Controls\\Keyboard, joystick and mouse settings"); - if ( num == EVENT_INTERFACE_SETUPs ) strcpy(text, "Sound\\Music and game sound volume"); - if ( num == EVENT_INTERFACE_DEVICE ) strcpy(text, "Unit"); - if ( num == EVENT_INTERFACE_RESOL ) strcpy(text, "Resolution"); - if ( num == EVENT_INTERFACE_FULL ) strcpy(text, "Full screen\\Full screen or window mode"); - if ( num == EVENT_INTERFACE_APPLY ) strcpy(text, "Apply changes\\Activates the changed settings"); - - if ( num == EVENT_INTERFACE_TOTO ) strcpy(text, "Robbie\\Your assistant"); - if ( num == EVENT_INTERFACE_SHADOW ) strcpy(text, "Shadows\\Shadows on the ground"); - if ( num == EVENT_INTERFACE_GROUND ) strcpy(text, "Marks on the ground\\Marks on the ground"); - if ( num == EVENT_INTERFACE_DIRTY ) strcpy(text, "Dust\\Dust and dirt on bots and buildings"); - if ( num == EVENT_INTERFACE_FOG ) strcpy(text, "Fog\\Fog"); - if ( num == EVENT_INTERFACE_LENS ) strcpy(text, "Sunbeams\\Sunbeams in the sky"); - if ( num == EVENT_INTERFACE_SKY ) strcpy(text, "Sky\\Clouds and nebulae"); - if ( num == EVENT_INTERFACE_PLANET ) strcpy(text, "Planets and stars\\Astronomical objects in the sky"); - if ( num == EVENT_INTERFACE_LIGHT ) strcpy(text, "Dynamic lighting\\Mobile light sources"); - if ( num == EVENT_INTERFACE_PARTI ) strcpy(text, "Number of particles\\Explosions, dust, reflections, etc."); - if ( num == EVENT_INTERFACE_CLIP ) strcpy(text, "Depth of field\\Maximum visibility"); - if ( num == EVENT_INTERFACE_DETAIL ) strcpy(text, "Details\\Visual quality of 3D objects"); - if ( num == EVENT_INTERFACE_TEXTURE) strcpy(text, "Textures\\Quality of textures "); - if ( num == EVENT_INTERFACE_GADGET ) strcpy(text, "Num of decorative objects\\Number of purely ornamental objects"); - if ( num == EVENT_INTERFACE_RAIN ) strcpy(text, "Particles in the interface\\Steam clouds and sparks in the interface"); - if ( num == EVENT_INTERFACE_GLINT ) strcpy(text, "Reflections on the buttons \\Shiny buttons"); - if ( num == EVENT_INTERFACE_TOOLTIP) strcpy(text, "Help balloons\\Explain the function of the buttons"); - if ( num == EVENT_INTERFACE_MOVIES ) strcpy(text, "Film sequences\\Films before and after the missions"); - if ( num == EVENT_INTERFACE_NICERST) strcpy(text, "Exit film\\Film at the exit of exercises"); - if ( num == EVENT_INTERFACE_HIMSELF) strcpy(text, "Friendly fire\\Your shooting can damage your own objects "); - if ( num == EVENT_INTERFACE_SCROLL ) strcpy(text, "Scrolling\\Scrolling when the mouse touches right or left border"); - if ( num == EVENT_INTERFACE_INVERTX) strcpy(text, "Mouse inversion X\\Inversion of the scrolling direction on the X axis"); - if ( num == EVENT_INTERFACE_INVERTY) strcpy(text, "Mouse inversion Y\\Inversion of the scrolling direction on the Y axis"); - if ( num == EVENT_INTERFACE_EFFECT ) strcpy(text, "Quake at explosions\\The screen shakes at explosions"); - if ( num == EVENT_INTERFACE_MOUSE ) strcpy(text, "Mouse shadow\\Gives the mouse a shadow"); - if ( num == EVENT_INTERFACE_EDITMODE) strcpy(text, "Automatic indent\\When program editing"); - if ( num == EVENT_INTERFACE_EDITVALUE)strcpy(text, "Big indent\\Indent 2 or 4 spaces per level defined by braces"); - if ( num == EVENT_INTERFACE_SOLUCE4) strcpy(text, "Access to solutions\\Show program \"4: Solution\" in the exercises"); //** - - if ( num == EVENT_INTERFACE_KDEF ) strcpy(text, "Standard controls\\Standard key functions"); - if ( num == EVENT_INTERFACE_KLEFT ) strcpy(text, "Turn left\\turns the bot to the left"); - if ( num == EVENT_INTERFACE_KRIGHT ) strcpy(text, "Turn right\\turns the bot to the right"); - if ( num == EVENT_INTERFACE_KUP ) strcpy(text, "Forward\\Moves forward"); - if ( num == EVENT_INTERFACE_KDOWN ) strcpy(text, "Backward\\Moves backward"); - if ( num == EVENT_INTERFACE_KGUP ) strcpy(text, "Climb\\Increases the power of the jet"); - if ( num == EVENT_INTERFACE_KGDOWN ) strcpy(text, "Descend\\Reduces the power of the jet"); - if ( num == EVENT_INTERFACE_KCAMERA) strcpy(text, "Change camera\\Switches between onboard camera and following camera"); - if ( num == EVENT_INTERFACE_KDESEL ) strcpy(text, "Previous object\\Selects the previous object"); - if ( num == EVENT_INTERFACE_KACTION) strcpy(text, "Standard action\\Standard action of the bot (take/grab, shoot, sniff, etc)"); - if ( num == EVENT_INTERFACE_KNEAR ) strcpy(text, "Camera closer\\Moves the camera forward"); - if ( num == EVENT_INTERFACE_KAWAY ) strcpy(text, "Camera back\\Moves the camera backward"); - if ( num == EVENT_INTERFACE_KNEXT ) strcpy(text, "Next object\\Selects the next object"); - if ( num == EVENT_INTERFACE_KHUMAN ) strcpy(text, "Select the astronaut\\Selects the astronaut"); - if ( num == EVENT_INTERFACE_KQUIT ) strcpy(text, "Quit\\Quit the current mission or exercise"); - if ( num == EVENT_INTERFACE_KHELP ) strcpy(text, "Instructions\\Shows the instructions for the current mission"); - if ( num == EVENT_INTERFACE_KPROG ) strcpy(text, "Programming help\\Gives more detailed help with programming"); - if ( num == EVENT_INTERFACE_KCBOT ) strcpy(text, "Key word help\\More detailed help about key words"); - if ( num == EVENT_INTERFACE_KVISIT ) strcpy(text, "Origin of last message\\Shows where the last message was sent from"); - if ( num == EVENT_INTERFACE_KSPEED10) strcpy(text, "Speed 1.0x\\Normal speed"); - if ( num == EVENT_INTERFACE_KSPEED15) strcpy(text, "Speed 1.5x\\1.5 times faster"); - if ( num == EVENT_INTERFACE_KSPEED20) strcpy(text, "Speed 2.0x\\Double speed"); - if ( num == EVENT_INTERFACE_KSPEED30) strcpy(text, "Speed 3.0x\\Three times faster"); - - if ( num == EVENT_INTERFACE_VOLSOUND) strcpy(text, "Sound effects:\\Volume of engines, voice, shooting, etc."); - if ( num == EVENT_INTERFACE_VOLMUSIC) strcpy(text, "Background sound :\\Volume of audio tracks on the CD"); - if ( num == EVENT_INTERFACE_SOUND3D) strcpy(text, "3D sound\\3D positioning of the sound"); - - if ( num == EVENT_INTERFACE_MIN ) strcpy(text, "Lowest\\Minimum graphic quality (highest frame rate)"); - if ( num == EVENT_INTERFACE_NORM ) strcpy(text, "Normal\\Normal graphic quality"); - if ( num == EVENT_INTERFACE_MAX ) strcpy(text, "Highest\\Highest graphic quality (lowest frame rate)"); - - if ( num == EVENT_INTERFACE_SILENT ) strcpy(text, "Mute\\No sound"); - if ( num == EVENT_INTERFACE_NOISY ) strcpy(text, "Normal\\Normal sound volume"); - - if ( num == EVENT_INTERFACE_JOYSTICK) strcpy(text, "Use a joystick\\Joystick or keyboard"); - if ( num == EVENT_INTERFACE_SOLUCE ) strcpy(text, "Access to solution\\Shows the solution (detailed instructions for missions)"); - - if ( num == EVENT_INTERFACE_NEDIT ) strcpy(text, "\\New player name"); - if ( num == EVENT_INTERFACE_NOK ) strcpy(text, "OK\\Choose the selected player"); - if ( num == EVENT_INTERFACE_NCANCEL) strcpy(text, "Cancel\\Keep current player name"); - if ( num == EVENT_INTERFACE_NDELETE) strcpy(text, "Delete player\\Deletes the player from the list"); - if ( num == EVENT_INTERFACE_NLABEL ) strcpy(text, "Player name"); - - if ( num == EVENT_INTERFACE_IOWRITE) strcpy(text, "Save\\Saves the current mission"); - if ( num == EVENT_INTERFACE_IOREAD ) strcpy(text, "Load\\Loads the selected mission"); - if ( num == EVENT_INTERFACE_IOLIST ) strcpy(text, "List of saved missions"); - if ( num == EVENT_INTERFACE_IOLABEL) strcpy(text, "Filename:"); - if ( num == EVENT_INTERFACE_IONAME ) strcpy(text, "Mission name"); - if ( num == EVENT_INTERFACE_IOIMAGE) strcpy(text, "Photography"); - if ( num == EVENT_INTERFACE_IODELETE) strcpy(text, "Delete\\Deletes the selected file"); - - if ( num == EVENT_INTERFACE_PERSO ) strcpy(text, "Appearance\\Choose your appearance"); - if ( num == EVENT_INTERFACE_POK ) strcpy(text, "OK"); - if ( num == EVENT_INTERFACE_PCANCEL) strcpy(text, "Cancel"); - if ( num == EVENT_INTERFACE_PDEF ) strcpy(text, "Standard\\Standard appearance settings"); - if ( num == EVENT_INTERFACE_PHEAD ) strcpy(text, "Head\\Face and hair"); - if ( num == EVENT_INTERFACE_PBODY ) strcpy(text, "Suit\\Astronaut suit"); - if ( num == EVENT_INTERFACE_PLROT ) strcpy(text, "\\Turn left"); - if ( num == EVENT_INTERFACE_PRROT ) strcpy(text, "\\Turn right"); - if ( num == EVENT_INTERFACE_PCRa ) strcpy(text, "Red"); - if ( num == EVENT_INTERFACE_PCGa ) strcpy(text, "Green"); - if ( num == EVENT_INTERFACE_PCBa ) strcpy(text, "Blue"); - if ( num == EVENT_INTERFACE_PCRb ) strcpy(text, "Red"); - if ( num == EVENT_INTERFACE_PCGb ) strcpy(text, "Green"); - if ( num == EVENT_INTERFACE_PCBb ) strcpy(text, "Blue"); - if ( num == EVENT_INTERFACE_PFACE1 ) strcpy(text, "\\Face 1"); - if ( num == EVENT_INTERFACE_PFACE2 ) strcpy(text, "\\Face 4"); - if ( num == EVENT_INTERFACE_PFACE3 ) strcpy(text, "\\Face 3"); - if ( num == EVENT_INTERFACE_PFACE4 ) strcpy(text, "\\Face 2"); - if ( num == EVENT_INTERFACE_PGLASS0) strcpy(text, "\\No eyeglasses"); - if ( num == EVENT_INTERFACE_PGLASS1) strcpy(text, "\\Eyeglasses 1"); - if ( num == EVENT_INTERFACE_PGLASS2) strcpy(text, "\\Eyeglasses 2"); - if ( num == EVENT_INTERFACE_PGLASS3) strcpy(text, "\\Eyeglasses 3"); - if ( num == EVENT_INTERFACE_PGLASS4) strcpy(text, "\\Eyeglasses 4"); - if ( num == EVENT_INTERFACE_PGLASS5) strcpy(text, "\\Eyeglasses 5"); - - if ( num == EVENT_OBJECT_DESELECT ) strcpy(text, "Previous selection (\\key desel;)"); - if ( num == EVENT_OBJECT_LEFT ) strcpy(text, "Turn left (\\key left;)"); - if ( num == EVENT_OBJECT_RIGHT ) strcpy(text, "Turn right (\\key right;)"); - if ( num == EVENT_OBJECT_UP ) strcpy(text, "Forward (\\key up;)"); - if ( num == EVENT_OBJECT_DOWN ) strcpy(text, "Backward (\\key down;)"); - if ( num == EVENT_OBJECT_GASUP ) strcpy(text, "Up (\\key gup;)"); - if ( num == EVENT_OBJECT_GASDOWN ) strcpy(text, "Down (\\key gdown;)"); - if ( num == EVENT_OBJECT_HTAKE ) strcpy(text, "Grab or drop (\\key action;)"); - if ( num == EVENT_OBJECT_MTAKE ) strcpy(text, "Grab or drop (\\key action;)"); - if ( num == EVENT_OBJECT_MFRONT ) strcpy(text, "..in front"); - if ( num == EVENT_OBJECT_MBACK ) strcpy(text, "..behind"); - if ( num == EVENT_OBJECT_MPOWER ) strcpy(text, "..power cell"); - if ( num == EVENT_OBJECT_BHELP ) strcpy(text, "Instructions for the mission (\\key help;)"); - if ( num == EVENT_OBJECT_BTAKEOFF ) strcpy(text, "Take off to finish the mission"); - if ( num == EVENT_OBJECT_BDERRICK ) strcpy(text, "Build a derrick"); - if ( num == EVENT_OBJECT_BSTATION ) strcpy(text, "Build a power station"); - if ( num == EVENT_OBJECT_BFACTORY ) strcpy(text, "Build a bot factory"); - if ( num == EVENT_OBJECT_BREPAIR ) strcpy(text, "Build a repair center"); - if ( num == EVENT_OBJECT_BCONVERT ) strcpy(text, "Build a converter"); - if ( num == EVENT_OBJECT_BTOWER ) strcpy(text, "Build a defense tower"); - if ( num == EVENT_OBJECT_BRESEARCH ) strcpy(text, "Build a research center"); - if ( num == EVENT_OBJECT_BRADAR ) strcpy(text, "Build a radar station"); - if ( num == EVENT_OBJECT_BENERGY ) strcpy(text, "Build a power cell factory"); - if ( num == EVENT_OBJECT_BLABO ) strcpy(text, "Build an autolab"); - if ( num == EVENT_OBJECT_BNUCLEAR ) strcpy(text, "Build a nuclear power plant"); - if ( num == EVENT_OBJECT_BPARA ) strcpy(text, "Build a lightning conductor"); - if ( num == EVENT_OBJECT_BINFO ) strcpy(text, "Build a exchange post"); - if ( num == EVENT_OBJECT_GFLAT ) strcpy(text, "Show if the ground is flat"); - if ( num == EVENT_OBJECT_FCREATE ) strcpy(text, "Plant a flag"); - if ( num == EVENT_OBJECT_FDELETE ) strcpy(text, "Remove a flag"); - if ( num == EVENT_OBJECT_FCOLORb ) strcpy(text, "\\Blue flags"); - if ( num == EVENT_OBJECT_FCOLORr ) strcpy(text, "\\Red flags"); - if ( num == EVENT_OBJECT_FCOLORg ) strcpy(text, "\\Green flags"); - if ( num == EVENT_OBJECT_FCOLORy ) strcpy(text, "\\Yellow flags"); - if ( num == EVENT_OBJECT_FCOLORv ) strcpy(text, "\\Violet flags"); - if ( num == EVENT_OBJECT_FACTORYfa ) strcpy(text, "Build a winged grabber"); - if ( num == EVENT_OBJECT_FACTORYta ) strcpy(text, "Build a tracked grabber"); - if ( num == EVENT_OBJECT_FACTORYwa ) strcpy(text, "Build a wheeled grabber"); - if ( num == EVENT_OBJECT_FACTORYia ) strcpy(text, "Build a legged grabber"); - if ( num == EVENT_OBJECT_FACTORYfc ) strcpy(text, "Build a winged shooter"); - if ( num == EVENT_OBJECT_FACTORYtc ) strcpy(text, "Build a tracked shooter"); - if ( num == EVENT_OBJECT_FACTORYwc ) strcpy(text, "Build a wheeled shooter"); - if ( num == EVENT_OBJECT_FACTORYic ) strcpy(text, "Build a legged shooter"); - if ( num == EVENT_OBJECT_FACTORYfi ) strcpy(text, "Build a winged orga shooter"); - if ( num == EVENT_OBJECT_FACTORYti ) strcpy(text, "Build a tracked orga shooter"); - if ( num == EVENT_OBJECT_FACTORYwi ) strcpy(text, "Build a wheeled orga shooter"); - if ( num == EVENT_OBJECT_FACTORYii ) strcpy(text, "Build a legged orga shooter"); - if ( num == EVENT_OBJECT_FACTORYfs ) strcpy(text, "Build a winged sniffer"); - if ( num == EVENT_OBJECT_FACTORYts ) strcpy(text, "Build a tracked sniffer"); - if ( num == EVENT_OBJECT_FACTORYws ) strcpy(text, "Build a wheeled sniffer"); - if ( num == EVENT_OBJECT_FACTORYis ) strcpy(text, "Build a legged sniffer"); - if ( num == EVENT_OBJECT_FACTORYrt ) strcpy(text, "Build a thumper"); - if ( num == EVENT_OBJECT_FACTORYrc ) strcpy(text, "Build a phazer shooter"); - if ( num == EVENT_OBJECT_FACTORYrr ) strcpy(text, "Build a recycler"); - if ( num == EVENT_OBJECT_FACTORYrs ) strcpy(text, "Build a shielder"); - if ( num == EVENT_OBJECT_FACTORYsa ) strcpy(text, "Build a subber"); - if ( num == EVENT_OBJECT_RTANK ) strcpy(text, "Run research program for tracked bots"); - if ( num == EVENT_OBJECT_RFLY ) strcpy(text, "Run research program for winged bots"); - if ( num == EVENT_OBJECT_RTHUMP ) strcpy(text, "Run research program for thumper"); - if ( num == EVENT_OBJECT_RCANON ) strcpy(text, "Run research program for shooter"); - if ( num == EVENT_OBJECT_RTOWER ) strcpy(text, "Run research program for defense tower"); - if ( num == EVENT_OBJECT_RPHAZER ) strcpy(text, "Run research program for phazer shooter"); - if ( num == EVENT_OBJECT_RSHIELD ) strcpy(text, "Run research program for shielder"); - if ( num == EVENT_OBJECT_RATOMIC ) strcpy(text, "Run research program for nuclear power"); - if ( num == EVENT_OBJECT_RiPAW ) strcpy(text, "Run research program for legged bots"); - if ( num == EVENT_OBJECT_RiGUN ) strcpy(text, "Run research program for orga shooter"); - if ( num == EVENT_OBJECT_RESET ) strcpy(text, "Return to start"); - if ( num == EVENT_OBJECT_SEARCH ) strcpy(text, "Sniff (\\key action;)"); - if ( num == EVENT_OBJECT_TERRAFORM ) strcpy(text, "Thump (\\key action;)"); - if ( num == EVENT_OBJECT_FIRE ) strcpy(text, "Shoot (\\key action;)"); - if ( num == EVENT_OBJECT_RECOVER ) strcpy(text, "Recycle (\\key action;)"); - if ( num == EVENT_OBJECT_BEGSHIELD ) strcpy(text, "Extend shield (\\key action;)"); - if ( num == EVENT_OBJECT_ENDSHIELD ) strcpy(text, "Withdraw shield (\\key action;)"); - if ( num == EVENT_OBJECT_DIMSHIELD ) strcpy(text, "Shield radius"); - if ( num == EVENT_OBJECT_PROGRUN ) strcpy(text, "Execute the selected program"); - if ( num == EVENT_OBJECT_PROGEDIT ) strcpy(text, "Edit the selected program"); - if ( num == EVENT_OBJECT_INFOOK ) strcpy(text, "\\SatCom on standby"); - if ( num == EVENT_OBJECT_DELETE ) strcpy(text, "Destroy the building"); - if ( num == EVENT_OBJECT_GENERGY ) strcpy(text, "Energy level"); - if ( num == EVENT_OBJECT_GSHIELD ) strcpy(text, "Shield level"); - if ( num == EVENT_OBJECT_GRANGE ) strcpy(text, "Jet temperature"); - if ( num == EVENT_OBJECT_GPROGRESS ) strcpy(text, "Still working ..."); - if ( num == EVENT_OBJECT_GRADAR ) strcpy(text, "Number of insects detected"); - if ( num == EVENT_OBJECT_GINFO ) strcpy(text, "Transmitted information"); - if ( num == EVENT_OBJECT_COMPASS ) strcpy(text, "Compass"); -//? if ( num == EVENT_OBJECT_MAP ) strcpy(text, "Mini-map"); - if ( num == EVENT_OBJECT_MAPZOOM ) strcpy(text, "Zoom mini-map"); - if ( num == EVENT_OBJECT_CAMERA ) strcpy(text, "Camera (\\key camera;)"); - if ( num == EVENT_OBJECT_CAMERAleft) strcpy(text, "Camera to left"); - if ( num == EVENT_OBJECT_CAMERAright) strcpy(text, "Camera to right"); - if ( num == EVENT_OBJECT_CAMERAnear) strcpy(text, "Camera nearest"); - if ( num == EVENT_OBJECT_CAMERAaway) strcpy(text, "Camera awayest"); - if ( num == EVENT_OBJECT_HELP ) strcpy(text, "Help about selected object"); - if ( num == EVENT_OBJECT_SOLUCE ) strcpy(text, "Show the solution"); - if ( num == EVENT_OBJECT_SHORTCUT00) strcpy(text, "Switch bots <-> buildings"); - if ( num == EVENT_OBJECT_LIMIT ) strcpy(text, "Show the range"); - if ( num == EVENT_OBJECT_PEN0 ) strcpy(text, "\\Raise the pencil"); - if ( num == EVENT_OBJECT_PEN1 ) strcpy(text, "\\Use the black pencil"); - if ( num == EVENT_OBJECT_PEN2 ) strcpy(text, "\\Use the yellow pencil"); - if ( num == EVENT_OBJECT_PEN3 ) strcpy(text, "\\Use the orange pencil"); - if ( num == EVENT_OBJECT_PEN4 ) strcpy(text, "\\Use the red pencil"); - if ( num == EVENT_OBJECT_PEN5 ) strcpy(text, "\\Use the purple pencil"); - if ( num == EVENT_OBJECT_PEN6 ) strcpy(text, "\\Use the blue pencil"); - if ( num == EVENT_OBJECT_PEN7 ) strcpy(text, "\\Use the green pencil"); - if ( num == EVENT_OBJECT_PEN8 ) strcpy(text, "\\Use the brown pencil"); - if ( num == EVENT_OBJECT_REC ) strcpy(text, "\\Start recording"); - if ( num == EVENT_OBJECT_STOP ) strcpy(text, "\\Stop recording"); - if ( num == EVENT_DT_VISIT0 || - num == EVENT_DT_VISIT1 || - num == EVENT_DT_VISIT2 || - num == EVENT_DT_VISIT3 || - num == EVENT_DT_VISIT4 ) strcpy(text, "Show the place"); - if ( num == EVENT_DT_END ) strcpy(text, "Continue"); - if ( num == EVENT_CMD ) strcpy(text, "Command line"); - if ( num == EVENT_SPEED ) strcpy(text, "Game speed"); - - if ( num == EVENT_HYPER_PREV ) strcpy(text, "Back"); - if ( num == EVENT_HYPER_NEXT ) strcpy(text, "Forward"); - if ( num == EVENT_HYPER_HOME ) strcpy(text, "Home"); - if ( num == EVENT_HYPER_COPY ) strcpy(text, "Copy"); - if ( num == EVENT_HYPER_SIZE1 ) strcpy(text, "Size 1"); - if ( num == EVENT_HYPER_SIZE2 ) strcpy(text, "Size 2"); - if ( num == EVENT_HYPER_SIZE3 ) strcpy(text, "Size 3"); - if ( num == EVENT_HYPER_SIZE4 ) strcpy(text, "Size 4"); - if ( num == EVENT_HYPER_SIZE5 ) strcpy(text, "Size 5"); - if ( num == EVENT_SATCOM_HUSTON ) strcpy(text, "Instructions from Houston"); -#if _TEEN - if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Dictionnary"); -#else - if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Satellite report"); -#endif - if ( num == EVENT_SATCOM_LOADING ) strcpy(text, "Programs dispatched by Houston"); - if ( num == EVENT_SATCOM_OBJECT ) strcpy(text, "List of objects"); - if ( num == EVENT_SATCOM_PROG ) strcpy(text, "Programming help"); - if ( num == EVENT_SATCOM_SOLUCE ) strcpy(text, "Solution"); - - if ( num == EVENT_STUDIO_OK ) strcpy(text, "OK\\Close program editor and return to game"); - if ( num == EVENT_STUDIO_CANCEL ) strcpy(text, "Cancel\\Cancel all changes"); - if ( num == EVENT_STUDIO_NEW ) strcpy(text, "New"); - if ( num == EVENT_STUDIO_OPEN ) strcpy(text, "Open (Ctrl+o)"); - if ( num == EVENT_STUDIO_SAVE ) strcpy(text, "Save (Ctrl+s)"); - if ( num == EVENT_STUDIO_UNDO ) strcpy(text, "Undo (Ctrl+z)"); - if ( num == EVENT_STUDIO_CUT ) strcpy(text, "Cut (Ctrl+x)"); - if ( num == EVENT_STUDIO_COPY ) strcpy(text, "Copy (Ctrl+c)"); - if ( num == EVENT_STUDIO_PASTE ) strcpy(text, "Paste (Ctrl+v)"); - if ( num == EVENT_STUDIO_SIZE ) strcpy(text, "Font size"); - if ( num == EVENT_STUDIO_TOOL ) strcpy(text, "Instructions (\\key help;)"); - if ( num == EVENT_STUDIO_HELP ) strcpy(text, "Programming help (\\key prog;)"); - if ( num == EVENT_STUDIO_COMPILE ) strcpy(text, "Compile"); - if ( num == EVENT_STUDIO_RUN ) strcpy(text, "Execute/stop"); - if ( num == EVENT_STUDIO_REALTIME ) strcpy(text, "Pause/continue"); - if ( num == EVENT_STUDIO_STEP ) strcpy(text, "One step"); - } - - if ( type == RES_OBJECT ) - { - if ( num == OBJECT_PORTICO ) strcpy(text, "Gantry crane"); - if ( num == OBJECT_BASE ) strcpy(text, "Spaceship"); - if ( num == OBJECT_DERRICK ) strcpy(text, "Derrick"); - if ( num == OBJECT_FACTORY ) strcpy(text, "Bot factory"); - if ( num == OBJECT_REPAIR ) strcpy(text, "Repair center"); - if ( num == OBJECT_DESTROYER ) strcpy(text, "Destroyer"); - if ( num == OBJECT_STATION ) strcpy(text, "Power station"); - if ( num == OBJECT_CONVERT ) strcpy(text, "Converts ore to titanium"); - if ( num == OBJECT_TOWER ) strcpy(text, "Defense tower"); - if ( num == OBJECT_NEST ) strcpy(text, "Nest"); - if ( num == OBJECT_RESEARCH ) strcpy(text, "Research center"); - if ( num == OBJECT_RADAR ) strcpy(text, "Radar station"); - if ( num == OBJECT_INFO ) strcpy(text, "Information exchange post"); -#if _TEEN - if ( num == OBJECT_ENERGY ) strcpy(text, "Power cell factory"); -#else - if ( num == OBJECT_ENERGY ) strcpy(text, "Power cell factory"); -#endif - if ( num == OBJECT_LABO ) strcpy(text, "Autolab"); - if ( num == OBJECT_NUCLEAR ) strcpy(text, "Nuclear power station"); - if ( num == OBJECT_PARA ) strcpy(text, "Lightning conductor"); - if ( num == OBJECT_SAFE ) strcpy(text, "Vault"); - if ( num == OBJECT_HUSTON ) strcpy(text, "Houston Mission Control"); - if ( num == OBJECT_TARGET1 ) strcpy(text, "Target"); - if ( num == OBJECT_TARGET2 ) strcpy(text, "Target"); - if ( num == OBJECT_START ) strcpy(text, "Start"); - if ( num == OBJECT_END ) strcpy(text, "Finish"); - if ( num == OBJECT_STONE ) strcpy(text, "Titanium ore"); - if ( num == OBJECT_URANIUM ) strcpy(text, "Uranium ore"); - if ( num == OBJECT_BULLET ) strcpy(text, "Organic matter"); - if ( num == OBJECT_METAL ) strcpy(text, "Titanium"); - if ( num == OBJECT_POWER ) strcpy(text, "Power cell"); - if ( num == OBJECT_ATOMIC ) strcpy(text, "Nuclear power cell"); - if ( num == OBJECT_BBOX ) strcpy(text, "Black box"); - if ( num == OBJECT_KEYa ) strcpy(text, "Key A"); - if ( num == OBJECT_KEYb ) strcpy(text, "Key B"); - if ( num == OBJECT_KEYc ) strcpy(text, "Key C"); - if ( num == OBJECT_KEYd ) strcpy(text, "Key D"); - if ( num == OBJECT_TNT ) strcpy(text, "Explosive"); - if ( num == OBJECT_BOMB ) strcpy(text, "Fixed mine"); - if ( num == OBJECT_BAG ) strcpy(text, "Survival kit"); - if ( num == OBJECT_WAYPOINT ) strcpy(text, "Checkpoint"); - if ( num == OBJECT_FLAGb ) strcpy(text, "Blue flag"); - if ( num == OBJECT_FLAGr ) strcpy(text, "Red flag"); - if ( num == OBJECT_FLAGg ) strcpy(text, "Green flag"); - if ( num == OBJECT_FLAGy ) strcpy(text, "Yellow flag"); - if ( num == OBJECT_FLAGv ) strcpy(text, "Violet flag"); - if ( num == OBJECT_MARKPOWER ) strcpy(text, "Energy deposit (site for power station)"); - if ( num == OBJECT_MARKURANIUM ) strcpy(text, "Uranium deposit (site for derrick)"); - if ( num == OBJECT_MARKKEYa ) strcpy(text, "Found key A (site for derrick)"); - if ( num == OBJECT_MARKKEYb ) strcpy(text, "Found key B (site for derrick)"); - if ( num == OBJECT_MARKKEYc ) strcpy(text, "Found key C (site for derrick)"); - if ( num == OBJECT_MARKKEYd ) strcpy(text, "Found key D (site for derrick)"); - if ( num == OBJECT_MARKSTONE ) strcpy(text, "Titanium deposit (site for derrick)"); - if ( num == OBJECT_MOBILEft ) strcpy(text, "Practice bot"); - if ( num == OBJECT_MOBILEtt ) strcpy(text, "Practice bot"); - if ( num == OBJECT_MOBILEwt ) strcpy(text, "Practice bot"); - if ( num == OBJECT_MOBILEit ) strcpy(text, "Practice bot"); - if ( num == OBJECT_MOBILEfa ) strcpy(text, "Winged grabber"); - if ( num == OBJECT_MOBILEta ) strcpy(text, "Tracked grabber"); - if ( num == OBJECT_MOBILEwa ) strcpy(text, "Wheeled grabber"); - if ( num == OBJECT_MOBILEia ) strcpy(text, "Legged grabber"); - if ( num == OBJECT_MOBILEfc ) strcpy(text, "Winged shooter"); - if ( num == OBJECT_MOBILEtc ) strcpy(text, "Tracked shooter"); - if ( num == OBJECT_MOBILEwc ) strcpy(text, "Wheeled shooter"); - if ( num == OBJECT_MOBILEic ) strcpy(text, "Legged shooter"); - if ( num == OBJECT_MOBILEfi ) strcpy(text, "Winged orga shooter"); - if ( num == OBJECT_MOBILEti ) strcpy(text, "Tracked orga shooter"); - if ( num == OBJECT_MOBILEwi ) strcpy(text, "Wheeled orga shooter"); - if ( num == OBJECT_MOBILEii ) strcpy(text, "Legged orga shooter"); - if ( num == OBJECT_MOBILEfs ) strcpy(text, "Winged sniffer"); - if ( num == OBJECT_MOBILEts ) strcpy(text, "Tracked sniffer"); - if ( num == OBJECT_MOBILEws ) strcpy(text, "Wheeled sniffer"); - if ( num == OBJECT_MOBILEis ) strcpy(text, "Legged sniffer"); - if ( num == OBJECT_MOBILErt ) strcpy(text, "Thumper"); - if ( num == OBJECT_MOBILErc ) strcpy(text, "Phazer shooter"); - if ( num == OBJECT_MOBILErr ) strcpy(text, "Recycler"); - if ( num == OBJECT_MOBILErs ) strcpy(text, "Shielder"); - if ( num == OBJECT_MOBILEsa ) strcpy(text, "Subber"); - if ( num == OBJECT_MOBILEtg ) strcpy(text, "Target bot"); - if ( num == OBJECT_MOBILEdr ) strcpy(text, "Drawer bot"); - if ( num == OBJECT_HUMAN ) strcpy(text, g_gamerName); - if ( num == OBJECT_TECH ) strcpy(text, "Engineer"); - if ( num == OBJECT_TOTO ) strcpy(text, "Robbie"); - if ( num == OBJECT_MOTHER ) strcpy(text, "Alien Queen"); - if ( num == OBJECT_ANT ) strcpy(text, "Ant"); - if ( num == OBJECT_SPIDER ) strcpy(text, "Spider"); - if ( num == OBJECT_BEE ) strcpy(text, "Wasp"); - if ( num == OBJECT_WORM ) strcpy(text, "Worm"); - if ( num == OBJECT_EGG ) strcpy(text, "Egg"); - if ( num == OBJECT_RUINmobilew1 ) strcpy(text, "Wreckage"); - if ( num == OBJECT_RUINmobilew2 ) strcpy(text, "Wreckage"); - if ( num == OBJECT_RUINmobilet1 ) strcpy(text, "Wreckage"); - if ( num == OBJECT_RUINmobilet2 ) strcpy(text, "Wreckage"); - if ( num == OBJECT_RUINmobiler1 ) strcpy(text, "Wreckage"); - if ( num == OBJECT_RUINmobiler2 ) strcpy(text, "Wreckage"); - if ( num == OBJECT_RUINfactory ) strcpy(text, "Ruin"); - if ( num == OBJECT_RUINdoor ) strcpy(text, "Ruin"); - if ( num == OBJECT_RUINsupport ) strcpy(text, "Waste"); - if ( num == OBJECT_RUINradar ) strcpy(text, "Ruin"); - if ( num == OBJECT_RUINconvert ) strcpy(text, "Ruin"); - if ( num == OBJECT_RUINbase ) strcpy(text, "Spaceship ruin"); - if ( num == OBJECT_RUINhead ) strcpy(text, "Spaceship ruin"); - if ( num == OBJECT_APOLLO1 || - num == OBJECT_APOLLO3 || - num == OBJECT_APOLLO4 || - num == OBJECT_APOLLO5 ) strcpy(text, "Remains of Apollo mission"); - if ( num == OBJECT_APOLLO2 ) strcpy(text, "Lunar Roving Vehicle"); - } - - if ( type == RES_ERR ) - { - strcpy(text, "Error"); - if ( num == ERR_CMD ) strcpy(text, "Unknown command"); -#if _NEWLOOK - if ( num == ERR_INSTALL ) strcpy(text, "CeeBot not installed."); - if ( num == ERR_NOCD ) strcpy(text, "Please insert the CeeBot CD\nand re-run the game."); -#else - if ( num == ERR_INSTALL ) strcpy(text, "COLOBOT not installed."); - if ( num == ERR_NOCD ) strcpy(text, "Please insert the COLOBOT CD\nand re-run the game."); -#endif - if ( num == ERR_MANIP_VEH ) strcpy(text, "Inappropriate bot"); - if ( num == ERR_MANIP_FLY ) strcpy(text, "Impossible when flying"); - if ( num == ERR_MANIP_BUSY ) strcpy(text, "Already carrying something"); - if ( num == ERR_MANIP_NIL ) strcpy(text, "Nothing to grab"); - if ( num == ERR_MANIP_MOTOR ) strcpy(text, "Impossible when moving"); - if ( num == ERR_MANIP_OCC ) strcpy(text, "Place occupied"); - if ( num == ERR_MANIP_FRIEND ) strcpy(text, "No other robot"); - if ( num == ERR_MANIP_RADIO ) strcpy(text, "You can not carry a radioactive object"); - if ( num == ERR_MANIP_WATER ) strcpy(text, "You can not carry an object under water"); - if ( num == ERR_MANIP_EMPTY ) strcpy(text, "Nothing to drop"); - if ( num == ERR_BUILD_FLY ) strcpy(text, "Impossible when flying"); - if ( num == ERR_BUILD_WATER ) strcpy(text, "Impossible under water"); - if ( num == ERR_BUILD_ENERGY ) strcpy(text, "Not enough energy"); - if ( num == ERR_BUILD_METALAWAY ) strcpy(text, "Titanium too far away"); - if ( num == ERR_BUILD_METALNEAR ) strcpy(text, "Titanium too close"); - if ( num == ERR_BUILD_METALINEX ) strcpy(text, "No titanium around"); - if ( num == ERR_BUILD_FLAT ) strcpy(text, "Ground not flat enough"); - if ( num == ERR_BUILD_FLATLIT ) strcpy(text, "Flat ground not large enough"); - if ( num == ERR_BUILD_BUSY ) strcpy(text, "Place occupied"); - if ( num == ERR_BUILD_BASE ) strcpy(text, "Too close to space ship"); - if ( num == ERR_BUILD_NARROW ) strcpy(text, "Too close to a building"); - if ( num == ERR_BUILD_MOTOR ) strcpy(text, "Impossible when moving"); - if ( num == ERR_SEARCH_FLY ) strcpy(text, "Impossible when flying"); - if ( num == ERR_SEARCH_VEH ) strcpy(text, "Inappropriate bot"); - if ( num == ERR_SEARCH_MOTOR ) strcpy(text, "Impossible when moving"); - if ( num == ERR_TERRA_VEH ) strcpy(text, "Inappropriate bot"); - if ( num == ERR_TERRA_ENERGY ) strcpy(text, "Not enough energy"); - if ( num == ERR_TERRA_FLOOR ) strcpy(text, "Ground inappropriate"); - if ( num == ERR_TERRA_BUILDING ) strcpy(text, "Building too close"); - if ( num == ERR_TERRA_OBJECT ) strcpy(text, "Object too close"); - if ( num == ERR_RECOVER_VEH ) strcpy(text, "Inappropriate bot"); - if ( num == ERR_RECOVER_ENERGY ) strcpy(text, "Not enough energy"); - if ( num == ERR_RECOVER_NULL ) strcpy(text, "Nothing to recycle"); - if ( num == ERR_SHIELD_VEH ) strcpy(text, "Inappropriate bot"); - if ( num == ERR_SHIELD_ENERGY ) strcpy(text, "No more energy"); - if ( num == ERR_MOVE_IMPOSSIBLE ) strcpy(text, "Error in instruction move"); - if ( num == ERR_FIND_IMPOSSIBLE ) strcpy(text, "Object not found"); - if ( num == ERR_GOTO_IMPOSSIBLE ) strcpy(text, "Goto: inaccessible destination"); - if ( num == ERR_GOTO_ITER ) strcpy(text, "Goto: inaccessible destination"); - if ( num == ERR_GOTO_BUSY ) strcpy(text, "Goto: destination occupied"); - if ( num == ERR_FIRE_VEH ) strcpy(text, "Inappropriate bot"); - if ( num == ERR_FIRE_ENERGY ) strcpy(text, "Not enough energy"); - if ( num == ERR_FIRE_FLY ) strcpy(text, "Impossible when flying"); - if ( num == ERR_CONVERT_EMPTY ) strcpy(text, "No titanium ore to convert"); - if ( num == ERR_DERRICK_NULL ) strcpy(text, "No ore in the subsoil"); - if ( num == ERR_STATION_NULL ) strcpy(text, "No energy in the subsoil"); - if ( num == ERR_TOWER_POWER ) strcpy(text, "No power cell"); - if ( num == ERR_TOWER_ENERGY ) strcpy(text, "No more energy"); - if ( num == ERR_RESEARCH_POWER ) strcpy(text, "No power cell"); - if ( num == ERR_RESEARCH_ENERGY ) strcpy(text, "Not enough energy"); - if ( num == ERR_RESEARCH_TYPE ) strcpy(text, "Inappropriate cell type"); - if ( num == ERR_RESEARCH_ALREADY) strcpy(text, "Research program already performed"); - if ( num == ERR_ENERGY_NULL ) strcpy(text, "No energy in the subsoil"); - if ( num == ERR_ENERGY_LOW ) strcpy(text, "Not enough energy yet"); - if ( num == ERR_ENERGY_EMPTY ) strcpy(text, "No titanium to transform"); - if ( num == ERR_ENERGY_BAD ) strcpy(text, "Transforms only titanium"); - if ( num == ERR_BASE_DLOCK ) strcpy(text, "Doors blocked by a robot or another object "); - if ( num == ERR_BASE_DHUMAN ) strcpy(text, "You must get on the spaceship to take off "); - if ( num == ERR_LABO_NULL ) strcpy(text, "Nothing to analyze"); - if ( num == ERR_LABO_BAD ) strcpy(text, "Analyzes only organic matter"); - if ( num == ERR_LABO_ALREADY ) strcpy(text, "Analysis already performed"); - if ( num == ERR_NUCLEAR_NULL ) strcpy(text, "No energy in the subsoil"); - if ( num == ERR_NUCLEAR_LOW ) strcpy(text, "Not yet enough energy"); - if ( num == ERR_NUCLEAR_EMPTY ) strcpy(text, "No uranium to transform"); - if ( num == ERR_NUCLEAR_BAD ) strcpy(text, "Transforms only uranium"); - if ( num == ERR_FACTORY_NULL ) strcpy(text, "No titanium"); - if ( num == ERR_FACTORY_NEAR ) strcpy(text, "Object too close"); - if ( num == ERR_RESET_NEAR ) strcpy(text, "Place occupied"); - if ( num == ERR_INFO_NULL ) strcpy(text, "No information exchange post within range"); - if ( num == ERR_VEH_VIRUS ) strcpy(text, "Program infected by a virus"); - if ( num == ERR_BAT_VIRUS ) strcpy(text, "Infected by a virus, temporarily out of order"); - if ( num == ERR_VEH_POWER ) strcpy(text, "No power cell"); - if ( num == ERR_VEH_ENERGY ) strcpy(text, "No more energy"); - if ( num == ERR_FLAG_FLY ) strcpy(text, "Impossible when flying"); - if ( num == ERR_FLAG_WATER ) strcpy(text, "Impossible when swimming"); - if ( num == ERR_FLAG_MOTOR ) strcpy(text, "Impossible when moving"); - if ( num == ERR_FLAG_BUSY ) strcpy(text, "Impossible when carrying an object"); - if ( num == ERR_FLAG_CREATE ) strcpy(text, "Too many flags of this color (maximum 5)"); - if ( num == ERR_FLAG_PROXY ) strcpy(text, "Too close to an existing flag"); - if ( num == ERR_FLAG_DELETE ) strcpy(text, "No flag nearby"); - if ( num == ERR_MISSION_NOTERM ) strcpy(text, "The mission is not accomplished yet (press \\key help; for more details)"); - if ( num == ERR_DELETEMOBILE ) strcpy(text, "Bot destroyed"); - if ( num == ERR_DELETEBUILDING ) strcpy(text, "Building destroyed"); - if ( num == ERR_TOOMANY ) strcpy(text, "Can not create this, there are too many objects"); - if ( num == ERR_OBLIGATORYTOKEN ) strcpy(text, "\"%s\" missing in this exercise"); //** - if ( num == ERR_PROHIBITEDTOKEN ) strcpy(text, "Do not use in this exercise"); //** - - if ( num == INFO_BUILD ) strcpy(text, "Building completed"); - if ( num == INFO_CONVERT ) strcpy(text, "Titanium available"); - if ( num == INFO_RESEARCH ) strcpy(text, "Research program completed"); - if ( num == INFO_RESEARCHTANK ) strcpy(text, "Plans for tracked robots available "); - if ( num == INFO_RESEARCHFLY ) strcpy(text, "You can fly with the keys (\\key gup;) and (\\key gdown;)"); - if ( num == INFO_RESEARCHTHUMP ) strcpy(text, "Plans for thumper available"); - if ( num == INFO_RESEARCHCANON ) strcpy(text, "Plans for shooter available"); - if ( num == INFO_RESEARCHTOWER ) strcpy(text, "Plans for defense tower available"); - if ( num == INFO_RESEARCHPHAZER ) strcpy(text, "Plans for phazer shooter available"); - if ( num == INFO_RESEARCHSHIELD ) strcpy(text, "Plans for shielder available"); - if ( num == INFO_RESEARCHATOMIC ) strcpy(text, "Plans for nuclear power plant available"); - if ( num == INFO_FACTORY ) strcpy(text, "New bot available"); - if ( num == INFO_LABO ) strcpy(text, "Analysis performed"); - if ( num == INFO_ENERGY ) strcpy(text, "Power cell available"); - if ( num == INFO_NUCLEAR ) strcpy(text, "Nuclear power cell available"); - if ( num == INFO_FINDING ) strcpy(text, "You found a usable object"); - if ( num == INFO_MARKPOWER ) strcpy(text, "Found a site for power station"); - if ( num == INFO_MARKURANIUM ) strcpy(text, "Found a site for a derrick"); - if ( num == INFO_MARKSTONE ) strcpy(text, "Found a site for a derrick"); - if ( num == INFO_MARKKEYa ) strcpy(text, "Found a site for a derrick"); - if ( num == INFO_MARKKEYb ) strcpy(text, "Found a site for a derrick"); - if ( num == INFO_MARKKEYc ) strcpy(text, "Found a site for a derrick"); - if ( num == INFO_MARKKEYd ) strcpy(text, "Found a site for a derrick"); - if ( num == INFO_WIN ) strcpy(text, "<<< Well done, mission accomplished >>>"); - if ( num == INFO_LOST ) strcpy(text, "<<< Sorry, mission failed >>>"); - if ( num == INFO_LOSTq ) strcpy(text, "<<< Sorry, mission failed >>>"); - if ( num == INFO_WRITEOK ) strcpy(text, "Current mission saved"); - if ( num == INFO_DELETEPATH ) strcpy(text, "Checkpoint crossed"); - if ( num == INFO_DELETEMOTHER ) strcpy(text, "Alien Queen killed"); - if ( num == INFO_DELETEANT ) strcpy(text, "Ant fatally wounded"); - if ( num == INFO_DELETEBEE ) strcpy(text, "Wasp fatally wounded"); - if ( num == INFO_DELETEWORM ) strcpy(text, "Worm fatally wounded"); - if ( num == INFO_DELETESPIDER ) strcpy(text, "Spider fatally wounded"); - if ( num == INFO_BEGINSATCOM ) strcpy(text, "Press \\key help; to read instructions on your SatCom"); - } - - if ( type == RES_CBOT ) - { - strcpy(text, "Error"); - if ( num == TX_OPENPAR ) strcpy(text, "Opening bracket missing"); - if ( num == TX_CLOSEPAR ) strcpy(text, "Closing bracket missing "); - if ( num == TX_NOTBOOL ) strcpy(text, "The expression must return a boolean value"); - if ( num == TX_UNDEFVAR ) strcpy(text, "Variable not declared"); - if ( num == TX_BADLEFT ) strcpy(text, "Assignment impossible"); - if ( num == TX_ENDOF ) strcpy(text, "Semicolon terminator missing"); - if ( num == TX_OUTCASE ) strcpy(text, "Instruction ""case"" outside a block ""switch"""); - if ( num == TX_NOTERM ) strcpy(text, "Instructions after the final closing brace"); - if ( num == TX_CLOSEBLK ) strcpy(text, "End of block missing"); - if ( num == TX_ELSEWITHOUTIF ) strcpy(text, "Instruction ""else"" without corresponding ""if"" "); - if ( num == TX_OPENBLK ) strcpy(text, "Opening brace missing ");//début d'un bloc attendu? - if ( num == TX_BADTYPE ) strcpy(text, "Wrong type for the assignment"); - if ( num == TX_REDEFVAR ) strcpy(text, "A variable can not be declared twice"); - if ( num == TX_BAD2TYPE ) strcpy(text, "The types of the two operands are incompatible "); - if ( num == TX_UNDEFCALL ) strcpy(text, "Unknown function"); - if ( num == TX_MISDOTS ) strcpy(text, "Sign "" : "" missing"); - if ( num == TX_WHILE ) strcpy(text, "Keyword ""while"" missing"); - if ( num == TX_BREAK ) strcpy(text, "Instruction ""break"" outside a loop"); - if ( num == TX_LABEL ) strcpy(text, "A label must be followed by ""for"", ""while"", ""do"" or ""switch"""); - if ( num == TX_NOLABEL ) strcpy(text, "This label does not exist");// Cette étiquette n'existe pas - if ( num == TX_NOCASE ) strcpy(text, "Instruction ""case"" missing"); - if ( num == TX_BADNUM ) strcpy(text, "Number missing"); - if ( num == TX_VOID ) strcpy(text, "Void parameter"); - if ( num == TX_NOTYP ) strcpy(text, "Type declaration missing"); - if ( num == TX_NOVAR ) strcpy(text, "Variable name missing"); - if ( num == TX_NOFONC ) strcpy(text, "Function name missing"); - if ( num == TX_OVERPARAM ) strcpy(text, "Too many parameters"); - if ( num == TX_REDEF ) strcpy(text, "Function already exists"); - if ( num == TX_LOWPARAM ) strcpy(text, "Parameters missing "); - if ( num == TX_BADPARAM ) strcpy(text, "No function with this name accepts this kind of parameter"); - if ( num == TX_NUMPARAM ) strcpy(text, "No function with this name accepts this number of parameters"); - if ( num == TX_NOITEM ) strcpy(text, "This is not a member of this class"); - if ( num == TX_DOT ) strcpy(text, "This object is not a member of a class"); - if ( num == TX_NOCONST ) strcpy(text, "Appropriate constructor missing"); - if ( num == TX_REDEFCLASS ) strcpy(text, "This class already exists"); - if ( num == TX_CLBRK ) strcpy(text, """ ] "" missing"); - if ( num == TX_RESERVED ) strcpy(text, "Reserved keyword of CBOT language"); - if ( num == TX_BADNEW ) strcpy(text, "Bad argument for ""new"""); - if ( num == TX_OPBRK ) strcpy(text, """ [ "" expected"); - if ( num == TX_BADSTRING ) strcpy(text, "String missing"); - if ( num == TX_BADINDEX ) strcpy(text, "Incorrect index type"); - if ( num == TX_PRIVATE ) strcpy(text, "Private element"); - if ( num == TX_NOPUBLIC ) strcpy(text, "Public required"); - if ( num == TX_DIVZERO ) strcpy(text, "Dividing by zero"); - if ( num == TX_NOTINIT ) strcpy(text, "Variable not initialized"); - if ( num == TX_BADTHROW ) strcpy(text, "Negative value rejected by ""throw""");//C'est quoi, ça? - if ( num == TX_NORETVAL ) strcpy(text, "The function returned no value "); - if ( num == TX_NORUN ) strcpy(text, "No function running"); - if ( num == TX_NOCALL ) strcpy(text, "Calling an unknown function"); - if ( num == TX_NOCLASS ) strcpy(text, "This class does not exist"); - if ( num == TX_NULLPT ) strcpy(text, "Unknown Object"); - if ( num == TX_OPNAN ) strcpy(text, "Operation impossible with value ""nan"""); - if ( num == TX_OUTARRAY ) strcpy(text, "Access beyond array limit"); - if ( num == TX_STACKOVER ) strcpy(text, "Stack overflow"); - if ( num == TX_DELETEDPT ) strcpy(text, "Illegal object"); - if ( num == TX_FILEOPEN ) strcpy(text, "Can't open file"); - if ( num == TX_NOTOPEN ) strcpy(text, "File not open"); - if ( num == TX_ERRREAD ) strcpy(text, "Read error"); - if ( num == TX_ERRWRITE ) strcpy(text, "Write error"); - } - - if ( type == RES_KEY ) - { - if ( num == 0 ) strcpy(text, "< none >"); - if ( num == VK_LEFT ) strcpy(text, "Arrow left"); - if ( num == VK_RIGHT ) strcpy(text, "Arrow right"); - if ( num == VK_UP ) strcpy(text, "Arrow up"); - if ( num == VK_DOWN ) strcpy(text, "Arrow down"); - if ( num == VK_CANCEL ) strcpy(text, "Control-break"); - if ( num == VK_BACK ) strcpy(text, "<--"); - if ( num == VK_TAB ) strcpy(text, "Tab"); - if ( num == VK_CLEAR ) strcpy(text, "Clear"); - if ( num == VK_RETURN ) strcpy(text, "Enter"); - if ( num == VK_SHIFT ) strcpy(text, "Shift"); - if ( num == VK_CONTROL ) strcpy(text, "Ctrl"); - if ( num == VK_MENU ) strcpy(text, "Alt"); - if ( num == VK_PAUSE ) strcpy(text, "Pause"); - if ( num == VK_CAPITAL ) strcpy(text, "Caps Lock"); - if ( num == VK_ESCAPE ) strcpy(text, "Esc"); - if ( num == VK_SPACE ) strcpy(text, "Space"); - if ( num == VK_PRIOR ) strcpy(text, "Page Up"); - if ( num == VK_NEXT ) strcpy(text, "Page Down"); - if ( num == VK_END ) strcpy(text, "End"); - if ( num == VK_HOME ) strcpy(text, "Home"); - if ( num == VK_SELECT ) strcpy(text, "Select"); - if ( num == VK_EXECUTE ) strcpy(text, "Execute"); - if ( num == VK_SNAPSHOT ) strcpy(text, "Print Scrn"); - if ( num == VK_INSERT ) strcpy(text, "Insert"); - if ( num == VK_DELETE ) strcpy(text, "Delete"); - if ( num == VK_HELP ) strcpy(text, "Help"); - if ( num == VK_LWIN ) strcpy(text, "Left Windows"); - if ( num == VK_RWIN ) strcpy(text, "Right Windows"); - if ( num == VK_APPS ) strcpy(text, "Application key"); - if ( num == VK_NUMPAD0 ) strcpy(text, "NumPad 0"); - if ( num == VK_NUMPAD1 ) strcpy(text, "NumPad 1"); - if ( num == VK_NUMPAD2 ) strcpy(text, "NumPad 2"); - if ( num == VK_NUMPAD3 ) strcpy(text, "NumPad 3"); - if ( num == VK_NUMPAD4 ) strcpy(text, "NumPad 4"); - if ( num == VK_NUMPAD5 ) strcpy(text, "NumPad 5"); - if ( num == VK_NUMPAD6 ) strcpy(text, "NumPad 6"); - if ( num == VK_NUMPAD7 ) strcpy(text, "NumPad 7"); - if ( num == VK_NUMPAD8 ) strcpy(text, "NumPad 8"); - if ( num == VK_NUMPAD9 ) strcpy(text, "NumPad 9"); - if ( num == VK_MULTIPLY ) strcpy(text, "NumPad *"); - if ( num == VK_ADD ) strcpy(text, "NumPad +"); - if ( num == VK_SEPARATOR ) strcpy(text, "NumPad sep"); - if ( num == VK_SUBTRACT ) strcpy(text, "NumPad -"); - if ( num == VK_DECIMAL ) strcpy(text, "NumPad ."); - if ( num == VK_DIVIDE ) strcpy(text, "NumPad /"); - if ( num == VK_F1 ) strcpy(text, "F1"); - if ( num == VK_F2 ) strcpy(text, "F2"); - if ( num == VK_F3 ) strcpy(text, "F3"); - if ( num == VK_F4 ) strcpy(text, "F4"); - if ( num == VK_F5 ) strcpy(text, "F5"); - if ( num == VK_F6 ) strcpy(text, "F6"); - if ( num == VK_F7 ) strcpy(text, "F7"); - if ( num == VK_F8 ) strcpy(text, "F8"); - if ( num == VK_F9 ) strcpy(text, "F9"); - if ( num == VK_F10 ) strcpy(text, "F10"); - if ( num == VK_F11 ) strcpy(text, "F11"); - if ( num == VK_F12 ) strcpy(text, "F12"); - if ( num == VK_F13 ) strcpy(text, "F13"); - if ( num == VK_F14 ) strcpy(text, "F14"); - if ( num == VK_F15 ) strcpy(text, "F15"); - if ( num == VK_F16 ) strcpy(text, "F16"); - if ( num == VK_F17 ) strcpy(text, "F17"); - if ( num == VK_F18 ) strcpy(text, "F18"); - if ( num == VK_F19 ) strcpy(text, "F19"); - if ( num == VK_F20 ) strcpy(text, "F20"); - if ( num == VK_NUMLOCK ) strcpy(text, "Num Lock"); - if ( num == VK_SCROLL ) strcpy(text, "Scroll"); - if ( num == VK_ATTN ) strcpy(text, "Attn"); - if ( num == VK_CRSEL ) strcpy(text, "CrSel"); - if ( num == VK_EXSEL ) strcpy(text, "ExSel"); - if ( num == VK_EREOF ) strcpy(text, "Erase EOF"); - if ( num == VK_PLAY ) strcpy(text, "Play"); - if ( num == VK_ZOOM ) strcpy(text, "Zoom"); - if ( num == VK_PA1 ) strcpy(text, "PA1"); - if ( num == VK_OEM_CLEAR ) strcpy(text, "Clear"); - if ( num == VK_BUTTON1 ) strcpy(text, "Button 1"); - if ( num == VK_BUTTON2 ) strcpy(text, "Button 2"); - if ( num == VK_BUTTON3 ) strcpy(text, "Button 3"); - if ( num == VK_BUTTON4 ) strcpy(text, "Button 4"); - if ( num == VK_BUTTON5 ) strcpy(text, "Button 5"); - if ( num == VK_BUTTON6 ) strcpy(text, "Button 6"); - if ( num == VK_BUTTON7 ) strcpy(text, "Button 7"); - if ( num == VK_BUTTON8 ) strcpy(text, "Button 8"); - if ( num == VK_BUTTON9 ) strcpy(text, "Button 9"); - if ( num == VK_BUTTON10 ) strcpy(text, "Button 10"); - if ( num == VK_BUTTON11 ) strcpy(text, "Button 11"); - if ( num == VK_BUTTON12 ) strcpy(text, "Button 12"); - if ( num == VK_BUTTON13 ) strcpy(text, "Button 13"); - if ( num == VK_BUTTON14 ) strcpy(text, "Button 14"); - if ( num == VK_BUTTON15 ) strcpy(text, "Button 15"); - if ( num == VK_BUTTON16 ) strcpy(text, "Button 16"); - if ( num == VK_BUTTON17 ) strcpy(text, "Button 17"); - if ( num == VK_BUTTON18 ) strcpy(text, "Button 18"); - if ( num == VK_BUTTON19 ) strcpy(text, "Button 19"); - if ( num == VK_BUTTON20 ) strcpy(text, "Button 20"); - if ( num == VK_BUTTON21 ) strcpy(text, "Button 21"); - if ( num == VK_BUTTON22 ) strcpy(text, "Button 22"); - if ( num == VK_BUTTON23 ) strcpy(text, "Button 23"); - if ( num == VK_BUTTON24 ) strcpy(text, "Button 24"); - if ( num == VK_BUTTON25 ) strcpy(text, "Button 25"); - if ( num == VK_BUTTON26 ) strcpy(text, "Button 26"); - if ( num == VK_BUTTON27 ) strcpy(text, "Button 27"); - if ( num == VK_BUTTON28 ) strcpy(text, "Button 28"); - if ( num == VK_BUTTON29 ) strcpy(text, "Button 29"); - if ( num == VK_BUTTON30 ) strcpy(text, "Button 30"); - if ( num == VK_BUTTON31 ) strcpy(text, "Button 31"); - if ( num == VK_BUTTON32 ) strcpy(text, "Button 32"); - if ( num == VK_WHEELUP ) strcpy(text, "Wheel up"); - if ( num == VK_WHEELDOWN ) strcpy(text, "Wheel down"); - } -#endif - -#if _FRENCH - if ( type == RES_TEXT ) - { - #if _FULL - if ( num == RT_VERSION_ID ) strcpy(text, "1.18 /f"); - #endif - #if _NET - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A 1.18"); - #endif - #if _SCHOOL & _EDU - #if _TEEN - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen EDU 1.18"); - #else - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A EDU 1.18"); - #endif - #endif - #if _SCHOOL & _PERSO - #if _TEEN - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen PERSO 1.18"); - #else - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A PERSO 1.18"); - #endif - #endif - #if _SCHOOL & _CEEBOTDEMO - #if _TEEN - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen DEMO 1.18"); - #else - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A DEMO 1.18"); - #endif - #endif - #if _DEMO - if ( num == RT_VERSION_ID ) strcpy(text, "Demo 1.18 /f"); - #endif - if ( num == RT_DISINFO_TITLE ) strcpy(text, "SatCom"); - if ( num == RT_WINDOW_MAXIMIZED ) strcpy(text, "Taille maximale"); - if ( num == RT_WINDOW_MINIMIZED ) strcpy(text, "Taille réduite"); - if ( num == RT_WINDOW_STANDARD ) strcpy(text, "Taille normale"); - if ( num == RT_WINDOW_CLOSE ) strcpy(text, "Fermer"); - - if ( num == RT_STUDIO_TITLE ) strcpy(text, "Edition du programme"); - if ( num == RT_SCRIPT_NEW ) strcpy(text, "Nouveau"); - if ( num == RT_NAME_DEFAULT ) strcpy(text, "Joueur"); - if ( num == RT_IO_NEW ) strcpy(text, "Nouveau ..."); - if ( num == RT_KEY_OR ) strcpy(text, " ou "); - -#if _NEWLOOK - if ( num == RT_TITLE_BASE ) strcpy(text, "CeeBot"); - if ( num == RT_TITLE_INIT ) strcpy(text, "CeeBot"); -#else - if ( num == RT_TITLE_BASE ) strcpy(text, "COLOBOT"); - if ( num == RT_TITLE_INIT ) strcpy(text, "COLOBOT"); -#endif - if ( num == RT_TITLE_TRAINER ) strcpy(text, "Programmation"); - if ( num == RT_TITLE_DEFI ) strcpy(text, "Défis"); - if ( num == RT_TITLE_MISSION ) strcpy(text, "Missions"); - if ( num == RT_TITLE_FREE ) strcpy(text, "Jeu libre"); - if ( num == RT_TITLE_TEEN ) strcpy(text, "Jeu libre"); - if ( num == RT_TITLE_USER ) strcpy(text, "Niveaux supplémentaires"); - if ( num == RT_TITLE_PROTO ) strcpy(text, "Prototypes"); - if ( num == RT_TITLE_SETUP ) strcpy(text, "Options"); - if ( num == RT_TITLE_NAME ) strcpy(text, "Nom du joueur"); - if ( num == RT_TITLE_PERSO ) strcpy(text, "Personnalisation de votre apparence"); - if ( num == RT_TITLE_WRITE ) strcpy(text, "Enregistrement de la mission en cours"); - if ( num == RT_TITLE_READ ) strcpy(text, "Chargement d'une mission enregistrée"); - - if ( num == RT_PLAY_CHAPt ) strcpy(text, " Liste des chapitres :"); - if ( num == RT_PLAY_CHAPd ) strcpy(text, " Liste des chapitres :"); - if ( num == RT_PLAY_CHAPm ) strcpy(text, " Liste des planètes :"); - if ( num == RT_PLAY_CHAPf ) strcpy(text, " Liste des planètes :"); - if ( num == RT_PLAY_CHAPu ) strcpy(text, " Niveaux supplémentaires :"); - if ( num == RT_PLAY_CHAPp ) strcpy(text, " Liste des planètes :"); - if ( num == RT_PLAY_CHAPte ) strcpy(text, " Liste des chapitres :"); - if ( num == RT_PLAY_LISTt ) strcpy(text, " Liste des exercices du chapitre :"); - if ( num == RT_PLAY_LISTd ) strcpy(text, " Liste des défis du chapitre :"); - if ( num == RT_PLAY_LISTm ) strcpy(text, " Liste des missions du chapitre :"); - if ( num == RT_PLAY_LISTf ) strcpy(text, " Liste des jeux libres du chapitre :"); - if ( num == RT_PLAY_LISTu ) strcpy(text, " Missions du niveau :"); - if ( num == RT_PLAY_LISTp ) strcpy(text, " Liste des prototypes du chapitre :"); - if ( num == RT_PLAY_LISTk ) strcpy(text, " Liste des jeux libres du chapitre :"); - if ( num == RT_PLAY_RESUME ) strcpy(text, " Résumé :"); - - if ( num == RT_SETUP_DEVICE ) strcpy(text, " Pilotes :"); - if ( num == RT_SETUP_MODE ) strcpy(text, " Résolutions :"); - if ( num == RT_SETUP_KEY1 ) strcpy(text, "1) Cliquez d'abord sur la touche à redéfinir."); - if ( num == RT_SETUP_KEY2 ) strcpy(text, "2) Appuyez ensuite sur la nouvelle touche souhaitée."); - - if ( num == RT_PERSO_FACE ) strcpy(text, "Type de visage :"); - if ( num == RT_PERSO_GLASSES ) strcpy(text, "Lunettes :"); - if ( num == RT_PERSO_HAIR ) strcpy(text, "Couleur des cheveux :"); - if ( num == RT_PERSO_COMBI ) strcpy(text, "Couleur de la combinaison :"); - if ( num == RT_PERSO_BAND ) strcpy(text, "Couleur des bandes :"); - -#if _NEWLOOK - if ( num == RT_DIALOG_TITLE ) strcpy(text, "CeeBot"); - if ( num == RT_DIALOG_QUIT ) strcpy(text, "Voulez-vous quitter CeeBot ?"); - if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Quitter\\Quitter CeeBot"); -#else - if ( num == RT_DIALOG_TITLE ) strcpy(text, "COLOBOT"); - if ( num == RT_DIALOG_QUIT ) strcpy(text, "Voulez-vous quitter COLOBOT ?"); - if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Quitter\\Quitter COLOBOT"); -#endif - if ( num == RT_DIALOG_ABORT ) strcpy(text, "Quitter la mission ?"); - if ( num == RT_DIALOG_YES ) strcpy(text, "Abandonner\\Abandonner la mission en cours"); - if ( num == RT_DIALOG_NO ) strcpy(text, "Continuer\\Continuer la mission en cours"); - if ( num == RT_DIALOG_NOQUIT ) strcpy(text, "Continuer\\Continuer de jouer"); - if ( num == RT_DIALOG_DELOBJ ) strcpy(text, "Voulez-vous vraiment détruire le bâtiment sélectionné ?"); - if ( num == RT_DIALOG_DELGAME ) strcpy(text, "Voulez-vous détruire les sauvegardes de %s ?"); - if ( num == RT_DIALOG_YESDEL ) strcpy(text, "Détruire"); - if ( num == RT_DIALOG_NODEL ) strcpy(text, "Annuler"); - if ( num == RT_DIALOG_LOADING ) strcpy(text, "CHARGEMENT"); - - if ( num == RT_STUDIO_LISTTT ) strcpy(text, "Aide sur le mot-clé (\\key cbot;)"); - if ( num == RT_STUDIO_COMPOK ) strcpy(text, "Compilation ok (0 erreur)"); - if ( num == RT_STUDIO_PROGSTOP ) strcpy(text, "Programme terminé"); - - if ( num == RT_SATCOM_LIST ) strcpy(text, "\\b;Listes des objets\n"); - if ( num == RT_SATCOM_BOT ) strcpy(text, "\\b;Listes des robots\n"); - if ( num == RT_SATCOM_BUILDING ) strcpy(text, "\\b;Listes des bâtiments\n"); - if ( num == RT_SATCOM_FRET ) strcpy(text, "\\b;Listes des objets transportables\n"); - if ( num == RT_SATCOM_ALIEN ) strcpy(text, "\\b;Listes des ennemis\n"); - if ( num == RT_SATCOM_NULL ) strcpy(text, "\\c; (aucun)\\n;\n"); - if ( num == RT_SATCOM_ERROR1 ) strcpy(text, "\\b;Erreur\n"); - if ( num == RT_SATCOM_ERROR2 ) strcpy(text, "Liste non disponible sans \\l;radar\\u object\\radar; !\n"); - - if ( num == RT_IO_OPEN ) strcpy(text, "Ouvrir"); - if ( num == RT_IO_SAVE ) strcpy(text, "Enregistrer"); - if ( num == RT_IO_LIST ) strcpy(text, "Dossier: %s"); - if ( num == RT_IO_NAME ) strcpy(text, "Nom:"); - if ( num == RT_IO_DIR ) strcpy(text, "Dans:"); - if ( num == RT_IO_PRIVATE ) strcpy(text, "Privé\\Dossier privé"); - if ( num == RT_IO_PUBLIC ) strcpy(text, "Public\\Dossier commun à tous les joueurs"); - - if ( num == RT_GENERIC_DEV1 ) strcpy(text, "Développé par :"); - if ( num == RT_GENERIC_DEV2 ) strcpy(text, "www.epsitec.com"); -#if _SCHOOL - if ( num == RT_GENERIC_EDIT1 ) strcpy(text, " "); - if ( num == RT_GENERIC_EDIT2 ) strcpy(text, " "); -#else - //?if ( num == RT_GENERIC_EDIT1 ) strcpy(text, "Version française éditée par :"); - //?if ( num == RT_GENERIC_EDIT2 ) strcpy(text, "www.alsyd.com"); - if ( num == RT_GENERIC_EDIT1 ) strcpy(text, " "); - if ( num == RT_GENERIC_EDIT2 ) strcpy(text, " "); -#endif - - if ( num == RT_INTERFACE_REC ) strcpy(text, "Enregistreur"); - } - - if ( type == RES_EVENT ) - { - if ( num == EVENT_BUTTON_OK ) strcpy(text, "D'accord"); - if ( num == EVENT_BUTTON_CANCEL ) strcpy(text, "Annuler"); - if ( num == EVENT_BUTTON_NEXT ) strcpy(text, "Suivant"); - if ( num == EVENT_BUTTON_PREV ) strcpy(text, "Précédent"); - if ( num == EVENT_BUTTON_QUIT ) strcpy(text, "Menu (\\key quit;)"); - - if ( num == EVENT_DIALOG_OK ) strcpy(text, "D'accord"); - if ( num == EVENT_DIALOG_CANCEL ) strcpy(text, "Annuler"); - - if ( num == EVENT_INTERFACE_TRAINER) strcpy(text, "Programmation\\Exercices de programmation"); - if ( num == EVENT_INTERFACE_DEFI ) strcpy(text, "Défis\\Défis de programmation"); - if ( num == EVENT_INTERFACE_MISSION) strcpy(text, "Missions\\La grande aventure"); - if ( num == EVENT_INTERFACE_FREE ) strcpy(text, "Jeu libre\\Jeu libre sans but précis"); - if ( num == EVENT_INTERFACE_TEEN ) strcpy(text, "Jeu libre\\Jeu libre sans but précis"); - if ( num == EVENT_INTERFACE_USER ) strcpy(text, "Suppl.\\Niveaux supplémentaires"); - if ( num == EVENT_INTERFACE_PROTO ) strcpy(text, "Proto\\Prototypes en cours d'élaboration"); - if ( num == EVENT_INTERFACE_NAME ) strcpy(text, "Autre joueur\\Choix du nom du joueur"); - if ( num == EVENT_INTERFACE_SETUP ) strcpy(text, "Options\\Réglages"); - if ( num == EVENT_INTERFACE_AGAIN ) strcpy(text, "Recommencer\\Recommencer la mission au début"); - if ( num == EVENT_INTERFACE_WRITE ) strcpy(text, "Enregistrer\\Enregistrer la mission en cours"); - if ( num == EVENT_INTERFACE_READ ) strcpy(text, "Charger\\Charger une mission enregistrée"); -#if _NEWLOOK - if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Retourner dans CeeBot"); - if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Quitter\\Quitter CeeBot"); -#else - if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Retourner dans COLOBOT"); - if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Quitter\\Quitter COLOBOT"); -#endif - if ( num == EVENT_INTERFACE_BACK ) strcpy(text, "<< Retour \\Retour au niveau précédent"); - if ( num == EVENT_INTERFACE_PLAY ) strcpy(text, "Jouer ...\\Démarrer l'action"); - if ( num == EVENT_INTERFACE_SETUPd ) strcpy(text, "Affichage\\Pilote et résolution d'affichage"); - if ( num == EVENT_INTERFACE_SETUPg ) strcpy(text, "Graphique\\Options graphiques"); - if ( num == EVENT_INTERFACE_SETUPp ) strcpy(text, "Jeu\\Options de jouabilité"); - if ( num == EVENT_INTERFACE_SETUPc ) strcpy(text, "Commandes\\Touches du clavier"); - if ( num == EVENT_INTERFACE_SETUPs ) strcpy(text, "Son\\Volumes bruitages & musiques"); - if ( num == EVENT_INTERFACE_DEVICE ) strcpy(text, "Unité"); - if ( num == EVENT_INTERFACE_RESOL ) strcpy(text, "Résolution"); - if ( num == EVENT_INTERFACE_FULL ) strcpy(text, "Plein écran\\Plein écran ou fenêtré"); - if ( num == EVENT_INTERFACE_APPLY ) strcpy(text, "Appliquer les changements\\Active les changements effectués"); - - if ( num == EVENT_INTERFACE_TOTO ) strcpy(text, "Robbie\\Votre assistant"); - if ( num == EVENT_INTERFACE_SHADOW ) strcpy(text, "Ombres\\Ombres projetées au sol"); - if ( num == EVENT_INTERFACE_GROUND ) strcpy(text, "Marques sur le sol\\Marques dessinées sur le sol"); - if ( num == EVENT_INTERFACE_DIRTY ) strcpy(text, "Salissures\\Salissures des robots et bâtiments"); - if ( num == EVENT_INTERFACE_FOG ) strcpy(text, "Brouillard\\Nappes de brouillard"); - if ( num == EVENT_INTERFACE_LENS ) strcpy(text, "Rayons du soleil\\Rayons selon l'orientation"); - if ( num == EVENT_INTERFACE_SKY ) strcpy(text, "Ciel\\Ciel et nuages"); - if ( num == EVENT_INTERFACE_PLANET ) strcpy(text, "Planètes et étoiles\\Motifs mobiles dans le ciel"); - if ( num == EVENT_INTERFACE_LIGHT ) strcpy(text, "Lumières dynamiques\\Eclairages mobiles"); - if ( num == EVENT_INTERFACE_PARTI ) strcpy(text, "Quantité de particules\\Explosions, poussières, reflets, etc."); - if ( num == EVENT_INTERFACE_CLIP ) strcpy(text, "Profondeur de champ\\Distance de vue maximale"); - if ( num == EVENT_INTERFACE_DETAIL ) strcpy(text, "Détails des objets\\Qualité des objets en 3D"); - if ( num == EVENT_INTERFACE_TEXTURE) strcpy(text, "Qualité des textures\\Qualité des images"); - if ( num == EVENT_INTERFACE_GADGET ) strcpy(text, "Nb d'objets décoratifs\\Qualité d'objets non indispensables"); - if ( num == EVENT_INTERFACE_RAIN ) strcpy(text, "Particules dans l'interface\\Pluie de particules"); - if ( num == EVENT_INTERFACE_GLINT ) strcpy(text, "Reflets sur les boutons\\Boutons brillants"); - if ( num == EVENT_INTERFACE_TOOLTIP) strcpy(text, "Bulles d'aide\\Bulles explicatives"); - if ( num == EVENT_INTERFACE_MOVIES ) strcpy(text, "Séquences cinématiques\\Films avant ou après une mission"); - if ( num == EVENT_INTERFACE_NICERST) strcpy(text, "Retour animé\\Retour animé dans les exercices"); - if ( num == EVENT_INTERFACE_HIMSELF) strcpy(text, "Dégâts à soi-même\\Vos tirs infligent des dommages à vos unités"); - if ( num == EVENT_INTERFACE_SCROLL ) strcpy(text, "Défilement dans les bords\\Défilement lorsque la souris touches les bords gauche ou droite"); - if ( num == EVENT_INTERFACE_INVERTX) strcpy(text, "Inversion souris X\\Inversion de la rotation lorsque la souris touche un bord"); - if ( num == EVENT_INTERFACE_INVERTY) strcpy(text, "Inversion souris Y\\Inversion de la rotation lorsque la souris touche un bord"); - if ( num == EVENT_INTERFACE_EFFECT ) strcpy(text, "Secousses lors d'explosions\\L'écran vibre lors d'une explosion"); - if ( num == EVENT_INTERFACE_MOUSE ) strcpy(text, "Souris ombrée\\Jolie souris avec une ombre"); - if ( num == EVENT_INTERFACE_EDITMODE) strcpy(text, "Indentation automatique\\Pendant l'édition d'un programme"); - if ( num == EVENT_INTERFACE_EDITVALUE)strcpy(text, "Grande indentation\\Indente avec 2 ou 4 espaces"); - if ( num == EVENT_INTERFACE_SOLUCE4) strcpy(text, "Accès aux solutions\\Programme \"4: Solution\" dans les exercices"); - - if ( num == EVENT_INTERFACE_KDEF ) strcpy(text, "Tout réinitialiser\\Remet toutes les touches standards"); - if ( num == EVENT_INTERFACE_KLEFT ) strcpy(text, "Tourner à gauche\\Moteur à gauche"); - if ( num == EVENT_INTERFACE_KRIGHT ) strcpy(text, "Tourner à droite\\Moteur à droite"); - if ( num == EVENT_INTERFACE_KUP ) strcpy(text, "Avancer\\Moteur en avant"); - if ( num == EVENT_INTERFACE_KDOWN ) strcpy(text, "Reculer\\Moteur en arrière"); - if ( num == EVENT_INTERFACE_KGUP ) strcpy(text, "Monter\\Augmenter la puissance du réacteur"); - if ( num == EVENT_INTERFACE_KGDOWN ) strcpy(text, "Descendre\\Diminuer la puissance du réacteur"); - if ( num == EVENT_INTERFACE_KCAMERA) strcpy(text, "Changement de caméra\\Autre de point de vue"); - if ( num == EVENT_INTERFACE_KDESEL ) strcpy(text, "Sélection précédente\\Sélectionne l'objet précédent"); - if ( num == EVENT_INTERFACE_KACTION) strcpy(text, "Action standard\\Action du bouton avec le cadre rouge"); - if ( num == EVENT_INTERFACE_KNEAR ) strcpy(text, "Caméra plus proche\\Avance la caméra"); - if ( num == EVENT_INTERFACE_KAWAY ) strcpy(text, "Caméra plus loin\\Recule la caméra"); - if ( num == EVENT_INTERFACE_KNEXT ) strcpy(text, "Sélectionner l'objet suivant\\Sélectionner l'objet suivant"); - if ( num == EVENT_INTERFACE_KHUMAN ) strcpy(text, "Sélectionner le cosmonaute\\Sélectionner le cosmonaute"); - if ( num == EVENT_INTERFACE_KQUIT ) strcpy(text, "Quitter la mission en cours\\Terminer un exercice ou une mssion"); - if ( num == EVENT_INTERFACE_KHELP ) strcpy(text, "Instructions mission\\Marche à suivre"); - if ( num == EVENT_INTERFACE_KPROG ) strcpy(text, "Instructions programmation\\Explication sur la programmation"); - if ( num == EVENT_INTERFACE_KCBOT ) strcpy(text, "Instructions mot-clé\\Explication sur le mot-clé"); - if ( num == EVENT_INTERFACE_KVISIT ) strcpy(text, "Montrer le lieu d'un message\\Montrer le lieu du dernier message"); - if ( num == EVENT_INTERFACE_KSPEED10) strcpy(text, "Vitesse 1.0x\\Vitesse normale"); - if ( num == EVENT_INTERFACE_KSPEED15) strcpy(text, "Vitesse 1.5x\\Une fois et demi plus rapide"); - if ( num == EVENT_INTERFACE_KSPEED20) strcpy(text, "Vitesse 2.0x\\Deux fois plus rapide"); - if ( num == EVENT_INTERFACE_KSPEED30) strcpy(text, "Vitesse 3.0x\\Trois fois plus rapide"); - - if ( num == EVENT_INTERFACE_VOLSOUND) strcpy(text, "Bruitages :\\Volume des moteurs, voix, etc."); - if ( num == EVENT_INTERFACE_VOLMUSIC) strcpy(text, "Fond sonore :\\Volume des pistes audio du CD"); - if ( num == EVENT_INTERFACE_SOUND3D) strcpy(text, "Bruitages 3D\\Positionnement sonore dans l'espace"); - - if ( num == EVENT_INTERFACE_MIN ) strcpy(text, "Mini\\Qualité minimale (+ rapide)"); - if ( num == EVENT_INTERFACE_NORM ) strcpy(text, "Normal\\Qualité standard"); - if ( num == EVENT_INTERFACE_MAX ) strcpy(text, "Maxi\\Haute qualité (+ lent)"); - - if ( num == EVENT_INTERFACE_SILENT ) strcpy(text, "Silencieux\\Totalement silencieux"); - if ( num == EVENT_INTERFACE_NOISY ) strcpy(text, "Normal\\Niveaux normaux"); - - if ( num == EVENT_INTERFACE_JOYSTICK) strcpy(text, "Utilise un joystick\\Joystick ou clavier"); - if ( num == EVENT_INTERFACE_SOLUCE ) strcpy(text, "Accès à la solution\\Donne la solution"); - - if ( num == EVENT_INTERFACE_NEDIT ) strcpy(text, "\\Nom du joueur à créer"); - if ( num == EVENT_INTERFACE_NOK ) strcpy(text, "D'accord\\Choisir le joueur"); - if ( num == EVENT_INTERFACE_NCANCEL) strcpy(text, "Annuler\\Conserver le joueur actuel"); - if ( num == EVENT_INTERFACE_NDELETE) strcpy(text, "Supprimer le joueur\\Supprimer le joueur de la liste"); - if ( num == EVENT_INTERFACE_NLABEL ) strcpy(text, "Nom du joueur"); - - if ( num == EVENT_INTERFACE_IOWRITE) strcpy(text, "Enregistrer\\Enregistrer la mission en cours"); - if ( num == EVENT_INTERFACE_IOREAD ) strcpy(text, "Charger\\Charger la mission sélectionnée"); - if ( num == EVENT_INTERFACE_IOLIST ) strcpy(text, "Liste des missions enregistrées"); - if ( num == EVENT_INTERFACE_IOLABEL) strcpy(text, "Nom du fichier :"); - if ( num == EVENT_INTERFACE_IONAME ) strcpy(text, "Nom de la mission"); - if ( num == EVENT_INTERFACE_IOIMAGE) strcpy(text, "Vue de la mission"); - if ( num == EVENT_INTERFACE_IODELETE) strcpy(text, "Supprimer\\Supprime l'enregistrement sélectionné"); - - if ( num == EVENT_INTERFACE_PERSO ) strcpy(text, "Aspect\\Choisir votre aspect"); - if ( num == EVENT_INTERFACE_POK ) strcpy(text, "D'accord"); - if ( num == EVENT_INTERFACE_PCANCEL) strcpy(text, "Annuler"); - if ( num == EVENT_INTERFACE_PDEF ) strcpy(text, "Standard\\Remet les couleurs standards"); - if ( num == EVENT_INTERFACE_PHEAD ) strcpy(text, "Tête\\Visage et cheveux"); - if ( num == EVENT_INTERFACE_PBODY ) strcpy(text, "Corps\\Combinaison"); - if ( num == EVENT_INTERFACE_PLROT ) strcpy(text, "\\Rotation à gauche"); - if ( num == EVENT_INTERFACE_PRROT ) strcpy(text, "\\Rotation à droite"); - if ( num == EVENT_INTERFACE_PCRa ) strcpy(text, "Rouge"); - if ( num == EVENT_INTERFACE_PCGa ) strcpy(text, "Vert"); - if ( num == EVENT_INTERFACE_PCBa ) strcpy(text, "Bleu"); - if ( num == EVENT_INTERFACE_PCRb ) strcpy(text, "Rouge"); - if ( num == EVENT_INTERFACE_PCGb ) strcpy(text, "Vert"); - if ( num == EVENT_INTERFACE_PCBb ) strcpy(text, "Bleu"); - if ( num == EVENT_INTERFACE_PFACE1 ) strcpy(text, "\\Visage 1"); - if ( num == EVENT_INTERFACE_PFACE2 ) strcpy(text, "\\Visage 4"); - if ( num == EVENT_INTERFACE_PFACE3 ) strcpy(text, "\\Visage 3"); - if ( num == EVENT_INTERFACE_PFACE4 ) strcpy(text, "\\Visage 2"); - if ( num == EVENT_INTERFACE_PGLASS0) strcpy(text, "\\Pas de lunettes"); - if ( num == EVENT_INTERFACE_PGLASS1) strcpy(text, "\\Lunettes 1"); - if ( num == EVENT_INTERFACE_PGLASS2) strcpy(text, "\\Lunettes 2"); - if ( num == EVENT_INTERFACE_PGLASS3) strcpy(text, "\\Lunettes 3"); - if ( num == EVENT_INTERFACE_PGLASS4) strcpy(text, "\\Lunettes 4"); - if ( num == EVENT_INTERFACE_PGLASS5) strcpy(text, "\\Lunettes 5"); - - if ( num == EVENT_OBJECT_DESELECT ) strcpy(text, "Sélection précédente (\\key desel;)"); - if ( num == EVENT_OBJECT_LEFT ) strcpy(text, "Tourne à gauche (\\key left;)"); - if ( num == EVENT_OBJECT_RIGHT ) strcpy(text, "Tourne à droite (\\key right;)"); - if ( num == EVENT_OBJECT_UP ) strcpy(text, "Avance (\\key up;)"); - if ( num == EVENT_OBJECT_DOWN ) strcpy(text, "Recule (\\key down;)"); - if ( num == EVENT_OBJECT_GASUP ) strcpy(text, "Monte (\\key gup;)"); - if ( num == EVENT_OBJECT_GASDOWN ) strcpy(text, "Descend (\\key gdown;)"); - if ( num == EVENT_OBJECT_HTAKE ) strcpy(text, "Prend ou dépose (\\key action;)"); - if ( num == EVENT_OBJECT_MTAKE ) strcpy(text, "Prend ou dépose (\\key action;)"); - if ( num == EVENT_OBJECT_MFRONT ) strcpy(text, "..devant"); - if ( num == EVENT_OBJECT_MBACK ) strcpy(text, "..derrière"); - if ( num == EVENT_OBJECT_MPOWER ) strcpy(text, "..pile"); - if ( num == EVENT_OBJECT_BHELP ) strcpy(text, "Instructions sur la mission (\\key help;)"); - if ( num == EVENT_OBJECT_BTAKEOFF ) strcpy(text, "Décolle pour terminer la mission"); - if ( num == EVENT_OBJECT_BDERRICK ) strcpy(text, "Construit un derrick"); - if ( num == EVENT_OBJECT_BSTATION ) strcpy(text, "Construit une station"); - if ( num == EVENT_OBJECT_BFACTORY ) strcpy(text, "Construit une fabrique de robots"); - if ( num == EVENT_OBJECT_BREPAIR ) strcpy(text, "Construit un centre de réparation"); - if ( num == EVENT_OBJECT_BCONVERT ) strcpy(text, "Construit un convertisseur"); - if ( num == EVENT_OBJECT_BTOWER ) strcpy(text, "Construit une tour"); - if ( num == EVENT_OBJECT_BRESEARCH ) strcpy(text, "Construit un centre de recherches"); - if ( num == EVENT_OBJECT_BRADAR ) strcpy(text, "Construit un radar"); - if ( num == EVENT_OBJECT_BENERGY ) strcpy(text, "Construit une fabrique de piles"); - if ( num == EVENT_OBJECT_BLABO ) strcpy(text, "Construit un laboratoire"); - if ( num == EVENT_OBJECT_BNUCLEAR ) strcpy(text, "Construit une centrale nucléaire"); - if ( num == EVENT_OBJECT_BPARA ) strcpy(text, "Construit un paratonnerre"); - if ( num == EVENT_OBJECT_BINFO ) strcpy(text, "Construit une borne d'information"); - if ( num == EVENT_OBJECT_GFLAT ) strcpy(text, "Montre si le sol est plat"); - if ( num == EVENT_OBJECT_FCREATE ) strcpy(text, "Pose un drapeau de couleur"); - if ( num == EVENT_OBJECT_FDELETE ) strcpy(text, "Enlève un drapeau"); - if ( num == EVENT_OBJECT_FCOLORb ) strcpy(text, "\\Drapeaux bleus"); - if ( num == EVENT_OBJECT_FCOLORr ) strcpy(text, "\\Drapeaux rouges"); - if ( num == EVENT_OBJECT_FCOLORg ) strcpy(text, "\\Drapeaux verts"); - if ( num == EVENT_OBJECT_FCOLORy ) strcpy(text, "\\Drapeaux jaunes"); - if ( num == EVENT_OBJECT_FCOLORv ) strcpy(text, "\\Drapeaux violets"); - if ( num == EVENT_OBJECT_FACTORYfa ) strcpy(text, "Fabrique un déménageur volant"); - if ( num == EVENT_OBJECT_FACTORYta ) strcpy(text, "Fabrique un déménageur à chenilles"); - if ( num == EVENT_OBJECT_FACTORYwa ) strcpy(text, "Fabrique un déménageur à roues"); - if ( num == EVENT_OBJECT_FACTORYia ) strcpy(text, "Fabrique un déménageur à pattes"); - if ( num == EVENT_OBJECT_FACTORYfc ) strcpy(text, "Fabrique un shooter volant"); - if ( num == EVENT_OBJECT_FACTORYtc ) strcpy(text, "Fabrique un shooter à chenilles"); - if ( num == EVENT_OBJECT_FACTORYwc ) strcpy(text, "Fabrique un shooter à roues"); - if ( num == EVENT_OBJECT_FACTORYic ) strcpy(text, "Fabrique un shooter à pattes"); - if ( num == EVENT_OBJECT_FACTORYfi ) strcpy(text, "Fabrique un orgaShooter volant"); - if ( num == EVENT_OBJECT_FACTORYti ) strcpy(text, "Fabrique un orgaShooter à chenilles"); - if ( num == EVENT_OBJECT_FACTORYwi ) strcpy(text, "Fabrique un orgaShooter à roues"); - if ( num == EVENT_OBJECT_FACTORYii ) strcpy(text, "Fabrique un orgaShooter à pattes"); - if ( num == EVENT_OBJECT_FACTORYfs ) strcpy(text, "Fabrique un renifleur volant"); - if ( num == EVENT_OBJECT_FACTORYts ) strcpy(text, "Fabrique un renifleur à chenilles"); - if ( num == EVENT_OBJECT_FACTORYws ) strcpy(text, "Fabrique un renifleur à roues"); - if ( num == EVENT_OBJECT_FACTORYis ) strcpy(text, "Fabrique un renifleur à pattes"); - if ( num == EVENT_OBJECT_FACTORYrt ) strcpy(text, "Fabrique un robot secoueur"); - if ( num == EVENT_OBJECT_FACTORYrc ) strcpy(text, "Fabrique un robot phazer"); - if ( num == EVENT_OBJECT_FACTORYrr ) strcpy(text, "Fabrique un robot recycleur"); - if ( num == EVENT_OBJECT_FACTORYrs ) strcpy(text, "Fabrique un robot bouclier"); - if ( num == EVENT_OBJECT_FACTORYsa ) strcpy(text, "Fabrique un robot sous-marin"); - if ( num == EVENT_OBJECT_RTANK ) strcpy(text, "Recherche les chenilles"); - if ( num == EVENT_OBJECT_RFLY ) strcpy(text, "Recherche les robots volants"); - if ( num == EVENT_OBJECT_RTHUMP ) strcpy(text, "Recherche le secoueur"); - if ( num == EVENT_OBJECT_RCANON ) strcpy(text, "Recherche le canon shooter"); - if ( num == EVENT_OBJECT_RTOWER ) strcpy(text, "Recherche la tour de défense"); - if ( num == EVENT_OBJECT_RPHAZER ) strcpy(text, "Recherche le canon phazer"); - if ( num == EVENT_OBJECT_RSHIELD ) strcpy(text, "Recherche le bouclier"); - if ( num == EVENT_OBJECT_RATOMIC ) strcpy(text, "Recherche le nucléaire"); - if ( num == EVENT_OBJECT_RiPAW ) strcpy(text, "Recherche les pattes"); - if ( num == EVENT_OBJECT_RiGUN ) strcpy(text, "Recherche le canon orgaShooter"); - if ( num == EVENT_OBJECT_RESET ) strcpy(text, "Remet au départ"); - if ( num == EVENT_OBJECT_SEARCH ) strcpy(text, "Cherche (\\key action;)"); - if ( num == EVENT_OBJECT_TERRAFORM ) strcpy(text, "Secoue (\\key action;)"); - if ( num == EVENT_OBJECT_FIRE ) strcpy(text, "Tir (\\key action;)"); - if ( num == EVENT_OBJECT_RECOVER ) strcpy(text, "Recycle (\\key action;)"); - if ( num == EVENT_OBJECT_BEGSHIELD ) strcpy(text, "Déploie le bouclier (\\key action;)"); - if ( num == EVENT_OBJECT_ENDSHIELD ) strcpy(text, "Stoppe le bouclier (\\key action;)"); - if ( num == EVENT_OBJECT_DIMSHIELD ) strcpy(text, "Rayon du bouclier"); - if ( num == EVENT_OBJECT_PROGRUN ) strcpy(text, "Exécute le programme sélectionné"); - if ( num == EVENT_OBJECT_PROGEDIT ) strcpy(text, "Edite le programme sélectionné"); - if ( num == EVENT_OBJECT_INFOOK ) strcpy(text, "\\Mettre le SatCom en veille"); - if ( num == EVENT_OBJECT_DELETE ) strcpy(text, "Démolit le bâtiment"); - if ( num == EVENT_OBJECT_GENERGY ) strcpy(text, "Niveau d'énergie"); - if ( num == EVENT_OBJECT_GSHIELD ) strcpy(text, "Niveau du bouclier"); - if ( num == EVENT_OBJECT_GRANGE ) strcpy(text, "Température du réacteur"); - if ( num == EVENT_OBJECT_GPROGRESS ) strcpy(text, "Travail en cours ..."); - if ( num == EVENT_OBJECT_GRADAR ) strcpy(text, "Nombre d'insectes détectés"); - if ( num == EVENT_OBJECT_GINFO ) strcpy(text, "Informations diffusées"); - if ( num == EVENT_OBJECT_COMPASS ) strcpy(text, "Boussole"); -//? if ( num == EVENT_OBJECT_MAP ) strcpy(text, "Mini-carte"); - if ( num == EVENT_OBJECT_MAPZOOM ) strcpy(text, "Zoom mini-carte"); - if ( num == EVENT_OBJECT_CAMERA ) strcpy(text, "Caméra (\\key camera;)"); - if ( num == EVENT_OBJECT_CAMERAleft) strcpy(text, "Caméra à gauche"); - if ( num == EVENT_OBJECT_CAMERAright) strcpy(text, "Caméra à droite"); - if ( num == EVENT_OBJECT_CAMERAnear) strcpy(text, "Caméra plus proche"); - if ( num == EVENT_OBJECT_CAMERAaway) strcpy(text, "Caméra plus loin"); - if ( num == EVENT_OBJECT_HELP ) strcpy(text, "Instructions sur la sélection"); - if ( num == EVENT_OBJECT_SOLUCE ) strcpy(text, "Donne la solution"); - if ( num == EVENT_OBJECT_SHORTCUT00) strcpy(text, "Permute robots <-> bâtiments"); - if ( num == EVENT_OBJECT_LIMIT ) strcpy(text, "Montre le rayon d'action"); - if ( num == EVENT_OBJECT_PEN0 ) strcpy(text, "\\Relève le crayon"); - if ( num == EVENT_OBJECT_PEN1 ) strcpy(text, "\\Abaisse le crayon noir"); - if ( num == EVENT_OBJECT_PEN2 ) strcpy(text, "\\Abaisse le crayon jaune"); - if ( num == EVENT_OBJECT_PEN3 ) strcpy(text, "\\Abaisse le crayon orange"); - if ( num == EVENT_OBJECT_PEN4 ) strcpy(text, "\\Abaisse le crayon rouge"); - if ( num == EVENT_OBJECT_PEN5 ) strcpy(text, "\\Abaisse le crayon violet"); - if ( num == EVENT_OBJECT_PEN6 ) strcpy(text, "\\Abaisse le crayon bleu"); - if ( num == EVENT_OBJECT_PEN7 ) strcpy(text, "\\Abaisse le crayon vert"); - if ( num == EVENT_OBJECT_PEN8 ) strcpy(text, "\\Abaisse le crayon brun"); - if ( num == EVENT_OBJECT_REC ) strcpy(text, "\\Démarre l'enregistrement"); - if ( num == EVENT_OBJECT_STOP ) strcpy(text, "\\Stoppe l'enregistrement"); - if ( num == EVENT_DT_VISIT0 || - num == EVENT_DT_VISIT1 || - num == EVENT_DT_VISIT2 || - num == EVENT_DT_VISIT3 || - num == EVENT_DT_VISIT4 ) strcpy(text, "Montre l'endroit"); - if ( num == EVENT_DT_END ) strcpy(text, "Continuer"); - if ( num == EVENT_CMD ) strcpy(text, "Console de commande"); - if ( num == EVENT_SPEED ) strcpy(text, "Vitesse du jeu"); - - if ( num == EVENT_HYPER_PREV ) strcpy(text, "Page précédente"); - if ( num == EVENT_HYPER_NEXT ) strcpy(text, "Page suivante"); - if ( num == EVENT_HYPER_HOME ) strcpy(text, "Page initiale"); - if ( num == EVENT_HYPER_COPY ) strcpy(text, "Copier"); - if ( num == EVENT_HYPER_SIZE1 ) strcpy(text, "Taille 1"); - if ( num == EVENT_HYPER_SIZE2 ) strcpy(text, "Taille 2"); - if ( num == EVENT_HYPER_SIZE3 ) strcpy(text, "Taille 3"); - if ( num == EVENT_HYPER_SIZE4 ) strcpy(text, "Taille 4"); - if ( num == EVENT_HYPER_SIZE5 ) strcpy(text, "Taille 5"); - if ( num == EVENT_SATCOM_HUSTON ) strcpy(text, "Instructions de Houston"); -#if _TEEN - if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Dictionnaire anglais-français"); -#else - if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Rapport du satellite"); -#endif - if ( num == EVENT_SATCOM_LOADING ) strcpy(text, "Programmes envoyés par Houston"); - if ( num == EVENT_SATCOM_OBJECT ) strcpy(text, "Liste des objets"); - if ( num == EVENT_SATCOM_PROG ) strcpy(text, "Aide à la programmation"); - if ( num == EVENT_SATCOM_SOLUCE ) strcpy(text, "Solution"); - - if ( num == EVENT_STUDIO_OK ) strcpy(text, "D'accord\\Compiler le programme"); - if ( num == EVENT_STUDIO_CANCEL ) strcpy(text, "Annuler\\Annuler toutes les modifications"); - if ( num == EVENT_STUDIO_NEW ) strcpy(text, "Nouveau"); - if ( num == EVENT_STUDIO_OPEN ) strcpy(text, "Ouvrir (Ctrl+o)"); - if ( num == EVENT_STUDIO_SAVE ) strcpy(text, "Enregistrer (Ctrl+s)"); - if ( num == EVENT_STUDIO_UNDO ) strcpy(text, "Annuler (Ctrl+z)"); - if ( num == EVENT_STUDIO_CUT ) strcpy(text, "Couper (Ctrl+x)"); - if ( num == EVENT_STUDIO_COPY ) strcpy(text, "Copier (Ctrl+c)"); - if ( num == EVENT_STUDIO_PASTE ) strcpy(text, "Coller (Ctrl+v)"); - if ( num == EVENT_STUDIO_SIZE ) strcpy(text, "Taille des caractères"); - if ( num == EVENT_STUDIO_TOOL ) strcpy(text, "Instructions (\\key help;)"); - if ( num == EVENT_STUDIO_HELP ) strcpy(text, "Aide à la programmation (\\key prog;)"); - if ( num == EVENT_STUDIO_COMPILE ) strcpy(text, "Compiler"); - if ( num == EVENT_STUDIO_RUN ) strcpy(text, "Démarrer/stopper"); - if ( num == EVENT_STUDIO_REALTIME ) strcpy(text, "Pause/continuer"); - if ( num == EVENT_STUDIO_STEP ) strcpy(text, "Un pas"); - } - - if ( type == RES_OBJECT ) - { - if ( num == OBJECT_PORTICO ) strcpy(text, "Portique"); - if ( num == OBJECT_BASE ) strcpy(text, "Vaisseau spatial"); - if ( num == OBJECT_DERRICK ) strcpy(text, "Derrick"); - if ( num == OBJECT_FACTORY ) strcpy(text, "Fabrique de robots"); - if ( num == OBJECT_REPAIR ) strcpy(text, "Centre de réparation"); - if ( num == OBJECT_DESTROYER ) strcpy(text, "Destructeur"); - if ( num == OBJECT_STATION ) strcpy(text, "Station de recharge"); - if ( num == OBJECT_CONVERT ) strcpy(text, "Conversion minerai en titanium"); - if ( num == OBJECT_TOWER ) strcpy(text, "Tour de défense"); - if ( num == OBJECT_NEST ) strcpy(text, "Nid"); - if ( num == OBJECT_RESEARCH ) strcpy(text, "Centre de recherches"); - if ( num == OBJECT_RADAR ) strcpy(text, "Radar"); - if ( num == OBJECT_INFO ) strcpy(text, "Borne d'information"); -#if _TEEN - if ( num == OBJECT_ENERGY ) strcpy(text, "Désintégrateur"); -#else - if ( num == OBJECT_ENERGY ) strcpy(text, "Fabrique de piles"); -#endif - if ( num == OBJECT_LABO ) strcpy(text, "Laboratoire de matières organiques"); - if ( num == OBJECT_NUCLEAR ) strcpy(text, "Centrale nucléaire"); - if ( num == OBJECT_PARA ) strcpy(text, "Paratonnerre"); - if ( num == OBJECT_SAFE ) strcpy(text, "Coffre-fort"); - if ( num == OBJECT_HUSTON ) strcpy(text, "Centre de contrôle"); - if ( num == OBJECT_TARGET1 ) strcpy(text, "Cible"); - if ( num == OBJECT_TARGET2 ) strcpy(text, "Cible"); - if ( num == OBJECT_START ) strcpy(text, "Départ"); - if ( num == OBJECT_END ) strcpy(text, "But"); - if ( num == OBJECT_STONE ) strcpy(text, "Minerai de titanium"); - if ( num == OBJECT_URANIUM ) strcpy(text, "Minerai d'uranium"); - if ( num == OBJECT_BULLET ) strcpy(text, "Matière organique"); - if ( num == OBJECT_METAL ) strcpy(text, "Titanium"); - if ( num == OBJECT_POWER ) strcpy(text, "Pile normale"); - if ( num == OBJECT_ATOMIC ) strcpy(text, "Pile nucléaire"); - if ( num == OBJECT_BBOX ) strcpy(text, "Boîte noire"); - if ( num == OBJECT_KEYa ) strcpy(text, "Clé A"); - if ( num == OBJECT_KEYb ) strcpy(text, "Clé B"); - if ( num == OBJECT_KEYc ) strcpy(text, "Clé C"); - if ( num == OBJECT_KEYd ) strcpy(text, "Clé D"); - if ( num == OBJECT_TNT ) strcpy(text, "Explosif"); - if ( num == OBJECT_BOMB ) strcpy(text, "Mine fixe"); - if ( num == OBJECT_BAG ) strcpy(text, "Sac de survie"); - if ( num == OBJECT_WAYPOINT ) strcpy(text, "Indicateur"); - if ( num == OBJECT_FLAGb ) strcpy(text, "Drapeau bleu"); - if ( num == OBJECT_FLAGr ) strcpy(text, "Drapeau rouge"); - if ( num == OBJECT_FLAGg ) strcpy(text, "Drapeau vert"); - if ( num == OBJECT_FLAGy ) strcpy(text, "Drapeau jaune"); - if ( num == OBJECT_FLAGv ) strcpy(text, "Drapeau violet"); - if ( num == OBJECT_MARKPOWER ) strcpy(text, "Emplacement pour station"); - if ( num == OBJECT_MARKURANIUM ) strcpy(text, "Emplacement pour derrick (uranium)"); - if ( num == OBJECT_MARKKEYa ) strcpy(text, "Emplacement pour derrick (clé A)"); - if ( num == OBJECT_MARKKEYb ) strcpy(text, "Emplacement pour derrick (clé B)"); - if ( num == OBJECT_MARKKEYc ) strcpy(text, "Emplacement pour derrick (clé C)"); - if ( num == OBJECT_MARKKEYd ) strcpy(text, "Emplacement pour derrick (clé D)"); - if ( num == OBJECT_MARKSTONE ) strcpy(text, "Emplacement pour derrick (titanium)"); - if ( num == OBJECT_MOBILEft ) strcpy(text, "Robot d'entraînement"); - if ( num == OBJECT_MOBILEtt ) strcpy(text, "Robot d'entraînement"); - if ( num == OBJECT_MOBILEwt ) strcpy(text, "Robot d'entraînement"); - if ( num == OBJECT_MOBILEit ) strcpy(text, "Robot d'entraînement"); - if ( num == OBJECT_MOBILEfa ) strcpy(text, "Robot déménageur"); - if ( num == OBJECT_MOBILEta ) strcpy(text, "Robot déménageur"); - if ( num == OBJECT_MOBILEwa ) strcpy(text, "Robot déménageur"); - if ( num == OBJECT_MOBILEia ) strcpy(text, "Robot déménageur"); - if ( num == OBJECT_MOBILEfc ) strcpy(text, "Robot shooter"); - if ( num == OBJECT_MOBILEtc ) strcpy(text, "Robot shooter"); - if ( num == OBJECT_MOBILEwc ) strcpy(text, "Robot shooter"); - if ( num == OBJECT_MOBILEic ) strcpy(text, "Robot shooter"); - if ( num == OBJECT_MOBILEfi ) strcpy(text, "Robot orgaShooter"); - if ( num == OBJECT_MOBILEti ) strcpy(text, "Robot orgaShooter"); - if ( num == OBJECT_MOBILEwi ) strcpy(text, "Robot orgaShooter"); - if ( num == OBJECT_MOBILEii ) strcpy(text, "Robot orgaShooter"); - if ( num == OBJECT_MOBILEfs ) strcpy(text, "Robot renifleur"); - if ( num == OBJECT_MOBILEts ) strcpy(text, "Robot renifleur"); - if ( num == OBJECT_MOBILEws ) strcpy(text, "Robot renifleur"); - if ( num == OBJECT_MOBILEis ) strcpy(text, "Robot renifleur"); - if ( num == OBJECT_MOBILErt ) strcpy(text, "Robot secoueur"); - if ( num == OBJECT_MOBILErc ) strcpy(text, "Robot phazer"); - if ( num == OBJECT_MOBILErr ) strcpy(text, "Robot recycleur"); - if ( num == OBJECT_MOBILErs ) strcpy(text, "Robot bouclier"); - if ( num == OBJECT_MOBILEsa ) strcpy(text, "Robot sous-marin"); - if ( num == OBJECT_MOBILEtg ) strcpy(text, "Cible d'entraînement"); - if ( num == OBJECT_MOBILEdr ) strcpy(text, "Robot dessinateur"); - if ( num == OBJECT_HUMAN ) strcpy(text, g_gamerName); - if ( num == OBJECT_TECH ) strcpy(text, "Technicien"); - if ( num == OBJECT_TOTO ) strcpy(text, "Robbie"); - if ( num == OBJECT_MOTHER ) strcpy(text, "Pondeuse"); - if ( num == OBJECT_ANT ) strcpy(text, "Fourmi"); - if ( num == OBJECT_SPIDER ) strcpy(text, "Araignée"); - if ( num == OBJECT_BEE ) strcpy(text, "Guêpe"); - if ( num == OBJECT_WORM ) strcpy(text, "Ver"); - if ( num == OBJECT_EGG ) strcpy(text, "Oeuf"); - if ( num == OBJECT_RUINmobilew1 ) strcpy(text, "Epave de robot"); - if ( num == OBJECT_RUINmobilew2 ) strcpy(text, "Epave de robot"); - if ( num == OBJECT_RUINmobilet1 ) strcpy(text, "Epave de robot"); - if ( num == OBJECT_RUINmobilet2 ) strcpy(text, "Epave de robot"); - if ( num == OBJECT_RUINmobiler1 ) strcpy(text, "Epave de robot"); - if ( num == OBJECT_RUINmobiler2 ) strcpy(text, "Epave de robot"); - if ( num == OBJECT_RUINfactory ) strcpy(text, "Bâtiment en ruine"); - if ( num == OBJECT_RUINdoor ) strcpy(text, "Bâtiment en ruine"); - if ( num == OBJECT_RUINsupport ) strcpy(text, "Déchet"); - if ( num == OBJECT_RUINradar ) strcpy(text, "Bâtiment en ruine"); - if ( num == OBJECT_RUINconvert ) strcpy(text, "Bâtiment en ruine"); - if ( num == OBJECT_RUINbase ) strcpy(text, "Epave de vaisseau spatial"); - if ( num == OBJECT_RUINhead ) strcpy(text, "Epave de vaisseau spatial"); - if ( num == OBJECT_APOLLO1 || - num == OBJECT_APOLLO3 || - num == OBJECT_APOLLO4 || - num == OBJECT_APOLLO5 ) strcpy(text, "Vestige d'une mission Apollo"); - if ( num == OBJECT_APOLLO2 ) strcpy(text, "Lunar Roving Vehicle"); - } - - if ( type == RES_ERR ) - { - strcpy(text, "Erreur"); - if ( num == ERR_CMD ) strcpy(text, "Commande inconnue"); -#if _NEWLOOK - if ( num == ERR_INSTALL ) strcpy(text, "CeeBot n'est pas installé."); - if ( num == ERR_NOCD ) strcpy(text, "Veuillez mettre le CD de CeeBot\net relancer le jeu."); -#else - if ( num == ERR_INSTALL ) strcpy(text, "COLOBOT n'est pas installé."); - if ( num == ERR_NOCD ) strcpy(text, "Veuillez mettre le CD de COLOBOT\net relancer le jeu."); -#endif - if ( num == ERR_MANIP_VEH ) strcpy(text, "Robot inadapté"); - if ( num == ERR_MANIP_FLY ) strcpy(text, "Impossible en vol"); - if ( num == ERR_MANIP_BUSY ) strcpy(text, "Porte déjà quelque chose"); - if ( num == ERR_MANIP_NIL ) strcpy(text, "Rien à prendre"); - if ( num == ERR_MANIP_MOTOR ) strcpy(text, "Impossible en mouvement"); - if ( num == ERR_MANIP_OCC ) strcpy(text, "Emplacement occupé"); - if ( num == ERR_MANIP_FRIEND ) strcpy(text, "Pas d'autre robot"); - if ( num == ERR_MANIP_RADIO ) strcpy(text, "Vous ne pouvez pas transporter un objet radioactif"); - if ( num == ERR_MANIP_WATER ) strcpy(text, "Vous ne pouvez pas transporter un objet sous l'eau"); - if ( num == ERR_MANIP_EMPTY ) strcpy(text, "Rien à déposer"); - if ( num == ERR_BUILD_FLY ) strcpy(text, "Impossible en vol"); - if ( num == ERR_BUILD_WATER ) strcpy(text, "Impossible sous l'eau"); - if ( num == ERR_BUILD_ENERGY ) strcpy(text, "Pas assez d'énergie"); - if ( num == ERR_BUILD_METALAWAY ) strcpy(text, "Titanium trop loin"); - if ( num == ERR_BUILD_METALNEAR ) strcpy(text, "Titanium trop proche"); - if ( num == ERR_BUILD_METALINEX ) strcpy(text, "Titanium inexistant"); - if ( num == ERR_BUILD_FLAT ) strcpy(text, "Sol pas assez plat"); - if ( num == ERR_BUILD_FLATLIT ) strcpy(text, "Sol plat pas assez grand"); - if ( num == ERR_BUILD_BUSY ) strcpy(text, "Emplacement occupé"); - if ( num == ERR_BUILD_BASE ) strcpy(text, "Trop proche du vaisseau spatial"); - if ( num == ERR_BUILD_NARROW ) strcpy(text, "Trop proche d'un bâtiment"); - if ( num == ERR_BUILD_MOTOR ) strcpy(text, "Impossible en mouvement"); - if ( num == ERR_SEARCH_FLY ) strcpy(text, "Impossible en vol"); - if ( num == ERR_SEARCH_VEH ) strcpy(text, "Robot inadapté"); - if ( num == ERR_SEARCH_MOTOR ) strcpy(text, "Impossible en mouvement"); - if ( num == ERR_TERRA_VEH ) strcpy(text, "Robot inadapté"); - if ( num == ERR_TERRA_ENERGY ) strcpy(text, "Pas assez d'énergie"); - if ( num == ERR_TERRA_FLOOR ) strcpy(text, "Terrain inadapté"); - if ( num == ERR_TERRA_BUILDING ) strcpy(text, "Bâtiment trop proche"); - if ( num == ERR_TERRA_OBJECT ) strcpy(text, "Objet trop proche"); - if ( num == ERR_RECOVER_VEH ) strcpy(text, "Robot inadapté"); - if ( num == ERR_RECOVER_ENERGY ) strcpy(text, "Pas assez d'énergie"); - if ( num == ERR_RECOVER_NULL ) strcpy(text, "Rien à recycler"); - if ( num == ERR_SHIELD_VEH ) strcpy(text, "Robot inadapté"); - if ( num == ERR_SHIELD_ENERGY ) strcpy(text, "Plus d'énergie"); - if ( num == ERR_MOVE_IMPOSSIBLE ) strcpy(text, "Déplacement impossible"); - if ( num == ERR_FIND_IMPOSSIBLE ) strcpy(text, "Objet n'existe pas"); - if ( num == ERR_GOTO_IMPOSSIBLE ) strcpy(text, "Chemin introuvable"); - if ( num == ERR_GOTO_ITER ) strcpy(text, "Position inaccessible"); - if ( num == ERR_GOTO_BUSY ) strcpy(text, "Destination occupée"); - if ( num == ERR_FIRE_VEH ) strcpy(text, "Robot inadapté"); - if ( num == ERR_FIRE_ENERGY ) strcpy(text, "Pas assez d'énergie"); - if ( num == ERR_FIRE_FLY ) strcpy(text, "Impossible en vol"); - if ( num == ERR_CONVERT_EMPTY ) strcpy(text, "Pas de minerai de titanium à convertir"); - if ( num == ERR_DERRICK_NULL ) strcpy(text, "Pas de minerai en sous-sol"); - if ( num == ERR_STATION_NULL ) strcpy(text, "Pas d'énergie en sous-sol"); - if ( num == ERR_TOWER_POWER ) strcpy(text, "Pas de pile"); - if ( num == ERR_TOWER_ENERGY ) strcpy(text, "Plus d'énergie"); - if ( num == ERR_RESEARCH_POWER ) strcpy(text, "Pas de pile"); - if ( num == ERR_RESEARCH_ENERGY ) strcpy(text, "Plus assez d'énergie"); - if ( num == ERR_RESEARCH_TYPE ) strcpy(text, "Pas le bon type de pile"); - if ( num == ERR_RESEARCH_ALREADY) strcpy(text, "Recherche déjà effectuée"); - if ( num == ERR_ENERGY_NULL ) strcpy(text, "Pas d'énergie en sous-sol"); - if ( num == ERR_ENERGY_LOW ) strcpy(text, "Pas encore assez d'énergie"); - if ( num == ERR_ENERGY_EMPTY ) strcpy(text, "Pas de titanium à transformer"); - if ( num == ERR_ENERGY_BAD ) strcpy(text, "Ne transforme que le titanium"); - if ( num == ERR_BASE_DLOCK ) strcpy(text, "Portes bloquées par un robot ou un objet"); - if ( num == ERR_BASE_DHUMAN ) strcpy(text, "Vous devez embarquer pour pouvoir décoller"); - if ( num == ERR_LABO_NULL ) strcpy(text, "Rien à analyser"); - if ( num == ERR_LABO_BAD ) strcpy(text, "N'analyse que la matière organique"); - if ( num == ERR_LABO_ALREADY ) strcpy(text, "Analyse déjà effectuée"); - if ( num == ERR_NUCLEAR_NULL ) strcpy(text, "Pas d'énergie en sous-sol"); - if ( num == ERR_NUCLEAR_LOW ) strcpy(text, "Pas encore assez d'énergie"); - if ( num == ERR_NUCLEAR_EMPTY ) strcpy(text, "Pas d'uranium à transformer"); - if ( num == ERR_NUCLEAR_BAD ) strcpy(text, "Ne transforme que l'uranium"); - if ( num == ERR_FACTORY_NULL ) strcpy(text, "Pas de titanium"); - if ( num == ERR_FACTORY_NEAR ) strcpy(text, "Quelque chose est trop proche"); - if ( num == ERR_RESET_NEAR ) strcpy(text, "Emplacement occupé"); - if ( num == ERR_INFO_NULL ) strcpy(text, "Pas trouvé de borne d'information"); - if ( num == ERR_VEH_VIRUS ) strcpy(text, "Un programme est infecté par un virus"); - if ( num == ERR_BAT_VIRUS ) strcpy(text, "Infecté par un virus, ne fonctionne plus temporairement"); - if ( num == ERR_VEH_POWER ) strcpy(text, "Pas de pile"); - if ( num == ERR_VEH_ENERGY ) strcpy(text, "Plus d'énergie"); - if ( num == ERR_FLAG_FLY ) strcpy(text, "Impossible en vol"); - if ( num == ERR_FLAG_WATER ) strcpy(text, "Impossible en nageant"); - if ( num == ERR_FLAG_MOTOR ) strcpy(text, "Impossible en mouvement"); - if ( num == ERR_FLAG_BUSY ) strcpy(text, "Impossible en portant un objet"); - if ( num == ERR_FLAG_CREATE ) strcpy(text, "Trop de drapeaux de cette couleur (maximum 5)"); - if ( num == ERR_FLAG_PROXY ) strcpy(text, "Trop proche d'un drapeau existant"); - if ( num == ERR_FLAG_DELETE ) strcpy(text, "Aucun drapeau à proximité"); - if ( num == ERR_MISSION_NOTERM ) strcpy(text, "La misssion n'est pas terminée (appuyez sur \\key help; pour plus de détails)"); - if ( num == ERR_DELETEMOBILE ) strcpy(text, "Robot détruit"); - if ( num == ERR_DELETEBUILDING ) strcpy(text, "Bâtiment détruit"); - if ( num == ERR_TOOMANY ) strcpy(text, "Création impossible, il y a trop d'objets"); - if ( num == ERR_OBLIGATORYTOKEN ) strcpy(text, "Il manque \"%s\" dans le programme"); - if ( num == ERR_PROHIBITEDTOKEN ) strcpy(text, "Interdit dans cet exercice"); - - if ( num == INFO_BUILD ) strcpy(text, "Bâtiment terminé"); - if ( num == INFO_CONVERT ) strcpy(text, "Titanium disponible"); - if ( num == INFO_RESEARCH ) strcpy(text, "Recherche terminée"); - if ( num == INFO_RESEARCHTANK ) strcpy(text, "Fabrication d'un robot à chenilles possible"); - if ( num == INFO_RESEARCHFLY ) strcpy(text, "Il est possible de voler avec les touches (\\key gup;) et (\\key gdown;)"); - if ( num == INFO_RESEARCHTHUMP ) strcpy(text, "Fabrication d'un robot secoueur possible"); - if ( num == INFO_RESEARCHCANON ) strcpy(text, "Fabrication de robots shooter possible"); - if ( num == INFO_RESEARCHTOWER ) strcpy(text, "Construction d'une tour de défense possible"); - if ( num == INFO_RESEARCHPHAZER ) strcpy(text, "Fabrication d'un robot phazer possible"); - if ( num == INFO_RESEARCHSHIELD ) strcpy(text, "Fabrication d'un robot bouclier possible"); - if ( num == INFO_RESEARCHATOMIC ) strcpy(text, "Construction d'une centrale nucléaire possible"); - if ( num == INFO_FACTORY ) strcpy(text, "Nouveau robot disponible"); - if ( num == INFO_LABO ) strcpy(text, "Analyse terminée"); - if ( num == INFO_ENERGY ) strcpy(text, "Pile disponible"); - if ( num == INFO_NUCLEAR ) strcpy(text, "Pile nucléaire disponible"); - if ( num == INFO_FINDING ) strcpy(text, "Vous avez trouvé un objet utilisable"); - if ( num == INFO_MARKPOWER ) strcpy(text, "Emplacement pour station trouvé"); - if ( num == INFO_MARKURANIUM ) strcpy(text, "Emplacement pour derrick trouvé"); - if ( num == INFO_MARKSTONE ) strcpy(text, "Emplacement pour derrick trouvé"); - if ( num == INFO_MARKKEYa ) strcpy(text, "Emplacement pour derrick trouvé"); - if ( num == INFO_MARKKEYb ) strcpy(text, "Emplacement pour derrick trouvé"); - if ( num == INFO_MARKKEYc ) strcpy(text, "Emplacement pour derrick trouvé"); - if ( num == INFO_MARKKEYd ) strcpy(text, "Emplacement pour derrick trouvé"); - if ( num == INFO_WIN ) strcpy(text, "<<< Bravo, mission terminée >>>"); - if ( num == INFO_LOST ) strcpy(text, "<<< Désolé, mission échouée >>>"); - if ( num == INFO_LOSTq ) strcpy(text, "<<< Désolé, mission échouée >>>"); - if ( num == INFO_WRITEOK ) strcpy(text, "Enregistrement effectué"); - if ( num == INFO_DELETEPATH ) strcpy(text, "Indicateur atteint"); - if ( num == INFO_DELETEMOTHER ) strcpy(text, "Pondeuse mortellement touchée"); - if ( num == INFO_DELETEANT ) strcpy(text, "Fourmi mortellement touchée"); - if ( num == INFO_DELETEBEE ) strcpy(text, "Guêpe mortellement touchée"); - if ( num == INFO_DELETEWORM ) strcpy(text, "Ver mortellement touché"); - if ( num == INFO_DELETESPIDER ) strcpy(text, "Araignée mortellement touchée"); - if ( num == INFO_BEGINSATCOM ) strcpy(text, "Consultez votre SatCom en appuyant sur \\key help;"); - } - - if ( type == RES_CBOT ) - { - strcpy(text, "Erreur"); - if ( num == TX_OPENPAR ) strcpy(text, "Il manque une parenthèse ouvrante"); - if ( num == TX_CLOSEPAR ) strcpy(text, "Il manque une parenthèse fermante"); - if ( num == TX_NOTBOOL ) strcpy(text, "L'expression doit être un boolean"); - if ( num == TX_UNDEFVAR ) strcpy(text, "Variable non déclarée"); - if ( num == TX_BADLEFT ) strcpy(text, "Assignation impossible"); - if ( num == TX_ENDOF ) strcpy(text, "Terminateur point-virgule non trouvé"); - if ( num == TX_OUTCASE ) strcpy(text, "Instruction ""case"" hors d'un bloc ""switch"""); - if ( num == TX_NOTERM ) strcpy(text, "Instructions après la fin"); - if ( num == TX_CLOSEBLK ) strcpy(text, "Il manque la fin du bloc"); - if ( num == TX_ELSEWITHOUTIF ) strcpy(text, "Instruction ""else"" sans ""if"" correspondant"); - if ( num == TX_OPENBLK ) strcpy(text, "Début d'un bloc attendu"); - if ( num == TX_BADTYPE ) strcpy(text, "Mauvais type de résultat pour l'assignation"); - if ( num == TX_REDEFVAR ) strcpy(text, "Redéfinition d'une variable"); - if ( num == TX_BAD2TYPE ) strcpy(text, "Les deux opérandes ne sont pas de types compatibles"); - if ( num == TX_UNDEFCALL ) strcpy(text, "Routine inconnue"); - if ( num == TX_MISDOTS ) strcpy(text, "Séparateur "" : "" attendu"); - if ( num == TX_WHILE ) strcpy(text, "Manque le mot ""while"""); - if ( num == TX_BREAK ) strcpy(text, "Instruction ""break"" en dehors d'une boucle"); - if ( num == TX_LABEL ) strcpy(text, "Un label ne peut se placer que devant un ""for"", un ""while"", un ""do"" ou un ""switch"""); - if ( num == TX_NOLABEL ) strcpy(text, "Cette étiquette n'existe pas"); - if ( num == TX_NOCASE ) strcpy(text, "Manque une instruction ""case"""); - if ( num == TX_BADNUM ) strcpy(text, "Un nombre est attendu"); - if ( num == TX_VOID ) strcpy(text, "Paramètre void"); - if ( num == TX_NOTYP ) strcpy(text, "Déclaration de type attendu"); - if ( num == TX_NOVAR ) strcpy(text, "Nom d'une variable attendu"); - if ( num == TX_NOFONC ) strcpy(text, "Nom de la fonction attendu"); - if ( num == TX_OVERPARAM ) strcpy(text, "Trop de paramètres"); - if ( num == TX_REDEF ) strcpy(text, "Cette fonction existe déjà"); - if ( num == TX_LOWPARAM ) strcpy(text, "Pas assez de paramètres"); - if ( num == TX_BADPARAM ) strcpy(text, "Aucune fonction de ce nom n'accepte ce(s) type(s) de paramètre(s)"); - if ( num == TX_NUMPARAM ) strcpy(text, "Aucune fonction de ce nom n'accepte ce nombre de paramètres"); - if ( num == TX_NOITEM ) strcpy(text, "Cet élément n'existe pas dans cette classe"); - if ( num == TX_DOT ) strcpy(text, "L'objet n'est pas une instance d'une classe"); - if ( num == TX_NOCONST ) strcpy(text, "Il n'y a pas de constructeur approprié"); - if ( num == TX_REDEFCLASS ) strcpy(text, "Cette classe existe déjà"); - if ( num == TX_CLBRK ) strcpy(text, """ ] "" attendu"); - if ( num == TX_RESERVED ) strcpy(text, "Ce mot est réservé"); - if ( num == TX_BADNEW ) strcpy(text, "Mauvais argument pour ""new"""); - if ( num == TX_OPBRK ) strcpy(text, """ [ "" attendu"); - if ( num == TX_BADSTRING ) strcpy(text, "Une chaîne de caractère est attendue"); - if ( num == TX_BADINDEX ) strcpy(text, "Mauvais type d'index"); - if ( num == TX_PRIVATE ) strcpy(text, "Elément protégé"); - if ( num == TX_NOPUBLIC ) strcpy(text, "Public requis"); - if ( num == TX_DIVZERO ) strcpy(text, "Division par zéro"); - if ( num == TX_NOTINIT ) strcpy(text, "Variable non initialisée"); - if ( num == TX_BADTHROW ) strcpy(text, "Valeur négative refusée pour ""throw"""); - if ( num == TX_NORETVAL ) strcpy(text, "La fonction n'a pas retourné de résultat"); - if ( num == TX_NORUN ) strcpy(text, "Pas de fonction en exécution"); - if ( num == TX_NOCALL ) strcpy(text, "Appel d'une fonction inexistante"); - if ( num == TX_NOCLASS ) strcpy(text, "Cette classe n'existe pas"); - if ( num == TX_NULLPT ) strcpy(text, "Objet n'existe pas"); - if ( num == TX_OPNAN ) strcpy(text, "Opération sur un ""nan"""); - if ( num == TX_OUTARRAY ) strcpy(text, "Accès hors du tableau"); - if ( num == TX_STACKOVER ) strcpy(text, "Débordement de la pile"); - if ( num == TX_DELETEDPT ) strcpy(text, "Objet inaccessible"); - if ( num == TX_FILEOPEN ) strcpy(text, "Ouverture du fichier impossible"); - if ( num == TX_NOTOPEN ) strcpy(text, "Le fichier n'est pas ouvert"); - if ( num == TX_ERRREAD ) strcpy(text, "Erreur à la lecture"); - if ( num == TX_ERRWRITE ) strcpy(text, "Erreur à l'écriture"); - } - - if ( type == RES_KEY ) - { - if ( num == 0 ) strcpy(text, "< aucune >"); - if ( num == VK_LEFT ) strcpy(text, "Flèche Gauche"); - if ( num == VK_RIGHT ) strcpy(text, "Flèche Droite"); - if ( num == VK_UP ) strcpy(text, "Flèche Haut"); - if ( num == VK_DOWN ) strcpy(text, "Flèche Bas"); - if ( num == VK_CANCEL ) strcpy(text, "Control-break"); - if ( num == VK_BACK ) strcpy(text, "<--"); - if ( num == VK_TAB ) strcpy(text, "Tab"); - if ( num == VK_CLEAR ) strcpy(text, "Clear"); - if ( num == VK_RETURN ) strcpy(text, "Entrée"); - if ( num == VK_SHIFT ) strcpy(text, "Shift"); - if ( num == VK_CONTROL ) strcpy(text, "Ctrl"); - if ( num == VK_MENU ) strcpy(text, "Alt"); - if ( num == VK_PAUSE ) strcpy(text, "Pause"); - if ( num == VK_CAPITAL ) strcpy(text, "Caps Lock"); - if ( num == VK_ESCAPE ) strcpy(text, "Esc"); - if ( num == VK_SPACE ) strcpy(text, "Espace"); - if ( num == VK_PRIOR ) strcpy(text, "Page Up"); - if ( num == VK_NEXT ) strcpy(text, "Page Down"); - if ( num == VK_END ) strcpy(text, "End"); - if ( num == VK_HOME ) strcpy(text, "Home"); - if ( num == VK_SELECT ) strcpy(text, "Select"); - if ( num == VK_EXECUTE ) strcpy(text, "Execute"); - if ( num == VK_SNAPSHOT ) strcpy(text, "Print Scrn"); - if ( num == VK_INSERT ) strcpy(text, "Insert"); - if ( num == VK_DELETE ) strcpy(text, "Delete"); - if ( num == VK_HELP ) strcpy(text, "Help"); - if ( num == VK_LWIN ) strcpy(text, "Left Windows"); - if ( num == VK_RWIN ) strcpy(text, "Right Windows"); - if ( num == VK_APPS ) strcpy(text, "Application key"); - if ( num == VK_NUMPAD0 ) strcpy(text, "NumPad 0"); - if ( num == VK_NUMPAD1 ) strcpy(text, "NumPad 1"); - if ( num == VK_NUMPAD2 ) strcpy(text, "NumPad 2"); - if ( num == VK_NUMPAD3 ) strcpy(text, "NumPad 3"); - if ( num == VK_NUMPAD4 ) strcpy(text, "NumPad 4"); - if ( num == VK_NUMPAD5 ) strcpy(text, "NumPad 5"); - if ( num == VK_NUMPAD6 ) strcpy(text, "NumPad 6"); - if ( num == VK_NUMPAD7 ) strcpy(text, "NumPad 7"); - if ( num == VK_NUMPAD8 ) strcpy(text, "NumPad 8"); - if ( num == VK_NUMPAD9 ) strcpy(text, "NumPad 9"); - if ( num == VK_MULTIPLY ) strcpy(text, "NumPad *"); - if ( num == VK_ADD ) strcpy(text, "NumPad +"); - if ( num == VK_SEPARATOR ) strcpy(text, "NumPad sep"); - if ( num == VK_SUBTRACT ) strcpy(text, "NumPad -"); - if ( num == VK_DECIMAL ) strcpy(text, "NumPad ."); - if ( num == VK_DIVIDE ) strcpy(text, "NumPad /"); - if ( num == VK_F1 ) strcpy(text, "F1"); - if ( num == VK_F2 ) strcpy(text, "F2"); - if ( num == VK_F3 ) strcpy(text, "F3"); - if ( num == VK_F4 ) strcpy(text, "F4"); - if ( num == VK_F5 ) strcpy(text, "F5"); - if ( num == VK_F6 ) strcpy(text, "F6"); - if ( num == VK_F7 ) strcpy(text, "F7"); - if ( num == VK_F8 ) strcpy(text, "F8"); - if ( num == VK_F9 ) strcpy(text, "F9"); - if ( num == VK_F10 ) strcpy(text, "F10"); - if ( num == VK_F11 ) strcpy(text, "F11"); - if ( num == VK_F12 ) strcpy(text, "F12"); - if ( num == VK_F13 ) strcpy(text, "F13"); - if ( num == VK_F14 ) strcpy(text, "F14"); - if ( num == VK_F15 ) strcpy(text, "F15"); - if ( num == VK_F16 ) strcpy(text, "F16"); - if ( num == VK_F17 ) strcpy(text, "F17"); - if ( num == VK_F18 ) strcpy(text, "F18"); - if ( num == VK_F19 ) strcpy(text, "F19"); - if ( num == VK_F20 ) strcpy(text, "F20"); - if ( num == VK_NUMLOCK ) strcpy(text, "Num Lock"); - if ( num == VK_SCROLL ) strcpy(text, "Scroll"); - if ( num == VK_ATTN ) strcpy(text, "Attn"); - if ( num == VK_CRSEL ) strcpy(text, "CrSel"); - if ( num == VK_EXSEL ) strcpy(text, "ExSel"); - if ( num == VK_EREOF ) strcpy(text, "Erase EOF"); - if ( num == VK_PLAY ) strcpy(text, "Play"); - if ( num == VK_ZOOM ) strcpy(text, "Zoom"); - if ( num == VK_PA1 ) strcpy(text, "PA1"); - if ( num == VK_OEM_CLEAR ) strcpy(text, "Clear"); - if ( num == VK_BUTTON1 ) strcpy(text, "Bouton 1"); - if ( num == VK_BUTTON2 ) strcpy(text, "Bouton 2"); - if ( num == VK_BUTTON3 ) strcpy(text, "Bouton 3"); - if ( num == VK_BUTTON4 ) strcpy(text, "Bouton 4"); - if ( num == VK_BUTTON5 ) strcpy(text, "Bouton 5"); - if ( num == VK_BUTTON6 ) strcpy(text, "Bouton 6"); - if ( num == VK_BUTTON7 ) strcpy(text, "Bouton 7"); - if ( num == VK_BUTTON8 ) strcpy(text, "Bouton 8"); - if ( num == VK_BUTTON9 ) strcpy(text, "Bouton 9"); - if ( num == VK_BUTTON10 ) strcpy(text, "Bouton 10"); - if ( num == VK_BUTTON11 ) strcpy(text, "Bouton 11"); - if ( num == VK_BUTTON12 ) strcpy(text, "Bouton 12"); - if ( num == VK_BUTTON13 ) strcpy(text, "Bouton 13"); - if ( num == VK_BUTTON14 ) strcpy(text, "Bouton 14"); - if ( num == VK_BUTTON15 ) strcpy(text, "Bouton 15"); - if ( num == VK_BUTTON16 ) strcpy(text, "Bouton 16"); - if ( num == VK_BUTTON17 ) strcpy(text, "Bouton 17"); - if ( num == VK_BUTTON18 ) strcpy(text, "Bouton 18"); - if ( num == VK_BUTTON19 ) strcpy(text, "Bouton 19"); - if ( num == VK_BUTTON20 ) strcpy(text, "Bouton 20"); - if ( num == VK_BUTTON21 ) strcpy(text, "Bouton 21"); - if ( num == VK_BUTTON22 ) strcpy(text, "Bouton 22"); - if ( num == VK_BUTTON23 ) strcpy(text, "Bouton 23"); - if ( num == VK_BUTTON24 ) strcpy(text, "Bouton 24"); - if ( num == VK_BUTTON25 ) strcpy(text, "Bouton 25"); - if ( num == VK_BUTTON26 ) strcpy(text, "Bouton 26"); - if ( num == VK_BUTTON27 ) strcpy(text, "Bouton 27"); - if ( num == VK_BUTTON28 ) strcpy(text, "Bouton 28"); - if ( num == VK_BUTTON29 ) strcpy(text, "Bouton 29"); - if ( num == VK_BUTTON30 ) strcpy(text, "Bouton 30"); - if ( num == VK_BUTTON31 ) strcpy(text, "Bouton 31"); - if ( num == VK_BUTTON32 ) strcpy(text, "Bouton 32"); - if ( num == VK_WHEELUP ) strcpy(text, "Molette haut"); - if ( num == VK_WHEELDOWN ) strcpy(text, "Molette bas"); - } -#endif - -#if _GERMAN | _WG - if ( type == RES_TEXT ) - { - #if _FULL - if ( num == RT_VERSION_ID ) strcpy(text, "1.18 /d"); - #endif - #if _NET - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A 1.18"); - #endif - #if _SCHOOL & _EDU - #if _TEEN - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen EDU 1.18"); - #else - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A EDU 1.18"); - #endif - #endif - #if _SCHOOL & _PERSO - #if _TEEN - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen PERSO 1.18"); - #else - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A PERSO 1.18"); - #endif - #endif - #if _SCHOOL & _CEEBOTDEMO - #if _TEEN - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen DEMO 1.18"); - #else - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A DEMO 1.18"); - #endif - #endif - #if _DEMO - if ( num == RT_VERSION_ID ) strcpy(text, "Demo 1.18 /d"); - #endif - if ( num == RT_DISINFO_TITLE ) strcpy(text, "SatCom"); - if ( num == RT_WINDOW_MAXIMIZED ) strcpy(text, "Großes Fenster"); - if ( num == RT_WINDOW_MINIMIZED ) strcpy(text, "Reduzieren"); - if ( num == RT_WINDOW_STANDARD ) strcpy(text, "Normale Größe"); - if ( num == RT_WINDOW_CLOSE ) strcpy(text, "Schließen"); - - if ( num == RT_STUDIO_TITLE ) strcpy(text, "Programmeditor"); - if ( num == RT_SCRIPT_NEW ) strcpy(text, "Neu"); - if ( num == RT_NAME_DEFAULT ) strcpy(text, "Spieler"); - if ( num == RT_IO_NEW ) strcpy(text, "Neu ..."); - if ( num == RT_KEY_OR ) strcpy(text, " oder "); - -#if _NEWLOOK - if ( num == RT_TITLE_BASE ) strcpy(text, "CeeBot"); - if ( num == RT_TITLE_INIT ) strcpy(text, "CeeBot"); -#else - if ( num == RT_TITLE_BASE ) strcpy(text, "COLOBOT"); - if ( num == RT_TITLE_INIT ) strcpy(text, "COLOBOT"); -#endif -#if _SCHOOL - if ( num == RT_TITLE_TRAINER ) strcpy(text, "Übungen"); -#else - if ( num == RT_TITLE_TRAINER ) strcpy(text, "Programmieren"); -#endif - if ( num == RT_TITLE_DEFI ) strcpy(text, "Challenges"); - if ( num == RT_TITLE_MISSION ) strcpy(text, "Missionen"); - if ( num == RT_TITLE_FREE ) strcpy(text, "Freestyle"); - if ( num == RT_TITLE_TEEN ) strcpy(text, "Freestyle"); - if ( num == RT_TITLE_USER ) strcpy(text, "Userlevels"); - if ( num == RT_TITLE_PROTO ) strcpy(text, "Prototypen"); - if ( num == RT_TITLE_SETUP ) strcpy(text, "Einstellungen"); - if ( num == RT_TITLE_NAME ) strcpy(text, "Name "); - if ( num == RT_TITLE_PERSO ) strcpy(text, "Aussehen einstellen"); - if ( num == RT_TITLE_WRITE ) strcpy(text, "Aktuelle Mission speichern"); - if ( num == RT_TITLE_READ ) strcpy(text, "Gespeicherte Mission laden"); - - if ( num == RT_PLAY_CHAPt ) strcpy(text, " Liste der Kapitel:"); - if ( num == RT_PLAY_CHAPd ) strcpy(text, " Liste der Kapitel:"); - if ( num == RT_PLAY_CHAPm ) strcpy(text, " Liste der Planeten:"); - if ( num == RT_PLAY_CHAPf ) strcpy(text, " Liste der Planeten:"); - if ( num == RT_PLAY_CHAPu ) strcpy(text, " Userlevels:"); - if ( num == RT_PLAY_CHAPp ) strcpy(text, " Liste der Planeten:"); - if ( num == RT_PLAY_CHAPte ) strcpy(text, " Liste der Kapitel:"); - if ( num == RT_PLAY_LISTt ) strcpy(text, " Liste der Übungen des Kapitels:"); - if ( num == RT_PLAY_LISTd ) strcpy(text, " Liste der Challenges des Kapitels:"); - if ( num == RT_PLAY_LISTm ) strcpy(text, " Liste der Missionen des Planeten:"); - if ( num == RT_PLAY_LISTf ) strcpy(text, " Liste der freien Levels des Planeten:"); - if ( num == RT_PLAY_LISTu ) strcpy(text, " Missionen des Userlevels:"); - if ( num == RT_PLAY_LISTp ) strcpy(text, " Liste der Prototypen des Planeten:"); - if ( num == RT_PLAY_LISTk ) strcpy(text, " Liste der freien Levels des Kapitel:"); - if ( num == RT_PLAY_RESUME ) strcpy(text, " Zusammenfassung:"); - - if ( num == RT_SETUP_DEVICE ) strcpy(text, " Driver:"); - if ( num == RT_SETUP_MODE ) strcpy(text, " Auflösung:"); - if ( num == RT_SETUP_KEY1 ) strcpy(text, "1) Klicken Sie auf die neu zu definierende Taste."); - if ( num == RT_SETUP_KEY2 ) strcpy(text, "2) Drücken Sie auf die neue Taste."); - - if ( num == RT_PERSO_FACE ) strcpy(text, "Kopf:"); - if ( num == RT_PERSO_GLASSES ) strcpy(text, "Brille:"); - if ( num == RT_PERSO_HAIR ) strcpy(text, "Haarfarbe:"); - if ( num == RT_PERSO_COMBI ) strcpy(text, "Farbe des Anzugs:"); - if ( num == RT_PERSO_BAND ) strcpy(text, "Farbe der Streifen:"); - -#if _NEWLOOK - if ( num == RT_DIALOG_TITLE ) strcpy(text, "CeeBot"); - if ( num == RT_DIALOG_QUIT ) strcpy(text, "Wollen Sie CeeBot schließen ?"); - if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Schließen\\CeeBot schließen"); -#else - if ( num == RT_DIALOG_TITLE ) strcpy(text, "COLOBOT"); - if ( num == RT_DIALOG_QUIT ) strcpy(text, "Wollen Sie COLOBOT schließen ?"); - if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Schließen\\COLOBOT schließen"); -#endif - if ( num == RT_DIALOG_ABORT ) strcpy(text, "Mission abbrechen ?"); - if ( num == RT_DIALOG_YES ) strcpy(text, "Abbrechen\\Mission abbrechen"); - if ( num == RT_DIALOG_NO ) strcpy(text, "Weitermachen\\Mission weitermachen"); - if ( num == RT_DIALOG_NOQUIT ) strcpy(text, "Weitermachen\\Weitermachen"); - if ( num == RT_DIALOG_DELOBJ ) strcpy(text, "Wollen Sie das angewählte Gebäude wirklich zerstören ?"); - if ( num == RT_DIALOG_DELGAME ) strcpy(text, "Wollen Sie die gespeicherten Missionen von %s löschen ?"); - if ( num == RT_DIALOG_YESDEL ) strcpy(text, "Zerstören"); - if ( num == RT_DIALOG_NODEL ) strcpy(text, "Abbrechen"); - if ( num == RT_DIALOG_LOADING ) strcpy(text, "Laden"); - - if ( num == RT_STUDIO_LISTTT ) strcpy(text, "Hilfe über den Begriff (\\key cbot;)"); - if ( num == RT_STUDIO_COMPOK ) strcpy(text, "Kompilieren OK (0 Fehler)"); - if ( num == RT_STUDIO_PROGSTOP ) strcpy(text, "Programm beendet"); - - if ( num == RT_SATCOM_LIST ) strcpy(text, "\\b;Liste der Objekte\n"); - if ( num == RT_SATCOM_BOT ) strcpy(text, "\\b;Liste der Roboter\n"); - if ( num == RT_SATCOM_BUILDING ) strcpy(text, "\\b;Listes der Gebäude\n"); - if ( num == RT_SATCOM_FRET ) strcpy(text, "\\b;Listes der tragbaren Gegenstände\n"); - if ( num == RT_SATCOM_ALIEN ) strcpy(text, "\\b;Listes der Feinde\n"); - if ( num == RT_SATCOM_NULL ) strcpy(text, "\\c; (keine)\\n;\n"); - if ( num == RT_SATCOM_ERROR1 ) strcpy(text, "\\b;Fehler\n"); - if ( num == RT_SATCOM_ERROR2 ) strcpy(text, "Die Liste ist ohne \\l;Radar\\u object\\radar; nicht verfügbar !\n"); - - if ( num == RT_IO_OPEN ) strcpy(text, "Öffnen"); - if ( num == RT_IO_SAVE ) strcpy(text, "Speichern"); - if ( num == RT_IO_LIST ) strcpy(text, "Ordner: %s"); - if ( num == RT_IO_NAME ) strcpy(text, "Name:"); - if ( num == RT_IO_DIR ) strcpy(text, "In:"); - if ( num == RT_IO_PRIVATE ) strcpy(text, "Privat\\Privater Ordner"); - if ( num == RT_IO_PUBLIC ) strcpy(text, "Öffentlich\\Gemeinsamer Ordner für alle Spieler"); - - if ( num == RT_GENERIC_DEV1 ) strcpy(text, "Entwickelt von:"); - if ( num == RT_GENERIC_DEV2 ) strcpy(text, "www.epsitec.com"); -#if _WG - if ( num == RT_GENERIC_EDIT1 ) strcpy(text, "Herausgegeben von:"); - if ( num == RT_GENERIC_EDIT2 ) strcpy(text, "www.wg-verlag.ch"); -#else - if ( num == RT_GENERIC_EDIT1 ) strcpy(text, " "); - if ( num == RT_GENERIC_EDIT2 ) strcpy(text, " "); -#endif - - if ( num == RT_INTERFACE_REC ) strcpy(text, "Recorder"); - } - - if ( type == RES_EVENT ) - { - if ( num == EVENT_BUTTON_OK ) strcpy(text, "OK"); - if ( num == EVENT_BUTTON_CANCEL ) strcpy(text, "Abbrechen"); - if ( num == EVENT_BUTTON_NEXT ) strcpy(text, "Nächster"); - if ( num == EVENT_BUTTON_PREV ) strcpy(text, "Vorherg."); - if ( num == EVENT_BUTTON_QUIT ) strcpy(text, "Menü (\\key quit;)"); - - if ( num == EVENT_DIALOG_OK ) strcpy(text, "OK"); - if ( num == EVENT_DIALOG_CANCEL ) strcpy(text, "Abbrechen"); - -#if _SCHOOL - if ( num == EVENT_INTERFACE_TRAINER) strcpy(text, "Übungen\\Programmierübungen"); -#else - if ( num == EVENT_INTERFACE_TRAINER) strcpy(text, "Programmieren\\Programmierübungen"); -#endif - if ( num == EVENT_INTERFACE_DEFI ) strcpy(text, "Challenges\\Herausforderungen"); - if ( num == EVENT_INTERFACE_MISSION) strcpy(text, "Missionen\\Aufbruch ins Weltall"); - if ( num == EVENT_INTERFACE_FREE ) strcpy(text, "Freestyle\\Freies Spielen ohne vorgegebenes Ziel"); - if ( num == EVENT_INTERFACE_TEEN ) strcpy(text, "Freestyle\\Freies Spielen ohne vorgegebenes Ziel"); - if ( num == EVENT_INTERFACE_USER ) strcpy(text, "User\\Userlevels"); - if ( num == EVENT_INTERFACE_PROTO ) strcpy(text, "Proto\\In Entwicklung befindliche Prototypen"); - if ( num == EVENT_INTERFACE_NAME ) strcpy(text, "Anderer Spieler\\Spielername ändern"); - if ( num == EVENT_INTERFACE_SETUP ) strcpy(text, "Einstellungen\\Einstellungen"); - if ( num == EVENT_INTERFACE_AGAIN ) strcpy(text, "Neu anfangen\\Die Mission von vorne anfangen"); - if ( num == EVENT_INTERFACE_WRITE ) strcpy(text, "Speichern\\Aktuelle Mission speichern"); - if ( num == EVENT_INTERFACE_READ ) strcpy(text, "Laden\\Eine gespeicherte Mission öffnen"); -#if _NEWLOOK - if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Zurück zu CeeBot"); - if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Schließen\\CeeBot schließen"); -#else - if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Zurück zu COLOBOT"); - if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Schließen\\COLOBOT schließen"); -#endif - if ( num == EVENT_INTERFACE_BACK ) strcpy(text, "<< Zurück \\Zurück zum Hauptmenü"); - if ( num == EVENT_INTERFACE_PLAY ) strcpy(text, "Spielen ...\\Los geht's"); - if ( num == EVENT_INTERFACE_SETUPd ) strcpy(text, "Bildschirm\\Driver und Bildschirmauflösung"); - if ( num == EVENT_INTERFACE_SETUPg ) strcpy(text, "Grafik\\Grafische Einstellungen"); - if ( num == EVENT_INTERFACE_SETUPp ) strcpy(text, "Spiel\\Gameplay Einstellungen"); - if ( num == EVENT_INTERFACE_SETUPc ) strcpy(text, "Steuerung\\Auswahl der Tasten"); - if ( num == EVENT_INTERFACE_SETUPs ) strcpy(text, "Geräusche\\Lautstärke Geräusche und Musik"); - if ( num == EVENT_INTERFACE_DEVICE ) strcpy(text, "Einheit"); - if ( num == EVENT_INTERFACE_RESOL ) strcpy(text, "Auflösung"); - if ( num == EVENT_INTERFACE_FULL ) strcpy(text, "Vollbildschirm\\Vollbildschirm oder Fenster"); - if ( num == EVENT_INTERFACE_APPLY ) strcpy(text, "Änderungen ausführen\\Getätigte Einstellungen ausführen"); - - if ( num == EVENT_INTERFACE_TOTO ) strcpy(text, "Robby\\Ihr Assistent"); - if ( num == EVENT_INTERFACE_SHADOW ) strcpy(text, "Schatten\\Schlagschatten auf dem Boden"); - if ( num == EVENT_INTERFACE_GROUND ) strcpy(text, "Markierungen\\Markierungen auf dem Boden"); - if ( num == EVENT_INTERFACE_DIRTY ) strcpy(text, "Schmutz\\Schmutz auf Robotern und Bauten"); - if ( num == EVENT_INTERFACE_FOG ) strcpy(text, "Nebel\\Nebelschwaden"); - if ( num == EVENT_INTERFACE_LENS ) strcpy(text, "Sonnenstrahlen\\Sonnenstrahlen"); - if ( num == EVENT_INTERFACE_SKY ) strcpy(text, "Himmel\\Himmel und Wolken"); - if ( num == EVENT_INTERFACE_PLANET ) strcpy(text, "Planeten und Sterne\\Kreisende Planeten und Sterne"); - if ( num == EVENT_INTERFACE_LIGHT ) strcpy(text, "Dynamische Beleuchtung\\Dynamische Beleuchtung"); - if ( num == EVENT_INTERFACE_PARTI ) strcpy(text, "Anzahl Partikel\\Explosionen, Staub, usw."); - if ( num == EVENT_INTERFACE_CLIP ) strcpy(text, "Sichtweite\\Maximale Sichtweite"); - if ( num == EVENT_INTERFACE_DETAIL ) strcpy(text, "Details\\Detailliertheit der Objekte in 3D"); - if ( num == EVENT_INTERFACE_TEXTURE) strcpy(text, "Qualität der Texturen\\Qualität der Anzeige"); - if ( num == EVENT_INTERFACE_GADGET ) strcpy(text, "Anzahl Ziergegenstände\\Anzahl Gegenstände ohne Funktion"); - if ( num == EVENT_INTERFACE_RAIN ) strcpy(text, "Partikel in den Menüs\\Funken und Sterne in den Menüs"); - if ( num == EVENT_INTERFACE_GLINT ) strcpy(text, "Glänzende Tasten\\Glänzende Tasten in den Menüs"); - if ( num == EVENT_INTERFACE_TOOLTIP) strcpy(text, "Hilfsblasen\\Hilfsblasen"); - if ( num == EVENT_INTERFACE_MOVIES ) strcpy(text, "Filme\\Filme vor und nach den Missionen"); - if ( num == EVENT_INTERFACE_NICERST) strcpy(text, "Zurücksetzen \\Kleine Show beim Zurücksetzen in den Übungen"); - if ( num == EVENT_INTERFACE_HIMSELF) strcpy(text, "Eigenbeschuss\\Ihre Einheiten werden von Ihren Waffen beschädigt."); - if ( num == EVENT_INTERFACE_SCROLL ) strcpy(text, "Kameradrehung mit der Maus\\Die Kamera dreht wenn die Maus den Rand erreicht"); - if ( num == EVENT_INTERFACE_INVERTX) strcpy(text, "Umkehr X\\Umkehr der Kameradrehung X-Achse"); - if ( num == EVENT_INTERFACE_INVERTY) strcpy(text, "Umkehr Y\\Umkehr der Kameradrehung Y-Achse"); - if ( num == EVENT_INTERFACE_EFFECT ) strcpy(text, "Beben bei Explosionen\\Die Kamera bebt bei Explosionen"); - if ( num == EVENT_INTERFACE_MOUSE ) strcpy(text, "Schatten unter der Maus\\Ein Schatten erscheint unter der Maus"); - if ( num == EVENT_INTERFACE_EDITMODE) strcpy(text, "Automatisches Einrücken\\Beim Bearbeiten der Programme"); - if ( num == EVENT_INTERFACE_EDITVALUE)strcpy(text, "Einrücken mit 4 Leerstellen\\Einrücken mit 2 oder 4 Leerstellen"); - if ( num == EVENT_INTERFACE_SOLUCE4) strcpy(text, "Lösung zugänglich\\Die Lösung ist im Programmslot \"4: Lösung\" zugänglich"); - - if ( num == EVENT_INTERFACE_KDEF ) strcpy(text, "Alles zurücksetzen\\Standarddefinition aller Tasten"); - if ( num == EVENT_INTERFACE_KLEFT ) strcpy(text, "Drehung nach links\\Steuer links"); - if ( num == EVENT_INTERFACE_KRIGHT ) strcpy(text, "Drehung nach rechts\\Steuer rechts"); - if ( num == EVENT_INTERFACE_KUP ) strcpy(text, "Vorwärts\\Bewegung nach vorne"); - if ( num == EVENT_INTERFACE_KDOWN ) strcpy(text, "Rückwärts\\Bewegung nach hinten"); - if ( num == EVENT_INTERFACE_KGUP ) strcpy(text, "Steigen\\Leistung des Triebwerks steigern"); - if ( num == EVENT_INTERFACE_KGDOWN ) strcpy(text, "Sinken\\Leistung des Triebwerks drosseln"); - if ( num == EVENT_INTERFACE_KCAMERA) strcpy(text, "Andere Kamera\\Sichtpunkt einstellen"); - if ( num == EVENT_INTERFACE_KDESEL ) strcpy(text, "Vorherg. Auswahl\\Das vorhergehende Objekt auswählen"); - if ( num == EVENT_INTERFACE_KACTION) strcpy(text, "Standardhandlung\\Führt die Standardhandlung des Roboters aus."); - if ( num == EVENT_INTERFACE_KNEAR ) strcpy(text, "Kamera näher\\Bewegung der Kamera vorwärts"); - if ( num == EVENT_INTERFACE_KAWAY ) strcpy(text, "Kamera weiter\\Bewegung der Kamera rückwärts"); - if ( num == EVENT_INTERFACE_KNEXT ) strcpy(text, "Nächstes auswählen\\Nächstes Objekt auswählen"); - if ( num == EVENT_INTERFACE_KHUMAN ) strcpy(text, "Astronauten auswählen\\Astronauten auswählen"); - if ( num == EVENT_INTERFACE_KQUIT ) strcpy(text, "Mission verlassen\\Eine Mission oder Übung verlassen"); - if ( num == EVENT_INTERFACE_KHELP ) strcpy(text, "Anweisungen\\Anweisungen für die Mission oder Übung"); - if ( num == EVENT_INTERFACE_KPROG ) strcpy(text, "Hilfe CBOT-Sprache\\Hilfe über die Programmiersprache CBOT"); - if ( num == EVENT_INTERFACE_KCBOT ) strcpy(text, "Hilfe über Begriff\\Hilfe über einen Begriff"); - if ( num == EVENT_INTERFACE_KVISIT ) strcpy(text, "Ort der Meldung\\Zeigt den Ort, von dem die letzte Meldung stammt"); - if ( num == EVENT_INTERFACE_KSPEED10) strcpy(text, "Geschwindigkeit 1.0x\\Normale Spielgeschwindigkeit"); - if ( num == EVENT_INTERFACE_KSPEED15) strcpy(text, "Geschwindigkeit 1.5x\\Spielgeschwindigkeit anderthalb Mal schneller"); - if ( num == EVENT_INTERFACE_KSPEED20) strcpy(text, "Geschwindigkeit 2.0x\\Spielgeschwindigkeit doppelt so schnell"); - if ( num == EVENT_INTERFACE_KSPEED30) strcpy(text, "Geschwindigkeit 3.0x\\Spielgeschwindigkeit drei Mal schneller"); - - if ( num == EVENT_INTERFACE_VOLSOUND) strcpy(text, "Geräusche:\\Lautstärke Motoren, Stimmen, usw."); - if ( num == EVENT_INTERFACE_VOLMUSIC) strcpy(text, "Geräuschkulisse:\\Lautstärke der Soundtracks der CD"); - if ( num == EVENT_INTERFACE_SOUND3D) strcpy(text, "3D-Geräusche\\Orten der Geräusche im Raum"); - - if ( num == EVENT_INTERFACE_MIN ) strcpy(text, "Min.\\Minimale Qualität (großes Framerate)"); - if ( num == EVENT_INTERFACE_NORM ) strcpy(text, "Normal\\Standardqualität"); - if ( num == EVENT_INTERFACE_MAX ) strcpy(text, "Max.\\Beste Qualität (niedriges Framerate)"); - - if ( num == EVENT_INTERFACE_SILENT ) strcpy(text, "Kein Ton\\Keine Geräusche und Geräuschkulisse"); - if ( num == EVENT_INTERFACE_NOISY ) strcpy(text, "Normal\\Normale Lautstärke"); - - if ( num == EVENT_INTERFACE_JOYSTICK) strcpy(text, "Joystick\\Joystick oder Tastatur"); - if ( num == EVENT_INTERFACE_SOLUCE ) strcpy(text, "Zeigt die Lösung\\Zeigt nach 3mal Scheitern die Lösung"); - - if ( num == EVENT_INTERFACE_NEDIT ) strcpy(text, "\\Name des Spielers"); - if ( num == EVENT_INTERFACE_NOK ) strcpy(text, "OK\\Spieler auswählen"); - if ( num == EVENT_INTERFACE_NCANCEL) strcpy(text, "Abbrechen\\Behält den bisherigen Spieler bei"); - if ( num == EVENT_INTERFACE_NDELETE) strcpy(text, "Spieler löschen\\Löscht den Spieler aus der Liste"); - if ( num == EVENT_INTERFACE_NLABEL ) strcpy(text, "Name "); - - if ( num == EVENT_INTERFACE_IOWRITE) strcpy(text, "Speichern\\Speichert die Mission"); - if ( num == EVENT_INTERFACE_IOREAD ) strcpy(text, "Laden\\Öffnet eine gespeicherte Mission"); - if ( num == EVENT_INTERFACE_IOLIST ) strcpy(text, "Liste der gespeicherten Missionen"); - if ( num == EVENT_INTERFACE_IOLABEL) strcpy(text, "Dateiname:"); - if ( num == EVENT_INTERFACE_IONAME ) strcpy(text, "Name der Mission"); - if ( num == EVENT_INTERFACE_IOIMAGE) strcpy(text, "Ansicht der Mission"); - if ( num == EVENT_INTERFACE_IODELETE) strcpy(text, "Löschen\\Löscht die gespeicherte Mission"); - - if ( num == EVENT_INTERFACE_PERSO ) strcpy(text, "Aussehen\\Erscheinungsbild des Astronauten einstellen"); - if ( num == EVENT_INTERFACE_POK ) strcpy(text, "OK"); - if ( num == EVENT_INTERFACE_PCANCEL) strcpy(text, "Abbrechen"); - if ( num == EVENT_INTERFACE_PDEF ) strcpy(text, "Standard\\Standardfarben einsetzen"); - if ( num == EVENT_INTERFACE_PHEAD ) strcpy(text, "Kopf\\Gesicht und Haare"); - if ( num == EVENT_INTERFACE_PBODY ) strcpy(text, "Anzug\\Raumfahrtanzug"); - if ( num == EVENT_INTERFACE_PLROT ) strcpy(text, "\\Drehung links"); - if ( num == EVENT_INTERFACE_PRROT ) strcpy(text, "\\Drehung rechts"); - if ( num == EVENT_INTERFACE_PCRa ) strcpy(text, "Rot"); - if ( num == EVENT_INTERFACE_PCGa ) strcpy(text, "Grün"); - if ( num == EVENT_INTERFACE_PCBa ) strcpy(text, "Blau"); - if ( num == EVENT_INTERFACE_PCRb ) strcpy(text, "Rot"); - if ( num == EVENT_INTERFACE_PCGb ) strcpy(text, "Grün"); - if ( num == EVENT_INTERFACE_PCBb ) strcpy(text, "Blau"); - if ( num == EVENT_INTERFACE_PFACE1 ) strcpy(text, "\\Kopf 1"); - if ( num == EVENT_INTERFACE_PFACE2 ) strcpy(text, "\\Kopf 4"); - if ( num == EVENT_INTERFACE_PFACE3 ) strcpy(text, "\\Kopf 3"); - if ( num == EVENT_INTERFACE_PFACE4 ) strcpy(text, "\\Kopf 2"); - if ( num == EVENT_INTERFACE_PGLASS0) strcpy(text, "\\Keine Brille"); - if ( num == EVENT_INTERFACE_PGLASS1) strcpy(text, "\\Brille 1"); - if ( num == EVENT_INTERFACE_PGLASS2) strcpy(text, "\\Brille 2"); - if ( num == EVENT_INTERFACE_PGLASS3) strcpy(text, "\\Brille 3"); - if ( num == EVENT_INTERFACE_PGLASS4) strcpy(text, "\\Brille 4"); - if ( num == EVENT_INTERFACE_PGLASS5) strcpy(text, "\\Brille 5"); - - if ( num == EVENT_OBJECT_DESELECT ) strcpy(text, "Vorherg. Auwahl (\\key desel;)"); - if ( num == EVENT_OBJECT_LEFT ) strcpy(text, "Drehung links (\\key left;)"); - if ( num == EVENT_OBJECT_RIGHT ) strcpy(text, "Drehung rechts (\\key right;)"); - if ( num == EVENT_OBJECT_UP ) strcpy(text, "Vorwärts (\\key up;)"); - if ( num == EVENT_OBJECT_DOWN ) strcpy(text, "Rückwärts (\\key down;)"); - if ( num == EVENT_OBJECT_GASUP ) strcpy(text, "Steigt (\\key gup;)"); - if ( num == EVENT_OBJECT_GASDOWN ) strcpy(text, "Sinkt (\\key gdown;)"); - if ( num == EVENT_OBJECT_HTAKE ) strcpy(text, "Nehmen oder hinlegen (\\key action;)"); - if ( num == EVENT_OBJECT_MTAKE ) strcpy(text, "Nehmen oder hinlegen (\\key action;)"); - if ( num == EVENT_OBJECT_MFRONT ) strcpy(text, "..vorne"); - if ( num == EVENT_OBJECT_MBACK ) strcpy(text, "..hinten"); - if ( num == EVENT_OBJECT_MPOWER ) strcpy(text, "..Batterie"); - if ( num == EVENT_OBJECT_BHELP ) strcpy(text, "Anweisungen über die Mission(\\key help;)"); - if ( num == EVENT_OBJECT_BTAKEOFF ) strcpy(text, "Abheben nach vollbrachter Mission"); - if ( num == EVENT_OBJECT_BDERRICK ) strcpy(text, "Baut einen Bohrturm"); - if ( num == EVENT_OBJECT_BSTATION ) strcpy(text, "Baut ein Kraftwerk"); - if ( num == EVENT_OBJECT_BFACTORY ) strcpy(text, "Baut eine Roboterfabrik"); - if ( num == EVENT_OBJECT_BREPAIR ) strcpy(text, "Baut ein Reparaturzentrum"); - if ( num == EVENT_OBJECT_BCONVERT ) strcpy(text, "Baut einen Konverter"); - if ( num == EVENT_OBJECT_BTOWER ) strcpy(text, "Baut einen Geschützturm"); - if ( num == EVENT_OBJECT_BRESEARCH ) strcpy(text, "Baut ein Forschungszentrum"); - if ( num == EVENT_OBJECT_BRADAR ) strcpy(text, "Baut ein Radar"); - if ( num == EVENT_OBJECT_BENERGY ) strcpy(text, "Baut eine Batteriefabrik"); - if ( num == EVENT_OBJECT_BLABO ) strcpy(text, "Baut ein automatisches Labor"); - if ( num == EVENT_OBJECT_BNUCLEAR ) strcpy(text, "Baut eine Brennstoffzellenfabrik"); - if ( num == EVENT_OBJECT_BPARA ) strcpy(text, "Baut einen Blitzableiter"); - if ( num == EVENT_OBJECT_BINFO ) strcpy(text, "Baut einen Infoserver"); - if ( num == EVENT_OBJECT_GFLAT ) strcpy(text, "Zeigt ob der Boden eben ist"); - if ( num == EVENT_OBJECT_FCREATE ) strcpy(text, "Setzt eine Fahne"); - if ( num == EVENT_OBJECT_FDELETE ) strcpy(text, "Sammelt die Fahne ein"); - if ( num == EVENT_OBJECT_FCOLORb ) strcpy(text, "\\Blaue Fahne"); - if ( num == EVENT_OBJECT_FCOLORr ) strcpy(text, "\\Rote Fahne"); - if ( num == EVENT_OBJECT_FCOLORg ) strcpy(text, "\\Grüne Fahne"); - if ( num == EVENT_OBJECT_FCOLORy ) strcpy(text, "\\Gelbe Fahne"); - if ( num == EVENT_OBJECT_FCOLORv ) strcpy(text, "\\Violette Fahne"); - if ( num == EVENT_OBJECT_FACTORYfa ) strcpy(text, "Baut einen Jettransporter"); - if ( num == EVENT_OBJECT_FACTORYta ) strcpy(text, "Baut einen Kettentransporter"); - if ( num == EVENT_OBJECT_FACTORYwa ) strcpy(text, "Baut einen Radtransporter"); - if ( num == EVENT_OBJECT_FACTORYia ) strcpy(text, "Baut einen Krabbeltransporter"); - if ( num == EVENT_OBJECT_FACTORYfc ) strcpy(text, "Baut einen Jetshooter"); - if ( num == EVENT_OBJECT_FACTORYtc ) strcpy(text, "Baut einen Kettenshooter"); - if ( num == EVENT_OBJECT_FACTORYwc ) strcpy(text, "Baut einen Radshooter"); - if ( num == EVENT_OBJECT_FACTORYic ) strcpy(text, "Baut einen Krabbelshooter"); - if ( num == EVENT_OBJECT_FACTORYfi ) strcpy(text, "Baut einen Jetorgashooter"); - if ( num == EVENT_OBJECT_FACTORYti ) strcpy(text, "Baut einen Kettenorgashooter"); - if ( num == EVENT_OBJECT_FACTORYwi ) strcpy(text, "Baut einen Radorgashooter"); - if ( num == EVENT_OBJECT_FACTORYii ) strcpy(text, "Baut einen Krabbelorgashooter"); - if ( num == EVENT_OBJECT_FACTORYfs ) strcpy(text, "Baut einen Jetschnüffler"); - if ( num == EVENT_OBJECT_FACTORYts ) strcpy(text, "Baut einen Kettenschnüffler"); - if ( num == EVENT_OBJECT_FACTORYws ) strcpy(text, "Baut einen Radschnüffler"); - if ( num == EVENT_OBJECT_FACTORYis ) strcpy(text, "Baut einen Krabbelschnüffler"); - if ( num == EVENT_OBJECT_FACTORYrt ) strcpy(text, "Baut einen Stampfer"); - if ( num == EVENT_OBJECT_FACTORYrc ) strcpy(text, "Baut einen Phazershooter"); - if ( num == EVENT_OBJECT_FACTORYrr ) strcpy(text, "Baut einen Recycler"); - if ( num == EVENT_OBJECT_FACTORYrs ) strcpy(text, "Baut einen Schutzschild"); - if ( num == EVENT_OBJECT_FACTORYsa ) strcpy(text, "Baut einen Kettentaucher"); - if ( num == EVENT_OBJECT_RTANK ) strcpy(text, "Forschungsprogramm Kettenantrieb"); - if ( num == EVENT_OBJECT_RFLY ) strcpy(text, "Forschungsprogramm Jetantrieb"); - if ( num == EVENT_OBJECT_RTHUMP ) strcpy(text, "Forschungsprogramm Stampfer"); - if ( num == EVENT_OBJECT_RCANON ) strcpy(text, "Forschungsprogramm Shooterkanone"); - if ( num == EVENT_OBJECT_RTOWER ) strcpy(text, "Forschungsprogramm Geschützturm"); - if ( num == EVENT_OBJECT_RPHAZER ) strcpy(text, "Forschungsprogramm Phazerkanone"); - if ( num == EVENT_OBJECT_RSHIELD ) strcpy(text, "Forschungsprogramm Schutzschild"); - if ( num == EVENT_OBJECT_RATOMIC ) strcpy(text, "Forschungsprogramm Brennstoffzelle"); - if ( num == EVENT_OBJECT_RiPAW ) strcpy(text, "Forschungsprogramm Krabbelantrieb"); - if ( num == EVENT_OBJECT_RiGUN ) strcpy(text, "Forschungsprogramm Orgashooterkanone"); - if ( num == EVENT_OBJECT_RESET ) strcpy(text, "Alles zurücksetzen"); - if ( num == EVENT_OBJECT_SEARCH ) strcpy(text, "Schnüffeln (\\key action;)"); - if ( num == EVENT_OBJECT_TERRAFORM ) strcpy(text, "Stampfen (\\key action;)"); - if ( num == EVENT_OBJECT_FIRE ) strcpy(text, "Feuer (\\key action;)"); - if ( num == EVENT_OBJECT_RECOVER ) strcpy(text, "Recyceln (\\key action;)"); - if ( num == EVENT_OBJECT_BEGSHIELD ) strcpy(text, "Schutzschild ausfahren (\\key action;)"); - if ( num == EVENT_OBJECT_ENDSHIELD ) strcpy(text, "Schutzschild einholen (\\key action;)"); - if ( num == EVENT_OBJECT_DIMSHIELD ) strcpy(text, "Reichweite Schutzschild"); - if ( num == EVENT_OBJECT_PROGRUN ) strcpy(text, "Gewähltes Programm ausführen"); - if ( num == EVENT_OBJECT_PROGEDIT ) strcpy(text, "Gewähltes Programm bearbeiten"); - if ( num == EVENT_OBJECT_INFOOK ) strcpy(text, "\\SatCom in Standby"); - if ( num == EVENT_OBJECT_DELETE ) strcpy(text, "Gebäude sprengen"); - if ( num == EVENT_OBJECT_GENERGY ) strcpy(text, "Energievorrat"); - if ( num == EVENT_OBJECT_GSHIELD ) strcpy(text, "Schäden"); - if ( num == EVENT_OBJECT_GRANGE ) strcpy(text, "Triebwerktemperatur"); - if ( num == EVENT_OBJECT_GPROGRESS ) strcpy(text, "Prozess im Gang ..."); - if ( num == EVENT_OBJECT_GRADAR ) strcpy(text, "Anzahl erfasster Insekten"); - if ( num == EVENT_OBJECT_GINFO ) strcpy(text, "Gesendete Informationen"); - if ( num == EVENT_OBJECT_COMPASS ) strcpy(text, "Kompass"); -//? if ( num == EVENT_OBJECT_MAP ) strcpy(text, "Minikarte"); - if ( num == EVENT_OBJECT_MAPZOOM ) strcpy(text, "Zoom Minikarte"); - if ( num == EVENT_OBJECT_CAMERA ) strcpy(text, "Kamera (\\key camera;)"); - if ( num == EVENT_OBJECT_CAMERAleft) strcpy(text, "Kamera links"); - if ( num == EVENT_OBJECT_CAMERAright) strcpy(text, "Kamera rechts"); - if ( num == EVENT_OBJECT_CAMERAnear) strcpy(text, "Kamera näher"); - if ( num == EVENT_OBJECT_CAMERAaway) strcpy(text, "Kamera weiter weg"); - if ( num == EVENT_OBJECT_HELP ) strcpy(text, "Anweisungen über das ausgewählte Objekt"); - if ( num == EVENT_OBJECT_SOLUCE ) strcpy(text, "Zeigt die Lösung"); - if ( num == EVENT_OBJECT_SHORTCUT00) strcpy(text, "Anzeige Roboter <-> Bauten"); - if ( num == EVENT_OBJECT_LIMIT ) strcpy(text, "Zeigt die Reichweite"); - if ( num == EVENT_OBJECT_PEN0 ) strcpy(text, "\\Bleistift abheben"); - if ( num == EVENT_OBJECT_PEN1 ) strcpy(text, "\\Schwarzen Bleistift hinunterlassen"); - if ( num == EVENT_OBJECT_PEN2 ) strcpy(text, "\\Gelben Bleistift hinunterlassen"); - if ( num == EVENT_OBJECT_PEN3 ) strcpy(text, "\\Orangefarbenen Bleistift hinunterlassen"); - if ( num == EVENT_OBJECT_PEN4 ) strcpy(text, "\\Roten Bleistift hinunterlassen"); - if ( num == EVENT_OBJECT_PEN5 ) strcpy(text, "\\Violetten Bleistift hinunterlassen"); - if ( num == EVENT_OBJECT_PEN6 ) strcpy(text, "\\Blauen Bleistift hinunterlassen"); - if ( num == EVENT_OBJECT_PEN7 ) strcpy(text, "\\Grünen Bleistift hinunterlassen"); - if ( num == EVENT_OBJECT_PEN8 ) strcpy(text, "\\Braunen Bleistift hinunterlassen"); - if ( num == EVENT_OBJECT_REC ) strcpy(text, "\\Aufnahme starten"); - if ( num == EVENT_OBJECT_STOP ) strcpy(text, "\\Aufnahme stoppen"); - if ( num == EVENT_DT_VISIT0 || - num == EVENT_DT_VISIT1 || - num == EVENT_DT_VISIT2 || - num == EVENT_DT_VISIT3 || - num == EVENT_DT_VISIT4 ) strcpy(text, "Zeigt den Ort"); - if ( num == EVENT_DT_END ) strcpy(text, "Weitermachen"); - if ( num == EVENT_CMD ) strcpy(text, "Befehleingabe"); - if ( num == EVENT_SPEED ) strcpy(text, "Spielgeschwindigkeit"); - - if ( num == EVENT_HYPER_PREV ) strcpy(text, "Vorherg. Seite"); - if ( num == EVENT_HYPER_NEXT ) strcpy(text, "Nächste Seite"); - if ( num == EVENT_HYPER_HOME ) strcpy(text, "Home"); - if ( num == EVENT_HYPER_COPY ) strcpy(text, "Kopieren"); - if ( num == EVENT_HYPER_SIZE1 ) strcpy(text, "Größe 1"); - if ( num == EVENT_HYPER_SIZE2 ) strcpy(text, "Größe 2"); - if ( num == EVENT_HYPER_SIZE3 ) strcpy(text, "Größe 3"); - if ( num == EVENT_HYPER_SIZE4 ) strcpy(text, "Größe 4"); - if ( num == EVENT_HYPER_SIZE5 ) strcpy(text, "Größe 5"); - if ( num == EVENT_SATCOM_HUSTON ) strcpy(text, "Anweisungen von Houston"); -#if _TEEN - if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Wörterbuch Englisch-Deutsch"); -#else - if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Satellitenbericht"); -#endif - if ( num == EVENT_SATCOM_LOADING ) strcpy(text, "Von Houston übermittelte Programme"); - if ( num == EVENT_SATCOM_OBJECT ) strcpy(text, "Liste der Objekte"); - if ( num == EVENT_SATCOM_PROG ) strcpy(text, "Hilfe über Programmieren"); - if ( num == EVENT_SATCOM_SOLUCE ) strcpy(text, "Lösung"); - - if ( num == EVENT_STUDIO_OK ) strcpy(text, "OK\\Programm kompilieren"); - if ( num == EVENT_STUDIO_CANCEL ) strcpy(text, "Abbrechen\\Editor schließen"); - if ( num == EVENT_STUDIO_NEW ) strcpy(text, "Neu"); - if ( num == EVENT_STUDIO_OPEN ) strcpy(text, "Öffnen (Ctrl+o)"); - if ( num == EVENT_STUDIO_SAVE ) strcpy(text, "Speichern (Ctrl+s)"); - if ( num == EVENT_STUDIO_UNDO ) strcpy(text, "Widerrufen (Ctrl+z)"); - if ( num == EVENT_STUDIO_CUT ) strcpy(text, "Ausschneiden (Ctrl+x)"); - if ( num == EVENT_STUDIO_COPY ) strcpy(text, "Kopieren (Ctrl+c)"); - if ( num == EVENT_STUDIO_PASTE ) strcpy(text, "Einfügen (Ctrl+v)"); - if ( num == EVENT_STUDIO_SIZE ) strcpy(text, "Zeichengröße"); - if ( num == EVENT_STUDIO_TOOL ) strcpy(text, "Anweisungen (\\key help;)"); - if ( num == EVENT_STUDIO_HELP ) strcpy(text, "Hilfe über Programmieren (\\key prog;)"); - if ( num == EVENT_STUDIO_COMPILE ) strcpy(text, "Kompilieren"); - if ( num == EVENT_STUDIO_RUN ) strcpy(text, "Start/Stop"); - if ( num == EVENT_STUDIO_REALTIME ) strcpy(text, "Pause/Weitermachen"); - if ( num == EVENT_STUDIO_STEP ) strcpy(text, "Ein Schritt"); - } - - if ( type == RES_OBJECT ) - { - if ( num == OBJECT_PORTICO ) strcpy(text, "Träger"); - if ( num == OBJECT_BASE ) strcpy(text, "Raumschiff"); - if ( num == OBJECT_DERRICK ) strcpy(text, "Bohrturm"); - if ( num == OBJECT_FACTORY ) strcpy(text, "Roboterfabrik"); - if ( num == OBJECT_REPAIR ) strcpy(text, "Reparaturzentrum"); - if ( num == OBJECT_DESTROYER ) strcpy(text, "Einstampfer"); - if ( num == OBJECT_STATION ) strcpy(text, "Kraftwerk"); - if ( num == OBJECT_CONVERT ) strcpy(text, "Konverter Erz-Titan"); - if ( num == OBJECT_TOWER ) strcpy(text, "Geschützturm"); - if ( num == OBJECT_NEST ) strcpy(text, "Orgastoffquelle"); - if ( num == OBJECT_RESEARCH ) strcpy(text, "Forschungszentrum"); - if ( num == OBJECT_RADAR ) strcpy(text, "Radar"); - if ( num == OBJECT_INFO ) strcpy(text, "Infoserver"); -#if _TEEN - if ( num == OBJECT_ENERGY ) strcpy(text, "Auflöser"); -#else - if ( num == OBJECT_ENERGY ) strcpy(text, "Batteriefabrik"); -#endif - if ( num == OBJECT_LABO ) strcpy(text, "Automatisches Labor"); - if ( num == OBJECT_NUCLEAR ) strcpy(text, "Brennstoffzellenfabrik"); - if ( num == OBJECT_PARA ) strcpy(text, "Blitzableiter"); - if ( num == OBJECT_SAFE ) strcpy(text, "Bunker"); - if ( num == OBJECT_HUSTON ) strcpy(text, "Kontrollzentrum"); - if ( num == OBJECT_TARGET1 ) strcpy(text, "Zielscheibe"); - if ( num == OBJECT_TARGET2 ) strcpy(text, "Zielscheibe"); - if ( num == OBJECT_START ) strcpy(text, "Startfläche"); - if ( num == OBJECT_END ) strcpy(text, "Zielfläche"); - if ( num == OBJECT_STONE ) strcpy(text, "Titanerz"); - if ( num == OBJECT_URANIUM ) strcpy(text, "Platinerz"); - if ( num == OBJECT_BULLET ) strcpy(text, "Orgastoff"); - if ( num == OBJECT_METAL ) strcpy(text, "Titan"); - if ( num == OBJECT_POWER ) strcpy(text, "Elektrolytische Batterie"); - if ( num == OBJECT_ATOMIC ) strcpy(text, "Brennstoffzelle"); - if ( num == OBJECT_BBOX ) strcpy(text, "Flugschreiber"); - if ( num == OBJECT_KEYa ) strcpy(text, "Schlüssel A"); - if ( num == OBJECT_KEYb ) strcpy(text, "Schlüssel B"); - if ( num == OBJECT_KEYc ) strcpy(text, "Schlüssel C"); - if ( num == OBJECT_KEYd ) strcpy(text, "Schlüssel D"); - if ( num == OBJECT_TNT ) strcpy(text, "Sprengstoff"); - if ( num == OBJECT_BOMB ) strcpy(text, "Landmine"); - if ( num == OBJECT_BAG ) strcpy(text, "Überlebenskit"); - if ( num == OBJECT_WAYPOINT ) strcpy(text, "Checkpoint"); - if ( num == OBJECT_FLAGb ) strcpy(text, "Blaue Fahne"); - if ( num == OBJECT_FLAGr ) strcpy(text, "Rote Fahne"); - if ( num == OBJECT_FLAGg ) strcpy(text, "Grüne Fahne"); - if ( num == OBJECT_FLAGy ) strcpy(text, "Gelbe Fahne"); - if ( num == OBJECT_FLAGv ) strcpy(text, "Violette Fahne"); - if ( num == OBJECT_MARKPOWER ) strcpy(text, "Markierung für unterirdische Energiequelle"); - if ( num == OBJECT_MARKURANIUM ) strcpy(text, "Markierung für unterirdisches Platinvorkommen"); - if ( num == OBJECT_MARKKEYa ) strcpy(text, "Markierung für vergrabenen Schlüssel A"); - if ( num == OBJECT_MARKKEYb ) strcpy(text, "Markierung für vergrabenen Schlüssel B"); - if ( num == OBJECT_MARKKEYc ) strcpy(text, "Markierung für vergrabenen Schlüssel C"); - if ( num == OBJECT_MARKKEYd ) strcpy(text, "Markierung für vergrabenen Schlüssel D"); - if ( num == OBJECT_MARKSTONE ) strcpy(text, "Markierung für unterirdisches Titanvorkommen"); - if ( num == OBJECT_MOBILEft ) strcpy(text, "Übungsroboter"); - if ( num == OBJECT_MOBILEtt ) strcpy(text, "Übungsroboter"); - if ( num == OBJECT_MOBILEwt ) strcpy(text, "Übungsroboter"); - if ( num == OBJECT_MOBILEit ) strcpy(text, "Übungsroboter"); - if ( num == OBJECT_MOBILEfa ) strcpy(text, "Transporter"); - if ( num == OBJECT_MOBILEta ) strcpy(text, "Transporter"); - if ( num == OBJECT_MOBILEwa ) strcpy(text, "Transporter"); - if ( num == OBJECT_MOBILEia ) strcpy(text, "Transporter"); - if ( num == OBJECT_MOBILEfc ) strcpy(text, "Shooter"); - if ( num == OBJECT_MOBILEtc ) strcpy(text, "Shooter"); - if ( num == OBJECT_MOBILEwc ) strcpy(text, "Shooter"); - if ( num == OBJECT_MOBILEic ) strcpy(text, "Shooter"); - if ( num == OBJECT_MOBILEfi ) strcpy(text, "OrgaShooter"); - if ( num == OBJECT_MOBILEti ) strcpy(text, "OrgaShooter"); - if ( num == OBJECT_MOBILEwi ) strcpy(text, "OrgaShooter"); - if ( num == OBJECT_MOBILEii ) strcpy(text, "OrgaShooter"); - if ( num == OBJECT_MOBILEfs ) strcpy(text, "Schnüffler"); - if ( num == OBJECT_MOBILEts ) strcpy(text, "Schnüffler"); - if ( num == OBJECT_MOBILEws ) strcpy(text, "Schnüffler"); - if ( num == OBJECT_MOBILEis ) strcpy(text, "Schnüffler"); - if ( num == OBJECT_MOBILErt ) strcpy(text, "Stampfer"); - if ( num == OBJECT_MOBILErc ) strcpy(text, "Phazershooter"); - if ( num == OBJECT_MOBILErr ) strcpy(text, "Recycler"); - if ( num == OBJECT_MOBILErs ) strcpy(text, "Schutzschild"); - if ( num == OBJECT_MOBILEsa ) strcpy(text, "Kettentaucher"); - if ( num == OBJECT_MOBILEtg ) strcpy(text, "Mobile Zielscheibe"); - if ( num == OBJECT_MOBILEdr ) strcpy(text, "Zeichner"); - if ( num == OBJECT_HUMAN ) strcpy(text, g_gamerName); - if ( num == OBJECT_TECH ) strcpy(text, "Techniker"); - if ( num == OBJECT_TOTO ) strcpy(text, "Robby"); - if ( num == OBJECT_MOTHER ) strcpy(text, "Insektenkönigin"); - if ( num == OBJECT_ANT ) strcpy(text, "Ameise"); - if ( num == OBJECT_SPIDER ) strcpy(text, "Spinne"); - if ( num == OBJECT_BEE ) strcpy(text, "Wespe"); - if ( num == OBJECT_WORM ) strcpy(text, "Wurm"); - if ( num == OBJECT_EGG ) strcpy(text, "Ei"); - if ( num == OBJECT_RUINmobilew1 ) strcpy(text, "Roboterwrack"); - if ( num == OBJECT_RUINmobilew2 ) strcpy(text, "Roboterwrack"); - if ( num == OBJECT_RUINmobilet1 ) strcpy(text, "Roboterwrack"); - if ( num == OBJECT_RUINmobilet2 ) strcpy(text, "Roboterwrack"); - if ( num == OBJECT_RUINmobiler1 ) strcpy(text, "Roboterwrack"); - if ( num == OBJECT_RUINmobiler2 ) strcpy(text, "Roboterwrack"); - if ( num == OBJECT_RUINfactory ) strcpy(text, "Gebäuderuine"); - if ( num == OBJECT_RUINdoor ) strcpy(text, "Gebäuderuine"); - if ( num == OBJECT_RUINsupport ) strcpy(text, "Abfall"); - if ( num == OBJECT_RUINradar ) strcpy(text, "Gebäuderuine"); - if ( num == OBJECT_RUINconvert ) strcpy(text, "Gebäuderuine"); - if ( num == OBJECT_RUINbase ) strcpy(text, "Raumschiffruine"); - if ( num == OBJECT_RUINhead ) strcpy(text, "Raumschiffruine"); - if ( num == OBJECT_APOLLO1 || - num == OBJECT_APOLLO3 || - num == OBJECT_APOLLO4 || - num == OBJECT_APOLLO5 ) strcpy(text, "Überreste einer Apollo-Mission"); - if ( num == OBJECT_APOLLO2 ) strcpy(text, "Lunar Roving Vehicle"); - } - - if ( type == RES_ERR ) - { - strcpy(text, "Fehler"); - if ( num == ERR_CMD ) strcpy(text, "Befehl unbekannt"); -#if _NEWLOOK - if ( num == ERR_INSTALL ) strcpy(text, "CeeBot wurde nicht installiert."); - if ( num == ERR_NOCD ) strcpy(text, "Legen Sie die CeeBot-CD ein\nund starten Sie das Spiel neu."); -#else - if ( num == ERR_INSTALL ) strcpy(text, "COLOBOT wurde nicht installiert."); - if ( num == ERR_NOCD ) strcpy(text, "Legen Sie die COLOBOT-CD ein\nund starten Sie das Spiel neu."); -#endif - if ( num == ERR_MANIP_VEH ) strcpy(text, "Roboter ungeeignet"); - if ( num == ERR_MANIP_FLY ) strcpy(text, "Im Flug unmöglich"); - if ( num == ERR_MANIP_BUSY ) strcpy(text, "Trägt schon etwas"); - if ( num == ERR_MANIP_NIL ) strcpy(text, "Nichts zu ergreifen"); - if ( num == ERR_MANIP_MOTOR ) strcpy(text, "In Fahrt unmöglich"); - if ( num == ERR_MANIP_OCC ) strcpy(text, "Stelle schon besetzt"); - if ( num == ERR_MANIP_FRIEND ) strcpy(text, "Kein anderer Roboter"); - if ( num == ERR_MANIP_RADIO ) strcpy(text, "Sie können keinen radioaktiven Gegenstand tragen"); - if ( num == ERR_MANIP_WATER ) strcpy(text, "Sie können unter Wasser nichts tragen"); - if ( num == ERR_MANIP_EMPTY ) strcpy(text, "Nichts abzulegen"); - if ( num == ERR_BUILD_FLY ) strcpy(text, "Im Flug unmöglich"); - if ( num == ERR_BUILD_WATER ) strcpy(text, "Unter Wasser unmöglich"); - if ( num == ERR_BUILD_ENERGY ) strcpy(text, "Nicht genug Energie"); - if ( num == ERR_BUILD_METALAWAY ) strcpy(text, "Titan zu weit weg"); - if ( num == ERR_BUILD_METALNEAR ) strcpy(text, "Titan zu nahe"); - if ( num == ERR_BUILD_METALINEX ) strcpy(text, "Kein Titan vorhanden"); - if ( num == ERR_BUILD_FLAT ) strcpy(text, "Boden nicht eben genug"); - if ( num == ERR_BUILD_FLATLIT ) strcpy(text, "Ebener Boden nicht groß genug"); - if ( num == ERR_BUILD_BUSY ) strcpy(text, "Stelle schon besetzt"); - if ( num == ERR_BUILD_BASE ) strcpy(text, "Zu nahe am Raumschiff"); - if ( num == ERR_BUILD_NARROW ) strcpy(text, "Zu nahe an einem Gebäude"); - if ( num == ERR_BUILD_MOTOR ) strcpy(text, "In Fahrt unmöglich"); - if ( num == ERR_SEARCH_FLY ) strcpy(text, "Im Flug unmöglich"); - if ( num == ERR_SEARCH_VEH ) strcpy(text, "Roboter ungeeignet"); - if ( num == ERR_SEARCH_MOTOR ) strcpy(text, "In Fahrt unmöglich"); - if ( num == ERR_TERRA_VEH ) strcpy(text, "Roboter ungeeignet"); - if ( num == ERR_TERRA_ENERGY ) strcpy(text, "Nicht genug Energie"); - if ( num == ERR_TERRA_FLOOR ) strcpy(text, "Boden ungeeignet"); - if ( num == ERR_TERRA_BUILDING ) strcpy(text, "Gebäude zu nahe"); - if ( num == ERR_TERRA_OBJECT ) strcpy(text, "Gegenstand zu nahe"); - if ( num == ERR_RECOVER_VEH ) strcpy(text, "Roboter ungeeignet"); - if ( num == ERR_RECOVER_ENERGY ) strcpy(text, "Nicht genug Energie"); - if ( num == ERR_RECOVER_NULL ) strcpy(text, "Nichts zu recyceln"); - if ( num == ERR_SHIELD_VEH ) strcpy(text, "Roboter ungeeignet"); - if ( num == ERR_SHIELD_ENERGY ) strcpy(text, "Keine Energie mehr"); -//? if ( num == ERR_COM ) strcpy(text, "Kommunikationsproblem mit dem Roboter"); - if ( num == ERR_MOVE_IMPOSSIBLE ) strcpy(text, "Ziel kann nicht erreicht werden"); - if ( num == ERR_FIND_IMPOSSIBLE ) strcpy(text, "Das Objekt existiert nicht"); - if ( num == ERR_GOTO_IMPOSSIBLE ) strcpy(text, "Ziel kann nicht erreicht werden"); - if ( num == ERR_GOTO_ITER ) strcpy(text, "Ziel kann nicht erreicht werden"); - if ( num == ERR_GOTO_BUSY ) strcpy(text, "Ziel ist schon besetzt"); - if ( num == ERR_FIRE_VEH ) strcpy(text, "Roboter ungeeignet"); - if ( num == ERR_FIRE_ENERGY ) strcpy(text, "Nicht genug Energie"); - if ( num == ERR_FIRE_FLY ) strcpy(text, "Im Flug unmöglich"); - if ( num == ERR_CONVERT_EMPTY ) strcpy(text, "Kein konvertierbares Titanerz vorhanden"); - if ( num == ERR_DERRICK_NULL ) strcpy(text, "Keine unterirdische Erzlagerstätte"); - if ( num == ERR_STATION_NULL ) strcpy(text, "Kein unterirdisches Energievorkommen"); - if ( num == ERR_TOWER_POWER ) strcpy(text, "Keine Batterie"); - if ( num == ERR_TOWER_ENERGY ) strcpy(text, "Keine Energie mehr"); - if ( num == ERR_RESEARCH_POWER ) strcpy(text, "Keine Batterie"); - if ( num == ERR_RESEARCH_ENERGY ) strcpy(text, "Nicht mehr genug Energie"); - if ( num == ERR_RESEARCH_TYPE ) strcpy(text, "Falscher Batterietyp"); - if ( num == ERR_RESEARCH_ALREADY) strcpy(text, "Forschungsprogramm schon ausgeführt"); - if ( num == ERR_ENERGY_NULL ) strcpy(text, "Kein unterirdisches Energievorkommen"); - if ( num == ERR_ENERGY_LOW ) strcpy(text, "Noch nicht genug Energie"); - if ( num == ERR_ENERGY_EMPTY ) strcpy(text, "Kein konvertierbares Titanerz vorhanden"); - if ( num == ERR_ENERGY_BAD ) strcpy(text, "Wandelt nur Titanerz um"); - if ( num == ERR_BASE_DLOCK ) strcpy(text, "Die Türen werden von einem Gegenstand blockiert"); - if ( num == ERR_BASE_DHUMAN ) strcpy(text, "Gehen Sie an Bord, bevor Sie abheben"); - if ( num == ERR_LABO_NULL ) strcpy(text, "Nichts zu analysieren"); - if ( num == ERR_LABO_BAD ) strcpy(text, "Analysiert nur Orgastoff"); - if ( num == ERR_LABO_ALREADY ) strcpy(text, "Analyse schon durchgeführt"); - if ( num == ERR_NUCLEAR_NULL ) strcpy(text, "Kein unterirdisches Energievorkommen"); - if ( num == ERR_NUCLEAR_LOW ) strcpy(text, "Noch nicht genug Energie"); - if ( num == ERR_NUCLEAR_EMPTY ) strcpy(text, "Kein konvertierbares Platin"); - if ( num == ERR_NUCLEAR_BAD ) strcpy(text, "Wandelt nur Platin um"); - if ( num == ERR_FACTORY_NULL ) strcpy(text, "Kein Titan vorhanden"); - if ( num == ERR_FACTORY_NEAR ) strcpy(text, "Ein Gegenstand ist zu nahe"); - if ( num == ERR_RESET_NEAR ) strcpy(text, "Stelle schon besetzt"); - if ( num == ERR_INFO_NULL ) strcpy(text, "Kein Infoserver in Reichweite"); - if ( num == ERR_VEH_VIRUS ) strcpy(text, "Ein Programm wurde von einem Virus infiziert"); - if ( num == ERR_BAT_VIRUS ) strcpy(text, "Von Virus infiziert, zeitweise außer Betrieb"); - if ( num == ERR_VEH_POWER ) strcpy(text, "Keine Batterie"); - if ( num == ERR_VEH_ENERGY ) strcpy(text, "Keine Energie mehr"); - if ( num == ERR_FLAG_FLY ) strcpy(text, "Im Flug unmöglich"); - if ( num == ERR_FLAG_WATER ) strcpy(text, "Im Wasser unmöglich"); - if ( num == ERR_FLAG_MOTOR ) strcpy(text, "Beim Gehen unmöglich"); - if ( num == ERR_FLAG_BUSY ) strcpy(text, "Unmöglich wenn Sie etwas tragen"); - if ( num == ERR_FLAG_CREATE ) strcpy(text, "Zu viele Fahnen dieser Farbe (Maximum 5)"); - if ( num == ERR_FLAG_PROXY ) strcpy(text, "Zu nahe an einer anderen Fahne"); - if ( num == ERR_FLAG_DELETE ) strcpy(text, "Keine Fahne in Reichweite"); - if ( num == ERR_MISSION_NOTERM ) strcpy(text, "Mission noch nicht beendet (Drücken Sie auf \\key help; für weitere Informationen)"); - if ( num == ERR_DELETEMOBILE ) strcpy(text, "Roboter zerstört"); - if ( num == ERR_DELETEBUILDING ) strcpy(text, "Gebäude zerstört"); - if ( num == ERR_TOOMANY ) strcpy(text, "Kein neues Objekt kann erstellt werden (zu viele vorhanden)"); - if ( num == ERR_OBLIGATORYTOKEN ) strcpy(text, "Es fehlt \"%s\" in Ihrem Programm"); - if ( num == ERR_PROHIBITEDTOKEN ) strcpy(text, "In dieser Übung verboten"); - - if ( num == INFO_BUILD ) strcpy(text, "Gebäude fertiggestellt"); - if ( num == INFO_CONVERT ) strcpy(text, "Titan verfügbar"); - if ( num == INFO_RESEARCH ) strcpy(text, "Forschungsprogramm abgeschlossen"); - if ( num == INFO_RESEARCHTANK ) strcpy(text, "Herstellung eines Roboters mit Kettenantrieb möglich"); - if ( num == INFO_RESEARCHFLY ) strcpy(text, "Sie können jetzt mit den Tasten \\key gup; und \\key gdown; fliegen"); - if ( num == INFO_RESEARCHTHUMP ) strcpy(text, "Herstellung eines Stampfers möglich"); - if ( num == INFO_RESEARCHCANON ) strcpy(text, "Herstellung eines Shooters möglich"); - if ( num == INFO_RESEARCHTOWER ) strcpy(text, "Errichtung eines Geschützturms möglich"); - if ( num == INFO_RESEARCHPHAZER ) strcpy(text, "Herstellung eines Phazershooters möglich"); - if ( num == INFO_RESEARCHSHIELD ) strcpy(text, "Herstellung eines Schutzschildes möglich"); - if ( num == INFO_RESEARCHATOMIC ) strcpy(text, "Errichtung einer Brennstoffzellenfabrik möglich"); - if ( num == INFO_FACTORY ) strcpy(text, "Neuer Roboter verfügbar"); - if ( num == INFO_LABO ) strcpy(text, "Analyse vollendet"); - if ( num == INFO_ENERGY ) strcpy(text, "Batterie verfügbar"); - if ( num == INFO_NUCLEAR ) strcpy(text, "Brennstoffzelle verfügbar"); - if ( num == INFO_FINDING ) strcpy(text, "Sie haben ein brauchbares Objekt gefunden"); - if ( num == INFO_MARKPOWER ) strcpy(text, "Geeignete Stelle für Kraftwerk gefunden"); - if ( num == INFO_MARKURANIUM ) strcpy(text, "Geeignete Stelle für Bohrturm gefunden"); - if ( num == INFO_MARKSTONE ) strcpy(text, "Geeignete Stelle für Bohrturm gefunden"); - if ( num == INFO_MARKKEYa ) strcpy(text, "Geeignete Stelle für Bohrturm gefunden"); - if ( num == INFO_MARKKEYb ) strcpy(text, "Geeignete Stelle für Bohrturm gefunden"); - if ( num == INFO_MARKKEYc ) strcpy(text, "Geeignete Stelle für Bohrturm gefunden"); - if ( num == INFO_MARKKEYd ) strcpy(text, "Geeignete Stelle für Bohrturm gefunden"); - if ( num == INFO_WIN ) strcpy(text, "<<< Bravo, Mission vollendet >>>"); - if ( num == INFO_LOST ) strcpy(text, "<<< Mission gescheitert >>>"); - if ( num == INFO_LOSTq ) strcpy(text, "<<< Mission gescheitert >>>"); - if ( num == INFO_WRITEOK ) strcpy(text, "Mission gespeichert"); - if ( num == INFO_DELETEPATH ) strcpy(text, "Checkpoint erreicht"); - if ( num == INFO_DELETEMOTHER ) strcpy(text, "Insektenkönigin tödlich verwundet"); - if ( num == INFO_DELETEANT ) strcpy(text, "Ameise tödlich verwundet"); - if ( num == INFO_DELETEBEE ) strcpy(text, "Wespe tödlich verwundet"); - if ( num == INFO_DELETEWORM ) strcpy(text, "Wurm tödlich verwundet"); - if ( num == INFO_DELETESPIDER ) strcpy(text, "Spinne tödlich verwundet"); - if ( num == INFO_BEGINSATCOM ) strcpy(text, "Beziehen Sie sich auf Ihren SatCom, indem Sie auf \\key help; drücken"); - } - - if ( type == RES_CBOT ) - { - strcpy(text, "Fehler"); - if ( num == TX_OPENPAR ) strcpy(text, "Es fehlt eine offene Klammer ""("""); - if ( num == TX_CLOSEPAR ) strcpy(text, "Es fehlt eine geschlossene Klammer "")"""); - if ( num == TX_NOTBOOL ) strcpy(text, "Der Ausdruck muss einen boolschen Wert ergeben"); - if ( num == TX_UNDEFVAR ) strcpy(text, "Variable nicht deklariert"); - if ( num == TX_BADLEFT ) strcpy(text, "Zuweisung unmöglich"); - if ( num == TX_ENDOF ) strcpy(text, "Es fehlt ein Strichpunkt "";"" am Ende der Anweisung"); - if ( num == TX_OUTCASE ) strcpy(text, "Anweisung ""case"" ohne vorhergehende Anweisung ""switch"""); - if ( num == TX_NOTERM ) strcpy(text, "Hier ist eine Anweisung nach dem Ende des Programms"); - if ( num == TX_CLOSEBLK ) strcpy(text, "Es fehlt eine geschlossene geschweifte Klammer ""}"" (Ende des Blocks)"); - if ( num == TX_ELSEWITHOUTIF ) strcpy(text, "Anweisung ""else"" ohne vorhergehende Anweisung ""if"""); - if ( num == TX_OPENBLK ) strcpy(text, "Es fehlt eine offene geschweifte Klammer""{"""); - if ( num == TX_BADTYPE ) strcpy(text, "Der Ausdruck ergibt einen falschen Typ für die Zuweisung"); - if ( num == TX_REDEFVAR ) strcpy(text, "Eine Variable wird zum zweiten Mal deklariert"); - if ( num == TX_BAD2TYPE ) strcpy(text, "Die zwei Operanden sind nicht kompatibel"); - if ( num == TX_UNDEFCALL ) strcpy(text, "Unbekannte Funktion"); - if ( num == TX_MISDOTS ) strcpy(text, "Es fehlt ein Doppelpunkt "" : """); - if ( num == TX_WHILE ) strcpy(text, "Es fehlt das Wort ""while"""); - if ( num == TX_BREAK ) strcpy(text, "Anweisung ""break"" außerhalb einer Schleife"); - if ( num == TX_LABEL ) strcpy(text, "Ein Label kann nur vor den Anweisungen ""for"", ""while"", ""do"" oder ""switch"" vorkommen"); - if ( num == TX_NOLABEL ) strcpy(text, "Dieses Label existiert nicht"); - if ( num == TX_NOCASE ) strcpy(text, "Es fehlt eine Anweisung ""case"""); - if ( num == TX_BADNUM ) strcpy(text, "Es fehlt eine Zahl"); - if ( num == TX_VOID ) strcpy(text, "Parameter void"); - if ( num == TX_NOTYP ) strcpy(text, "Hier muss ein Variablentyp stehen"); - if ( num == TX_NOVAR ) strcpy(text, "Es fehlt der Name einer Variable"); - if ( num == TX_NOFONC ) strcpy(text, "Hier muss der Name der Funktion stehen"); - if ( num == TX_OVERPARAM ) strcpy(text, "Zu viele Parameter"); - if ( num == TX_REDEF ) strcpy(text, "Diese Funktion gibt es schon"); - if ( num == TX_LOWPARAM ) strcpy(text, "Nicht genug Parameter"); - if ( num == TX_BADPARAM ) strcpy(text, "Keine Funktion mit diesem Namen verträgt Parameter diesen Typs"); - if ( num == TX_NUMPARAM ) strcpy(text, "Keine Funktion mit diesem Namen verträgt diese Anzahl Parameter"); - if ( num == TX_NOITEM ) strcpy(text, "Dieses Element gibt es nicht in dieser Klasse"); - if ( num == TX_DOT ) strcpy(text, "Das Objekt ist nicht eine Instanz einer Klasse"); - if ( num == TX_NOCONST ) strcpy(text, "Es gibt keinen geeigneten Konstruktor"); - if ( num == TX_REDEFCLASS ) strcpy(text, "Diese Klasse gibt es schon"); - if ( num == TX_CLBRK ) strcpy(text, "Es fehlt eine geschlossene eckige Klammer "" ] """); - if ( num == TX_RESERVED ) strcpy(text, "Dieses Wort ist reserviert"); - if ( num == TX_BADNEW ) strcpy(text, "Falsche Argumente für ""new"""); - if ( num == TX_OPBRK ) strcpy(text, "Es fehlt eine offene eckige Klammer "" [ """); - if ( num == TX_BADSTRING ) strcpy(text, "Hier wird eine Zeichenkette erwartet"); - if ( num == TX_BADINDEX ) strcpy(text, "Falscher Typ für einen Index"); - if ( num == TX_PRIVATE ) strcpy(text, "Geschütztes Element (private)"); - if ( num == TX_NOPUBLIC ) strcpy(text, "Hier muss das Wort ""public"" stehen"); - if ( num == TX_DIVZERO ) strcpy(text, "Teilung durch Null"); - if ( num == TX_NOTINIT ) strcpy(text, "Der Wert dieser Variable wurde nicht definiert"); - if ( num == TX_BADTHROW ) strcpy(text, "Negativer Wert ungeeignet für Anweisung ""throw"""); - if ( num == TX_NORETVAL ) strcpy(text, "Die Funktion hat kein Ergebnis zurückgegeben"); - if ( num == TX_NORUN ) strcpy(text, "Keine Funktion wird ausgeführt"); - if ( num == TX_NOCALL ) strcpy(text, "Die aufgerufene Funktion existiert nicht"); - if ( num == TX_NOCLASS ) strcpy(text, "Diese Klasse existiert nicht"); - if ( num == TX_NULLPT ) strcpy(text, "Das Objekt existiert nicht"); - if ( num == TX_OPNAN ) strcpy(text, "Operation mit dem Wert ""nan"""); - if ( num == TX_OUTARRAY ) strcpy(text, "Zugriff im Array außerhalb der Grenzen"); - if ( num == TX_STACKOVER ) strcpy(text, "Stack overflow"); - if ( num == TX_DELETEDPT ) strcpy(text, "Objekt nicht verfügbar"); - if ( num == TX_FILEOPEN ) strcpy(text, "Die Datei kann nicht geöffnet werden"); - if ( num == TX_NOTOPEN ) strcpy(text, "Die Datei wurde nicht geöffnet"); - if ( num == TX_ERRREAD ) strcpy(text, "Fehler beim Lesezugriff"); - if ( num == TX_ERRWRITE ) strcpy(text, "Fehler beim Schreibzugriff"); - } - - if ( type == RES_KEY ) - { - if ( num == 0 ) strcpy(text, "< keine >"); - if ( num == VK_LEFT ) strcpy(text, "Pfeiltaste links"); - if ( num == VK_RIGHT ) strcpy(text, "Pfeiltaste rechts"); - if ( num == VK_UP ) strcpy(text, "Pfeil nach oben"); - if ( num == VK_DOWN ) strcpy(text, "Pfeil nach unten"); - if ( num == VK_CANCEL ) strcpy(text, "Ctrl-Break"); - if ( num == VK_BACK ) strcpy(text, "<--"); - if ( num == VK_TAB ) strcpy(text, "Tab"); - if ( num == VK_CLEAR ) strcpy(text, "Clear"); - if ( num == VK_RETURN ) strcpy(text, "Eingabe"); - if ( num == VK_SHIFT ) strcpy(text, "Shift"); - if ( num == VK_CONTROL ) strcpy(text, "Ctrl"); - if ( num == VK_MENU ) strcpy(text, "Alt"); - if ( num == VK_PAUSE ) strcpy(text, "Pause"); - if ( num == VK_CAPITAL ) strcpy(text, "Caps Lock"); - if ( num == VK_ESCAPE ) strcpy(text, "Esc"); - if ( num == VK_SPACE ) strcpy(text, "Leertaste"); - if ( num == VK_PRIOR ) strcpy(text, "Page Up"); - if ( num == VK_NEXT ) strcpy(text, "Page Down"); - if ( num == VK_END ) strcpy(text, "End"); - if ( num == VK_HOME ) strcpy(text, "Home"); - if ( num == VK_SELECT ) strcpy(text, "Select"); - if ( num == VK_EXECUTE ) strcpy(text, "Execute"); - if ( num == VK_SNAPSHOT ) strcpy(text, "Print Scrn"); - if ( num == VK_INSERT ) strcpy(text, "Insert"); - if ( num == VK_DELETE ) strcpy(text, "Delete"); - if ( num == VK_HELP ) strcpy(text, "Help"); - if ( num == VK_LWIN ) strcpy(text, "Left Windows"); - if ( num == VK_RWIN ) strcpy(text, "Right Windows"); - if ( num == VK_APPS ) strcpy(text, "Application key"); - if ( num == VK_NUMPAD0 ) strcpy(text, "NumPad 0"); - if ( num == VK_NUMPAD1 ) strcpy(text, "NumPad 1"); - if ( num == VK_NUMPAD2 ) strcpy(text, "NumPad 2"); - if ( num == VK_NUMPAD3 ) strcpy(text, "NumPad 3"); - if ( num == VK_NUMPAD4 ) strcpy(text, "NumPad 4"); - if ( num == VK_NUMPAD5 ) strcpy(text, "NumPad 5"); - if ( num == VK_NUMPAD6 ) strcpy(text, "NumPad 6"); - if ( num == VK_NUMPAD7 ) strcpy(text, "NumPad 7"); - if ( num == VK_NUMPAD8 ) strcpy(text, "NumPad 8"); - if ( num == VK_NUMPAD9 ) strcpy(text, "NumPad 9"); - if ( num == VK_MULTIPLY ) strcpy(text, "NumPad *"); - if ( num == VK_ADD ) strcpy(text, "NumPad +"); - if ( num == VK_SEPARATOR ) strcpy(text, "NumPad sep"); - if ( num == VK_SUBTRACT ) strcpy(text, "NumPad -"); - if ( num == VK_DECIMAL ) strcpy(text, "NumPad ."); - if ( num == VK_DIVIDE ) strcpy(text, "NumPad /"); - if ( num == VK_F1 ) strcpy(text, "F1"); - if ( num == VK_F2 ) strcpy(text, "F2"); - if ( num == VK_F3 ) strcpy(text, "F3"); - if ( num == VK_F4 ) strcpy(text, "F4"); - if ( num == VK_F5 ) strcpy(text, "F5"); - if ( num == VK_F6 ) strcpy(text, "F6"); - if ( num == VK_F7 ) strcpy(text, "F7"); - if ( num == VK_F8 ) strcpy(text, "F8"); - if ( num == VK_F9 ) strcpy(text, "F9"); - if ( num == VK_F10 ) strcpy(text, "F10"); - if ( num == VK_F11 ) strcpy(text, "F11"); - if ( num == VK_F12 ) strcpy(text, "F12"); - if ( num == VK_F13 ) strcpy(text, "F13"); - if ( num == VK_F14 ) strcpy(text, "F14"); - if ( num == VK_F15 ) strcpy(text, "F15"); - if ( num == VK_F16 ) strcpy(text, "F16"); - if ( num == VK_F17 ) strcpy(text, "F17"); - if ( num == VK_F18 ) strcpy(text, "F18"); - if ( num == VK_F19 ) strcpy(text, "F19"); - if ( num == VK_F20 ) strcpy(text, "F20"); - if ( num == VK_NUMLOCK ) strcpy(text, "Num Lock"); - if ( num == VK_SCROLL ) strcpy(text, "Scroll"); - if ( num == VK_ATTN ) strcpy(text, "Attn"); - if ( num == VK_CRSEL ) strcpy(text, "CrSel"); - if ( num == VK_EXSEL ) strcpy(text, "ExSel"); - if ( num == VK_EREOF ) strcpy(text, "Erase EOF"); - if ( num == VK_PLAY ) strcpy(text, "Play"); - if ( num == VK_ZOOM ) strcpy(text, "Zoom"); - if ( num == VK_PA1 ) strcpy(text, "PA1"); - if ( num == VK_OEM_CLEAR ) strcpy(text, "Clear"); - if ( num == VK_BUTTON1 ) strcpy(text, "Knopf 1"); - if ( num == VK_BUTTON2 ) strcpy(text, "Knopf 2"); - if ( num == VK_BUTTON3 ) strcpy(text, "Knopf 3"); - if ( num == VK_BUTTON4 ) strcpy(text, "Knopf 4"); - if ( num == VK_BUTTON5 ) strcpy(text, "Knopf 5"); - if ( num == VK_BUTTON6 ) strcpy(text, "Knopf 6"); - if ( num == VK_BUTTON7 ) strcpy(text, "Knopf 7"); - if ( num == VK_BUTTON8 ) strcpy(text, "Knopf 8"); - if ( num == VK_BUTTON9 ) strcpy(text, "Knopf 9"); - if ( num == VK_BUTTON10 ) strcpy(text, "Knopf 10"); - if ( num == VK_BUTTON11 ) strcpy(text, "Knopf 11"); - if ( num == VK_BUTTON12 ) strcpy(text, "Knopf 12"); - if ( num == VK_BUTTON13 ) strcpy(text, "Knopf 13"); - if ( num == VK_BUTTON14 ) strcpy(text, "Knopf 14"); - if ( num == VK_BUTTON15 ) strcpy(text, "Knopf 15"); - if ( num == VK_BUTTON16 ) strcpy(text, "Knopf 16"); - if ( num == VK_BUTTON17 ) strcpy(text, "Knopf 17"); - if ( num == VK_BUTTON18 ) strcpy(text, "Knopf 18"); - if ( num == VK_BUTTON19 ) strcpy(text, "Knopf 19"); - if ( num == VK_BUTTON20 ) strcpy(text, "Knopf 20"); - if ( num == VK_BUTTON21 ) strcpy(text, "Knopf 21"); - if ( num == VK_BUTTON22 ) strcpy(text, "Knopf 22"); - if ( num == VK_BUTTON23 ) strcpy(text, "Knopf 23"); - if ( num == VK_BUTTON24 ) strcpy(text, "Knopf 24"); - if ( num == VK_BUTTON25 ) strcpy(text, "Knopf 25"); - if ( num == VK_BUTTON26 ) strcpy(text, "Knopf 26"); - if ( num == VK_BUTTON27 ) strcpy(text, "Knopf 27"); - if ( num == VK_BUTTON28 ) strcpy(text, "Knopf 28"); - if ( num == VK_BUTTON29 ) strcpy(text, "Knopf 29"); - if ( num == VK_BUTTON30 ) strcpy(text, "Knopf 30"); - if ( num == VK_BUTTON31 ) strcpy(text, "Knopf 31"); - if ( num == VK_BUTTON32 ) strcpy(text, "Knopf 32"); - if ( num == VK_WHEELUP ) strcpy(text, "Mausrad nach vorne"); - if ( num == VK_WHEELDOWN ) strcpy(text, "Mausrad zurück"); - } -#endif - -#if _POLISH - if ( type == RES_TEXT ) - { - #if _FULL - if ( num == RT_VERSION_ID ) strcpy(text, "Wersja 1.18 /pl"); - #endif - #if _NET - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A 1.18"); - #endif - #if _SCHOOL & _EDU - #if _TEEN - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen EDU 1.18"); - #else - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A EDU 1.18"); - #endif - #endif - #if _SCHOOL & _PERSO - #if _TEEN - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen PERSO 1.18"); - #else - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A PERSO 1.18"); - #endif - #endif - #if _SCHOOL & _CEEBOTDEMO - #if _TEEN - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen DEMO 1.18"); - #else - if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A DEMO 1.18"); - #endif - #endif - #if _DEMO - if ( num == RT_VERSION_ID ) strcpy(text, "Demo 1.18 /pl"); - #endif - if ( num == RT_DISINFO_TITLE ) strcpy(text, "SatCom"); - if ( num == RT_WINDOW_MAXIMIZED ) strcpy(text, "Powiêksz"); - if ( num == RT_WINDOW_MINIMIZED ) strcpy(text, "Pomniejsz"); - if ( num == RT_WINDOW_STANDARD ) strcpy(text, "Normalna wielkoœæ"); - if ( num == RT_WINDOW_CLOSE ) strcpy(text, "Zamknij"); - - if ( num == RT_STUDIO_TITLE ) strcpy(text, "Edytor programu"); - if ( num == RT_SCRIPT_NEW ) strcpy(text, "Nowy"); - if ( num == RT_NAME_DEFAULT ) strcpy(text, "Gracz"); - if ( num == RT_IO_NEW ) strcpy(text, "Nowy ..."); - if ( num == RT_KEY_OR ) strcpy(text, " lub "); - -#if _NEWLOOK - if ( num == RT_TITLE_BASE ) strcpy(text, "CeeBot"); - if ( num == RT_TITLE_INIT ) strcpy(text, "CeeBot"); -#else - if ( num == RT_TITLE_BASE ) strcpy(text, "COLOBOT"); - if ( num == RT_TITLE_INIT ) strcpy(text, "COLOBOT"); -#endif - if ( num == RT_TITLE_TRAINER ) strcpy(text, "Æwiczenia programistyczne"); - if ( num == RT_TITLE_DEFI ) strcpy(text, "Wyzwania"); - if ( num == RT_TITLE_MISSION ) strcpy(text, "Misje"); - if ( num == RT_TITLE_FREE ) strcpy(text, "Swobodna gra"); - if ( num == RT_TITLE_TEEN ) strcpy(text, "Swobodna gra"); - if ( num == RT_TITLE_USER ) strcpy(text, "Poziomy u¿ytkownika"); - if ( num == RT_TITLE_PROTO ) strcpy(text, "Prototypy"); - if ( num == RT_TITLE_SETUP ) strcpy(text, "Opcje"); - if ( num == RT_TITLE_NAME ) strcpy(text, "Imiê gracza"); - if ( num == RT_TITLE_PERSO ) strcpy(text, "Dostosuj wygl¹d"); - if ( num == RT_TITLE_WRITE ) strcpy(text, "Zapisz bie¿¹c¹ misjê"); - if ( num == RT_TITLE_READ ) strcpy(text, "Wczytaj zapisan¹ misjê"); - - if ( num == RT_PLAY_CHAPt ) strcpy(text, " Rozdzia³y:"); - if ( num == RT_PLAY_CHAPd ) strcpy(text, " Rozdzia³y:"); - if ( num == RT_PLAY_CHAPm ) strcpy(text, " Planety:"); - if ( num == RT_PLAY_CHAPf ) strcpy(text, " Planety:"); - if ( num == RT_PLAY_CHAPu ) strcpy(text, " Poziomy u¿ytkownika:"); - if ( num == RT_PLAY_CHAPp ) strcpy(text, " Planety:"); - if ( num == RT_PLAY_CHAPte ) strcpy(text, " Planety:"); - if ( num == RT_PLAY_LISTt ) strcpy(text, " Æwiczenia w tym rozdziale:"); - if ( num == RT_PLAY_LISTd ) strcpy(text, " Wyzwania w tym rozdziale:"); - if ( num == RT_PLAY_LISTm ) strcpy(text, " Misje na tej planecie:"); - if ( num == RT_PLAY_LISTf ) strcpy(text, " Swobodna gra na tej planecie:"); - if ( num == RT_PLAY_LISTu ) strcpy(text, " Misje na tym poziomie:"); - if ( num == RT_PLAY_LISTp ) strcpy(text, " Prototypy na tej planecie:"); - if ( num == RT_PLAY_LISTk ) strcpy(text, " Prototypy na tej planecie:"); - if ( num == RT_PLAY_RESUME ) strcpy(text, " Streszczenie:"); - - if ( num == RT_SETUP_DEVICE ) strcpy(text, " Sterowniki:"); - if ( num == RT_SETUP_MODE ) strcpy(text, " Rozdzielczoœæ:"); - if ( num == RT_SETUP_KEY1 ) strcpy(text, "1) Najpierw kliknij klawisz, który chcesz przedefiniowaæ."); - if ( num == RT_SETUP_KEY2 ) strcpy(text, "2) Nastêpnie naciœnij klawisz, którego chcesz u¿ywaæ."); - - if ( num == RT_PERSO_FACE ) strcpy(text, "Rodzaj twarzy:"); - if ( num == RT_PERSO_GLASSES ) strcpy(text, "Okulary:"); - if ( num == RT_PERSO_HAIR ) strcpy(text, "Kolor w³osów:"); - if ( num == RT_PERSO_COMBI ) strcpy(text, "Kolor skafandra:"); - if ( num == RT_PERSO_BAND ) strcpy(text, "Kolor pasków:"); - -#if _NEWLOOK - if ( num == RT_DIALOG_TITLE ) strcpy(text, "CeeBot"); - if ( num == RT_DIALOG_QUIT ) strcpy(text, "Czy na pewno chcesz opuœciæ grê CeeBot?"); - if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Zakoñcz\\Koñczy grê CeeBot"); -#else - if ( num == RT_DIALOG_TITLE ) strcpy(text, "COLOBOT"); - if ( num == RT_DIALOG_QUIT ) strcpy(text, "Czy na pewno chcesz opuœciæ grê COLOBOT?"); - if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Zakoñcz\\Koñczy grê COLOBOT"); -#endif - if ( num == RT_DIALOG_ABORT ) strcpy(text, "Opuœciæ misjê?"); - if ( num == RT_DIALOG_YES ) strcpy(text, "Przerwij\\Przerywa bie¿¹c¹ misjê"); - if ( num == RT_DIALOG_NO ) strcpy(text, "Kontynuuj\\Kontynuuje bie¿¹c¹ misjê"); - if ( num == RT_DIALOG_NOQUIT ) strcpy(text, "Kontynuuj\\Kontynuuje grê"); - if ( num == RT_DIALOG_DELOBJ ) strcpy(text, "Czy na pewno chcesz zniszczyæ zaznaczony budynek?"); - if ( num == RT_DIALOG_DELGAME ) strcpy(text, "Czy na pewno chcesz skasowaæ zapisane gry gracza %s? "); - if ( num == RT_DIALOG_YESDEL ) strcpy(text, "Usuñ"); - if ( num == RT_DIALOG_NODEL ) strcpy(text, "Anuluj"); - if ( num == RT_DIALOG_LOADING ) strcpy(text, "WCZYTYWANIE"); - - if ( num == RT_STUDIO_LISTTT ) strcpy(text, "Skróty klawiszowe (\\key cbot;)"); - if ( num == RT_STUDIO_COMPOK ) strcpy(text, "Program skompilowany (0 b³êdów)"); - if ( num == RT_STUDIO_PROGSTOP ) strcpy(text, "Program zakoñczony"); - - if ( num == RT_SATCOM_LIST ) strcpy(text, "\\b;Lista obiektów\n"); - if ( num == RT_SATCOM_BOT ) strcpy(text, "\\b;Roboty\n"); - if ( num == RT_SATCOM_BUILDING ) strcpy(text, "\\b;Budynki\n"); - if ( num == RT_SATCOM_FRET ) strcpy(text, "\\b;Obiekty ruchome\n"); - if ( num == RT_SATCOM_ALIEN ) strcpy(text, "\\b;Obcy\n"); - if ( num == RT_SATCOM_NULL ) strcpy(text, "\\c; (brak)\\n;\n"); - if ( num == RT_SATCOM_ERROR1 ) strcpy(text, "\\b;B³¹d\n"); - if ( num == RT_SATCOM_ERROR2 ) strcpy(text, "Lista jest dostêpna jedynie gdy dzia³a \\l;stacja radarowa\\u object\\radar;.\n"); - - if ( num == RT_IO_OPEN ) strcpy(text, "Otwórz"); - if ( num == RT_IO_SAVE ) strcpy(text, "Zapisz"); - if ( num == RT_IO_LIST ) strcpy(text, "Folder: %s"); - if ( num == RT_IO_NAME ) strcpy(text, "Nazwa:"); - if ( num == RT_IO_DIR ) strcpy(text, "Folder:"); - if ( num == RT_IO_PRIVATE ) strcpy(text, "Prywatny\\Folder prywatny"); - if ( num == RT_IO_PUBLIC ) strcpy(text, "Publiczny\\Folder ogólnodostêpny"); - - if ( num == RT_GENERIC_DEV1 ) strcpy(text, "Twórcy:"); - if ( num == RT_GENERIC_DEV2 ) strcpy(text, "www.epsitec.com"); - if ( num == RT_GENERIC_EDIT1 ) strcpy(text, "Wersja polska wydana przez:"); - if ( num == RT_GENERIC_EDIT2 ) strcpy(text, "www.manta.com.pl"); - if ( num == RT_GENERIC_EDIT1 ) strcpy(text, " "); - if ( num == RT_GENERIC_EDIT2 ) strcpy(text, " "); - - if ( num == RT_INTERFACE_REC ) strcpy(text, "Recorder"); - } - - if ( type == RES_EVENT ) - { - if ( num == EVENT_BUTTON_OK ) strcpy(text, "OK"); - if ( num == EVENT_BUTTON_CANCEL ) strcpy(text, "Anuluj"); - if ( num == EVENT_BUTTON_NEXT ) strcpy(text, "Nastêpny"); - if ( num == EVENT_BUTTON_PREV ) strcpy(text, "Poprzedni"); - if ( num == EVENT_BUTTON_QUIT ) strcpy(text, "Menu (\\key quit;)"); - - if ( num == EVENT_DIALOG_OK ) strcpy(text, "OK"); - if ( num == EVENT_DIALOG_CANCEL ) strcpy(text, "Anuluj"); - - if ( num == EVENT_INTERFACE_TRAINER) strcpy(text, "Æwiczenia\\Æwiczenia programistyczne"); - if ( num == EVENT_INTERFACE_DEFI ) strcpy(text, "Wyzwania\\Wyzwania programistyczne"); - if ( num == EVENT_INTERFACE_MISSION) strcpy(text, "Misje\\Wybierz misjê"); - if ( num == EVENT_INTERFACE_FREE ) strcpy(text, "Swobodna gra\\Swobodna gra bez konkretnych celów"); - if ( num == EVENT_INTERFACE_TEEN ) strcpy(text, "Swobodna gra\\Swobodna gra bez konkretnych celów"); - if ( num == EVENT_INTERFACE_USER ) strcpy(text, "Poziomy\\Poziomy u¿ytkownika"); - if ( num == EVENT_INTERFACE_PROTO ) strcpy(text, "Prototypy\\Prototypy w trakcie rozwijania"); - if ( num == EVENT_INTERFACE_NAME ) strcpy(text, "Nowy gracz\\Wybierz imiê gracza"); - if ( num == EVENT_INTERFACE_SETUP ) strcpy(text, "Opcje\\Preferencje"); - if ( num == EVENT_INTERFACE_AGAIN ) strcpy(text, "Uruchom ponownie\\Uruchamia ponownie misjê od pocz¹tku"); - if ( num == EVENT_INTERFACE_WRITE ) strcpy(text, "Zapisz\\Zapisuje bie¿¹c¹ misjê"); - if ( num == EVENT_INTERFACE_READ ) strcpy(text, "Wczytaj\\Wczytuje zapisan¹ misjê"); -#if _NEWLOOK - if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Powróæ do gry CeeBot"); - if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Zakoñcz\\Koñczy grê CeeBot"); -#else - if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Powróæ do gry COLOBOT"); - if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Zakoñcz\\Koñczy grê COLOBOT"); -#endif - if ( num == EVENT_INTERFACE_BACK ) strcpy(text, "<< Wstecz \\Wraca do poprzedniego ekranu"); - if ( num == EVENT_INTERFACE_PLAY ) strcpy(text, "Graj\\Rozpoczyna misjê!"); - if ( num == EVENT_INTERFACE_SETUPd ) strcpy(text, "Urz¹dzenie\\Ustawienia sterownika i rozdzielczoœci"); - if ( num == EVENT_INTERFACE_SETUPg ) strcpy(text, "Grafika\\Ustawienia grafiki"); - if ( num == EVENT_INTERFACE_SETUPp ) strcpy(text, "Gra\\Ustawienia gry"); - if ( num == EVENT_INTERFACE_SETUPc ) strcpy(text, "Sterowanie\\Ustawienia klawiatury, joysticka i myszy"); - if ( num == EVENT_INTERFACE_SETUPs ) strcpy(text, "DŸwiêk\\G³oœnoœæ muzyki i dŸwiêków gry"); - if ( num == EVENT_INTERFACE_DEVICE ) strcpy(text, "Jednostka"); - if ( num == EVENT_INTERFACE_RESOL ) strcpy(text, "Rozdzielczoœæ"); - if ( num == EVENT_INTERFACE_FULL ) strcpy(text, "Pe³ny ekran\\Pe³ny ekran lub tryb okna"); - if ( num == EVENT_INTERFACE_APPLY ) strcpy(text, "Zastosuj zmiany\\Aktywuje zmienione ustawienia"); - - if ( num == EVENT_INTERFACE_TOTO ) strcpy(text, "Robbie\\Twój asystent"); - if ( num == EVENT_INTERFACE_SHADOW ) strcpy(text, "Cienie\\Cienie na ziemi"); - if ( num == EVENT_INTERFACE_GROUND ) strcpy(text, "Znaki na ziemi\\Znaki na ziemi"); - if ( num == EVENT_INTERFACE_DIRTY ) strcpy(text, "Kurz\\Kurz i bród na robotach i budynkach"); - if ( num == EVENT_INTERFACE_FOG ) strcpy(text, "Mg³a\\Mg³a"); - if ( num == EVENT_INTERFACE_LENS ) strcpy(text, "Promienie s³oneczne\\Promienie s³oneczne na niebie"); - if ( num == EVENT_INTERFACE_SKY ) strcpy(text, "Niebo\\Chmury i mg³awice"); - if ( num == EVENT_INTERFACE_PLANET ) strcpy(text, "Planety i gwiazdy\\Obiekty astronomiczne na niebie"); - if ( num == EVENT_INTERFACE_LIGHT ) strcpy(text, "Dynamiczne oœwietlenie\\Ruchome Ÿród³a œwiat³a"); - if ( num == EVENT_INTERFACE_PARTI ) strcpy(text, "Liczba cz¹stek\\Wybuchy, kurz, odbicia, itp."); - if ( num == EVENT_INTERFACE_CLIP ) strcpy(text, "G³êbokoœæ pola\\Maksymalna widocznoœæ"); - if ( num == EVENT_INTERFACE_DETAIL ) strcpy(text, "Szczegó³y\\Jakoœæ wizualna obiektów 3D"); - if ( num == EVENT_INTERFACE_TEXTURE) strcpy(text, "Tekstury\\Jakoœæ tekstur "); - if ( num == EVENT_INTERFACE_GADGET ) strcpy(text, "Iloœæ elementów dekoracyjnych \\Iloœæ elementów czysto dekoracyjnych"); - if ( num == EVENT_INTERFACE_RAIN ) strcpy(text, "Cz¹stki w interfejsie\\Para i iskry z silników w interfejsie"); - if ( num == EVENT_INTERFACE_GLINT ) strcpy(text, "Odbicia na przyciskach \\Œwiec¹ce przyciski"); - if ( num == EVENT_INTERFACE_TOOLTIP) strcpy(text, "Dymki pomocy\\Wyjaœnia funkcje przycisków"); - if ( num == EVENT_INTERFACE_MOVIES ) strcpy(text, "Sekwencje filmowe\\Filmy przed rozpoczêciem i na zakoñczenie misji"); - if ( num == EVENT_INTERFACE_NICERST) strcpy(text, "Koñcowy film\\Film na zakoñczenie æwiczeñ"); - if ( num == EVENT_INTERFACE_HIMSELF) strcpy(text, "Przyjacielski ogieñ\\W³asne strza³y uszkadzaj¹ Twoje obiekty"); - if ( num == EVENT_INTERFACE_SCROLL ) strcpy(text, "Przewijanie\\Ekran jest przewijany gdy mysz dotknie prawej lub lewej jego krawêdzi"); - if ( num == EVENT_INTERFACE_INVERTX) strcpy(text, "Odwrócenie myszy X\\Odwrócenie kierunków przewijania w poziomie"); - if ( num == EVENT_INTERFACE_INVERTY) strcpy(text, "Odwrócenie myszy Y\\Odwrócenie kierunków przewijania w pionie"); - if ( num == EVENT_INTERFACE_EFFECT ) strcpy(text, "Wstrz¹sy przy wybuchach\\Ekran trzêsie siê podczas wybuchów"); - if ( num == EVENT_INTERFACE_MOUSE ) strcpy(text, "Cieñ kursora myszy\\Dodaje cieñ kursorowi myszy"); - if ( num == EVENT_INTERFACE_EDITMODE) strcpy(text, "Automatyczne wciêcia\\Automatyczne wciêcia podczas edycji programu"); - if ( num == EVENT_INTERFACE_EDITVALUE)strcpy(text, "Du¿e wciêcie\\2 lub 4 spacje wciêcia na ka¿dy poziom zdefiniowany przez klamry"); - if ( num == EVENT_INTERFACE_SOLUCE4) strcpy(text, "Accès aux solutions\\Programme \"4: Solution\" dans les exercices"); - - if ( num == EVENT_INTERFACE_KDEF ) strcpy(text, "Standardowa kontrola\\Standardowe klawisze funkcyjne"); - if ( num == EVENT_INTERFACE_KLEFT ) strcpy(text, "Skrêæ w lewo\\Obraca robota w lewo"); - if ( num == EVENT_INTERFACE_KRIGHT ) strcpy(text, "Obróæ w prawo\\Obraca robota w prawo"); - if ( num == EVENT_INTERFACE_KUP ) strcpy(text, "Naprzód\\Porusza do przodu"); - if ( num == EVENT_INTERFACE_KDOWN ) strcpy(text, "Wstecz\\Porusza do ty³u"); - if ( num == EVENT_INTERFACE_KGUP ) strcpy(text, "W górê\\Zwiêksza moc silnika"); - if ( num == EVENT_INTERFACE_KGDOWN ) strcpy(text, "W dó³\\Zmniejsza moc silnika"); - if ( num == EVENT_INTERFACE_KCAMERA) strcpy(text, "Zmieñ kamerê\\Prze³¹cza pomiêdzy kamer¹ pok³adow¹ i œledz¹c¹"); - if ( num == EVENT_INTERFACE_KDESEL ) strcpy(text, "Poprzedni obiekt\\Zaznacz poprzedni obiekt"); - if ( num == EVENT_INTERFACE_KACTION) strcpy(text, "Standardowa akcja\\Standardowa akcja robota (podnieœ/upuœæ, strzelaj, szukaj, itp.)"); - if ( num == EVENT_INTERFACE_KNEAR ) strcpy(text, "Kamera bli¿ej\\Przybli¿a kamerê"); - if ( num == EVENT_INTERFACE_KAWAY ) strcpy(text, "Kamera dalej\\Oddala kamerê"); - if ( num == EVENT_INTERFACE_KNEXT ) strcpy(text, "Nastêpny obiekt\\Zaznacza nastêpny obiekt"); - if ( num == EVENT_INTERFACE_KHUMAN ) strcpy(text, "Zaznacz astronautê\\Zaznacza astronautê"); - if ( num == EVENT_INTERFACE_KQUIT ) strcpy(text, "Zakoñcz\\Koñczy bie¿¹c¹ misjê lub æwiczenie"); - if ( num == EVENT_INTERFACE_KHELP ) strcpy(text, "Rozkazy\\Pokazuje rozkazy dotycz¹ce bie¿¹cej misji"); - if ( num == EVENT_INTERFACE_KPROG ) strcpy(text, "Podrêcznik programowania\\Dostarcza szczegó³ow¹ pomoc w programowaniu"); - if ( num == EVENT_INTERFACE_KCBOT ) strcpy(text, "Pomoc dot. s³ów kluczowych\\Dok³adniejsza pomoc na temat s³ów kluczowych"); - if ( num == EVENT_INTERFACE_KVISIT ) strcpy(text, "Miejsce nadania wiadomoœci\\Pokazuje sk¹d zosta³a wys³ana ostatnia wiadomoœæ"); - if ( num == EVENT_INTERFACE_KSPEED10) strcpy(text, "Prêdkoœæ 1,0x\\Prêdkoœæ normalna"); - if ( num == EVENT_INTERFACE_KSPEED15) strcpy(text, "Prêdkoœæ 1,5x\\1,5 raza szybciej"); - if ( num == EVENT_INTERFACE_KSPEED20) strcpy(text, "Prêdkoœæ 2,0x\\Dwa razy szybciej"); - if ( num == EVENT_INTERFACE_KSPEED30) strcpy(text, "Prêdkoœæ 3,0x\\Trzy razy szybciej"); - - if ( num == EVENT_INTERFACE_VOLSOUND) strcpy(text, "Efekty dŸwiêkowe:\\G³oœnoœæ silników, g³osów, strza³ów, itp."); - if ( num == EVENT_INTERFACE_VOLMUSIC) strcpy(text, "Muzyka w tle :\\G³oœnoœæ œcie¿ek dŸwiêkowych z p³yty CD"); - if ( num == EVENT_INTERFACE_SOUND3D) strcpy(text, "DŸwiêk 3D\\Przestrzenne pozycjonowanie dŸwiêków"); - - if ( num == EVENT_INTERFACE_MIN ) strcpy(text, "Najni¿sza\\Minimalna jakoœæ grafiki (najwy¿sza czêstotliwoœæ odœwie¿ania)"); - if ( num == EVENT_INTERFACE_NORM ) strcpy(text, "Normalna\\Normalna jakoœæ grafiki"); - if ( num == EVENT_INTERFACE_MAX ) strcpy(text, "Najwy¿sza\\Maksymalna jakoœæ grafiki (najni¿sza czêstotliwoœæ odœwie¿ania)"); - - if ( num == EVENT_INTERFACE_SILENT ) strcpy(text, "Cisza\\Brak dŸwiêków"); - if ( num == EVENT_INTERFACE_NOISY ) strcpy(text, "Normalne\\Normalna g³oœnoœæ dŸwiêków"); - - if ( num == EVENT_INTERFACE_JOYSTICK) strcpy(text, "U¿ywaj joysticka\\Joystick lub klawiatura"); - if ( num == EVENT_INTERFACE_SOLUCE ) strcpy(text, "Dostêp do rozwi¹zania\\Pokazuje rozwi¹zanie (szczegó³owe instrukcje dotycz¹ce misji)"); - - if ( num == EVENT_INTERFACE_NEDIT ) strcpy(text, "\\Nowe imiê gracza"); - if ( num == EVENT_INTERFACE_NOK ) strcpy(text, "OK\\Wybiera zaznaczonego gracza"); - if ( num == EVENT_INTERFACE_NCANCEL) strcpy(text, "Anuluj\\Zachowuje bie¿¹ce imiê gracza"); - if ( num == EVENT_INTERFACE_NDELETE) strcpy(text, "Usuñ gracza\\Usuwa gracza z listy"); - if ( num == EVENT_INTERFACE_NLABEL ) strcpy(text, "Imiê gracza"); - - if ( num == EVENT_INTERFACE_IOWRITE) strcpy(text, "Zapisz\\Zapisuje bie¿¹c¹ misjê"); - if ( num == EVENT_INTERFACE_IOREAD ) strcpy(text, "Wczytaj\\Wczytuje zaznaczon¹ misjê"); - if ( num == EVENT_INTERFACE_IOLIST ) strcpy(text, "Lista zapisanych misji"); - if ( num == EVENT_INTERFACE_IOLABEL) strcpy(text, "Nazwa pliku:"); - if ( num == EVENT_INTERFACE_IONAME ) strcpy(text, "Nazwa misji"); - if ( num == EVENT_INTERFACE_IOIMAGE) strcpy(text, "Fotografia"); - if ( num == EVENT_INTERFACE_IODELETE) strcpy(text, "Usuñ\\Usuwa zaznaczony plik"); - - if ( num == EVENT_INTERFACE_PERSO ) strcpy(text, "Wygl¹d\\Wybierz swoj¹ postaæ"); - if ( num == EVENT_INTERFACE_POK ) strcpy(text, "OK"); - if ( num == EVENT_INTERFACE_PCANCEL) strcpy(text, "Anuluj"); - if ( num == EVENT_INTERFACE_PDEF ) strcpy(text, "Standardowe\\Standardowe ustawienia wygl¹du"); - if ( num == EVENT_INTERFACE_PHEAD ) strcpy(text, "G³owa\\Twarz i w³osy"); - if ( num == EVENT_INTERFACE_PBODY ) strcpy(text, "Skafander\\Skafander astronauty"); - if ( num == EVENT_INTERFACE_PLROT ) strcpy(text, "\\Obróæ w lewo"); - if ( num == EVENT_INTERFACE_PRROT ) strcpy(text, "\\Obróæ w prawo"); - if ( num == EVENT_INTERFACE_PCRa ) strcpy(text, "Czerwony"); - if ( num == EVENT_INTERFACE_PCGa ) strcpy(text, "Zielony"); - if ( num == EVENT_INTERFACE_PCBa ) strcpy(text, "Niebieski"); - if ( num == EVENT_INTERFACE_PCRb ) strcpy(text, "Czerwony"); - if ( num == EVENT_INTERFACE_PCGb ) strcpy(text, "Zielony"); - if ( num == EVENT_INTERFACE_PCBb ) strcpy(text, "Niebieski"); - if ( num == EVENT_INTERFACE_PFACE1 ) strcpy(text, "\\Twarz 1"); - if ( num == EVENT_INTERFACE_PFACE2 ) strcpy(text, "\\Twarz 4"); - if ( num == EVENT_INTERFACE_PFACE3 ) strcpy(text, "\\Twarz 3"); - if ( num == EVENT_INTERFACE_PFACE4 ) strcpy(text, "\\Twarz 2"); - if ( num == EVENT_INTERFACE_PGLASS0) strcpy(text, "\\Bez okularów"); - if ( num == EVENT_INTERFACE_PGLASS1) strcpy(text, "\\Okulary 1"); - if ( num == EVENT_INTERFACE_PGLASS2) strcpy(text, "\\Okulary 2"); - if ( num == EVENT_INTERFACE_PGLASS3) strcpy(text, "\\Okulary 3"); - if ( num == EVENT_INTERFACE_PGLASS4) strcpy(text, "\\Okulary 4"); - if ( num == EVENT_INTERFACE_PGLASS5) strcpy(text, "\\Okulary 5"); - - if ( num == EVENT_OBJECT_DESELECT ) strcpy(text, "Poprzednie zaznaczenie (\\key desel;)"); - if ( num == EVENT_OBJECT_LEFT ) strcpy(text, "Skrêæ w lewo (\\key left;)"); - if ( num == EVENT_OBJECT_RIGHT ) strcpy(text, "Skrêæ w prawo (\\key right;)"); - if ( num == EVENT_OBJECT_UP ) strcpy(text, "Naprzód (\\key up;)"); - if ( num == EVENT_OBJECT_DOWN ) strcpy(text, "Cofnij (\\key down;)"); - if ( num == EVENT_OBJECT_GASUP ) strcpy(text, "Góra (\\key gup;)"); - if ( num == EVENT_OBJECT_GASDOWN ) strcpy(text, "Dó³ (\\key gdown;)"); - if ( num == EVENT_OBJECT_HTAKE ) strcpy(text, "Podnieœ lub upuœæ (\\key action;)"); - if ( num == EVENT_OBJECT_MTAKE ) strcpy(text, "Podnieœ lub upuœæ (\\key action;)"); - if ( num == EVENT_OBJECT_MFRONT ) strcpy(text, "..przed"); - if ( num == EVENT_OBJECT_MBACK ) strcpy(text, "..za"); - if ( num == EVENT_OBJECT_MPOWER ) strcpy(text, "..ogniwo elektryczne"); - if ( num == EVENT_OBJECT_BHELP ) strcpy(text, "Rozkazy dotycz¹ce misji (\\key help;)"); - if ( num == EVENT_OBJECT_BTAKEOFF ) strcpy(text, "Odleæ, aby zakoñczyæ misjê"); - if ( num == EVENT_OBJECT_BDERRICK ) strcpy(text, "Zbuduj kopalniê"); - if ( num == EVENT_OBJECT_BSTATION ) strcpy(text, "Zbuduj elektrowniê"); - if ( num == EVENT_OBJECT_BFACTORY ) strcpy(text, "Zbuduj fabrykê robotów"); - if ( num == EVENT_OBJECT_BREPAIR ) strcpy(text, "Zbuduj warsztat"); - if ( num == EVENT_OBJECT_BCONVERT ) strcpy(text, "Zbuduj hutê"); - if ( num == EVENT_OBJECT_BTOWER ) strcpy(text, "Zbuduj wie¿ê obronn¹"); - if ( num == EVENT_OBJECT_BRESEARCH ) strcpy(text, "Zbuduj centrum badawcze"); - if ( num == EVENT_OBJECT_BRADAR ) strcpy(text, "Zbuduj stacjê radarow¹"); - if ( num == EVENT_OBJECT_BENERGY ) strcpy(text, "Zbuduj fabrykê ogniw elektrycznych"); - if ( num == EVENT_OBJECT_BLABO ) strcpy(text, "Zbuduj laboratorium"); - if ( num == EVENT_OBJECT_BNUCLEAR ) strcpy(text, "Zbuduj elektrowniê atomow¹"); - if ( num == EVENT_OBJECT_BPARA ) strcpy(text, "Zbuduj odgromnik"); - if ( num == EVENT_OBJECT_BINFO ) strcpy(text, "Zbuduj stacjê przekaŸnikow¹"); - if ( num == EVENT_OBJECT_GFLAT ) strcpy(text, "Poka¿ czy teren jest p³aski"); - if ( num == EVENT_OBJECT_FCREATE ) strcpy(text, "Postaw flagê"); - if ( num == EVENT_OBJECT_FDELETE ) strcpy(text, "Usuñ flagê"); - if ( num == EVENT_OBJECT_FCOLORb ) strcpy(text, "\\Niebieskie flagi"); - if ( num == EVENT_OBJECT_FCOLORr ) strcpy(text, "\\Czerwone flagi"); - if ( num == EVENT_OBJECT_FCOLORg ) strcpy(text, "\\Zielone flagi"); - if ( num == EVENT_OBJECT_FCOLORy ) strcpy(text, "\\¯ó³te flagi"); - if ( num == EVENT_OBJECT_FCOLORv ) strcpy(text, "\\Fioletowe flagi"); - if ( num == EVENT_OBJECT_FACTORYfa ) strcpy(text, "Zbuduj transporter lataj¹cy"); - if ( num == EVENT_OBJECT_FACTORYta ) strcpy(text, "Zbuduj transporter na g¹sienicach"); - if ( num == EVENT_OBJECT_FACTORYwa ) strcpy(text, "Zbuduj transporter na ko³ach"); - if ( num == EVENT_OBJECT_FACTORYia ) strcpy(text, "Zbuduj transporter na nogach"); - if ( num == EVENT_OBJECT_FACTORYfc ) strcpy(text, "Zbuduj dzia³o lataj¹ce"); - if ( num == EVENT_OBJECT_FACTORYtc ) strcpy(text, "Zbuduj dzia³o na g¹sienicach"); - if ( num == EVENT_OBJECT_FACTORYwc ) strcpy(text, "Zbuduj dzia³o na ko³ach"); - if ( num == EVENT_OBJECT_FACTORYic ) strcpy(text, "Zbuduj dzia³o na nogach"); - if ( num == EVENT_OBJECT_FACTORYfi ) strcpy(text, "Zbuduj lataj¹ce dzia³o organiczne"); - if ( num == EVENT_OBJECT_FACTORYti ) strcpy(text, "Zbuduj dzia³o organiczne na g¹sienicach"); - if ( num == EVENT_OBJECT_FACTORYwi ) strcpy(text, "Zbuduj dzia³o organiczne na ko³ach"); - if ( num == EVENT_OBJECT_FACTORYii ) strcpy(text, "Zbuduj dzia³o organiczne na nogach"); - if ( num == EVENT_OBJECT_FACTORYfs ) strcpy(text, "Zbuduj szperacz lataj¹cy"); - if ( num == EVENT_OBJECT_FACTORYts ) strcpy(text, "Zbuduj szperacz na g¹sienicach"); - if ( num == EVENT_OBJECT_FACTORYws ) strcpy(text, "Zbuduj szperacz na ko³ach"); - if ( num == EVENT_OBJECT_FACTORYis ) strcpy(text, "Zbuduj szperacz na nogach"); - if ( num == EVENT_OBJECT_FACTORYrt ) strcpy(text, "Zbuduj robota uderzacza"); - if ( num == EVENT_OBJECT_FACTORYrc ) strcpy(text, "Zbuduj dzia³o fazowe"); - if ( num == EVENT_OBJECT_FACTORYrr ) strcpy(text, "Zbuduj robota recyklera"); - if ( num == EVENT_OBJECT_FACTORYrs ) strcpy(text, "Zbuduj robota os³aniajacza"); - if ( num == EVENT_OBJECT_FACTORYsa ) strcpy(text, "Zbuduj robota nurka"); - if ( num == EVENT_OBJECT_RTANK ) strcpy(text, "Rozpocznij prace badawcze nad transporterem na g¹sienicach"); - if ( num == EVENT_OBJECT_RFLY ) strcpy(text, "Rozpocznij prace badawcze nad transporterem lataj¹cym"); - if ( num == EVENT_OBJECT_RTHUMP ) strcpy(text, "Rozpocznij prace badawcze nad robotem uderzaczem"); - if ( num == EVENT_OBJECT_RCANON ) strcpy(text, "Rozpocznij prace badawcze nad dzia³em"); - if ( num == EVENT_OBJECT_RTOWER ) strcpy(text, "Rozpocznij prace badawcze nad wie¿¹ obronn¹"); - if ( num == EVENT_OBJECT_RPHAZER ) strcpy(text, "Rozpocznij prace badawcze nad dzia³em fazowym"); - if ( num == EVENT_OBJECT_RSHIELD ) strcpy(text, "Rozpocznij prace badawcze nad robotem os³aniaczem"); - if ( num == EVENT_OBJECT_RATOMIC ) strcpy(text, "Rozpocznij prace badawcze nad energi¹ atomow¹"); - if ( num == EVENT_OBJECT_RiPAW ) strcpy(text, "Rozpocznij prace badawcze nad transporterem na nogach"); - if ( num == EVENT_OBJECT_RiGUN ) strcpy(text, "Rozpocznij prace badawcze nad dzia³em organicznym"); - if ( num == EVENT_OBJECT_RESET ) strcpy(text, "Powrót do pocz¹tku"); - if ( num == EVENT_OBJECT_SEARCH ) strcpy(text, "Szukaj (\\key action;)"); - if ( num == EVENT_OBJECT_TERRAFORM ) strcpy(text, "Uderz (\\key action;)"); - if ( num == EVENT_OBJECT_FIRE ) strcpy(text, "Strzelaj (\\key action;)"); - if ( num == EVENT_OBJECT_RECOVER ) strcpy(text, "Odzyskaj (\\key action;)"); - if ( num == EVENT_OBJECT_BEGSHIELD ) strcpy(text, "Rozszerz os³onê (\\key action;)"); - if ( num == EVENT_OBJECT_ENDSHIELD ) strcpy(text, "Wy³¹cz os³onê (\\key action;)"); - if ( num == EVENT_OBJECT_DIMSHIELD ) strcpy(text, "Zasiêg os³ony"); - if ( num == EVENT_OBJECT_PROGRUN ) strcpy(text, "Wykonaj zaznaczony program"); - if ( num == EVENT_OBJECT_PROGEDIT ) strcpy(text, "Edytuj zaznaczony program"); - if ( num == EVENT_OBJECT_INFOOK ) strcpy(text, "\\Prze³¹cz przekaŸnik SatCom w stan gotowoœci"); - if ( num == EVENT_OBJECT_DELETE ) strcpy(text, "Zniszcz budynek"); - if ( num == EVENT_OBJECT_GENERGY ) strcpy(text, "Poziom energii"); - if ( num == EVENT_OBJECT_GSHIELD ) strcpy(text, "Poziom os³ony"); - if ( num == EVENT_OBJECT_GRANGE ) strcpy(text, "Temperatura silnika"); - if ( num == EVENT_OBJECT_GPROGRESS ) strcpy(text, "Wci¹¿ pracuje..."); - if ( num == EVENT_OBJECT_GRADAR ) strcpy(text, "Liczba wykrytych insektów"); - if ( num == EVENT_OBJECT_GINFO ) strcpy(text, "Przes³ane informacje"); - if ( num == EVENT_OBJECT_COMPASS ) strcpy(text, "Kompas"); -//? if ( num == EVENT_OBJECT_MAP ) strcpy(text, "Mapka"); - if ( num == EVENT_OBJECT_MAPZOOM ) strcpy(text, "Powiêkszenie mapki"); - if ( num == EVENT_OBJECT_CAMERA ) strcpy(text, "Kamera (\\key camera;)"); - if ( num == EVENT_OBJECT_CAMERAleft) strcpy(text, "Camera to left"); - if ( num == EVENT_OBJECT_CAMERAright) strcpy(text, "Camera to right"); - if ( num == EVENT_OBJECT_CAMERAnear) strcpy(text, "Camera nearest"); - if ( num == EVENT_OBJECT_CAMERAaway) strcpy(text, "Camera awayest"); - if ( num == EVENT_OBJECT_HELP ) strcpy(text, "Pomoc na temat zaznaczonego obiektu"); - if ( num == EVENT_OBJECT_SOLUCE ) strcpy(text, "Poka¿ rozwi¹zanie"); - if ( num == EVENT_OBJECT_SHORTCUT00) strcpy(text, "Prze³¹cz roboty <-> budynki"); - if ( num == EVENT_OBJECT_LIMIT ) strcpy(text, "Poka¿ zasiêg"); - if ( num == EVENT_OBJECT_PEN0 ) strcpy(text, "\\Relève le crayon"); - if ( num == EVENT_OBJECT_PEN1 ) strcpy(text, "\\Abaisse le crayon noir"); - if ( num == EVENT_OBJECT_PEN2 ) strcpy(text, "\\Abaisse le crayon jaune"); - if ( num == EVENT_OBJECT_PEN3 ) strcpy(text, "\\Abaisse le crayon orange"); - if ( num == EVENT_OBJECT_PEN4 ) strcpy(text, "\\Abaisse le crayon rouge"); - if ( num == EVENT_OBJECT_PEN5 ) strcpy(text, "\\Abaisse le crayon violet"); - if ( num == EVENT_OBJECT_PEN6 ) strcpy(text, "\\Abaisse le crayon bleu"); - if ( num == EVENT_OBJECT_PEN7 ) strcpy(text, "\\Abaisse le crayon vert"); - if ( num == EVENT_OBJECT_PEN8 ) strcpy(text, "\\Abaisse le crayon brun"); - if ( num == EVENT_OBJECT_REC ) strcpy(text, "\\Démarre l'enregistrement"); - if ( num == EVENT_OBJECT_STOP ) strcpy(text, "\\Stoppe l'enregistrement"); - if ( num == EVENT_DT_VISIT0 || - num == EVENT_DT_VISIT1 || - num == EVENT_DT_VISIT2 || - num == EVENT_DT_VISIT3 || - num == EVENT_DT_VISIT4 ) strcpy(text, "Poka¿ miejsce"); - if ( num == EVENT_DT_END ) strcpy(text, "Kontynuuj"); - if ( num == EVENT_CMD ) strcpy(text, "Linia polecenia"); - if ( num == EVENT_SPEED ) strcpy(text, "Prêdkoœæ gry"); - - if ( num == EVENT_HYPER_PREV ) strcpy(text, "Wstecz"); - if ( num == EVENT_HYPER_NEXT ) strcpy(text, "Naprzód"); - if ( num == EVENT_HYPER_HOME ) strcpy(text, "Pocz¹tek"); - if ( num == EVENT_HYPER_COPY ) strcpy(text, "Kopiuj"); - if ( num == EVENT_HYPER_SIZE1 ) strcpy(text, "Wielkoœæ 1"); - if ( num == EVENT_HYPER_SIZE2 ) strcpy(text, "Wielkoœæ 2"); - if ( num == EVENT_HYPER_SIZE3 ) strcpy(text, "Wielkoœæ 3"); - if ( num == EVENT_HYPER_SIZE4 ) strcpy(text, "Wielkoœæ 4"); - if ( num == EVENT_HYPER_SIZE5 ) strcpy(text, "Wielkoœæ 5"); - if ( num == EVENT_SATCOM_HUSTON ) strcpy(text, "Rozkazy z Houston"); -#if _TEEN - if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Raport z satelity"); -#else - if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Raport z satelity"); -#endif - if ( num == EVENT_SATCOM_LOADING ) strcpy(text, "Program dostarczony z Houston"); - if ( num == EVENT_SATCOM_OBJECT ) strcpy(text, "Lista obiektów"); - if ( num == EVENT_SATCOM_PROG ) strcpy(text, "Podrêcznik programowania"); - if ( num == EVENT_SATCOM_SOLUCE ) strcpy(text, "Rozwi¹zanie"); - - if ( num == EVENT_STUDIO_OK ) strcpy(text, "OK\\Zamyka edytor programu i powraca do gry"); - if ( num == EVENT_STUDIO_CANCEL ) strcpy(text, "Anuluj\\Pomija wszystkie zmiany"); - if ( num == EVENT_STUDIO_NEW ) strcpy(text, "Nowy"); - if ( num == EVENT_STUDIO_OPEN ) strcpy(text, "Otwórz (Ctrl+O)"); - if ( num == EVENT_STUDIO_SAVE ) strcpy(text, "Zapisz (Ctrl+S)"); - if ( num == EVENT_STUDIO_UNDO ) strcpy(text, "Cofnij (Ctrl+Z)"); - if ( num == EVENT_STUDIO_CUT ) strcpy(text, "Wytnij (Ctrl+X)"); - if ( num == EVENT_STUDIO_COPY ) strcpy(text, "Kopiuj (Ctrl+C)"); - if ( num == EVENT_STUDIO_PASTE ) strcpy(text, "Wklej (Ctrl+V)"); - if ( num == EVENT_STUDIO_SIZE ) strcpy(text, "Wielkoœæ czcionki"); - if ( num == EVENT_STUDIO_TOOL ) strcpy(text, "Rozkazy (\\key help;)"); - if ( num == EVENT_STUDIO_HELP ) strcpy(text, "Podrêcznik programowania (\\key prog;)"); - if ( num == EVENT_STUDIO_COMPILE ) strcpy(text, "Kompiluj"); - if ( num == EVENT_STUDIO_RUN ) strcpy(text, "Wykonaj/Zatrzymaj"); - if ( num == EVENT_STUDIO_REALTIME ) strcpy(text, "Pauza/Kontynuuj"); - if ( num == EVENT_STUDIO_STEP ) strcpy(text, "Jeden krok"); - } - - if ( type == RES_OBJECT ) - { - if ( num == OBJECT_PORTICO ) strcpy(text, "¯uraw przesuwalny"); - if ( num == OBJECT_BASE ) strcpy(text, "Statek kosmiczny"); - if ( num == OBJECT_DERRICK ) strcpy(text, "Kopalnia"); - if ( num == OBJECT_FACTORY ) strcpy(text, "Fabryka robotów"); - if ( num == OBJECT_REPAIR ) strcpy(text, "Warsztat"); - if ( num == OBJECT_DESTROYER ) strcpy(text, "Destroyer"); - if ( num == OBJECT_STATION ) strcpy(text, "Stacja energetyczna"); - if ( num == OBJECT_CONVERT ) strcpy(text, "Przetop rudê na tytan"); - if ( num == OBJECT_TOWER ) strcpy(text, "Wie¿a obronna"); - if ( num == OBJECT_NEST ) strcpy(text, "Gniazdo"); - if ( num == OBJECT_RESEARCH ) strcpy(text, "Centrum badawcze"); - if ( num == OBJECT_RADAR ) strcpy(text, "Stacja radarowa"); - if ( num == OBJECT_INFO ) strcpy(text, "Stacja przekaŸnikowa informacji"); -#if _TEEN - if ( num == OBJECT_ENERGY ) strcpy(text, "Fabryka ogniw elektrycznych"); -#else - if ( num == OBJECT_ENERGY ) strcpy(text, "Fabryka ogniw elektrycznych"); -#endif - if ( num == OBJECT_LABO ) strcpy(text, "Laboratorium"); - if ( num == OBJECT_NUCLEAR ) strcpy(text, "Elektrownia atomowa"); - if ( num == OBJECT_PARA ) strcpy(text, "Odgromnik"); - if ( num == OBJECT_SAFE ) strcpy(text, "Skrytka"); - if ( num == OBJECT_HUSTON ) strcpy(text, "Centrum Kontroli Misji w Houston"); - if ( num == OBJECT_TARGET1 ) strcpy(text, "Cel"); - if ( num == OBJECT_TARGET2 ) strcpy(text, "Cel"); - if ( num == OBJECT_START ) strcpy(text, "Pocz¹tek"); - if ( num == OBJECT_END ) strcpy(text, "Koniec"); - if ( num == OBJECT_STONE ) strcpy(text, "Ruda tytanu"); - if ( num == OBJECT_URANIUM ) strcpy(text, "Ruda uranu"); - if ( num == OBJECT_BULLET ) strcpy(text, "Materia organiczna"); - if ( num == OBJECT_METAL ) strcpy(text, "Tytan"); - if ( num == OBJECT_POWER ) strcpy(text, "Ogniwo elektryczne"); - if ( num == OBJECT_ATOMIC ) strcpy(text, "Atomowe ogniwa elektryczne"); - if ( num == OBJECT_BBOX ) strcpy(text, "Czarna skrzynka"); - if ( num == OBJECT_KEYa ) strcpy(text, "Klucz A"); - if ( num == OBJECT_KEYb ) strcpy(text, "Klucz B"); - if ( num == OBJECT_KEYc ) strcpy(text, "Klucz C"); - if ( num == OBJECT_KEYd ) strcpy(text, "Klucz D"); - if ( num == OBJECT_TNT ) strcpy(text, "Materia³y wybuchowe"); - if ( num == OBJECT_BOMB ) strcpy(text, "Mina"); - if ( num == OBJECT_BAG ) strcpy(text, "Zestaw przetrwania"); - if ( num == OBJECT_WAYPOINT ) strcpy(text, "Punkt kontrolny"); - if ( num == OBJECT_FLAGb ) strcpy(text, "Niebieska flaga"); - if ( num == OBJECT_FLAGr ) strcpy(text, "Czerwona flaga"); - if ( num == OBJECT_FLAGg ) strcpy(text, "Zielona flaga"); - if ( num == OBJECT_FLAGy ) strcpy(text, "¯ó³ta flaga"); - if ( num == OBJECT_FLAGv ) strcpy(text, "Fioletowa flaga"); - if ( num == OBJECT_MARKPOWER ) strcpy(text, "ród³o energii (miejsce na elektrowniê)"); - if ( num == OBJECT_MARKURANIUM ) strcpy(text, "Z³o¿e uranu (miejsce na kopalniê)"); - if ( num == OBJECT_MARKKEYa ) strcpy(text, "Znaleziono klucz A (miejsce na kopalniê)"); - if ( num == OBJECT_MARKKEYb ) strcpy(text, "Znaleziono klucz B (miejsce na kopalniê)"); - if ( num == OBJECT_MARKKEYc ) strcpy(text, "Znaleziono klucz C (miejsce na kopalniê)"); - if ( num == OBJECT_MARKKEYd ) strcpy(text, "Znaleziono klucz D (miejsce na kopalniê)"); - if ( num == OBJECT_MARKSTONE ) strcpy(text, "Z³o¿e tytanu (miejsce na kopalniê)"); - if ( num == OBJECT_MOBILEft ) strcpy(text, "Robot treningowy"); - if ( num == OBJECT_MOBILEtt ) strcpy(text, "Robot treningowy"); - if ( num == OBJECT_MOBILEwt ) strcpy(text, "Robot treningowy"); - if ( num == OBJECT_MOBILEit ) strcpy(text, "Robot treningowy"); - if ( num == OBJECT_MOBILEfa ) strcpy(text, "Transporter lataj¹cy"); - if ( num == OBJECT_MOBILEta ) strcpy(text, "Transporter na g¹sienicach"); - if ( num == OBJECT_MOBILEwa ) strcpy(text, "Transporter na ko³ach"); - if ( num == OBJECT_MOBILEia ) strcpy(text, "Transporter na nogach"); - if ( num == OBJECT_MOBILEfc ) strcpy(text, "Dzia³o lataj¹ce"); - if ( num == OBJECT_MOBILEtc ) strcpy(text, "Dzia³o na g¹sienicach"); - if ( num == OBJECT_MOBILEwc ) strcpy(text, "Dzia³o na ko³ach"); - if ( num == OBJECT_MOBILEic ) strcpy(text, "Dzia³o na nogach"); - if ( num == OBJECT_MOBILEfi ) strcpy(text, "Lataj¹ce dzia³o organiczne"); - if ( num == OBJECT_MOBILEti ) strcpy(text, "Dzia³o organiczne na g¹sienicach"); - if ( num == OBJECT_MOBILEwi ) strcpy(text, "Dzia³o organiczne na ko³ach"); - if ( num == OBJECT_MOBILEii ) strcpy(text, "Dzia³o organiczne na nogach"); - if ( num == OBJECT_MOBILEfs ) strcpy(text, "Szperacz lataj¹cy"); - if ( num == OBJECT_MOBILEts ) strcpy(text, "Szperacz na g¹sienicach"); - if ( num == OBJECT_MOBILEws ) strcpy(text, "Szperacz na ko³ach"); - if ( num == OBJECT_MOBILEis ) strcpy(text, "Szperacz na nogach"); - if ( num == OBJECT_MOBILErt ) strcpy(text, "Uderzacz"); - if ( num == OBJECT_MOBILErc ) strcpy(text, "Dzia³o fazowe"); - if ( num == OBJECT_MOBILErr ) strcpy(text, "Recykler"); - if ( num == OBJECT_MOBILErs ) strcpy(text, "Os³aniacz"); - if ( num == OBJECT_MOBILEsa ) strcpy(text, "Robot nurek"); - if ( num == OBJECT_MOBILEtg ) strcpy(text, "Robot cel"); - if ( num == OBJECT_MOBILEdr ) strcpy(text, "Drawer bot"); - if ( num == OBJECT_HUMAN ) strcpy(text, g_gamerName); - if ( num == OBJECT_TECH ) strcpy(text, "In¿ynier"); - if ( num == OBJECT_TOTO ) strcpy(text, "Robbie"); - if ( num == OBJECT_MOTHER ) strcpy(text, "Królowa Obcych"); - if ( num == OBJECT_ANT ) strcpy(text, "Mrówka"); - if ( num == OBJECT_SPIDER ) strcpy(text, "Paj¹k"); - if ( num == OBJECT_BEE ) strcpy(text, "Osa"); - if ( num == OBJECT_WORM ) strcpy(text, "Robal"); - if ( num == OBJECT_EGG ) strcpy(text, "Jajo"); - if ( num == OBJECT_RUINmobilew1 ) strcpy(text, "Wrak"); - if ( num == OBJECT_RUINmobilew2 ) strcpy(text, "Wrak"); - if ( num == OBJECT_RUINmobilet1 ) strcpy(text, "Wrak"); - if ( num == OBJECT_RUINmobilet2 ) strcpy(text, "Wrak"); - if ( num == OBJECT_RUINmobiler1 ) strcpy(text, "Wrak"); - if ( num == OBJECT_RUINmobiler2 ) strcpy(text, "Wrak"); - if ( num == OBJECT_RUINfactory ) strcpy(text, "Ruiny"); - if ( num == OBJECT_RUINdoor ) strcpy(text, "Ruiny"); - if ( num == OBJECT_RUINsupport ) strcpy(text, "Odpady"); - if ( num == OBJECT_RUINradar ) strcpy(text, "Ruiny"); - if ( num == OBJECT_RUINconvert ) strcpy(text, "Ruiny"); - if ( num == OBJECT_RUINbase ) strcpy(text, "Ruiny statku kosmicznego"); - if ( num == OBJECT_RUINhead ) strcpy(text, "Ruiny statku kosmicznego"); - if ( num == OBJECT_APOLLO1 || - num == OBJECT_APOLLO3 || - num == OBJECT_APOLLO4 || - num == OBJECT_APOLLO5 ) strcpy(text, "Pozosta³oœci z misji Apollo"); - if ( num == OBJECT_APOLLO2 ) strcpy(text, "Pojazd Ksiê¿ycowy"); - } - - if ( type == RES_ERR ) - { - strcpy(text, "B³¹d"); - if ( num == ERR_CMD ) strcpy(text, "Nieznane polecenie"); -#if _NEWLOOK - if ( num == ERR_INSTALL ) strcpy(text, "Gra CeeBot nie jest zainstalowana."); - if ( num == ERR_NOCD ) strcpy(text, "W³ó¿ dysk CD z gr¹ CeeBot\ni uruchom grê jeszcze raz."); -#else - if ( num == ERR_INSTALL ) strcpy(text, "Gra COLOBOT nie jest zainstalowana."); - if ( num == ERR_NOCD ) strcpy(text, "W³ó¿ dysk CD z gr¹ COLOBOT\ni uruchom grê jeszcze raz."); -#endif - if ( num == ERR_MANIP_VEH ) strcpy(text, "Nieodpowiedni robot"); - if ( num == ERR_MANIP_FLY ) strcpy(text, "Niemo¿liwe podczas lotu"); - if ( num == ERR_MANIP_BUSY ) strcpy(text, "Nie mo¿na nieœæ wiêcej przedmiotów"); - if ( num == ERR_MANIP_NIL ) strcpy(text, "Nie ma nic do podniesienia"); - if ( num == ERR_MANIP_MOTOR ) strcpy(text, "Niemo¿liwe podczas ruchu"); - if ( num == ERR_MANIP_OCC ) strcpy(text, "Miejsce zajête"); - if ( num == ERR_MANIP_FRIEND ) strcpy(text, "Brak innego robota"); - if ( num == ERR_MANIP_RADIO ) strcpy(text, "Nie mo¿esz przenosiæ przedmiotów radioaktywnych"); - if ( num == ERR_MANIP_WATER ) strcpy(text, "Nie mo¿esz przenosiæ przedmiotów pod wod¹"); - if ( num == ERR_MANIP_EMPTY ) strcpy(text, "Nie ma nic do upuszczenia"); - if ( num == ERR_BUILD_FLY ) strcpy(text, "Niemo¿liwe podczas lotu"); - if ( num == ERR_BUILD_WATER ) strcpy(text, "Niemo¿liwe pod wod¹"); - if ( num == ERR_BUILD_ENERGY ) strcpy(text, "Za ma³o energii"); - if ( num == ERR_BUILD_METALAWAY ) strcpy(text, "Tytan za daleko"); - if ( num == ERR_BUILD_METALNEAR ) strcpy(text, "Tytan za blisko"); - if ( num == ERR_BUILD_METALINEX ) strcpy(text, "Brak tytanu w pobli¿u"); - if ( num == ERR_BUILD_FLAT ) strcpy(text, "Powierzchnia nie jest wystarczaj¹co p³aska"); - if ( num == ERR_BUILD_FLATLIT ) strcpy(text, "Za ma³o p³askiego terenu"); - if ( num == ERR_BUILD_BUSY ) strcpy(text, "Miejsce zajête"); - if ( num == ERR_BUILD_BASE ) strcpy(text, "Za blisko statku kosmicznego"); - if ( num == ERR_BUILD_NARROW ) strcpy(text, "Za blisko budynku"); - if ( num == ERR_BUILD_MOTOR ) strcpy(text, "Niemo¿liwe podczas ruchu"); - if ( num == ERR_SEARCH_FLY ) strcpy(text, "Niemo¿liwe podczas lotu"); - if ( num == ERR_SEARCH_VEH ) strcpy(text, "Nieodpowiedni robot"); - if ( num == ERR_SEARCH_MOTOR ) strcpy(text, "Niemo¿liwe podczas ruchu"); - if ( num == ERR_TERRA_VEH ) strcpy(text, "Nieodpowiedni robot"); - if ( num == ERR_TERRA_ENERGY ) strcpy(text, "Za ma³o energii"); - if ( num == ERR_TERRA_FLOOR ) strcpy(text, "Nieodpowiedni teren"); - if ( num == ERR_TERRA_BUILDING ) strcpy(text, "Budynek za blisko"); - if ( num == ERR_TERRA_OBJECT ) strcpy(text, "Obiekt za blisko"); - if ( num == ERR_RECOVER_VEH ) strcpy(text, "Nieodpowiedni robot"); - if ( num == ERR_RECOVER_ENERGY ) strcpy(text, "Za ma³o energii"); - if ( num == ERR_RECOVER_NULL ) strcpy(text, "Nie ma niczego do odzysku"); - if ( num == ERR_SHIELD_VEH ) strcpy(text, "Nieodpowiedni robot"); - if ( num == ERR_SHIELD_ENERGY ) strcpy(text, "Nie ma wiêcej energii"); - if ( num == ERR_MOVE_IMPOSSIBLE ) strcpy(text, "B³¹d w poleceniu ruchu"); - if ( num == ERR_FIND_IMPOSSIBLE ) strcpy(text, "Obiekt nieznany"); - if ( num == ERR_GOTO_IMPOSSIBLE ) strcpy(text, "Goto: miejsce docelowe niedostêpne"); - if ( num == ERR_GOTO_ITER ) strcpy(text, "Goto: miejsce docelowe niedostêpne"); - if ( num == ERR_GOTO_BUSY ) strcpy(text, "Goto: miejsce docelowe zajête"); - if ( num == ERR_FIRE_VEH ) strcpy(text, "Nieodpowiedni robot"); - if ( num == ERR_FIRE_ENERGY ) strcpy(text, "Za ma³o energii"); - if ( num == ERR_FIRE_FLY ) strcpy(text, "Niemo¿liwe podczas lotu"); - if ( num == ERR_CONVERT_EMPTY ) strcpy(text, "Brak rudy tytanu do przetopienia"); - if ( num == ERR_DERRICK_NULL ) strcpy(text, "W ziemi nie ma ¿adnej rudy"); - if ( num == ERR_STATION_NULL ) strcpy(text, "Brak energii w ziemi"); - if ( num == ERR_TOWER_POWER ) strcpy(text, "Brak ogniwa elektrycznego"); - if ( num == ERR_TOWER_ENERGY ) strcpy(text, "Nie ma wiêcej energii"); - if ( num == ERR_RESEARCH_POWER ) strcpy(text, "Brak ogniwa elektrycznego"); - if ( num == ERR_RESEARCH_ENERGY ) strcpy(text, "Za ma³o energii"); - if ( num == ERR_RESEARCH_TYPE ) strcpy(text, "Nieodpowiedni rodzaj ogniw"); - if ( num == ERR_RESEARCH_ALREADY) strcpy(text, "Program badawczy zosta³ ju¿ wykonany"); - if ( num == ERR_ENERGY_NULL ) strcpy(text, "Brak energii w ziemi"); - if ( num == ERR_ENERGY_LOW ) strcpy(text, "Wci¹¿ za ma³o energii"); - if ( num == ERR_ENERGY_EMPTY ) strcpy(text, "Brak tytanu do przetworzenia"); - if ( num == ERR_ENERGY_BAD ) strcpy(text, "Przetwarza jedynie tytan"); - if ( num == ERR_BASE_DLOCK ) strcpy(text, "Drzwi zablokowane przez robota lub inny obiekt "); - if ( num == ERR_BASE_DHUMAN ) strcpy(text, "Musisz byæ na statku kosmicznym aby nim odlecieæ"); - if ( num == ERR_LABO_NULL ) strcpy(text, "Nie ma niczego do zanalizowania"); - if ( num == ERR_LABO_BAD ) strcpy(text, "Analizuje jedynie materiê organiczn¹"); - if ( num == ERR_LABO_ALREADY ) strcpy(text, "Analiza zosta³a ju¿ wykonana"); - if ( num == ERR_NUCLEAR_NULL ) strcpy(text, "Brak energii w ziemi"); - if ( num == ERR_NUCLEAR_LOW ) strcpy(text, "Wci¹¿ za ma³o energii"); - if ( num == ERR_NUCLEAR_EMPTY ) strcpy(text, "Brak uranu do przetworzenia"); - if ( num == ERR_NUCLEAR_BAD ) strcpy(text, "Przetwarza jedynie uran"); - if ( num == ERR_FACTORY_NULL ) strcpy(text, "Brak tytanu"); - if ( num == ERR_FACTORY_NEAR ) strcpy(text, "Obiekt za blisko"); - if ( num == ERR_RESET_NEAR ) strcpy(text, "Miejsce zajête"); - if ( num == ERR_INFO_NULL ) strcpy(text, "Nie ma ¿adnej stacji przekaŸnikowej w zasiêgu"); - if ( num == ERR_VEH_VIRUS ) strcpy(text, "Program zawirusowany"); - if ( num == ERR_BAT_VIRUS ) strcpy(text, "Zainfekowane wirusem, chwilowo niesprawne"); - if ( num == ERR_VEH_POWER ) strcpy(text, "Brak ogniwa elektrycznego"); - if ( num == ERR_VEH_ENERGY ) strcpy(text, "Nie ma wiêcej energii"); - if ( num == ERR_FLAG_FLY ) strcpy(text, "Niemo¿liwe podczas lotu"); - if ( num == ERR_FLAG_WATER ) strcpy(text, "Niemo¿liwe podczas p³ywania"); - if ( num == ERR_FLAG_MOTOR ) strcpy(text, "Niemo¿liwe podczas ruchu"); - if ( num == ERR_FLAG_BUSY ) strcpy(text, "Niemo¿liwe podczas przenoszenia przedmiotu"); - if ( num == ERR_FLAG_CREATE ) strcpy(text, "Za du¿o flag w tym kolorze (maksymalnie 5)"); - if ( num == ERR_FLAG_PROXY ) strcpy(text, "Za blisko istniej¹cej flagi"); - if ( num == ERR_FLAG_DELETE ) strcpy(text, "Nie ma flagi w pobli¿u"); - if ( num == ERR_MISSION_NOTERM ) strcpy(text, "Misja nie jest wype³niona (naciœnij \\key help; aby uzyskaæ szczegó³y)"); - if ( num == ERR_DELETEMOBILE ) strcpy(text, "Robot zniszczony"); - if ( num == ERR_DELETEBUILDING ) strcpy(text, "Budynek zniszczony"); - if ( num == ERR_TOOMANY ) strcpy(text, "Nie mo¿na tego utworzyæ, za du¿o obiektów"); - if ( num == ERR_OBLIGATORYTOKEN ) strcpy(text, "It misses \"%s\" in this exercise"); - if ( num == ERR_PROHIBITEDTOKEN ) strcpy(text, "Do not use in this exercise"); - - if ( num == INFO_BUILD ) strcpy(text, "Budowa zakoñczona"); - if ( num == INFO_CONVERT ) strcpy(text, "Tytan dostêpny"); - if ( num == INFO_RESEARCH ) strcpy(text, "Program badawczy zakoñczony"); - if ( num == INFO_RESEARCHTANK ) strcpy(text, "Dostêpne plany tranporterów na g¹sienicach"); - if ( num == INFO_RESEARCHFLY ) strcpy(text, "Mo¿esz lataæ u¿ywaj¹c klawiszy (\\key gup;) oraz (\\key gdown;)"); - if ( num == INFO_RESEARCHTHUMP ) strcpy(text, "Dostêpne plany robota uderzacza"); - if ( num == INFO_RESEARCHCANON ) strcpy(text, "Dostêpne plany dzia³a"); - if ( num == INFO_RESEARCHTOWER ) strcpy(text, "Dostêpne plany wie¿y obronnej"); - if ( num == INFO_RESEARCHPHAZER ) strcpy(text, "Dostêpne plany dzia³a fazowego"); - if ( num == INFO_RESEARCHSHIELD ) strcpy(text, "Dostêpne plany robota os³aniacza"); - if ( num == INFO_RESEARCHATOMIC ) strcpy(text, "Dostêpne plany elektrowni atomowej"); - if ( num == INFO_FACTORY ) strcpy(text, "Dostêpny nowy robot"); - if ( num == INFO_LABO ) strcpy(text, "Analiza wykonana"); - if ( num == INFO_ENERGY ) strcpy(text, "Wytworzono ogniwo elektryczne"); - if ( num == INFO_NUCLEAR ) strcpy(text, "Wytworzono atomowe ogniwo elektryczne"); - if ( num == INFO_FINDING ) strcpy(text, "Znaleziono u¿yteczny przedmiot"); - if ( num == INFO_MARKPOWER ) strcpy(text, "Znaleziono miejsce na elektrowniê"); - if ( num == INFO_MARKURANIUM ) strcpy(text, "Znaleziono miejsce na kopalniê"); - if ( num == INFO_MARKSTONE ) strcpy(text, "Znaleziono miejsce na kopalniê"); - if ( num == INFO_MARKKEYa ) strcpy(text, "Znaleziono miejsce na kopalniê"); - if ( num == INFO_MARKKEYb ) strcpy(text, "Znaleziono miejsce na kopalniê"); - if ( num == INFO_MARKKEYc ) strcpy(text, "Znaleziono miejsce na kopalniê"); - if ( num == INFO_MARKKEYd ) strcpy(text, "Znaleziono miejsce na kopalniê"); - if ( num == INFO_WIN ) strcpy(text, "<<< Dobra robota, misja wype³niona >>>"); - if ( num == INFO_LOST ) strcpy(text, "<<< Niestety, misja nie powiod³a siê >>>"); - if ( num == INFO_LOSTq ) strcpy(text, "<<< Niestety, misja nie powiod³a siê >>>"); - if ( num == INFO_WRITEOK ) strcpy(text, "Bie¿¹ca misja zapisana"); - if ( num == INFO_DELETEPATH ) strcpy(text, "Przekroczono punkt kontrolny"); - if ( num == INFO_DELETEMOTHER ) strcpy(text, "Królowa Obcych zosta³a zabita"); - if ( num == INFO_DELETEANT ) strcpy(text, "Mrówka œmiertelnie raniona"); - if ( num == INFO_DELETEBEE ) strcpy(text, "Osa œmiertelnie raniona"); - if ( num == INFO_DELETEWORM ) strcpy(text, "Robal œmiertelnie raniony"); - if ( num == INFO_DELETESPIDER ) strcpy(text, "Paj¹k œmiertelnie raniony"); - if ( num == INFO_BEGINSATCOM ) strcpy(text, "Naciœnij klawisz \\key help; aby wyœwietliæ rozkazy na przekaŸniku SatCom"); - } - - if ( type == RES_CBOT ) - { - strcpy(text, "B³¹d"); - if ( num == TX_OPENPAR ) strcpy(text, "Brak nawiasu otwieraj¹cego"); - if ( num == TX_CLOSEPAR ) strcpy(text, "Brak nawiasu zamykaj¹cego"); - if ( num == TX_NOTBOOL ) strcpy(text, "Wyra¿enie musi zwróciæ wartoœæ logiczn¹"); - if ( num == TX_UNDEFVAR ) strcpy(text, "Zmienna nie zosta³a zadeklarowana"); - if ( num == TX_BADLEFT ) strcpy(text, "Przypisanie niemo¿liwe"); - if ( num == TX_ENDOF ) strcpy(text, "Brak œrednika na koñcu wiersza"); - if ( num == TX_OUTCASE ) strcpy(text, "Polecenie ""case"" na zewn¹trz bloku ""switch"""); - if ( num == TX_NOTERM ) strcpy(text, "Polecenie po koñcowej klamrze zamykaj¹cej"); - if ( num == TX_CLOSEBLK ) strcpy(text, "Brak koñca bloku"); - if ( num == TX_ELSEWITHOUTIF ) strcpy(text, "Polecenie ""else"" bez wyst¹pienia ""if"" "); - if ( num == TX_OPENBLK ) strcpy(text, "Brak klamry otwieraj¹cej");//début d'un bloc attendu? - if ( num == TX_BADTYPE ) strcpy(text, "Z³y typ dla przypisania"); - if ( num == TX_REDEFVAR ) strcpy(text, "Zmienna nie mo¿e byæ zadeklarowana dwukrotnie"); - if ( num == TX_BAD2TYPE ) strcpy(text, "Niezgodne typy operatorów"); - if ( num == TX_UNDEFCALL ) strcpy(text, "Funkcja nieznana"); - if ( num == TX_MISDOTS ) strcpy(text, "Brak znaku "" : "); - if ( num == TX_WHILE ) strcpy(text, "Brak kluczowego s³owa ""while"); - if ( num == TX_BREAK ) strcpy(text, "Polecenie ""break"" na zewn¹trz pêtli"); - if ( num == TX_LABEL ) strcpy(text, "Po etykiecie musi wyst¹piæ ""for"", ""while"", ""do"" lub ""switch"""); - if ( num == TX_NOLABEL ) strcpy(text, "Taka etykieta nie istnieje");// Cette étiquette n'existe pas - if ( num == TX_NOCASE ) strcpy(text, "Brak polecenia ""case"); - if ( num == TX_BADNUM ) strcpy(text, "Brak liczby"); - if ( num == TX_VOID ) strcpy(text, "Pusty parametr"); - if ( num == TX_NOTYP ) strcpy(text, "Brak deklaracji typu"); - if ( num == TX_NOVAR ) strcpy(text, "Brak nazwy zmiennej"); - if ( num == TX_NOFONC ) strcpy(text, "Brakuj¹ca nazwa funkcji"); - if ( num == TX_OVERPARAM ) strcpy(text, "Za du¿o parametrów"); - if ( num == TX_REDEF ) strcpy(text, "Funkcja ju¿ istnieje"); - if ( num == TX_LOWPARAM ) strcpy(text, "Brak wymaganego parametru"); - if ( num == TX_BADPARAM ) strcpy(text, "Funkcja o tej nazwie nie akceptuje parametrów tego typu"); - if ( num == TX_NUMPARAM ) strcpy(text, "Funkcja o tej nazwie nie akceptuje takiej liczby parametrów"); - if ( num == TX_NOITEM ) strcpy(text, "To nie jest obiekt tej klasy"); - if ( num == TX_DOT ) strcpy(text, "Ten obiekt nie jest cz³onkiem klasy"); - if ( num == TX_NOCONST ) strcpy(text, "Brak odpowiedniego konstruktora"); - if ( num == TX_REDEFCLASS ) strcpy(text, "Taka klasa ju¿ istnieje"); - if ( num == TX_CLBRK ) strcpy(text, "Brak "" ] """); - if ( num == TX_RESERVED ) strcpy(text, "S³owo zarezerwowane jêzyka CBOT"); - if ( num == TX_BADNEW ) strcpy(text, "Z³y argument dla funkcji ""new"""); - if ( num == TX_OPBRK ) strcpy(text, "Oczekiwane "" [ """); - if ( num == TX_BADSTRING ) strcpy(text, "Brak ³añcucha"); - if ( num == TX_BADINDEX ) strcpy(text, "Nieprawid³owy typ indeksu"); - if ( num == TX_PRIVATE ) strcpy(text, "Element prywatny"); - if ( num == TX_NOPUBLIC ) strcpy(text, "Wymagany publiczny"); - if ( num == TX_DIVZERO ) strcpy(text, "Dzielenie przez zero"); - if ( num == TX_NOTINIT ) strcpy(text, "Zmienna nie zosta³a zainicjalizowana"); - if ( num == TX_BADTHROW ) strcpy(text, "Wartoœæ ujemna odrzucona przez ""throw""");//C'est quoi, ça? - if ( num == TX_NORETVAL ) strcpy(text, "Funkcja nie zwróci³a ¿adnej wartoœci "); - if ( num == TX_NORUN ) strcpy(text, "¯adna funkcja nie dzia³a"); - if ( num == TX_NOCALL ) strcpy(text, "Odwo³anie do nieznanej funkcji"); - if ( num == TX_NOCLASS ) strcpy(text, "Taka klasa nie istnieje"); - if ( num == TX_NULLPT ) strcpy(text, "Obiekt nieznany"); - if ( num == TX_OPNAN ) strcpy(text, "Dzia³anie niemo¿liwe z wartoœci¹ ""nan"""); - if ( num == TX_OUTARRAY ) strcpy(text, "Dostêp poza tablicê"); - if ( num == TX_STACKOVER ) strcpy(text, "Przepe³nienie stosu"); - if ( num == TX_DELETEDPT ) strcpy(text, "Nieprawid³owy obiekt"); - if ( num == TX_FILEOPEN ) strcpy(text, "Nie mo¿na otworzyæ pliku"); - if ( num == TX_NOTOPEN ) strcpy(text, "Plik nie jest otwarty"); - if ( num == TX_ERRREAD ) strcpy(text, "B³¹d odczytu"); - if ( num == TX_ERRWRITE ) strcpy(text, "B³¹d zapisu"); - } - - if ( type == RES_KEY ) - { - if ( num == 0 ) strcpy(text, "< brak >"); - if ( num == VK_LEFT ) strcpy(text, "Strza³ka w lewo"); - if ( num == VK_RIGHT ) strcpy(text, "Strza³ka w prawo"); - if ( num == VK_UP ) strcpy(text, "Strza³ka w górê"); - if ( num == VK_DOWN ) strcpy(text, "Strza³ka w dó³"); - if ( num == VK_CANCEL ) strcpy(text, "Ctrl-break"); - if ( num == VK_BACK ) strcpy(text, "<--"); - if ( num == VK_TAB ) strcpy(text, "Tab"); - if ( num == VK_CLEAR ) strcpy(text, "Delete"); - if ( num == VK_RETURN ) strcpy(text, "Enter"); - if ( num == VK_SHIFT ) strcpy(text, "Shift"); - if ( num == VK_CONTROL ) strcpy(text, "Ctrl"); - if ( num == VK_MENU ) strcpy(text, "Alt"); - if ( num == VK_PAUSE ) strcpy(text, "Pause"); - if ( num == VK_CAPITAL ) strcpy(text, "Caps Lock"); - if ( num == VK_ESCAPE ) strcpy(text, "Esc"); - if ( num == VK_SPACE ) strcpy(text, "Spacja"); - if ( num == VK_PRIOR ) strcpy(text, "Page Up"); - if ( num == VK_NEXT ) strcpy(text, "Page Down"); - if ( num == VK_END ) strcpy(text, "End"); - if ( num == VK_HOME ) strcpy(text, "Home"); - if ( num == VK_SELECT ) strcpy(text, "Zaznacz"); - if ( num == VK_EXECUTE ) strcpy(text, "Wykonaj"); - if ( num == VK_SNAPSHOT ) strcpy(text, "Print Scrn"); - if ( num == VK_INSERT ) strcpy(text, "Insert"); - if ( num == VK_DELETE ) strcpy(text, "Delete"); - if ( num == VK_HELP ) strcpy(text, "Pomoc"); - if ( num == VK_LWIN ) strcpy(text, "Lewy klawisz Windows"); - if ( num == VK_RWIN ) strcpy(text, "Prawy klawisz Windows"); - if ( num == VK_APPS ) strcpy(text, "Klawisz menu kontekstowego"); - if ( num == VK_NUMPAD0 ) strcpy(text, "Klaw. Num. 0"); - if ( num == VK_NUMPAD1 ) strcpy(text, "Klaw. Num. 1"); - if ( num == VK_NUMPAD2 ) strcpy(text, "Klaw. Num. 2"); - if ( num == VK_NUMPAD3 ) strcpy(text, "Klaw. Num. 3"); - if ( num == VK_NUMPAD4 ) strcpy(text, "Klaw. Num. 4"); - if ( num == VK_NUMPAD5 ) strcpy(text, "Klaw. Num. 5"); - if ( num == VK_NUMPAD6 ) strcpy(text, "Klaw. Num. 6"); - if ( num == VK_NUMPAD7 ) strcpy(text, "Klaw. Num. 7"); - if ( num == VK_NUMPAD8 ) strcpy(text, "Klaw. Num. 8"); - if ( num == VK_NUMPAD9 ) strcpy(text, "Klaw. Num. 9"); - if ( num == VK_MULTIPLY ) strcpy(text, "Klaw. Num. *"); - if ( num == VK_ADD ) strcpy(text, "Klaw. Num. +"); - if ( num == VK_SEPARATOR ) strcpy(text, "Klaw. Num. separator"); - if ( num == VK_SUBTRACT ) strcpy(text, "Klaw. Num. -"); - if ( num == VK_DECIMAL ) strcpy(text, "Klaw. Num. ."); - if ( num == VK_DIVIDE ) strcpy(text, "Klaw. Num. /"); - if ( num == VK_F1 ) strcpy(text, "F1"); - if ( num == VK_F2 ) strcpy(text, "F2"); - if ( num == VK_F3 ) strcpy(text, "F3"); - if ( num == VK_F4 ) strcpy(text, "F4"); - if ( num == VK_F5 ) strcpy(text, "F5"); - if ( num == VK_F6 ) strcpy(text, "F6"); - if ( num == VK_F7 ) strcpy(text, "F7"); - if ( num == VK_F8 ) strcpy(text, "F8"); - if ( num == VK_F9 ) strcpy(text, "F9"); - if ( num == VK_F10 ) strcpy(text, "F10"); - if ( num == VK_F11 ) strcpy(text, "F11"); - if ( num == VK_F12 ) strcpy(text, "F12"); - if ( num == VK_F13 ) strcpy(text, "F13"); - if ( num == VK_F14 ) strcpy(text, "F14"); - if ( num == VK_F15 ) strcpy(text, "F15"); - if ( num == VK_F16 ) strcpy(text, "F16"); - if ( num == VK_F17 ) strcpy(text, "F17"); - if ( num == VK_F18 ) strcpy(text, "F18"); - if ( num == VK_F19 ) strcpy(text, "F19"); - if ( num == VK_F20 ) strcpy(text, "F20"); - if ( num == VK_NUMLOCK ) strcpy(text, "Num Lock"); - if ( num == VK_SCROLL ) strcpy(text, "Scroll Lock"); - if ( num == VK_ATTN ) strcpy(text, "Attn"); - if ( num == VK_CRSEL ) strcpy(text, "CrSel"); - if ( num == VK_EXSEL ) strcpy(text, "ExSel"); - if ( num == VK_EREOF ) strcpy(text, "Erase EOF"); - if ( num == VK_PLAY ) strcpy(text, "Graj"); - if ( num == VK_ZOOM ) strcpy(text, "Powiêkszenie"); - if ( num == VK_PA1 ) strcpy(text, "PA1"); - if ( num == VK_OEM_CLEAR ) strcpy(text, "Wyczyœæ"); - if ( num == VK_BUTTON1 ) strcpy(text, "Przycisk 1"); - if ( num == VK_BUTTON2 ) strcpy(text, "Przycisk 2"); - if ( num == VK_BUTTON3 ) strcpy(text, "Przycisk 3"); - if ( num == VK_BUTTON4 ) strcpy(text, "Przycisk 4"); - if ( num == VK_BUTTON5 ) strcpy(text, "Przycisk 5"); - if ( num == VK_BUTTON6 ) strcpy(text, "Przycisk 6"); - if ( num == VK_BUTTON7 ) strcpy(text, "Przycisk 7"); - if ( num == VK_BUTTON8 ) strcpy(text, "Przycisk 8"); - if ( num == VK_BUTTON9 ) strcpy(text, "Przycisk 9"); - if ( num == VK_BUTTON10 ) strcpy(text, "Przycisk 10"); - if ( num == VK_BUTTON11 ) strcpy(text, "Przycisk 11"); - if ( num == VK_BUTTON12 ) strcpy(text, "Przycisk 12"); - if ( num == VK_BUTTON13 ) strcpy(text, "Przycisk 13"); - if ( num == VK_BUTTON14 ) strcpy(text, "Przycisk 14"); - if ( num == VK_BUTTON15 ) strcpy(text, "Przycisk 15"); - if ( num == VK_BUTTON16 ) strcpy(text, "Przycisk 16"); - if ( num == VK_BUTTON17 ) strcpy(text, "Przycisk 17"); - if ( num == VK_BUTTON18 ) strcpy(text, "Przycisk 18"); - if ( num == VK_BUTTON19 ) strcpy(text, "Przycisk 19"); - if ( num == VK_BUTTON20 ) strcpy(text, "Przycisk 20"); - if ( num == VK_BUTTON21 ) strcpy(text, "Przycisk 21"); - if ( num == VK_BUTTON22 ) strcpy(text, "Przycisk 22"); - if ( num == VK_BUTTON23 ) strcpy(text, "Przycisk 23"); - if ( num == VK_BUTTON24 ) strcpy(text, "Przycisk 24"); - if ( num == VK_BUTTON25 ) strcpy(text, "Przycisk 25"); - if ( num == VK_BUTTON26 ) strcpy(text, "Przycisk 26"); - if ( num == VK_BUTTON27 ) strcpy(text, "Przycisk 27"); - if ( num == VK_BUTTON28 ) strcpy(text, "Przycisk 28"); - if ( num == VK_BUTTON29 ) strcpy(text, "Przycisk 29"); - if ( num == VK_BUTTON30 ) strcpy(text, "Przycisk 30"); - if ( num == VK_BUTTON31 ) strcpy(text, "Przycisk 31"); - if ( num == VK_BUTTON32 ) strcpy(text, "Przycisk 32"); - if ( num == VK_WHEELUP ) strcpy(text, "Kó³ko w górê"); - if ( num == VK_WHEELDOWN ) strcpy(text, "Kó³ko w dó³"); - } -#endif - - return ( text[0] != 0 ); -} - - diff --git a/src/restext.h b/src/restext.h deleted file mode 100644 index 2fe53fe..0000000 --- a/src/restext.h +++ /dev/null @@ -1,159 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// restext.h - -#ifndef _RESTEXT_H_ -#define _RESTEXT_H_ - - -#define STRICT -#define D3D_OVERLOADS - - -#include "d3dengine.h" -#include "event.h" - - - - -// Possible types of the text resources. - -enum ResType -{ - RES_TEXT = 0, // RT_* - RES_EVENT = 1, // EVENT_* (EventMsg) - RES_OBJECT = 2, // OBJECT_* (ObjectType) - RES_ERR = 3, // ERR_* (Error) - RES_KEY = 4, // VK_* (keys) - RES_CBOT = 5, // TX_* (cbot.dll) -}; - - -// Resources of type RES_TEXT. - -#define RT_VERSION_ID 1 -#define RT_DISINFO_TITLE 2 -#define RT_WINDOW_MAXIMIZED 3 -#define RT_WINDOW_MINIMIZED 4 -#define RT_WINDOW_STANDARD 5 -#define RT_WINDOW_CLOSE 6 - -#define RT_STUDIO_TITLE 10 -#define RT_SCRIPT_NEW 20 -#define RT_NAME_DEFAULT 21 -#define RT_IO_NEW 22 -#define RT_KEY_OR 23 - -#define RT_TITLE_BASE 40 -#define RT_TITLE_INIT 41 -#define RT_TITLE_TRAINER 42 -#define RT_TITLE_DEFI 43 -#define RT_TITLE_MISSION 44 -#define RT_TITLE_FREE 45 -#define RT_TITLE_PROTO 46 -#define RT_TITLE_SETUP 47 -#define RT_TITLE_NAME 48 -#define RT_TITLE_PERSO 49 -#define RT_TITLE_WRITE 50 -#define RT_TITLE_READ 51 -#define RT_TITLE_USER 52 -#define RT_TITLE_TEEN 53 - -#define RT_PLAY_CHAPt 60 -#define RT_PLAY_CHAPd 61 -#define RT_PLAY_CHAPm 62 -#define RT_PLAY_CHAPf 63 -#define RT_PLAY_CHAPp 64 -#define RT_PLAY_LISTt 65 -#define RT_PLAY_LISTd 66 -#define RT_PLAY_LISTm 67 -#define RT_PLAY_LISTf 68 -#define RT_PLAY_LISTp 69 -#define RT_PLAY_RESUME 70 -#define RT_PLAY_CHAPu 71 -#define RT_PLAY_LISTu 72 -#define RT_PLAY_CHAPte 73 -#define RT_PLAY_LISTk 74 - -#define RT_SETUP_DEVICE 80 -#define RT_SETUP_MODE 81 -#define RT_SETUP_KEY1 82 -#define RT_SETUP_KEY2 83 - -#define RT_PERSO_FACE 90 -#define RT_PERSO_GLASSES 91 -#define RT_PERSO_HAIR 92 -#define RT_PERSO_COMBI 93 -#define RT_PERSO_BAND 94 - -#define RT_DIALOG_TITLE 100 -#define RT_DIALOG_ABORT 101 -#define RT_DIALOG_QUIT 102 -#define RT_DIALOG_YES 103 -#define RT_DIALOG_NO 104 -#define RT_DIALOG_DELOBJ 105 -#define RT_DIALOG_DELGAME 106 -#define RT_DIALOG_YESDEL 107 -#define RT_DIALOG_NODEL 108 -#define RT_DIALOG_LOADING 109 -#define RT_DIALOG_YESQUIT 110 -#define RT_DIALOG_NOQUIT 111 - -#define RT_STUDIO_LISTTT 120 -#define RT_STUDIO_COMPOK 121 -#define RT_STUDIO_PROGSTOP 122 - -#define RT_SATCOM_LIST 140 -#define RT_SATCOM_BOT 141 -#define RT_SATCOM_BUILDING 142 -#define RT_SATCOM_FRET 143 -#define RT_SATCOM_ALIEN 144 -#define RT_SATCOM_NULL 145 -#define RT_SATCOM_ERROR1 146 -#define RT_SATCOM_ERROR2 147 - -#define RT_IO_OPEN 150 -#define RT_IO_SAVE 151 -#define RT_IO_LIST 152 -#define RT_IO_NAME 153 -#define RT_IO_DIR 154 -#define RT_IO_PRIVATE 155 -#define RT_IO_PUBLIC 156 - -#define RT_GENERIC_DEV1 170 -#define RT_GENERIC_DEV2 171 -#define RT_GENERIC_EDIT1 172 -#define RT_GENERIC_EDIT2 173 - -#define RT_INTERFACE_REC 180 - -#define RT_MESSAGE_WIN 200 -#define RT_MESSAGE_LOST 201 - - -static CD3DEngine* g_engine = 0; -static char g_gamerName[100]; - -extern void SetEngine(CD3DEngine *engine); -extern void SetGlobalGamerName(char *name); -extern BOOL SearchKey(char *cmd, KeyRank &key); -extern void PutKeyName(char* dst, char* src); -extern BOOL GetResource(ResType type, int num, char* text); -extern BOOL GetResourceBase(ResType type, int num, char* text); - - -#endif //_RESTEXT_H_ diff --git a/src/robotmain.cpp b/src/robotmain.cpp deleted file mode 100644 index a6d92e5..0000000 --- a/src/robotmain.cpp +++ /dev/null @@ -1,7031 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// robotmain.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "CBot/CBotDll.h" -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "language.h" -#include "global.h" -#include "event.h" -#include "misc.h" -#include "profile.h" -#include "iman.h" -#include "restext.h" -#include "math3d.h" -#include "light.h" -#include "particule.h" -#include "terrain.h" -#include "water.h" -#include "cloud.h" -#include "blitz.h" -#include "planet.h" -#include "object.h" -#include "motion.h" -#include "motiontoto.h" -#include "motionhuman.h" -#include "physics.h" -#include "brain.h" -#include "pyro.h" -#include "modfile.h" -#include "model.h" -#include "camera.h" -#include "task.h" -#include "taskmanip.h" -#include "taskbuild.h" -#include "auto.h" -#include "autobase.h" -#include "displayinfo.h" -#include "interface.h" -#include "shortcut.h" -#include "map.h" -#include "label.h" -#include "button.h" -#include "slider.h" -#include "window.h" -#include "edit.h" -#include "displaytext.h" -#include "text.h" -#include "sound.h" -#include "cbottoken.h" -#include "cmdtoken.h" -#include "mainmovie.h" -#include "maindialog.h" -#include "mainshort.h" -#include "mainmap.h" -#include "script.h" -#include "robotmain.h" - - - -#define CBOT_STACK TRUE // saves the stack of programs CBOT -#define UNIT 4.0f - - - -// Global variables. - -long g_id; // unique identifier -long g_build; // constructible buildings -long g_researchDone; // research done -long g_researchEnable; // research available -float g_unit; // conversion factor - - - -#include "ClassFILE.cpp" - - - -// Compilation of class "point". - -CBotTypResult cPoint(CBotVar* pThis, CBotVar* &var) -{ - if ( !pThis->IsElemOfClass("point") ) return CBotTypResult(CBotErrBadNum); - - if ( var == NULL ) return CBotTypResult(0); // ok if no parameter - - // First parameter (x): - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - // Second parameter (y): - if ( var == NULL ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - // Third parameter (z): - if ( var == NULL ) // only 2 parameters? - { - return CBotTypResult(0); // this function returns void - } - - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - if ( var != NULL ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(0); // this function returns void -} - -//Execution of the class "point". - -BOOL rPoint(CBotVar* pThis, CBotVar* var, CBotVar* pResult, int& Exception) -{ - CBotVar *pX, *pY, *pZ; - - if ( var == NULL ) return TRUE; // constructor with no parameters is ok - - if ( var->GivType() > CBotTypDouble ) - { - Exception = CBotErrBadNum; return FALSE; - } - - pX = pThis->GivItem("x"); - if ( pX == NULL ) - { - Exception = CBotErrUndefItem; return FALSE; - } - pX->SetValFloat( var->GivValFloat() ); - var = var->GivNext(); - - if ( var == NULL ) - { - Exception = CBotErrLowParam; return FALSE; - } - - if ( var->GivType() > CBotTypDouble ) - { - Exception = CBotErrBadNum; return FALSE; - } - - pY = pThis->GivItem("y"); - if ( pY == NULL ) - { - Exception = CBotErrUndefItem; return FALSE; - } - pY->SetValFloat( var->GivValFloat() ); - var = var->GivNext(); - - if ( var == NULL ) - { - return TRUE; // ok with only two parameters - } - - pZ = pThis->GivItem("z"); - if ( pZ == NULL ) - { - Exception = CBotErrUndefItem; return FALSE; - } - pZ->SetValFloat( var->GivValFloat() ); - var = var->GivNext(); - - if ( var != NULL ) - { - Exception = CBotErrOverParam; return FALSE; - } - - return TRUE; // no interruption -} - - - - -// Constructor of robot application. - -CRobotMain::CRobotMain(CInstanceManager* iMan) -{ - ObjectType type; - float fValue; - int iValue, i; - char* token; - - m_iMan = iMan; - m_iMan->AddInstance(CLASS_MAIN, this); - - m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - m_cloud = (CCloud*)m_iMan->SearchInstance(CLASS_CLOUD); - m_blitz = (CBlitz*)m_iMan->SearchInstance(CLASS_BLITZ); - m_planet = (CPlanet*)m_iMan->SearchInstance(CLASS_PLANET); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - - m_interface = new CInterface(m_iMan); - m_terrain = new CTerrain(m_iMan); - m_model = new CModel(m_iMan); - m_camera = new CCamera(m_iMan); - m_displayText = new CDisplayText(m_iMan); - m_movie = new CMainMovie(m_iMan); - m_dialog = new CMainDialog(m_iMan); - m_short = new CMainShort(m_iMan); - m_map = new CMainMap(m_iMan); - m_displayInfo = 0; - - m_engine->SetTerrain(m_terrain); - m_filesDir = m_dialog->RetFilesDir(); - - m_time = 0.0f; - m_gameTime = 0.0f; - m_checkEndTime = 0.0f; - - m_phase = PHASE_NAME; - m_cameraRank = -1; - m_visitLast = EVENT_NULL; - m_visitObject = 0; - m_visitArrow = 0; - m_audioTrack = 0; - m_bAudioRepeat = TRUE; - m_delayWriteMessage = 0; - m_selectObject = 0; - m_infoUsed = 0; - - m_bBeginSatCom = FALSE; - m_bMovieLock = FALSE; - m_bSatComLock = FALSE; - m_bEditLock = FALSE; - m_bEditFull = FALSE; - m_bPause = FALSE; - m_bHilite = FALSE; - m_bFreePhoto = FALSE; - m_bShowPos = FALSE; - m_bSelectInsect = FALSE; - m_bShowSoluce = FALSE; - m_bShowAll = FALSE; - m_bCheatRadar = FALSE; - m_bFixScene = FALSE; - m_bTrainerPilot = FALSE; - m_bSuspend = FALSE; - m_bFriendAim = FALSE; - m_bResetCreate = FALSE; - m_bShortCut = TRUE; - - m_engine->SetMovieLock(m_bMovieLock); - - m_movie->Flush(); - m_movieInfoIndex = -1; - - m_tooltipPos = FPOINT(0.0f, 0.0f); - m_tooltipName[0] = 0; - m_tooltipTime = 0.0f; - - m_endingWinRank = 0; - m_endingLostRank = 0; - m_bWinTerminate = FALSE; - - FlushDisplayInfo(); - - m_fontSize = 9.0f; - m_windowPos = FPOINT(0.15f, 0.17f); - m_windowDim = FPOINT(0.70f, 0.66f); - - if ( GetProfileFloat("Edit", "FontSize", fValue) ) m_fontSize = fValue; - if ( GetProfileFloat("Edit", "WindowPos.x", fValue) ) m_windowPos.x = fValue; - if ( GetProfileFloat("Edit", "WindowPos.y", fValue) ) m_windowPos.y = fValue; - if ( GetProfileFloat("Edit", "WindowDim.x", fValue) ) m_windowDim.x = fValue; - if ( GetProfileFloat("Edit", "WindowDim.y", fValue) ) m_windowDim.y = fValue; - - m_IOPublic = FALSE; - m_IODim = FPOINT(320.0f/640.0f, (121.0f+18.0f*8)/480.0f); - m_IOPos.x = (1.0f-m_IODim.x)/2.0f; // in the middle - m_IOPos.y = (1.0f-m_IODim.y)/2.0f; - - if ( GetProfileInt ("Edit", "IOPublic", iValue) ) m_IOPublic = iValue; - if ( GetProfileFloat("Edit", "IOPos.x", fValue) ) m_IOPos.x = fValue; - if ( GetProfileFloat("Edit", "IOPos.y", fValue) ) m_IOPos.y = fValue; - if ( GetProfileFloat("Edit", "IODim.x", fValue) ) m_IODim.x = fValue; - if ( GetProfileFloat("Edit", "IODim.y", fValue) ) m_IODim.y = fValue; - - m_short->FlushShortcuts(); - InitEye(); - - m_engine->SetTracePrecision(1.0f); - - m_cameraPan = 0.0f; - m_cameraZoom = 0.0f; - - g_id = 0; - g_build = 0; - g_researchDone = 0; // no research done - g_researchEnable = 0; - g_unit = 4.0f; - - m_gamerName[0] = 0; - GetProfileString("Gamer", "LastName", m_gamerName, 100); - SetGlobalGamerName(m_gamerName); - ReadFreeParam(); - m_dialog->SetupRecall(); - - for ( i=0 ; iAddItem("x", CBotTypFloat); - bc->AddItem("y", CBotTypFloat); - bc->AddItem("z", CBotTypFloat); - bc->AddFunction("point", rPoint, cPoint); - - // Adds the class Object. - bc = new CBotClass("object", NULL); - bc->AddItem("category", CBotTypResult(CBotTypInt), PR_READ); - bc->AddItem("position", CBotTypResult(CBotTypClass, "point"), PR_READ); - bc->AddItem("orientation", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("pitch", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("roll", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("energyLevel", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("shieldLevel", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("temperature", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("altitude", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("lifeTime", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("material", CBotTypResult(CBotTypInt), PR_READ); - bc->AddItem("energyCell", CBotTypResult(CBotTypPointer, "object"), PR_READ); - bc->AddItem("load", CBotTypResult(CBotTypPointer, "object"), PR_READ); - - // Initializes the class FILE. - InitClassFILE(); - - CScript::InitFonctions(); -} - -// Destructor of robot application. - -CRobotMain::~CRobotMain() -{ - delete m_movie; - delete m_dialog; - delete m_short; - delete m_map; - delete m_terrain; - delete m_model; -} - - -// Creates the file colobot.ini at the first time. - -void CRobotMain::CreateIni() -{ - int iValue; - - // colobot.ini don't exist? - if ( !GetProfileInt("Setup", "TotoMode", iValue) ) - { - m_dialog->SetupMemorize(); - } -} - - -// Changes phase. - -void CRobotMain::ChangePhase(Phase phase) -{ - CEdit* pe; - CButton* pb; - D3DCOLORVALUE color; - FPOINT pos, dim, ddim; - float ox, oy, sx, sy; - char* read; - int rank, numTry; - BOOL bLoading; - - if ( m_phase == PHASE_SIMUL ) // ends a simulation? - { - SaveAllScript(); - m_sound->StopMusic(); - m_camera->SetObject(0); - -#if _SCHOOL - if ( TRUE ) -#else - if ( m_gameTime > 10.0f ) // did you play at least 10 seconds? -#endif - { - rank = m_dialog->RetSceneRank(); - numTry = m_dialog->RetGamerInfoTry(rank); - m_dialog->SetGamerInfoTry(rank, numTry+1); - m_dialog->WriteGamerInfo(); - } - } - - if ( phase == PHASE_WIN ) // wins a simulation? - { - rank = m_dialog->RetSceneRank(); - m_dialog->SetGamerInfoPassed(rank, TRUE); - m_dialog->NextMission(); // passes to the next mission - m_dialog->WriteGamerInfo(); - } - - DeleteAllObjects(); // removes all the current 3D Scene - - m_phase = phase; - m_winDelay = 0.0f; - m_lostDelay = 0.0f; - m_bBeginSatCom = FALSE; - m_bMovieLock = FALSE; - m_bSatComLock = FALSE; - m_bEditLock = FALSE; - m_bFreePhoto = FALSE; - m_bResetCreate = FALSE; - - m_engine->SetMovieLock(m_bMovieLock); - ChangePause(FALSE); - FlushDisplayInfo(); - m_engine->SetRankView(0); - m_engine->FlushObject(); - color.r = color.g = color.b = color.a = 0.0f; - m_engine->SetWaterAddColor(color); - m_engine->SetBackground(""); - m_engine->SetBackForce(FALSE); - m_engine->SetFrontsizeName(""); - m_engine->SetOverColor(); - m_engine->GroundMarkDelete(0); - SetSpeed(1.0f); - m_terrain->SetWind(D3DVECTOR(0.0f, 0.0f, 0.0f)); - m_terrain->FlushBuildingLevel(); - m_terrain->FlushFlyingLimit(); - m_light->FlushLight(); - m_particule->FlushParticule(); - m_water->Flush(); - m_cloud->Flush(); - m_blitz->Flush(); - m_planet->Flush(); - m_iMan->Flush(CLASS_OBJECT); - m_iMan->Flush(CLASS_PHYSICS); - m_iMan->Flush(CLASS_BRAIN); - m_iMan->Flush(CLASS_PYRO); - m_model->StopUserAction(); - m_interface->Flush(); - ClearInterface(); - FlushNewScriptName(); - m_sound->SetListener(D3DVECTOR(0.0f, 0.0f, 0.0f), D3DVECTOR(0.0f, 0.0f, 1.0f)); - m_camera->SetType(CAMERA_DIALOG); - m_movie->Flush(); - m_movieInfoIndex = -1; - m_cameraPan = 0.0f; - m_cameraZoom = 0.0f; - m_bShortCut = TRUE; - - // Creates and hide the command console. - dim.x = 200.0f/640.0f; - dim.y = 18.0f/480.0f; - pos.x = 50.0f/640.0f; - pos.y = 452.0f/480.0f; - pe = m_interface->CreateEdit(pos, dim, 0, EVENT_CMD); - if ( pe == 0 ) return; - pe->ClearState(STATE_VISIBLE); - m_bCmdEdit = FALSE; // hidden for now - - // Creates the speedometer. -#if _TEEN - dim.x = 30.0f/640.0f; - dim.y = 20.0f/480.0f; - pos.x = 4.0f/640.0f; - pos.y = 454.0f/480.0f; -#else - dim.x = 30.0f/640.0f; - dim.y = 20.0f/480.0f; - pos.x = 4.0f/640.0f; - pos.y = 426.0f/480.0f; -#endif - pb = m_interface->CreateButton(pos, dim, 0, EVENT_SPEED); - if ( pb == 0 ) return; - pb->SetState(STATE_SIMPLY); - pb->ClearState(STATE_VISIBLE); - - m_dialog->ChangePhase(m_phase); - - dim.x = 32.0f/640.0f; - dim.y = 32.0f/480.0f; - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = (32.0f+2.0f)/640.0f; - sy = (32.0f+2.0f)/480.0f; - - if ( m_phase != PHASE_PERSO ) - { - m_engine->SetDrawWorld(TRUE); - m_engine->SetDrawFront(FALSE); - m_bFixScene = FALSE; - } - - if ( m_phase == PHASE_INIT ) - { -#if _NEWLOOK - m_engine->FreeTexture("generna.tga"); - m_engine->FreeTexture("genernb.tga"); - m_engine->FreeTexture("genernc.tga"); - m_engine->FreeTexture("genernd.tga"); -#else -#if _FRENCH -#if _DEMO - m_engine->FreeTexture("genedfa.tga"); - m_engine->FreeTexture("genedfb.tga"); - m_engine->FreeTexture("genedfc.tga"); - m_engine->FreeTexture("genedfd.tga"); -#else - m_engine->FreeTexture("generfa.tga"); - m_engine->FreeTexture("generfb.tga"); - m_engine->FreeTexture("generfc.tga"); - m_engine->FreeTexture("generfd.tga"); -#endif -#endif -#if _ENGLISH -#if _DEMO - m_engine->FreeTexture("genedea.tga"); - m_engine->FreeTexture("genedeb.tga"); - m_engine->FreeTexture("genedec.tga"); - m_engine->FreeTexture("geneded.tga"); -#else - m_engine->FreeTexture("generea.tga"); - m_engine->FreeTexture("genereb.tga"); - m_engine->FreeTexture("generec.tga"); - m_engine->FreeTexture("genered.tga"); -#endif -#endif -#if _GERMAN -#if _DEMO - m_engine->FreeTexture("genedda.tga"); - m_engine->FreeTexture("geneddb.tga"); - m_engine->FreeTexture("geneddc.tga"); - m_engine->FreeTexture("geneddd.tga"); -#else - m_engine->FreeTexture("generea.tga"); - m_engine->FreeTexture("genereb.tga"); - m_engine->FreeTexture("generec.tga"); - m_engine->FreeTexture("genered.tga"); -#endif -#endif -#if _WG -#if _DEMO - m_engine->FreeTexture("genedda.tga"); - m_engine->FreeTexture("geneddb.tga"); - m_engine->FreeTexture("geneddc.tga"); - m_engine->FreeTexture("geneddd.tga"); -#else - m_engine->FreeTexture("generda.tga"); - m_engine->FreeTexture("generdb.tga"); - m_engine->FreeTexture("generdc.tga"); - m_engine->FreeTexture("generdd.tga"); -#endif -#endif -#if _POLISH -#if _DEMO - m_engine->FreeTexture("genedpa.tga"); - m_engine->FreeTexture("genedpb.tga"); - m_engine->FreeTexture("genedpc.tga"); - m_engine->FreeTexture("genedpd.tga"); -#else - m_engine->FreeTexture("generpa.tga"); - m_engine->FreeTexture("generpb.tga"); - m_engine->FreeTexture("generpc.tga"); - m_engine->FreeTexture("generpd.tga"); -#endif -#endif -#endif - } - - if ( m_phase == PHASE_SIMUL ) - { - m_engine->FreeTexture("inter01a.tga"); - m_engine->FreeTexture("inter01b.tga"); - m_engine->FreeTexture("inter01c.tga"); - m_engine->FreeTexture("inter01d.tga"); - - read = m_dialog->RetSceneRead(); - bLoading = (read[0] != 0); - - m_map->CreateMap(); - CreateScene(m_dialog->RetSceneSoluce(), FALSE, FALSE); // interactive scene - if ( m_bMapImage ) - { - m_map->SetFixImage(m_mapFilename); - } - - pos.x = 620.0f/640.0f; - pos.y = 460.0f/480.0f; - ddim.x = 20.0f/640.0f; - ddim.y = 20.0f/480.0f; - m_interface->CreateButton(pos, ddim, 11, EVENT_BUTTON_QUIT); - - if ( m_bImmediatSatCom && !bLoading && - m_infoFilename[SATCOM_HUSTON][0] != 0 ) - { - StartDisplayInfo(SATCOM_HUSTON, FALSE); // shows the instructions - } - - m_sound->StopMusic(); - if ( !m_bBase || bLoading ) StartMusic(); - } - - if ( m_phase == PHASE_WIN ) - { - if ( m_endingWinRank == -1 ) - { - ChangePhase(PHASE_TERM); - } - else - { -#if _TEEN - m_bWinTerminate = (m_endingWinRank == 900); - m_dialog->SetSceneName("teenw"); -#else - m_bWinTerminate = (m_endingWinRank == 904); - m_dialog->SetSceneName("win"); -#endif - m_dialog->SetSceneRank(m_endingWinRank); - CreateScene(FALSE, TRUE, FALSE); // sets scene - - pos.x = ox+sx*1; pos.y = oy+sy*1; - ddim.x = dim.x*2; ddim.y = dim.y*2; - m_interface->CreateButton(pos, ddim, 16, EVENT_BUTTON_OK); - - if ( m_bWinTerminate ) - { -#if _TEEN - pos.x = ox+sx*3; pos.y = oy+sy*1; - ddim.x = dim.x*15; ddim.y = dim.y*2; - pe = m_interface->CreateEdit(pos, ddim, 0, EVENT_EDIT0); - pe->SetFontType(FONT_COLOBOT); - pe->SetEditCap(FALSE); - pe->SetHiliteCap(FALSE); - pe->ReadText("help\\teenw.txt"); -#else - pos.x = ox+sx*3; pos.y = oy+sy*0.2f; - ddim.x = dim.x*15; ddim.y = dim.y*3.0f; - pe = m_interface->CreateEdit(pos, ddim, 0, EVENT_EDIT0); - pe->SetGenericMode(TRUE); - pe->SetFontType(FONT_COLOBOT); - pe->SetEditCap(FALSE); - pe->SetHiliteCap(FALSE); - pe->ReadText("help\\win.txt"); -#endif - } - else - { - m_displayText->DisplayError(INFO_WIN, D3DVECTOR(0.0f,0.0f,0.0f), 15.0f, 60.0f, 1000.0f); - } - } - m_sound->StopAll(); - StartMusic(); - } - - if ( m_phase == PHASE_LOST ) - { - if ( m_endingLostRank == -1 ) - { - ChangePhase(PHASE_TERM); - } - else - { - m_bWinTerminate = FALSE; - m_dialog->SetSceneName("lost"); - m_dialog->SetSceneRank(m_endingLostRank); - CreateScene(FALSE, TRUE, FALSE); // sets scene - - pos.x = ox+sx*1; pos.y = oy+sy*1; - ddim.x = dim.x*2; ddim.y = dim.y*2; - m_interface->CreateButton(pos, ddim, 16, EVENT_BUTTON_OK); - m_displayText->DisplayError(INFO_LOST, D3DVECTOR(0.0f,0.0f,0.0f), 15.0f, 60.0f, 1000.0f); - } - m_sound->StopAll(); - StartMusic(); - } - - if ( m_phase == PHASE_MODEL ) - { - pos.x = ox+sx*0; pos.y = oy+sy*0; - m_interface->CreateButton(pos, dim, 11, EVENT_BUTTON_CANCEL); - - CreateModel(); - } - - if ( m_phase == PHASE_LOADING ) - { - m_engine->SetMouseHide(TRUE); - } - else - { - m_engine->SetMouseHide(FALSE); - } - - m_engine->LoadAllTexture(); -} - - -// Processes an event. - -BOOL CRobotMain::EventProcess(const Event &event) -{ - CEdit* pe; - CObject* pObj; - Event newEvent; - MainMovieType type; - int i; - - if ( event.event == EVENT_FRAME ) - { - if ( !m_movie->EventProcess(event) ) // end of the movie? - { - type = m_movie->RetStopType(); - if ( type == MM_SATCOMopen ) - { - ChangePause(FALSE); - SelectObject(m_infoObject, FALSE); // hands over the command buttons - m_map->ShowMap(m_bMapShow); - m_displayText->HideText(FALSE); - i = m_movieInfoIndex; - StartDisplayInfo(m_movieInfoIndex, FALSE); - m_movieInfoIndex = i; - } - } - - m_dialog->EventProcess(event); - m_displayText->EventProcess(event); - RemoteCamera(m_cameraPan, m_cameraZoom, event.rTime); - - m_interface->EventProcess(event); - if ( m_displayInfo != 0 ) // current edition? - { - m_displayInfo->EventProcess(event); - } - return EventFrame(event); - } - - // Management of the console. -#if 0 - if ( m_phase != PHASE_NAME && - !m_movie->IsExist() && - event.event == EVENT_KEYDOWN && - event.param == VK_PAUSE && - (event.keyState&KS_CONTROL) != 0 ) -#else - if ( m_phase != PHASE_NAME && - !m_movie->IsExist() && - event.event == EVENT_KEYDOWN && - event.param == VK_CANCEL ) // Ctrl+Pause ? -#endif - { - pe = (CEdit*)m_interface->SearchControl(EVENT_CMD); - if ( pe == 0 ) return FALSE; - pe->SetState(STATE_VISIBLE); - pe->SetFocus(TRUE); - if ( m_phase == PHASE_SIMUL ) ChangePause(TRUE); - m_bCmdEdit = TRUE; - return FALSE; - } - if ( event.event == EVENT_KEYDOWN && - event.param == VK_RETURN && m_bCmdEdit ) - { - char cmd[50]; - pe = (CEdit*)m_interface->SearchControl(EVENT_CMD); - if ( pe == 0 ) return FALSE; - pe->GetText(cmd, 50); - pe->SetText(""); - pe->ClearState(STATE_VISIBLE); - if ( m_phase == PHASE_SIMUL ) ChangePause(FALSE); - ExecuteCmd(cmd); - m_bCmdEdit = FALSE; - return FALSE; - } - - // Management of the speed change. - if ( event.event == EVENT_SPEED ) - { - SetSpeed(1.0f); - } - - if ( !m_dialog->EventProcess(event) ) - { - if ( event.event == EVENT_MOUSEMOVE ) - { - m_lastMousePos = event.pos; - HiliteObject(event.pos); - } - return FALSE; - } - - if ( !m_displayText->EventProcess(event) ) - { - return FALSE; - } - - if ( event.event == EVENT_MOUSEMOVE ) - { - m_lastMousePos = event.pos; - HiliteObject(event.pos); - } - - if ( m_displayInfo != 0 ) // current info? - { - m_displayInfo->EventProcess(event); - - if ( event.event == EVENT_KEYDOWN ) - { - if ( event.param == m_engine->RetKey(KEYRANK_HELP, 0) || - event.param == m_engine->RetKey(KEYRANK_HELP, 1) || - event.param == m_engine->RetKey(KEYRANK_PROG, 0) || - event.param == m_engine->RetKey(KEYRANK_PROG, 1) || - event.param == VK_ESCAPE ) - { - StopDisplayInfo(); - } - } - if ( event.event == EVENT_OBJECT_INFOOK ) - { - StopDisplayInfo(); - } - return FALSE; - } - - // Simulation phase of the game - if ( m_phase == PHASE_SIMUL ) - { - UpdateInfoText(); - - if ( !m_bEditFull ) - { - m_camera->EventProcess(event); - } - - switch( event.event ) - { - case EVENT_KEYDOWN: - KeyCamera(event.event, event.param); - HiliteClear(); - if ( event.param == VK_F11 ) - { - m_particule->WriteWheelTrace("Savegame\\t.bmp", 256, 256, D3DVECTOR(16.0f, 0.0f, -368.0f), D3DVECTOR(140.0f, 0.0f, -248.0f)); - return FALSE; - } - if ( m_bEditLock ) // current edition? - { - if ( event.param == m_engine->RetKey(KEYRANK_HELP, 0) || - event.param == m_engine->RetKey(KEYRANK_HELP, 1) ) - { - StartDisplayInfo(SATCOM_HUSTON, FALSE); - return FALSE; - } - if ( event.param == m_engine->RetKey(KEYRANK_PROG, 0) || - event.param == m_engine->RetKey(KEYRANK_PROG, 1) ) - { - StartDisplayInfo(SATCOM_PROG, FALSE); - return FALSE; - } - break; - } - if ( m_bMovieLock ) // current movie? - { - if ( event.param == m_engine->RetKey(KEYRANK_QUIT, 0) || - event.param == m_engine->RetKey(KEYRANK_QUIT, 1) || - event.param == VK_ESCAPE ) - { - AbortMovie(); - } - return FALSE; - } - if ( m_camera->RetType() == CAMERA_VISIT ) - { - if ( event.param == m_engine->RetKey(KEYRANK_VISIT, 0) || - event.param == m_engine->RetKey(KEYRANK_VISIT, 1) ) - { - StartDisplayVisit(EVENT_NULL); - } - if ( event.param == m_engine->RetKey(KEYRANK_QUIT, 0) || - event.param == m_engine->RetKey(KEYRANK_QUIT, 1) || - event.param == VK_ESCAPE ) - { - StopDisplayVisit(); - } - return FALSE; - } - if ( event.param == m_engine->RetKey(KEYRANK_QUIT, 0) || - event.param == m_engine->RetKey(KEYRANK_QUIT, 1) ) - { - if ( m_movie->IsExist() ) - { - StartDisplayInfo(SATCOM_HUSTON, FALSE); - } - else if ( m_winDelay > 0.0f ) - { - ChangePhase(PHASE_WIN); - } - else if ( m_lostDelay > 0.0f ) - { - ChangePhase(PHASE_LOST); - } - else - { - m_dialog->StartAbort(); // do you want to leave? - } - } - if ( event.param == VK_PAUSE ) - { - if ( !m_bMovieLock && !m_bEditLock && !m_bCmdEdit && - m_camera->RetType() != CAMERA_VISIT && - !m_movie->IsExist() ) - { - ChangePause(!m_engine->RetPause()); - } - } - if ( event.param == m_engine->RetKey(KEYRANK_CAMERA, 0) || - event.param == m_engine->RetKey(KEYRANK_CAMERA, 1) ) - { - ChangeCamera(); - } - if ( event.param == m_engine->RetKey(KEYRANK_DESEL, 0) || - event.param == m_engine->RetKey(KEYRANK_DESEL, 1) ) - { - if ( m_bShortCut ) - { - DeselectObject(); - } - } - if ( event.param == m_engine->RetKey(KEYRANK_HUMAN, 0) || - event.param == m_engine->RetKey(KEYRANK_HUMAN, 1) ) - { - SelectHuman(); - } - if ( event.param == m_engine->RetKey(KEYRANK_NEXT, 0) || - event.param == m_engine->RetKey(KEYRANK_NEXT, 1) ) - { - if ( m_bShortCut ) - { - m_short->SelectNext(); - } - } - if ( event.param == m_engine->RetKey(KEYRANK_HELP, 0) || - event.param == m_engine->RetKey(KEYRANK_HELP, 1) ) - { - StartDisplayInfo(SATCOM_HUSTON, TRUE); - } - if ( event.param == m_engine->RetKey(KEYRANK_PROG, 0) || - event.param == m_engine->RetKey(KEYRANK_PROG, 1) ) - { - StartDisplayInfo(SATCOM_PROG, TRUE); - } - if ( event.param == m_engine->RetKey(KEYRANK_VISIT, 0) || - event.param == m_engine->RetKey(KEYRANK_VISIT, 1) ) - { - StartDisplayVisit(EVENT_NULL); - } - if ( event.param == m_engine->RetKey(KEYRANK_SPEED10, 0) || - event.param == m_engine->RetKey(KEYRANK_SPEED10, 1) ) - { - SetSpeed(1.0f); - } - if ( event.param == m_engine->RetKey(KEYRANK_SPEED15, 0) || - event.param == m_engine->RetKey(KEYRANK_SPEED15, 1) ) - { - SetSpeed(1.5f); - } - if ( event.param == m_engine->RetKey(KEYRANK_SPEED20, 0) || - event.param == m_engine->RetKey(KEYRANK_SPEED20, 1) ) - { - SetSpeed(2.0f); - } - if ( event.param == m_engine->RetKey(KEYRANK_SPEED30, 0) || - event.param == m_engine->RetKey(KEYRANK_SPEED30, 1) ) - { - SetSpeed(3.0f); - } - break; - - case EVENT_KEYUP: - KeyCamera(event.event, event.param); - break; - - case EVENT_LBUTTONDOWN: - pObj = DetectObject(event.pos); - if ( !m_bShortCut ) pObj = 0; - if ( pObj != 0 && pObj->RetType() == OBJECT_TOTO ) - { - if ( m_displayInfo != 0 ) // current info? - { - StopDisplayInfo(); - } - else - { - if ( !m_bEditLock ) - { - StartDisplayInfo(SATCOM_HUSTON, TRUE); - } - } - } - else - { - SelectObject(pObj); - } - break; - - case EVENT_LBUTTONUP: - m_cameraPan = 0.0f; - m_cameraZoom = 0.0f; - break; - - case EVENT_BUTTON_QUIT: - if ( m_movie->IsExist() ) - { - StartDisplayInfo(SATCOM_HUSTON, FALSE); - } - else if ( m_winDelay > 0.0f ) - { - ChangePhase(PHASE_WIN); - } - else if ( m_lostDelay > 0.0f ) - { - ChangePhase(PHASE_LOST); - } - else - { - m_dialog->StartAbort(); // do you want to leave? - } - break; - - case EVENT_OBJECT_LIMIT: - StartShowLimit(); - break; - - case EVENT_OBJECT_DESELECT: - if ( m_bShortCut ) - { - DeselectObject(); - } - break; - - case EVENT_OBJECT_HELP: - HelpObject(); - break; - - case EVENT_OBJECT_CAMERA: - ChangeCamera(); - break; - - case EVENT_OBJECT_CAMERAleft: - m_cameraPan = -1.0f; - break; - case EVENT_OBJECT_CAMERAright: - m_cameraPan = 1.0f; - break; - case EVENT_OBJECT_CAMERAnear: - m_cameraZoom = -1.0f; - break; - case EVENT_OBJECT_CAMERAaway: - m_cameraZoom = 1.0f; - break; - - case EVENT_OBJECT_DELETE: - m_dialog->StartDeleteObject(); // do you want to destroy it? - break; - - case EVENT_OBJECT_BHELP: - StartDisplayInfo(SATCOM_HUSTON, TRUE); - break; - - case EVENT_OBJECT_SOLUCE: - StartDisplayInfo(SATCOM_SOLUCE, TRUE); - break; - - case EVENT_OBJECT_MAPZOOM: - m_map->ZoomMap(); - break; - - case EVENT_DT_VISIT0: - case EVENT_DT_VISIT1: - case EVENT_DT_VISIT2: - case EVENT_DT_VISIT3: - case EVENT_DT_VISIT4: - StartDisplayVisit(event.event); - break; - - case EVENT_DT_END: - StopDisplayVisit(); - break; - - case EVENT_OBJECT_SHORTCUT00: - case EVENT_OBJECT_SHORTCUT01: - case EVENT_OBJECT_SHORTCUT02: - case EVENT_OBJECT_SHORTCUT03: - case EVENT_OBJECT_SHORTCUT04: - case EVENT_OBJECT_SHORTCUT05: - case EVENT_OBJECT_SHORTCUT06: - case EVENT_OBJECT_SHORTCUT07: - case EVENT_OBJECT_SHORTCUT08: - case EVENT_OBJECT_SHORTCUT09: - case EVENT_OBJECT_SHORTCUT10: - case EVENT_OBJECT_SHORTCUT11: - case EVENT_OBJECT_SHORTCUT12: - case EVENT_OBJECT_SHORTCUT13: - case EVENT_OBJECT_SHORTCUT14: - case EVENT_OBJECT_SHORTCUT15: - case EVENT_OBJECT_SHORTCUT16: - case EVENT_OBJECT_SHORTCUT17: - case EVENT_OBJECT_SHORTCUT18: - case EVENT_OBJECT_SHORTCUT19: - m_short->SelectShortcut(event.event); - break; - - case EVENT_OBJECT_MOVIELOCK: - AbortMovie(); - break; - - case EVENT_WIN: - ChangePhase(PHASE_WIN); - break; - - case EVENT_LOST: - ChangePhase(PHASE_LOST); - break; - } - - EventObject(event); - return FALSE; - } - - if ( m_phase == PHASE_PERSO ) - { - EventObject(event); - } - - if ( m_phase == PHASE_WIN || - m_phase == PHASE_LOST ) - { - EventObject(event); - - switch( event.event ) - { - case EVENT_KEYDOWN: - if ( event.param == VK_ESCAPE || - event.param == VK_RETURN ) - { - if ( m_bWinTerminate ) - { - ChangePhase(PHASE_INIT); - } - else - { - ChangePhase(PHASE_TERM); - } - } - break; - - case EVENT_BUTTON_OK: - if ( m_bWinTerminate ) - { - ChangePhase(PHASE_INIT); - } - else - { - ChangePhase(PHASE_TERM); - } - break; - } - } - - if ( m_phase == PHASE_MODEL ) - { - switch( event.event ) - { - case EVENT_KEYDOWN: - if ( event.param == VK_ESCAPE ) - { - ChangePhase(PHASE_INIT); - } - if ( event.param == VK_HOME ) - { - InitEye(); - } - break; - - case EVENT_BUTTON_CANCEL: - ChangePhase(PHASE_INIT); - break; - } - - m_model->EventProcess(event); - return FALSE; - } - - return TRUE; -} - - - -// Executes a command. - -void CRobotMain::ExecuteCmd(char *cmd) -{ - if ( cmd[0] == 0 ) return; - - if ( m_phase == PHASE_SIMUL ) - { - if ( strcmp(cmd, "winmission") == 0 ) - { - Event newEvent; - m_event->MakeEvent(newEvent, EVENT_WIN); - m_event->AddEvent(newEvent); - } - - if ( strcmp(cmd, "lostmission") == 0 ) - { - Event newEvent; - m_event->MakeEvent(newEvent, EVENT_LOST); - m_event->AddEvent(newEvent); - } - - if ( strcmp(cmd, "trainerpilot") == 0 ) - { - m_bTrainerPilot = !m_bTrainerPilot; - return; - } - - if ( strcmp(cmd, "fly") == 0 ) - { - Event newEvent; - - g_researchDone |= RESEARCH_FLY; - - m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); - m_event->AddEvent(newEvent); - return; - } - - if ( strcmp(cmd, "allresearch") == 0 ) - { - Event newEvent; - - g_researchDone = -1; // all research are done - - m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); - m_event->AddEvent(newEvent); - return; - } - - if ( strcmp(cmd, "nolimit") == 0 ) - { - m_terrain->SetFlyingMaxHeight(280.0f); - return; - } - - if ( strcmp(cmd, "photo1") == 0 ) - { - m_bFreePhoto = !m_bFreePhoto; - if ( m_bFreePhoto ) - { - m_camera->SetType(CAMERA_FREE); - ChangePause(TRUE); - } - else - { - m_camera->SetType(CAMERA_BACK); - ChangePause(FALSE); - } - return; - } - - if ( strcmp(cmd, "photo2") == 0 ) - { - m_bFreePhoto = !m_bFreePhoto; - if ( m_bFreePhoto ) - { - m_camera->SetType(CAMERA_FREE); - ChangePause(TRUE); - DeselectAll(); // removes the control buttons - m_map->ShowMap(FALSE); - m_displayText->HideText(TRUE); - } - else - { - m_camera->SetType(CAMERA_BACK); - ChangePause(FALSE); - m_map->ShowMap(m_bMapShow); - m_displayText->HideText(FALSE); - } - return; - } - - if ( strcmp(cmd, "noclip") == 0 ) - { - CObject* object; - - object = RetSelect(); - if ( object != 0 ) - { - object->SetClip(FALSE); - } - return; - } - - if ( strcmp(cmd, "clip") == 0 ) - { - CObject* object; - - object = RetSelect(); - if ( object != 0 ) - { - object->SetClip(TRUE); - } - return; - } - - if ( strcmp(cmd, "addhusky") == 0 ) - { - CObject* object; - - object = RetSelect(); - if ( object != 0 ) - { - object->SetMagnifyDamage(object->RetMagnifyDamage()*0.1f); - } - return; - } - - if ( strcmp(cmd, "addfreezer") == 0 ) - { - CObject* object; - - object = RetSelect(); - if ( object != 0 ) - { - object->SetRange(object->RetRange()*10.0f); - } - return; - } - - if ( strcmp(cmd, "fullpower") == 0 ) - { - CObject* object; - CObject* power; - CPhysics* physics; - - object = RetSelect(); - if ( object != 0 ) - { - power = object->RetPower(); - if ( power != 0 ) - { - power->SetEnergy(1.0f); - } - object->SetShield(1.0f); - physics = object->RetPhysics(); - if ( physics != 0 ) - { - physics->SetReactorRange(1.0f); - } - } - return; - } - - if ( strcmp(cmd, "fullenergy") == 0 ) - { - CObject* object; - CObject* power; - - object = RetSelect(); - if ( object != 0 ) - { - power = object->RetPower(); - if ( power != 0 ) - { - power->SetEnergy(1.0f); - } - } - return; - } - - if ( strcmp(cmd, "fullshield") == 0 ) - { - CObject* object; - - object = RetSelect(); - if ( object != 0 ) - { - object->SetShield(1.0f); - } - return; - } - - if ( strcmp(cmd, "fullrange") == 0 ) - { - CObject* object; - CPhysics* physics; - - object = RetSelect(); - if ( object != 0 ) - { - physics = object->RetPhysics(); - if ( physics != 0 ) - { - physics->SetReactorRange(1.0f); - } - } - return; - } - } - - if ( strcmp(cmd, "debugmode") == 0 ) - { - m_engine->SetDebugMode(!m_engine->RetDebugMode()); - return; - } - - if ( strcmp(cmd, "showstat") == 0 ) - { - m_engine->SetShowStat(!m_engine->RetShowStat()); - return; - } - - if ( strcmp(cmd, "invshadow") == 0 ) - { - m_engine->SetShadow(!m_engine->RetShadow()); - return; - } - - if ( strcmp(cmd, "invdirty") == 0 ) - { - m_engine->SetDirty(!m_engine->RetDirty()); - return; - } - - if ( strcmp(cmd, "invfog") == 0 ) - { - m_engine->SetFog(!m_engine->RetFog()); - return; - } - - if ( strcmp(cmd, "invlens") == 0 ) - { - m_engine->SetLensMode(!m_engine->RetLensMode()); - return; - } - - if ( strcmp(cmd, "invwater") == 0 ) - { - m_engine->SetWaterMode(!m_engine->RetWaterMode()); - return; - } - - if ( strcmp(cmd, "invsky") == 0 ) - { - m_engine->SetSkyMode(!m_engine->RetSkyMode()); - return; - } - - if ( strcmp(cmd, "invplanet") == 0 ) - { - m_engine->SetPlanetMode(!m_engine->RetPlanetMode()); - return; - } - - if ( strcmp(cmd, "showpos") == 0 ) - { - m_bShowPos = !m_bShowPos; - return; - } - - if ( strcmp(cmd, "selectinsect") == 0 ) - { - m_bSelectInsect = !m_bSelectInsect; - return; - } - - if ( strcmp(cmd, "showsoluce") == 0 ) - { - m_bShowSoluce = !m_bShowSoluce; - m_dialog->ShowSoluceUpdate(); - return; - } - -#if _TEEN - if ( strcmp(cmd, "allteens") == 0 ) -#else - if ( strcmp(cmd, "allmission") == 0 ) -#endif - { - m_bShowAll = !m_bShowAll; - m_dialog->AllMissionUpdate(); - return; - } - - if ( strcmp(cmd, "invradar") == 0 ) - { - m_bCheatRadar = !m_bCheatRadar; - return; - } - - if ( m_phase == PHASE_SIMUL ) - { - m_displayText->DisplayError(ERR_CMD, D3DVECTOR(0.0f,0.0f,0.0f)); - } -} - - - -// Returns the type of current movie. - -MainMovieType CRobotMain::RetMainMovie() -{ - return m_movie->RetType(); -} - - -// Clears the display of instructions. - -void CRobotMain::FlushDisplayInfo() -{ - int i; - - for ( i=0 ; iRetType() == OBJECT_HUMAN ); - - if ( !m_bEditLock && bMovie && !m_movie->IsExist() && bHuman ) - { - motion = pObj->RetMotion(); - if ( motion != 0 && motion->RetAction() == -1 ) - { - m_movieInfoIndex = index; - m_movie->Start(MM_SATCOMopen, 2.5f); - ChangePause(TRUE); -//? m_map->ShowMap(FALSE); - m_infoObject = DeselectAll(); // removes the control buttons - m_displayText->HideText(TRUE); - return; - } - } - - if ( m_movie->IsExist() ) - { - m_movie->Stop(); - ChangePause(FALSE); - SelectObject(m_infoObject, FALSE); // hands over the command buttons -//? m_map->ShowMap(m_bMapShow); - m_displayText->HideText(FALSE); - } - - StartDisplayInfo(m_infoFilename[index], index); -} - -// Beginning of the displaying of instructions. - -void CRobotMain::StartDisplayInfo(char *filename, int index) -{ - CButton* pb; - BOOL bSoluce; - - if ( m_bCmdEdit ) return; - - m_movieInfoIndex = -1; - ClearInterface(); // removes setting evidence and tooltip - - if ( !m_bEditLock ) - { -//? m_map->ShowMap(FALSE); - m_infoObject = DeselectAll(); // removes the control buttons - m_displayText->HideText(TRUE); - m_sound->MuteAll(TRUE); - } - - pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); - if ( pb != 0 ) - { - pb->ClearState(STATE_VISIBLE); - } - - bSoluce = m_dialog->RetSceneSoluce(); - - m_displayInfo = new CDisplayInfo(m_iMan); - m_displayInfo->StartDisplayInfo(filename, index, bSoluce); - - m_infoIndex = index; - if ( index != -1 ) - { - m_displayInfo->SetPosition(m_infoPos[index]); - } -} - -// End of displaying of instructions. - -void CRobotMain::StopDisplayInfo() -{ - CButton* pb; - - if ( m_movieInfoIndex != -1 ) // film to read the SatCom? - { - m_movie->Start(MM_SATCOMclose, 2.0f); - } - - if ( m_infoIndex != -1 ) - { - m_infoPos[m_infoIndex] = m_displayInfo->RetPosition(); - } - m_displayInfo->StopDisplayInfo(); - - delete m_displayInfo; - m_displayInfo = 0; - - if ( !m_bEditLock ) - { - pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); - if ( pb != 0 ) - { - pb->SetState(STATE_VISIBLE); - } - - SelectObject(m_infoObject, FALSE); // gives the command buttons -//? m_map->ShowMap(m_bMapShow); - m_displayText->HideText(FALSE); - - m_sound->MuteAll(FALSE); - } - - if ( m_infoUsed == 0 ) - { - m_displayText->ClearText(); // removes message "see SatCom ..." - } - m_infoUsed ++; -} - -// Returns the name of the text display. - -char* CRobotMain::RetDisplayInfoName(int index) -{ - return m_infoFilename[index]; -} - -// Returns the name of the text display. - -int CRobotMain::RetDisplayInfoPosition(int index) -{ - return m_infoPos[index]; -} - -// Returns the name of the text display. - -void CRobotMain::SetDisplayInfoPosition(int index, int pos) -{ - m_infoPos[index] = pos; -} - - -// Beginning of a dialogue during the game, - -void CRobotMain::StartSuspend() -{ - CButton* pb; - - m_map->ShowMap(FALSE); - m_infoObject = DeselectAll(); // removes the control buttons - m_displayText->HideText(TRUE); - - pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); - if ( pb != 0 ) - { - pb->ClearState(STATE_VISIBLE); - } - - m_bSuspend = TRUE; -} - -// End of dialogue during the game, - -void CRobotMain::StopSuspend() -{ - CButton* pb; - - pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); - if ( pb != 0 ) - { - pb->SetState(STATE_VISIBLE); - } - - SelectObject(m_infoObject, FALSE); // gives the command buttons - m_map->ShowMap(m_bMapShow); - m_displayText->HideText(FALSE); - - m_bSuspend = FALSE; -} - - -// Returns the absolute time of the game - -float CRobotMain::RetGameTime() -{ - return m_gameTime; -} - - - -// Managing the size of the default fonts. - -void CRobotMain::SetFontSize(float size) -{ - m_fontSize = size; - SetProfileFloat("Edit", "FontSize", m_fontSize); -} - -float CRobotMain::RetFontSize() -{ - return m_fontSize; -} - -// Managing the size of the default window. - -void CRobotMain::SetWindowPos(FPOINT pos) -{ - m_windowPos = pos; - SetProfileFloat("Edit", "WindowPos.x", m_windowPos.x); - SetProfileFloat("Edit", "WindowPos.y", m_windowPos.y); -} - -FPOINT CRobotMain::RetWindowPos() -{ - return m_windowPos; -} - -void CRobotMain::SetWindowDim(FPOINT dim) -{ - m_windowDim = dim; - SetProfileFloat("Edit", "WindowDim.x", m_windowDim.x); - SetProfileFloat("Edit", "WindowDim.y", m_windowDim.y); -} - -FPOINT CRobotMain::RetWindowDim() -{ - return m_windowDim; -} - - -// Managing windows open/save. - -void CRobotMain::SetIOPublic(BOOL bMode) -{ - m_IOPublic = bMode; - SetProfileInt("Edit", "IOPublic", m_IOPublic); -} - -BOOL CRobotMain::RetIOPublic() -{ - return m_IOPublic; -} - -void CRobotMain::SetIOPos(FPOINT pos) -{ - m_IOPos = pos; - SetProfileFloat("Edit", "IOPos.x", m_IOPos.x); - SetProfileFloat("Edit", "IOPos.y", m_IOPos.y); -} - -FPOINT CRobotMain::RetIOPos() -{ - return m_IOPos; -} - -void CRobotMain::SetIODim(FPOINT dim) -{ - m_IODim = dim; - SetProfileFloat("Edit", "IODim.x", m_IODim.x); - SetProfileFloat("Edit", "IODim.y", m_IODim.y); -} - -FPOINT CRobotMain::RetIODim() -{ - return m_IODim; -} - - - -// Start of the visit instead of an error. - -void CRobotMain::StartDisplayVisit(EventMsg event) -{ - CWindow* pw; - CButton* button; - CGroup* group; - D3DVECTOR goal; - FPOINT pos, dim; - int i, j; - - if ( m_bEditLock ) return; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); - if ( pw == 0 ) return; - - if ( event == EVENT_NULL ) // visit by keyboard shortcut? - { - if ( m_visitLast != EVENT_NULL ) // already a current visit? - { - i = m_visitLast-EVENT_DT_VISIT0; - } - else - { - i = MAXDTLINE; - } - - // Seeks the last. - for ( j=0 ; jSearchControl(EventMsg(EVENT_DT_VISIT0+i)); - if ( button == 0 || !button->TestState(STATE_ENABLE) ) continue; - - group = (CGroup*)pw->SearchControl(EventMsg(EVENT_DT_GROUP0+i)); - if ( group != 0 ) - { - event = EventMsg(EVENT_DT_VISIT0+i); - break; - } - } - } - if ( event == EVENT_NULL ) - { - m_sound->Play(SOUND_TZOING); // nothing to do! - return; - } - - m_visitLast = event; - - ClearInterface(); // removes setting evidence and tooltip - - if ( m_camera->RetType() == CAMERA_VISIT ) // already a current visit? - { - m_camera->StopVisit(); - m_displayText->ClearVisit(); - } - else - { - m_visitObject = DeselectAll(); // removes the control buttons - } - - // Creates the "continue" button. - if ( m_interface->SearchControl(EVENT_DT_END) == 0 ) - { - pos.x = 10.0f/640.0f; - pos.y = 10.0f/480.0f; - dim.x = 50.0f/640.0f; - dim.y = 50.0f/480.0f; - m_interface->CreateButton(pos, dim, 16, EVENT_DT_END); - } - - // Creates the arrow to show the place. - if ( m_visitArrow != 0 ) - { - m_visitArrow->DeleteObject(); - delete m_visitArrow; - m_visitArrow = 0; - } - goal = m_displayText->RetVisitGoal(event); - m_visitArrow = CreateObject(goal, 0.0f, 1.0f, 10.0f, OBJECT_SHOW, FALSE, FALSE, 0); - - m_visitPos = m_visitArrow->RetPosition(0); - m_visitPosArrow = m_visitPos; - m_visitPosArrow.y += m_displayText->RetVisitHeight(event); - m_visitArrow->SetPosition(0, m_visitPosArrow); - - m_visitTime = 0.0; - m_visitParticule = 0.0f; - - m_particule->DeleteParticule(PARTISHOW); - - m_camera->StartVisit(m_displayText->RetVisitGoal(event), - m_displayText->RetVisitDist(event)); - m_displayText->SetVisit(event); - ChangePause(TRUE); -} - -// Move the arrow to visit. - -void CRobotMain::FrameVisit(float rTime) -{ - D3DVECTOR pos, speed; - FPOINT dim; - float level; - - if ( m_visitArrow == 0 ) return; - - // Moves the arrow. - m_visitTime += rTime; - - pos = m_visitPosArrow; - pos.y += 1.5f+sinf(m_visitTime*4.0f)*4.0f; - m_visitArrow->SetPosition(0, pos); - m_visitArrow->SetAngleY(0, m_visitTime*2.0f); - - // Manages the particles "arrows". - m_visitParticule -= rTime; - if ( m_visitParticule <= 0.0f ) - { - m_visitParticule = 1.5f; - - pos = m_visitPos; - level = m_terrain->RetFloorLevel(pos)+2.0f; - if ( pos.y < level ) pos.y = level; // not below the ground - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 30.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISHOW, 2.0f); - } -} - -// End of the visit instead of an error. - -void CRobotMain::StopDisplayVisit() -{ - m_visitLast = EVENT_NULL; - - // Removes the button. - m_interface->DeleteControl(EVENT_DT_END); - - // Removes the arrow. - if ( m_visitArrow != 0 ) - { - m_visitArrow->DeleteObject(); - delete m_visitArrow; - m_visitArrow = 0; - } - - // Removes particles "arrows". - m_particule->DeleteParticule(PARTISHOW); - - m_camera->StopVisit(); - m_displayText->ClearVisit(); - ChangePause(FALSE); - if ( m_visitObject != 0 ) - { - SelectObject(m_visitObject, FALSE); // gives the command buttons - m_visitObject = 0; - } -} - - - -// Updates all the shortcuts. - -void CRobotMain::UpdateShortcuts() -{ - m_short->UpdateShortcuts(); -} - -// Returns the object that default was select after the creation of a scene. - -CObject* CRobotMain::RetSelectObject() -{ - if ( m_selectObject != 0 ) return m_selectObject; - return SearchHuman(); -} - -// Deselects everything, and returns the object that was selected. - -CObject* CRobotMain::DeselectAll() -{ - CObject* pObj; - CObject* pPrev; - int i; - - pPrev = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj->RetSelect() ) pPrev = pObj; - pObj->SetSelect(FALSE); - } - return pPrev; -} - -// Selects an object, without attending to deselect the rest. - -void CRobotMain::SelectOneObject(CObject* pObj, BOOL bDisplayError) -{ - ObjectType type; - CObject* toto; - CMotionToto* mt; - - pObj->SetSelect(TRUE, bDisplayError); - m_camera->SetObject(pObj); - - type = pObj->RetType(); - if ( type == OBJECT_HUMAN || - type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs || - type == OBJECT_MOBILEsa || - type == OBJECT_MOBILEft || - type == OBJECT_MOBILEtt || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEit || - type == OBJECT_MOBILEdr || - type == OBJECT_APOLLO2 ) - { - m_camera->SetType(pObj->RetCameraType()); - m_camera->SetDist(pObj->RetCameraDist()); - } - else - { - m_camera->SetType(CAMERA_BACK); - } - - toto = SearchToto(); - if ( toto != 0 ) - { - mt = (CMotionToto*)toto->RetMotion(); - if ( mt != 0 ) - { - mt->SetLinkType(type); - } - } -} - -// Selects the object aimed by the mouse. - -BOOL CRobotMain::SelectObject(CObject* pObj, BOOL bDisplayError) -{ - CObject* pPrev; - - if ( m_camera->RetType() == CAMERA_VISIT ) - { - StopDisplayVisit(); - } - - if ( m_bMovieLock || m_bEditLock || m_bPause ) return FALSE; - if ( m_movie->IsExist() ) return FALSE; - if ( pObj == 0 || !IsSelectable(pObj) ) return FALSE; - - pPrev = DeselectAll(); - - if ( pPrev != 0 && pPrev != pObj ) - { - pObj->AddDeselList(pPrev); - } - - SelectOneObject(pObj, bDisplayError); - m_short->UpdateShortcuts(); - return TRUE; -} - -// Deselects the selected object. - -BOOL CRobotMain::DeselectObject() -{ - CObject* pObj; - CObject* pPrev; - - pPrev = DeselectAll(); - - if ( pPrev == 0 ) - { - pObj = SearchHuman(); - } - else - { - pObj = pPrev->SubDeselList(); - } - if ( pObj == 0 ) - { - pObj = SearchHuman(); - } - - if ( pObj != 0 ) - { - SelectOneObject(pObj); - } - else - { - m_camera->SetType(CAMERA_FREE); - } - - m_short->UpdateShortcuts(); - return TRUE; -} - -// Quickly removes all objects. - -void CRobotMain::DeleteAllObjects() -{ - CPyro* pyro; - CObject* pObj; - int i; - - // Removes all pyrotechnic effects in progress. - while ( TRUE ) - { - pyro = (CPyro*)m_iMan->SearchInstance(CLASS_PYRO, 0); - if ( pyro == 0 ) break; - - pyro->DeleteObject(); - delete pyro; - } - - // Removes the arrow. - if ( m_visitArrow != 0 ) - { - m_visitArrow->DeleteObject(); - delete m_visitArrow; - m_visitArrow = 0; - } - - for ( i=0 ; iSearchInstance(CLASS_OBJECT, 0); - if ( pObj == 0 ) break; - - pObj->DeleteObject(TRUE); // destroys rapidly - delete pObj; - } -} - -// Selects the human. - -void CRobotMain::SelectHuman() -{ - SelectObject(SearchHuman()); -} - -// Returns the object human. - -CObject* CRobotMain::SearchHuman() -{ - ObjectType type; - CObject* pObj; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type == OBJECT_HUMAN ) - { - return pObj; - } - } - return 0; -} - -// Returns the object toto. - -CObject* CRobotMain::SearchToto() -{ - ObjectType type; - CObject* pObj; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type == OBJECT_TOTO ) - { - return pObj; - } - } - return 0; -} - -// Returns the nearest selectable object from a given position. - -CObject* CRobotMain::SearchNearest(D3DVECTOR pos, CObject* pExclu) -{ - ObjectType type; - CObject *pObj, *pBest; - D3DVECTOR oPos; - float min, dist; - int i; - - min = 100000.0f; - pBest = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj == pExclu ) continue; - if ( !IsSelectable(pObj) ) continue; - - type = pObj->RetType(); - if ( type == OBJECT_TOTO ) continue; - - oPos = pObj->RetPosition(0); - dist = Length2d(oPos, pos); - if ( dist < min ) - { - min = dist; - pBest = pObj; - } - } - return pBest; -} - -// Returns the selected object. - -CObject* CRobotMain::RetSelect() -{ - CObject* pObj; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj->RetSelect() ) - { - return pObj; - } - } - return 0; -} - -CObject* CRobotMain::SearchObject(ObjectType type) -{ - CObject* pObj; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj->RetType() == type ) - { - return pObj; - } - } - return 0; -} - -// Detects the object aimed by the mouse. - -CObject* CRobotMain::DetectObject(FPOINT pos) -{ - ObjectType type; - CObject *pObj, *pTarget; - int objRank, i, j, rank; - - objRank = m_engine->DetectObject(pos); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetActif() ) continue; - if ( pObj->RetProxyActivate() ) continue; - - pTarget = 0; - type = pObj->RetType(); - if ( type == OBJECT_PORTICO || - type == OBJECT_BASE || - type == OBJECT_DERRICK || - type == OBJECT_FACTORY || - type == OBJECT_REPAIR || - type == OBJECT_DESTROYER || - type == OBJECT_STATION || - type == OBJECT_CONVERT || - type == OBJECT_TOWER || - type == OBJECT_RESEARCH || - type == OBJECT_RADAR || - type == OBJECT_INFO || - type == OBJECT_ENERGY || - type == OBJECT_LABO || - type == OBJECT_NUCLEAR || - type == OBJECT_PARA || - type == OBJECT_SAFE || - type == OBJECT_HUSTON || - type == OBJECT_TARGET1 || - type == OBJECT_TARGET2 || - type == OBJECT_START || - type == OBJECT_END || - type == OBJECT_STONE || - type == OBJECT_URANIUM || - type == OBJECT_BULLET || - type == OBJECT_METAL || - type == OBJECT_BBOX || - type == OBJECT_KEYa || - type == OBJECT_KEYb || - type == OBJECT_KEYc || - type == OBJECT_KEYd || - type == OBJECT_TNT || - type == OBJECT_SCRAP1 || - type == OBJECT_SCRAP2 || - type == OBJECT_SCRAP3 || - type == OBJECT_SCRAP4 || - type == OBJECT_SCRAP5 || - type == OBJECT_BOMB || - type == OBJECT_BAG || - type == OBJECT_WAYPOINT || - type == OBJECT_FLAGb || - type == OBJECT_FLAGr || - type == OBJECT_FLAGg || - type == OBJECT_FLAGy || - type == OBJECT_FLAGv || - type == OBJECT_MARKPOWER || - type == OBJECT_MARKSTONE || - type == OBJECT_MARKURANIUM || - type == OBJECT_MARKKEYa || - type == OBJECT_MARKKEYb || - type == OBJECT_MARKKEYc || - type == OBJECT_MARKKEYd || - type == OBJECT_HUMAN || - type == OBJECT_TECH || - type == OBJECT_TOTO || - type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs || - type == OBJECT_MOBILEsa || - type == OBJECT_MOBILEtg || - type == OBJECT_MOBILEft || - type == OBJECT_MOBILEtt || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEit || - type == OBJECT_MOBILEdr || - type == OBJECT_MOTHER || - type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_BEE || - type == OBJECT_WORM || - type == OBJECT_EGG || - type == OBJECT_RUINmobilew1 || - type == OBJECT_RUINmobilew2 || - type == OBJECT_RUINmobilet1 || - type == OBJECT_RUINmobilet2 || - type == OBJECT_RUINmobiler1 || - type == OBJECT_RUINmobiler2 || - type == OBJECT_RUINfactory || - type == OBJECT_RUINdoor || - type == OBJECT_RUINsupport || - type == OBJECT_RUINradar || - type == OBJECT_RUINconvert || - type == OBJECT_RUINbase || - type == OBJECT_RUINhead || - type == OBJECT_APOLLO1 || - type == OBJECT_APOLLO2 || - type == OBJECT_APOLLO3 || - type == OBJECT_APOLLO4 || - type == OBJECT_APOLLO5 ) - { - pTarget = pObj; - } - else if ( (type == OBJECT_POWER || - type == OBJECT_ATOMIC ) && - pObj->RetTruck() != 0 ) // battery used? - { - pTarget = pObj->RetTruck(); - } - else if ( type == OBJECT_POWER || - type == OBJECT_ATOMIC ) - { - pTarget = pObj; - } - - for ( j=0 ; jRetObjectRank(j); - if ( rank == -1 ) continue; - if ( rank != objRank ) continue; - return pTarget; - } - } - return 0; -} - -// Indicates whether an object is selectable. - -BOOL CRobotMain::IsSelectable(CObject* pObj) -{ - ObjectType type; - - if ( !pObj->RetSelectable() ) return FALSE; - - type = pObj->RetType(); - if ( type == OBJECT_HUMAN || - type == OBJECT_TOTO || - type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs || - type == OBJECT_MOBILEsa || - type == OBJECT_MOBILEft || - type == OBJECT_MOBILEtt || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEit || - type == OBJECT_MOBILEdr || - type == OBJECT_APOLLO2 || - type == OBJECT_BASE || - type == OBJECT_DERRICK || - type == OBJECT_FACTORY || - type == OBJECT_REPAIR || - type == OBJECT_DESTROYER|| - type == OBJECT_STATION || - type == OBJECT_CONVERT || - type == OBJECT_TOWER || - type == OBJECT_RESEARCH || - type == OBJECT_RADAR || - type == OBJECT_INFO || - type == OBJECT_ENERGY || - type == OBJECT_LABO || - type == OBJECT_NUCLEAR || - type == OBJECT_PARA || - type == OBJECT_SAFE || - type == OBJECT_HUSTON ) - { - return TRUE; - } - - if ( m_bSelectInsect ) - { - if ( type == OBJECT_MOTHER || - type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_BEE || - type == OBJECT_WORM || - type == OBJECT_MOBILEtg ) - { - return TRUE; - } - } - - return FALSE; -} - - -// Deletes the selected object. - -BOOL CRobotMain::DeleteObject() -{ - CObject* pObj; - CPyro* pyro; - - pObj = RetSelect(); - if ( pObj == 0 ) return FALSE; - - pyro = new CPyro(m_iMan); - pyro->Create(PT_FRAGT, pObj); - - pObj->SetSelect(FALSE); // deselects the object - m_camera->SetType(CAMERA_EXPLO); - DeselectAll(); - pObj->DeleteDeselList(pObj); - - return TRUE; -} - - -// Removes setting evidence of the object with the mouse hovers over. - -void CRobotMain::HiliteClear() -{ - CObject* pObj; - int i; - - ClearTooltip(); - m_tooltipName[0] = 0; // really removes the tooltip - - if ( !m_bHilite ) return; - - i = -1; - m_engine->SetHiliteRank(&i); // nothing more selected - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - pObj->SetHilite(FALSE); - m_map->SetHilite(0); - m_short->SetHilite(0); - } - - m_bHilite = FALSE; -} - -// Highlights the object with the mouse hovers over. - -void CRobotMain::HiliteObject(FPOINT pos) -{ - CObject* pObj; - char name[100]; - BOOL bInMap; - - if ( m_bFixScene && m_phase != PHASE_PERSO ) return; - if ( m_bMovieLock ) return; - if ( m_movie->IsExist() ) return; - if ( m_engine->RetMouseHide() ) return; - - ClearInterface(); // removes setting evidence and tooltip - - pObj = m_short->DetectShort(pos); - - if ( m_dialog->RetTooltip() && m_interface->GetTooltip(pos, name) ) - { - m_tooltipPos = pos; - strcpy(m_tooltipName, name); - m_tooltipTime = 0.0f; - if ( pObj == 0 ) return; - } - - if ( m_bSuspend ) return; - - if ( pObj == 0 ) - { - pObj = m_map->DetectMap(pos, bInMap); - if ( pObj == 0 ) - { - if ( bInMap ) return; - - pObj = DetectObject(pos); - - if ( m_camera->RetType() == CAMERA_ONBOARD && - m_camera->RetObject() == pObj ) - { - return; - } - } - } - - if ( pObj != 0 ) - { - if ( m_dialog->RetTooltip() && pObj->GetTooltipName(name) ) - { - m_tooltipPos = pos; - strcpy(m_tooltipName, name); - m_tooltipTime = 0.0f; - } - - if ( IsSelectable(pObj) ) - { - pObj->SetHilite(TRUE); - m_map->SetHilite(pObj); - m_short->SetHilite(pObj); - m_bHilite = TRUE; - } - } -} - -// Highlights the object with the mouse hovers over. - -void CRobotMain::HiliteFrame(float rTime) -{ - if ( m_bFixScene && m_phase != PHASE_PERSO ) return; - if ( m_bMovieLock ) return; - if ( m_movie->IsExist() ) return; - - m_tooltipTime += rTime; - - ClearTooltip(); - - if ( m_tooltipTime >= 0.2f && - m_tooltipName[0] != 0 ) - { - CreateTooltip(m_tooltipPos, m_tooltipName); - } -} - -// Creates a tooltip. - -void CRobotMain::CreateTooltip(FPOINT pos, char* text) -{ - CWindow* pw; - FPOINT start, end, dim, offset, corner; - - corner.x = pos.x+0.022f; - corner.y = pos.y-0.052f; - - m_engine->RetText()->DimText(text, corner, 1, - SMALLFONT, NORMSTRETCH, FONT_COLOBOT, - start, end); - start.x -= 0.010f; - start.y -= 0.002f; - end.x += 0.010f; - end.y += 0.004f; // ch'tite (?) margin - - pos.x = start.x; - pos.y = start.y; - dim.x = end.x-start.x; - dim.y = end.y-start.y; - - offset.x = 0.0f; - offset.y = 0.0f; - if ( pos.x+dim.x > 1.0f ) offset.x = 1.0f-(pos.x+dim.x); - if ( pos.y < 0.0f ) offset.y = -pos.y; - - corner.x += offset.x; - corner.y += offset.y; - pos.x += offset.x; - pos.y += offset.y; - - m_interface->CreateWindows(pos, dim, 1, EVENT_TOOLTIP); - - pw = (CWindow*)m_interface->SearchControl(EVENT_TOOLTIP); - if ( pw != 0 ) - { - pw->SetState(STATE_SHADOW); - pw->SetTrashEvent(FALSE); - - pos.y -= m_engine->RetText()->RetHeight(SMALLFONT, FONT_COLOBOT)/2.0f; - pw->CreateLabel(pos, dim, -1, EVENT_LABEL2, text); - } -} - -// Clears the previous tooltip. - -void CRobotMain::ClearTooltip() -{ - m_interface->DeleteControl(EVENT_TOOLTIP); -} - - -// Displays help for an object. - -void CRobotMain::HelpObject() -{ - CObject* pObj; - char* filename; - - pObj = RetSelect(); - if ( pObj == 0 ) return; - - filename = RetHelpFilename(pObj->RetType()); - if ( filename[0] == 0 ) return; - - StartDisplayInfo(filename, -1); -} - - -// Change the mode of the camera. - -void CRobotMain::ChangeCamera() -{ - CObject* pObj; - ObjectType oType; - CameraType type; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj->RetSelect() ) - { - if ( pObj->RetCameraLock() ) return; - - oType = pObj->RetType(); - type = pObj->RetCameraType(); - - if ( oType != OBJECT_MOBILEfa && - oType != OBJECT_MOBILEta && - oType != OBJECT_MOBILEwa && - oType != OBJECT_MOBILEia && - oType != OBJECT_MOBILEfc && - oType != OBJECT_MOBILEtc && - oType != OBJECT_MOBILEwc && - oType != OBJECT_MOBILEic && - oType != OBJECT_MOBILEfi && - oType != OBJECT_MOBILEti && - oType != OBJECT_MOBILEwi && - oType != OBJECT_MOBILEii && - oType != OBJECT_MOBILEfs && - oType != OBJECT_MOBILEts && - oType != OBJECT_MOBILEws && - oType != OBJECT_MOBILEis && - oType != OBJECT_MOBILErt && - oType != OBJECT_MOBILErc && - oType != OBJECT_MOBILErr && - oType != OBJECT_MOBILErs && - oType != OBJECT_MOBILEsa && - oType != OBJECT_MOBILEtg && - oType != OBJECT_MOBILEft && - oType != OBJECT_MOBILEtt && - oType != OBJECT_MOBILEwt && - oType != OBJECT_MOBILEit && - oType != OBJECT_MOBILEdr && - oType != OBJECT_APOLLO2 ) return; - - if ( oType == OBJECT_MOBILEdr ) // designer? - { - if ( type == CAMERA_PLANE ) type = CAMERA_BACK; - else if ( type == CAMERA_BACK ) type = CAMERA_PLANE; - } - else if ( pObj->RetTrainer() ) // trainer? - { - if ( type == CAMERA_ONBOARD ) type = CAMERA_FIX; - else if ( type == CAMERA_FIX ) type = CAMERA_PLANE; - else if ( type == CAMERA_PLANE ) type = CAMERA_BACK; - else if ( type == CAMERA_BACK ) type = CAMERA_ONBOARD; - } - else - { - if ( type == CAMERA_ONBOARD ) type = CAMERA_BACK; - else if ( type == CAMERA_BACK ) type = CAMERA_ONBOARD; - } - - pObj->SetCameraType(type); - m_camera->SetType(type); - } - } -} - -// Remote control the camera using the arrow keys. - -void CRobotMain::KeyCamera(EventMsg event, long param) -{ - CObject* pObj; - - if ( event == EVENT_KEYUP ) - { - if ( param == m_engine->RetKey(KEYRANK_LEFT, 0) || - param == m_engine->RetKey(KEYRANK_LEFT, 1) ) - { - m_cameraPan = 0.0f; - } - - if ( param == m_engine->RetKey(KEYRANK_RIGHT, 0) || - param == m_engine->RetKey(KEYRANK_RIGHT, 1) ) - { - m_cameraPan = 0.0f; - } - - if ( param == m_engine->RetKey(KEYRANK_UP, 0) || - param == m_engine->RetKey(KEYRANK_UP, 1) ) - { - m_cameraZoom = 0.0f; - } - - if ( param == m_engine->RetKey(KEYRANK_DOWN, 0) || - param == m_engine->RetKey(KEYRANK_DOWN, 1) ) - { - m_cameraZoom = 0.0f; - } - } - - if ( m_phase != PHASE_SIMUL ) return; - if ( m_bEditLock ) return; // current edition? - if ( m_bTrainerPilot ) return; - - pObj = RetSelect(); - if ( pObj == 0 ) return; - if ( !pObj->RetTrainer() ) return; - - if ( event == EVENT_KEYDOWN ) - { - if ( param == m_engine->RetKey(KEYRANK_LEFT, 0) || - param == m_engine->RetKey(KEYRANK_LEFT, 1) ) - { - m_cameraPan = -1.0f; - } - - if ( param == m_engine->RetKey(KEYRANK_RIGHT, 0) || - param == m_engine->RetKey(KEYRANK_RIGHT, 1) ) - { - m_cameraPan = 1.0f; - } - - if ( param == m_engine->RetKey(KEYRANK_UP, 0) || - param == m_engine->RetKey(KEYRANK_UP, 1) ) - { - m_cameraZoom = -1.0f; - } - - if ( param == m_engine->RetKey(KEYRANK_DOWN, 0) || - param == m_engine->RetKey(KEYRANK_DOWN, 1) ) - { - m_cameraZoom = 1.0f; - } - } -} - -// Panned with the camera if a button is pressed. - -void CRobotMain::RemoteCamera(float pan, float zoom, float rTime) -{ - float value; - - if ( pan != 0.0f ) - { - value = m_camera->RetRemotePan(); - value += pan*rTime*1.5f; - m_camera->SetRemotePan(value); - } - - if ( zoom != 0.0f ) - { - value = m_camera->RetRemoteZoom(); - value += zoom*rTime*0.3f; - m_camera->SetRemoteZoom(value); - } -} - - - -// Cancels the current movie. - -void CRobotMain::AbortMovie() -{ - CObject* pObj; - CAuto* automat; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - automat = pObj->RetAuto(); - if ( automat != 0 ) - { - automat->Abort(); - } - } - - m_engine->SetMouseHide(FALSE); -} - - - -// Updates the text information. - -void CRobotMain::UpdateInfoText() -{ - CObject* pObj; - D3DVECTOR pos; - char info[100]; - - if ( m_bShowPos ) - { - pObj = RetSelect(); - if ( pObj != 0 ) - { - pos = pObj->RetPosition(0); - sprintf(info, "Pos = %.2f ; %.2f", pos.x/g_unit, pos.z/g_unit); - m_engine->SetInfoText(4, info); - } - } -} - - -// Initializes the view. - -void CRobotMain::InitEye() -{ - if ( m_phase == PHASE_SIMUL ) - { - m_camera->Init(D3DVECTOR( 0.0f, 10.0f, 0.0f), - D3DVECTOR(10.0f, 5.0f, 0.0f), 0.0f); - } - - if ( m_phase == PHASE_MODEL ) - { - m_model->InitView(); - } -} - -// Advances the entire scene. - -BOOL CRobotMain::EventFrame(const Event &event) -{ - ObjectType type; - CObject *pObj, *toto; - CPyro* pPyro; - CWindow* pw; - CMap* pm; - int i; - - m_time += event.rTime; - if ( !m_bMovieLock ) m_gameTime += event.rTime; - - if ( !m_bImmediatSatCom && !m_bBeginSatCom && - m_gameTime > 0.1f && m_phase == PHASE_SIMUL ) - { - m_displayText->DisplayError(INFO_BEGINSATCOM, D3DVECTOR(0.0f,0.0f,0.0f)); - m_bBeginSatCom = TRUE; // message appears - } - - m_water->EventProcess(event); - m_cloud->EventProcess(event); - m_blitz->EventProcess(event); - m_planet->EventProcess(event); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw == 0 ) - { - pm = 0; - } - else - { - pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); - if ( pm != 0 ) pm->FlushObject(); - } - - toto = 0; - if ( !m_bFreePhoto ) - { - // Advances all the robots, but not toto. - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - if ( pm != 0 ) pm->UpdateObject(pObj); - if ( pObj->RetTruck() != 0 ) continue; - type = pObj->RetType(); - if ( type == OBJECT_TOTO ) - { - toto = pObj; - } - else - { - pObj->EventProcess(event); - } - } - // Advances all objects transported by robots. - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - if ( pObj->RetTruck() == 0 ) continue; - pObj->EventProcess(event); - } - - // Advances pyrotechnic effects. - for ( i=0 ; i<1000000 ; i++ ) - { - pPyro = (CPyro*)m_iMan->SearchInstance(CLASS_PYRO, i); - if ( pPyro == 0 ) break; - - pPyro->EventProcess(event); - if ( pPyro->IsEnded() != ERR_CONTINUE ) - { - pPyro->DeleteObject(); - delete pPyro; - } - } - } - - // The camera follows the object, because its position - // may depend on the selected object (CAMERA_ONBOARD or CAMERA_BACK). - if ( m_phase == PHASE_SIMUL && !m_bEditFull ) - { - m_camera->EventProcess(event); - - if ( m_engine->RetFog() ) - { - m_camera->SetOverBaseColor(m_particule->RetFogColor(m_engine->RetEyePt())); - } - } - if ( m_phase == PHASE_PERSO || - m_phase == PHASE_WIN || - m_phase == PHASE_LOST ) - { - m_camera->EventProcess(event); - } - - // Advances toto following the camera, because its position depends on the camera. - if ( toto != 0 ) - { - toto->EventProcess(event); - } - - // Advances model. - if ( m_phase == PHASE_MODEL ) - { - m_model->ViewMove(event, 2.0f); - m_model->UpdateView(); - m_model->EventProcess(event); - } - - HiliteFrame(event.rTime); - - // Moves the film indicator. - if ( m_bMovieLock && !m_bEditLock ) // movie in progress? - { - CControl* pc; - FPOINT pos, dim; - float zoom; - - pc = m_interface->SearchControl(EVENT_OBJECT_MOVIELOCK); - if ( pc != 0 ) - { - dim.x = 32.0f/640.0f; - dim.y = 32.0f/480.0f; - pos.x = 20.0f/640.0f; - pos.y = (480.0f-24.0f)/480.0f; - - zoom = 1.0f+sinf(m_time*6.0f)*0.1f; // 0.9 .. 1.1 - dim.x *= zoom; - dim.y *= zoom; - pos.x -= dim.x/2.0f; - pos.y -= dim.y/2.0f; - - pc->SetPos(pos); - pc->SetDim(dim); - } - } - - // Moves edition indicator. - if ( m_bEditLock || m_bPause ) // edition in progress? - { - CControl* pc; - FPOINT pos, dim; - float zoom; - - pc = m_interface->SearchControl(EVENT_OBJECT_EDITLOCK); - if ( pc != 0 ) - { - if ( m_bEditFull || m_bEditLock ) - { - dim.x = 10.0f/640.0f; - dim.y = 10.0f/480.0f; - pos.x = -20.0f/640.0f; - pos.y = -20.0f/480.0f; // invisible! - } - else - { - dim.x = 32.0f/640.0f; - dim.y = 32.0f/480.0f; - pos.x = 20.0f/640.0f; - pos.y = (480.0f-24.0f)/480.0f; - - zoom = 1.0f+sinf(m_time*6.0f)*0.1f; // 0.9 .. 1.1 - dim.x *= zoom; - dim.y *= zoom; - pos.x -= dim.x/2.0f; - pos.y -= dim.y/2.0f; - } - pc->SetPos(pos); - pc->SetDim(dim); - } - } - - // Will move the arrow to visit. - if ( m_camera->RetType() == CAMERA_VISIT ) - { - FrameVisit(event.rTime); - } - - // Moves the boundaries. - FrameShowLimit(event.rTime); - - if ( m_phase == PHASE_SIMUL ) - { - if ( !m_bEditLock && m_checkEndTime+1.0f < m_time ) - { - m_checkEndTime = m_time; - CheckEndMission(TRUE); - } - - if ( m_winDelay > 0.0f && !m_bEditLock ) - { - m_winDelay -= event.rTime; - if ( m_winDelay <= 0.0f ) - { - if ( m_bMovieLock ) - { - m_winDelay = 1.0f; - } - else - { - Event newEvent; - m_event->MakeEvent(newEvent, EVENT_WIN); - m_event->AddEvent(newEvent); - } - } - } - - if ( m_lostDelay > 0.0f && !m_bEditLock ) - { - m_lostDelay -= event.rTime; - if ( m_lostDelay <= 0.0f ) - { - if ( m_bMovieLock ) - { - m_winDelay = 1.0f; - } - else - { - Event newEvent; - m_event->MakeEvent(newEvent, EVENT_LOST); - m_event->AddEvent(newEvent); - } - } - } - } - - if ( m_delayWriteMessage > 0 ) - { - m_delayWriteMessage --; - if ( m_delayWriteMessage == 0 ) - { - m_displayText->DisplayError(INFO_WRITEOK, D3DVECTOR(0.0f,0.0f,0.0f)); - } - } - - return S_OK; -} - -// Makes the event for all robots. - -BOOL CRobotMain::EventObject(const Event &event) -{ - CObject* pObj; - int i; - - if ( m_bFreePhoto ) return S_OK; - - m_bResetCreate = FALSE; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - pObj->EventProcess(event); - } - - if ( m_bResetCreate ) - { - ResetCreate(); - } - - return S_OK; -} - - -// Calculates the point of arrival of the camera. - -D3DVECTOR CRobotMain::LookatPoint(D3DVECTOR eye, float angleH, float angleV, - float length) -{ - D3DVECTOR lookat; - - lookat = eye; - lookat.z += length; - - RotatePoint(eye, angleH, angleV, lookat); - return lookat; -} - - - -char* SkipNum(char *p) -{ - while ( *p == ' ' || *p == '.' || *p == '-' || (*p >= '0' && *p <= '9') ) - { - p++; - } - return p; -} - -// Conversion of units. - -void CRobotMain::Convert() -{ - FILE* file = NULL; - FILE* fileNew = NULL; - char line[500]; - char lineNew[500]; - char s[200]; - char* base; - char* p; - int rank; - D3DVECTOR pos; - float value; - - base = m_dialog->RetSceneName(); - rank = m_dialog->RetSceneRank(); - - m_dialog->BuildSceneName(line, base, rank); - file = fopen(line, "r"); - if ( file == NULL ) return; - - strcpy(line+strlen(line)-4, ".new"); - fileNew = fopen(line, "w"); - if ( fileNew == NULL ) return; - - while ( fgets(line, 500, file) != NULL ) - { - strcpy(lineNew, line); - - if ( Cmd(line, "DeepView") ) - { - p = strstr(line, "air="); - if ( p != 0 ) - { - value = OpFloat(line, "air", 500.0f); - value /= g_unit; - p[0] = 0; - p = SkipNum(p+4); - strcpy(lineNew, line); - strcat(lineNew, "air="); - sprintf(s, "%.2f", value); - strcat(lineNew, s); - strcat(lineNew, " "); - strcat(lineNew, p); - } - strcpy(line, lineNew); - - p = strstr(line, "water="); - if ( p != 0 ) - { - value = OpFloat(line, "water", 100.0f); - value /= g_unit; - p[0] = 0; - p = SkipNum(p+6); - strcpy(lineNew, line); - strcat(lineNew, "water="); - sprintf(s, "%.2f", value); - strcat(lineNew, s); - strcat(lineNew, " "); - strcat(lineNew, p); - } - strcpy(line, lineNew); - } - - if ( Cmd(line, "TerrainGenerate") ) - { - p = strstr(line, "vision="); - if ( p != 0 ) - { - value = OpFloat(line, "vision", 500.0f); - value /= g_unit; - p[0] = 0; - p = SkipNum(p+7); - strcpy(lineNew, line); - strcat(lineNew, "vision="); - sprintf(s, "%.2f", value); - strcat(lineNew, s); - strcat(lineNew, " "); - strcat(lineNew, p); - } - } - - if ( Cmd(line, "CreateObject") || - Cmd(line, "CreateSpot") ) - { - p = strstr(line, "pos="); - if ( p != 0 ) - { - pos = OpPos(line, "pos"); - pos.x /= g_unit; - pos.y /= g_unit; - pos.z /= g_unit; - p[0] = 0; - p = SkipNum(p+4); - p = SkipNum(p+1); - strcpy(lineNew, line); - strcat(lineNew, "pos="); - sprintf(s, "%.2f", pos.x); - strcat(lineNew, s); - strcat(lineNew, ";"); - sprintf(s, "%.2f", pos.z); - strcat(lineNew, s); - strcat(lineNew, " "); - strcat(lineNew, p); - } - } - - if ( Cmd(line, "EndMissionTake") ) - { - p = strstr(line, "pos="); - if ( p != 0 ) - { - pos = OpPos(line, "pos"); - pos.x /= g_unit; - pos.y /= g_unit; - pos.z /= g_unit; - p[0] = 0; - p = SkipNum(p+4); - p = SkipNum(p+1); - strcpy(lineNew, line); - strcat(lineNew, "pos="); - sprintf(s, "%.2f", pos.x); - strcat(lineNew, s); - strcat(lineNew, ";"); - sprintf(s, "%.2f", pos.z); - strcat(lineNew, s); - strcat(lineNew, " "); - strcat(lineNew, p); - } - strcpy(line, lineNew); - - p = strstr(line, "dist="); - if ( p != 0 ) - { - value = OpFloat(line, "dist", 32.0f); - value /= g_unit; - p[0] = 0; - p = SkipNum(p+5); - strcpy(lineNew, line); - strcat(lineNew, "dist="); - sprintf(s, "%.2f", value); - strcat(lineNew, s); - strcat(lineNew, " "); - strcat(lineNew, p); - } - strcpy(line, lineNew); - } - - if ( Cmd(line, "Camera") ) - { - p = strstr(line, "pos="); - if ( p != 0 ) - { - pos = OpPos(line, "pos"); - pos.x /= g_unit; - pos.y /= g_unit; - pos.z /= g_unit; - p[0] = 0; - p = SkipNum(p+4); - p = SkipNum(p+1); - strcpy(lineNew, line); - strcat(lineNew, "pos="); - sprintf(s, "%.2f", pos.x); - strcat(lineNew, s); - strcat(lineNew, ";"); - sprintf(s, "%.2f", pos.z); - strcat(lineNew, s); - strcat(lineNew, " "); - strcat(lineNew, p); - } - strcpy(line, lineNew); - - p = strstr(line, "h="); - if ( p != 0 ) - { - value = OpFloat(line, "h", 32.0f); - value /= g_unit; - p[0] = 0; - p = SkipNum(p+2); - strcpy(lineNew, line); - strcat(lineNew, "h="); - sprintf(s, "%.2f", value); - strcat(lineNew, s); - strcat(lineNew, " "); - strcat(lineNew, p); - } - strcpy(line, lineNew); - } - - fputs(lineNew, fileNew); - } - - fclose(fileNew); - fclose(file); -} - -// Load the scene for the character. - -void CRobotMain::ScenePerso() -{ - CObject* pObj; - - DeleteAllObjects(); // removes all the current 3D Scene - m_engine->FlushObject(); - m_terrain->FlushRelief(); // all flat - m_terrain->FlushBuildingLevel(); - m_terrain->FlushFlyingLimit(); - m_light->FlushLight(); - m_particule->FlushParticule(); - m_iMan->Flush(CLASS_OBJECT); - m_iMan->Flush(CLASS_PHYSICS); - m_iMan->Flush(CLASS_BRAIN); - m_iMan->Flush(CLASS_PYRO); - - m_dialog->SetSceneName("perso"); - m_dialog->SetSceneRank(0); - CreateScene(FALSE, TRUE, FALSE); // sets scene - - m_engine->SetDrawWorld(FALSE); // does not draw anything on the interface - m_engine->SetDrawFront(TRUE); // draws on the human interface - pObj = SearchHuman(); - if ( pObj != 0 ) - { - CMotionHuman* mh; - - pObj->SetDrawFront(TRUE); // draws the interface - - mh = (CMotionHuman*)pObj->RetMotion(); - if ( mh != 0 ) - { - mh->StartDisplayPerso(); - } - } -} - -// Creates the whole stage. - -void CRobotMain::CreateScene(BOOL bSoluce, BOOL bFixScene, BOOL bResetObject) -{ - CObject* pObj; - CObject* pSel; - CMotion* motion; - FILE* file = NULL; - char line[500]; - char name[200]; - char dir[100]; - char op[100]; - char* read; - char* stack; - char* base; - D3DCOLORVALUE color; - D3DVECTOR pos; - int rank, obj, i, rankObj, rankGadget; - -//? Convert(); - - base = m_dialog->RetSceneName(); - rank = m_dialog->RetSceneRank(); - read = m_dialog->RetSceneRead(); - stack = m_dialog->RetStackRead(); - m_dialog->SetUserDir(base, rank); - - m_bFixScene = bFixScene; - - g_id = 0; - m_bBase = FALSE; - - if ( !bResetObject ) - { - g_build = 0; - g_researchDone = 0; // no research done - g_researchEnable = 0; - - FlushDisplayInfo(); - m_terrain->LevelFlush(); - m_audioTrack = 0; - m_bAudioRepeat = TRUE; - m_displayText->SetDelay(1.0f); - m_displayText->SetEnable(TRUE); - m_bImmediatSatCom = FALSE; - m_endingWinRank = 0; - m_endingLostRank = 0; - m_endTakeTotal = 0; - m_endTakeResearch = 0; - m_endTakeWinDelay = 2.0f; - m_endTakeLostDelay = 2.0f; - m_obligatoryTotal = 0; - m_prohibitedTotal = 0; - m_bMapShow = TRUE; - m_bMapImage = FALSE; - m_mapFilename[0] = 0; - - m_colorRefBot.r = 10.0f/256.0f; - m_colorRefBot.g = 166.0f/256.0f; - m_colorRefBot.b = 254.0f/256.0f; // blue - m_colorRefBot.a = 0.0f; - m_colorNewBot = m_colorRefBot; - - m_colorRefAlien.r = 135.0f/256.0f; - m_colorRefAlien.g = 170.0f/256.0f; - m_colorRefAlien.b = 13.0f/256.0f; // green - m_colorRefAlien.a = 0.0f; - m_colorNewAlien = m_colorRefAlien; - - m_colorRefGreen.r = 135.0f/256.0f; - m_colorRefGreen.g = 170.0f/256.0f; - m_colorRefGreen.b = 13.0f/256.0f; // green - m_colorRefGreen.a = 0.0f; - m_colorNewGreen = m_colorRefGreen; - - m_colorRefWater.r = 25.0f/256.0f; - m_colorRefWater.g = 255.0f/256.0f; - m_colorRefWater.b = 240.0f/256.0f; // cyan - m_colorRefWater.a = 0.0f; - m_colorNewWater = m_colorRefWater; - - m_dialog->BuildResumeName(m_title, base, rank); - m_dialog->BuildResumeName(m_resume, base, rank); - GetResource(RES_TEXT, RT_SCRIPT_NEW, m_scriptName); - m_scriptFile[0] = 0; - } - - m_dialog->BuildSceneName(line, base, rank); - file = fopen(line, "r"); - if ( file == NULL ) return; - - rankObj = 0; - rankGadget = 0; - pSel = 0; - - while ( fgets(line, 500, file) != NULL ) - { - for ( i=0 ; i<500 ; i++ ) - { - if ( line[i] == '\t' ) line[i] = ' '; // replace tab by space - if ( line[i] == '/' && line[i+1] == '/' ) - { - line[i] = 0; - break; - } - } - - sprintf(op, "Title.%c", RetLanguageLetter()); - if ( Cmd(line, op) && !bResetObject ) - { - OpString(line, "text", m_title); - } - - sprintf(op, "Resume.%c", RetLanguageLetter()); - if ( Cmd(line, op) && !bResetObject ) - { - OpString(line, "text", m_resume); - } - - sprintf(op, "ScriptName.%c", RetLanguageLetter()); - if ( Cmd(line, op) && !bResetObject ) - { - OpString(line, "text", m_scriptName); - } - - if ( Cmd(line, "ScriptFile") && !bResetObject ) - { - OpString(line, "name", m_scriptFile); - } - - if ( Cmd(line, "Instructions") && !bResetObject ) - { - OpString(line, "name", name); -//? sprintf(m_infoFilename[SATCOM_HUSTON], "help\\%s", name); - UserDir(m_infoFilename[SATCOM_HUSTON], name, "help"); - - m_bImmediatSatCom = OpInt(line, "immediat", 0); - } - - if ( Cmd(line, "Satellite") && !bResetObject ) - { - OpString(line, "name", name); -//? sprintf(m_infoFilename[SATCOM_SAT], "help\\%s", name); - UserDir(m_infoFilename[SATCOM_SAT], name, "help"); - } - - if ( Cmd(line, "Loading") && !bResetObject ) - { - OpString(line, "name", name); -//? sprintf(m_infoFilename[SATCOM_LOADING], "help\\%s", name); - UserDir(m_infoFilename[SATCOM_LOADING], name, "help"); - } - - if ( Cmd(line, "HelpFile") && !bResetObject ) - { - OpString(line, "name", name); -//? sprintf(m_infoFilename[SATCOM_PROG], "help\\%s", name); - UserDir(m_infoFilename[SATCOM_PROG], name, "help"); - } - if ( Cmd(line, "SoluceFile") && !bResetObject ) - { - OpString(line, "name", name); -//? sprintf(m_infoFilename[SATCOM_SOLUCE], "help\\%s", name); - UserDir(m_infoFilename[SATCOM_SOLUCE], name, "help"); - } - - if ( Cmd(line, "EndingFile") && !bResetObject ) - { - m_endingWinRank = OpInt(line, "win", 0); - m_endingLostRank = OpInt(line, "lost", 0); - } - - if ( Cmd(line, "MessageDelay") && !bResetObject ) - { - m_displayText->SetDelay(OpFloat(line, "factor", 1.0f)); - } - - if ( Cmd(line, "Audio") && !bResetObject ) - { - m_audioTrack = OpInt(line, "track", 0); - m_bAudioRepeat = OpInt(line, "repeat", 1); - } - - if ( Cmd(line, "AmbiantColor") && !bResetObject ) - { - m_engine->SetAmbiantColor(OpColor(line, "air", 0x88888888), 0); - m_engine->SetAmbiantColor(OpColor(line, "water", 0x88888888), 1); - } - - if ( Cmd(line, "FogColor") && !bResetObject ) - { - m_engine->SetFogColor(OpColor(line, "air", 0x88888888), 0); - m_engine->SetFogColor(OpColor(line, "water", 0x88888888), 1); - } - - if ( Cmd(line, "VehicleColor") && !bResetObject ) - { - m_colorNewBot = RetColor(OpColor(line, "color", 0x88888888)); - } - - if ( Cmd(line, "InsectColor") && !bResetObject ) - { - m_colorNewAlien = RetColor(OpColor(line, "color", 0x88888888)); - } - - if ( Cmd(line, "GreeneryColor") && !bResetObject ) - { - m_colorNewGreen = RetColor(OpColor(line, "color", 0x88888888)); - } - - if ( Cmd(line, "DeepView") && !bResetObject ) - { - m_engine->SetDeepView(OpFloat(line, "air", 500.0f)*UNIT, 0, TRUE); - m_engine->SetDeepView(OpFloat(line, "water", 100.0f)*UNIT, 1, TRUE); - } - - if ( Cmd(line, "FogStart") && !bResetObject ) - { - m_engine->SetFogStart(OpFloat(line, "air", 0.5f), 0); - m_engine->SetFogStart(OpFloat(line, "water", 0.5f), 1); - } - - if ( Cmd(line, "SecondTexture") && !bResetObject ) - { - m_engine->SetSecondTexture(OpInt(line, "rank", 1)); - } - - if ( Cmd(line, "Background") && !bResetObject ) - { - OpString(line, "image", name); - UserDir(dir, name, ""); - m_engine->SetBackground(dir, - OpColor(line, "up", 0x00000000), - OpColor(line, "down", 0x00000000), - OpColor(line, "cloudUp", 0x00000000), - OpColor(line, "cloudDown", 0x00000000), - OpInt(line, "full", 0)); - } - - if ( Cmd(line, "Planet") && !bResetObject ) - { - D3DVECTOR ppos, uv1, uv2; - - ppos = OpPos(line, "pos"); - uv1 = OpPos(line, "uv1"); - uv2 = OpPos(line, "uv2"); - OpString(line, "image", name); - UserDir(dir, name, ""); - m_planet->Create(OpInt(line, "mode", 0), - FPOINT(ppos.x, ppos.z), - OpFloat(line, "dim", 0.2f), - OpFloat(line, "speed", 0.0f), - OpFloat(line, "dir", 0.0f), - dir, - FPOINT(uv1.x, uv1.z), - FPOINT(uv2.x, uv2.z)); - } - - if ( Cmd(line, "FrontsizeName") && !bResetObject ) - { - OpString(line, "image", name); - UserDir(dir, name, ""); - m_engine->SetFrontsizeName(dir); - } - - if ( Cmd(line, "Global") && !bResetObject ) - { - g_unit = OpFloat(line, "unitScale", 4.0f); - m_engine->SetTracePrecision(OpFloat(line, "traceQuality", 1.0f)); - m_bShortCut = OpInt(line, "shortcut", 1); - } - - if ( Cmd(line, "TerrainGenerate") && !bResetObject ) - { - m_terrain->Generate(OpInt(line, "mosaic", 20), - OpInt(line, "brick", 3), - OpFloat(line, "size", 20.0f), - OpFloat(line, "vision", 500.0f)*UNIT, - OpInt(line, "depth", 2), - OpFloat(line, "hard", 0.5f)); - } - - if ( Cmd(line, "TerrainWind") && !bResetObject ) - { - m_terrain->SetWind(OpPos(line, "speed")); - } - - if ( Cmd(line, "TerrainRelief") && !bResetObject ) - { - OpString(line, "image", name); - UserDir(dir, name, "textures"); - m_terrain->ReliefFromBMP(dir, OpFloat(line, "factor", 1.0f), OpInt(line, "border", 1)); - } - - if ( Cmd(line, "TerrainReliefDXF") && !bResetObject ) - { - OpString(line, "image", name); - UserDir(dir, name, "textures"); - m_terrain->ReliefFromDXF(dir, OpFloat(line, "factor", 1.0f)); - } - - if ( Cmd(line, "TerrainResource") && !bResetObject ) - { - OpString(line, "image", name); - UserDir(dir, name, "textures"); - m_terrain->ResFromBMP(dir); - } - - if ( Cmd(line, "TerrainWater") && !bResetObject ) - { - OpString(line, "image", name); - UserDir(dir, name, ""); - pos.x = OpFloat(line, "moveX", 0.0f); - pos.y = OpFloat(line, "moveY", 0.0f); - pos.z = pos.x; - m_water->Create(OpTypeWater(line, "air", WATER_TT), - OpTypeWater(line, "water", WATER_TT), - dir, - RetColor(OpColor(line, "diffuse", 0xffffffff)), - RetColor(OpColor(line, "ambiant", 0xffffffff)), - OpFloat(line, "level", 100.0f)*UNIT, - OpFloat(line, "glint", 1.0f), - pos); - m_colorNewWater = RetColor(OpColor(line, "color", RetColor(m_colorRefWater))); - m_colorShiftWater = OpFloat(line, "brightness", 0.0f); - } - - if ( Cmd(line, "TerrainLava") && !bResetObject ) - { - m_water->SetLava(OpInt(line, "mode", 0)); - } - - if ( Cmd(line, "TerrainCloud") && !bResetObject ) - { - OpString(line, "image", name); - UserDir(dir, name, ""); - m_cloud->Create(dir, - RetColor(OpColor(line, "diffuse", 0xffffffff)), - RetColor(OpColor(line, "ambiant", 0xffffffff)), - OpFloat(line, "level", 500.0f)*UNIT); - } - - if ( Cmd(line, "TerrainBlitz") && !bResetObject ) - { - m_blitz->Create(OpFloat(line, "sleep", 0.0f), - OpFloat(line, "delay", 3.0f), - OpFloat(line, "magnetic", 50.0f)*UNIT); - } - - if ( Cmd(line, "TerrainInitTextures") && !bResetObject ) - { - int dx, dy, tt[100]; - char* op; - - OpString(line, "image", name); - AddExt(name, ".tga"); - dx = OpInt(line, "dx", 1); - dy = OpInt(line, "dy", 1); - op = SearchOp(line, "table"); - for ( i=0 ; iInitTextures(name, tt, dx, dy); - } - - if ( Cmd(line, "TerrainInit") && !bResetObject ) - { - m_terrain->LevelInit(OpInt(line, "id", 1)); - } - - if ( Cmd(line, "TerrainMaterial") && !bResetObject ) - { - OpString(line, "image", name); - AddExt(name, ".tga"); - if ( strstr(name, "%user%") != 0 ) - { - CopyFileToTemp(name); - } - - m_terrain->LevelMaterial(OpInt(line, "id", 0), - name, - OpFloat(line, "u", 0.0f), - OpFloat(line, "v", 0.0f), - OpInt(line, "up", 1), - OpInt(line, "right", 1), - OpInt(line, "down", 1), - OpInt(line, "left", 1), - OpFloat(line, "hard", 0.5f)); - } - - if ( Cmd(line, "TerrainLevel") && !bResetObject ) - { - int id[50]; - char* op; - - op = SearchOp(line, "id"); - i = 0; - while ( TRUE ) - { - id[i] = GetInt(op, i, 0); - if ( id[i++] == 0 ) break; - } - - m_terrain->LevelGenerate(id, - OpFloat(line, "min", 0.0f)*UNIT, - OpFloat(line, "max", 100.0f)*UNIT, - OpFloat(line, "slope", 5.0f), - OpFloat(line, "freq", 100.0f), - OpPos(line, "center")*g_unit, - OpFloat(line, "radius", 0.0f)*g_unit); - } - - if ( Cmd(line, "TerrainCreate") && !bResetObject ) - { - m_terrain->CreateObjects(TRUE); - } - - if ( Cmd(line, "BeginObject") ) - { - InitEye(); - SetMovieLock(FALSE); - if ( !m_bFixScene ) - { -//? CreateObject(D3DVECTOR(0.0f, 0.0f, 0.0f), 0.0f, 0.0f, OBJECT_TOTO); - } - - if ( read[0] != 0 ) // loading file ? - { - pSel = IOReadScene(read, stack); - } - } - - if ( Cmd(line, "CreateObject") && read[0] == 0 ) - { - CObject* pObj; - CBrain* pBrain; - CAuto* pAuto; - CPyro* pyro; - ObjectType type; - PyroType pType; - CameraType cType; - Info info; - float dir; - char op[20]; - char text[100]; - char* p; - int run, gadget; - - type = OpTypeObject(line, "type", OBJECT_NULL); - - gadget = OpInt(line, "gadget", -1); - if ( gadget == -1 ) - { - gadget = 0; - if ( type == OBJECT_TECH || - (type >= OBJECT_PLANT0 && - type <= OBJECT_PLANT19 ) || - (type >= OBJECT_TREE0 && - type <= OBJECT_TREE9 ) || - (type >= OBJECT_TEEN0 && - type <= OBJECT_TEEN49 ) || - (type >= OBJECT_QUARTZ0 && - type <= OBJECT_QUARTZ9 ) || - (type >= OBJECT_ROOT0 && - type <= OBJECT_ROOT4 ) ) // not ROOT5! - { - if ( type != OBJECT_TEEN11 && // lamp? - type != OBJECT_TEEN12 && // coke? - type != OBJECT_TEEN20 && // wall? - type != OBJECT_TEEN21 && // wall? - type != OBJECT_TEEN22 && // wall? - type != OBJECT_TEEN26 && // lamp? - type != OBJECT_TEEN28 && // bottle? - type != OBJECT_TEEN34 ) // stone? - { - gadget = 1; - } - } - } - if ( gadget != 0 ) // is this a gadget? - { - if ( !TestGadgetQuantity(rankGadget++) ) continue; - } - - pos = OpPos(line, "pos")*g_unit; - dir = OpFloat(line, "dir", 0.0f)*PI; - pObj = CreateObject(pos, dir, - OpFloat(line, "z", 1.0f), - OpFloat(line, "h", 0.0f), - type, - OpFloat(line, "power", 1.0f), - OpInt(line, "trainer", 0), - OpInt(line, "toy", 0), - OpInt(line, "option", 0)); - - if ( pObj != 0 ) - { - pObj->SetDefRank(rankObj); - - if ( type == OBJECT_BASE ) m_bBase = TRUE; - - cType = OpCamera(line, "camera"); - if ( cType != CAMERA_NULL ) - { - pObj->SetCameraType(cType); - } - pObj->SetCameraDist(OpFloat(line, "cameraDist", 50.0f)); - pObj->SetCameraLock(OpInt(line, "cameraLock", 0)); - - pType = OpPyro(line, "pyro"); - if ( pType != PT_NULL ) - { - pyro = new CPyro(m_iMan); - pyro->Create(pType, pObj); - } - - // Puts information in terminal (OBJECT_INFO). - for ( i=0 ; iSearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - if ( pObj->RetTruck() != 0 ) continue; - - brain = pObj->RetBrain(); - if ( brain == 0 ) continue; - - for ( j=0 ; j<10 ; j++ ) - { - if ( brain->RetCompile(j) ) continue; - - name = brain->RetScriptName(j); - if ( name[0] != 0 ) - { - brain->ReadProgram(j, name); - if ( !brain->RetCompile(j) ) nbError++; - } - } - - LoadOneScript(pObj, nbError); - } - } - while ( nbError > 0 && nbError != lastError ); - - // Load all solutions. - if ( bSoluce ) - { - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - if ( pObj->RetTruck() != 0 ) continue; - - brain = pObj->RetBrain(); - if ( brain == 0 ) continue; - - name = brain->RetSoluceName(); - if ( name[0] != 0 ) - { - brain->ReadSoluce(name); // load solution - } - } - } - - // Start all programs according to the command "run". - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - if ( pObj->RetTruck() != 0 ) continue; - - brain = pObj->RetBrain(); - if ( brain == 0 ) continue; - - run = brain->RetScriptRun(); - if ( run != -1 ) - { - brain->RunProgram(run); // starts the program - } - } -} - -// Load all programs of the robot. - -void CRobotMain::LoadOneScript(CObject *pObj, int &nbError) -{ - ObjectType type; - CBrain* brain; - char filename[_MAX_FNAME]; - char* name; - int rank, i, objRank; - - brain = pObj->RetBrain(); - if ( brain == 0 ) return; - - if ( !IsSelectable(pObj) ) return; - - type = pObj->RetType(); - if ( type == OBJECT_HUMAN ) return; - - objRank = pObj->RetDefRank(); - if ( objRank == -1 ) return; - - name = m_dialog->RetSceneName(); - rank = m_dialog->RetSceneRank(); - - for ( i=0 ; iRetCompile(i) ) continue; -//? if ( brain->ProgramExist(i) ) continue; - - sprintf(filename, "%s\\%s\\%c%.3d%.3d%.1d.txt", - RetSavegameDir(), m_gamerName, name[0], rank, objRank, i); - brain->ReadProgram(i, filename); - if ( !brain->RetCompile(i) ) nbError++; - } -} - -// Load all programs of the robot. - -void CRobotMain::LoadFileScript(CObject *pObj, char* filename, int objRank, - int &nbError) -{ - ObjectType type; - CBrain* brain; - char fn[_MAX_FNAME]; - char* ldir; - char* name; - int rank, i; - - if ( objRank == -1 ) return; - - brain = pObj->RetBrain(); - if ( brain == 0 ) return; - - type = pObj->RetType(); - if ( type == OBJECT_HUMAN ) return; - - name = m_dialog->RetSceneName(); - rank = m_dialog->RetSceneRank(); - - strcpy(fn, filename); - ldir = SearchLastDir(fn); - if ( ldir == 0 ) return; - - for ( i=0 ; iRetCompile(i) ) continue; -//? if ( brain->ProgramExist(i) ) continue; - - sprintf(ldir, "\\prog%.3d%.1d.txt", objRank, i); - brain->ReadProgram(i, fn); - if ( !brain->RetCompile(i) ) nbError++; - } -} - -// Saves all programs of all the robots. - -void CRobotMain::SaveAllScript() -{ - CObject* pObj; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - SaveOneScript(pObj); - } -} - -// Saves all programs of the robot. -// If a program does not exist, the corresponding file is destroyed. - -void CRobotMain::SaveOneScript(CObject *pObj) -{ - ObjectType type; - CBrain* brain; - char filename[_MAX_FNAME]; - char* name; - int rank, i, objRank; - - brain = pObj->RetBrain(); - if ( brain == 0 ) return; - - if ( !IsSelectable(pObj) ) return; - - type = pObj->RetType(); - if ( type == OBJECT_HUMAN ) return; - - objRank = pObj->RetDefRank(); - if ( objRank == -1 ) return; - - name = m_dialog->RetSceneName(); - rank = m_dialog->RetSceneRank(); - - for ( i=0 ; iWriteProgram(i, filename); - } -} - -// Saves all programs of the robot. -// If a program does not exist, the corresponding file is destroyed. - -void CRobotMain::SaveFileScript(CObject *pObj, char* filename, int objRank) -{ - ObjectType type; - CBrain* brain; - char fn[_MAX_FNAME]; - char* ldir; - char* name; - int rank, i; - - if ( objRank == -1 ) return; - - brain = pObj->RetBrain(); - if ( brain == 0 ) return; - - type = pObj->RetType(); - if ( type == OBJECT_HUMAN ) return; - - name = m_dialog->RetSceneName(); - rank = m_dialog->RetSceneRank(); - - strcpy(fn, filename); - ldir = SearchLastDir(fn); - if ( ldir == 0 ) return; - - for ( i=0 ; iWriteProgram(i, fn); - } -} - -// Saves the stack of the program in execution of a robot. - -BOOL CRobotMain::SaveFileStack(CObject *pObj, FILE *file, int objRank) -{ - ObjectType type; - CBrain* brain; - - if ( objRank == -1 ) return TRUE; - - brain = pObj->RetBrain(); - if ( brain == 0 ) return TRUE; - - type = pObj->RetType(); - if ( type == OBJECT_HUMAN ) return TRUE; - - return brain->WriteStack(file); -} - -// Resumes the execution stack of the program in a robot. - -BOOL CRobotMain::ReadFileStack(CObject *pObj, FILE *file, int objRank) -{ - ObjectType type; - CBrain* brain; - - if ( objRank == -1 ) return TRUE; - - brain = pObj->RetBrain(); - if ( brain == 0 ) return TRUE; - - type = pObj->RetType(); - if ( type == OBJECT_HUMAN ) return TRUE; - - return brain->ReadStack(file); -} - - -// Empty the list. - -BOOL CRobotMain::FlushNewScriptName() -{ - int i; - - for ( i=0 ; i 0 ) return TRUE; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - pBrain = pObj->RetBrain(); - if ( pBrain != 0 ) - { - if ( pBrain->IsBusy() ) return TRUE; - } - -//? pAuto = pObj->RetAuto(); -//? if ( pAuto != 0 ) -//? { -//? if ( pAuto->RetBusy() ) return TRUE; -//? } - } - return FALSE; -} - -// Writes an object into the backup file. - -void CRobotMain::IOWriteObject(FILE *file, CObject* pObj, char *cmd) -{ - D3DVECTOR pos; - CBrain* pBrain; - char line[3000]; - char name[100]; - int run, i; - - if ( pObj->RetType() == OBJECT_FIX ) return; - - strcpy(line, cmd); - - sprintf(name, " type=%s", GetTypeObject(pObj->RetType())); - strcat(line, name); - - sprintf(name, " id=%d", pObj->RetID()); - strcat(line, name); - - pos = pObj->RetPosition(0)/g_unit; - sprintf(name, " pos=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); - strcat(line, name); - - pos = pObj->RetAngle(0)/(PI/180.0f); - sprintf(name, " angle=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); - strcat(line, name); - - pos = pObj->RetZoom(0); - sprintf(name, " zoom=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); - strcat(line, name); - - for ( i=1 ; iRetObjectRank(i) == -1 ) continue; - - pos = pObj->RetPosition(i); - if ( pos.x != 0.0f || pos.y != 0.0f || pos.z != 0.0f ) - { - pos /= g_unit; - sprintf(name, " p%d=%.2f;%.2f;%.2f", i, pos.x, pos.y, pos.z); - strcat(line, name); - } - - pos = pObj->RetAngle(i); - if ( pos.x != 0.0f || pos.y != 0.0f || pos.z != 0.0f ) - { - pos /= (PI/180.0f); - sprintf(name, " a%d=%.2f;%.2f;%.2f", i, pos.x, pos.y, pos.z); - strcat(line, name); - } - - pos = pObj->RetZoom(i); - if ( pos.x != 1.0f || pos.y != 1.0f || pos.z != 1.0f ) - { - sprintf(name, " z%d=%.2f;%.2f;%.2f", i, pos.x, pos.y, pos.z); - strcat(line, name); - } - } - - sprintf(name, " trainer=%d", pObj->RetTrainer()); - strcat(line, name); - - sprintf(name, " option=%d", pObj->RetOption()); - strcat(line, name); - - if ( pObj == m_infoObject ) // selects object? - { - sprintf(name, " select=1"); - strcat(line, name); - } - - pObj->Write(line); - - if ( pObj->RetType() == OBJECT_BASE ) - { - sprintf(name, " run=3"); // stops and open (PARAM_FIXSCENE) - strcat(line, name); - } - - pBrain = pObj->RetBrain(); - if ( pBrain != 0 ) - { - run = pBrain->RetProgram(); - if ( run != -1 ) - { - sprintf(name, " run=%d", run+1); - strcat(line, name); - } - } - - strcat(line, "\n"); - fputs(line, file); -} - -// Saves the current game. - -BOOL CRobotMain::IOWriteScene(char *filename, char *filecbot, char *info) -{ - FILE* file; - char line[500]; - char* name; - CObject *pObj, *pPower, *pFret; - float sleep, delay, magnetic, progress; - int i, objRank; - long version; - - file = fopen(filename, "w"); - if ( file == NULL ) return FALSE; - - sprintf(line, "Title text=\"%s\"\n", info); - fputs(line, file); - - sprintf(line, "Version maj=%d min=%d\n", 0, 1); - fputs(line, file); - - name = m_dialog->RetSceneName(); - if ( strcmp(name, "user") == 0 ) - { - sprintf(line, "Mission base=\"%s\" rank=%.3d dir=\"%s\"\n", name, m_dialog->RetSceneRank(), m_dialog->RetSceneDir()); - } - else - { - sprintf(line, "Mission base=\"%s\" rank=%.3d\n", name, m_dialog->RetSceneRank()); - } - fputs(line, file); - - sprintf(line, "Map zoom=%.2f\n", m_map->RetZoomMap()); - fputs(line, file); - - sprintf(line, "DoneResearch bits=%d\n", g_researchDone); - fputs(line, file); - - if ( m_blitz->GetStatus(sleep, delay, magnetic, progress) ) - { - sprintf(line, "BlitzMode sleep=%.2f delay=%.2f magnetic=%.2f progress=%.2f\n", sleep, delay, magnetic/g_unit, progress); - fputs(line, file); - } - - objRank = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj->RetType() == OBJECT_TOTO ) continue; - if ( pObj->RetType() == OBJECT_FIX ) continue; - if ( pObj->RetTruck() != 0 ) continue; - if ( pObj->RetBurn() ) continue; - if ( pObj->RetDead() ) continue; - if ( pObj->RetExplo() ) continue; - - pPower = pObj->RetPower(); - pFret = pObj->RetFret(); - - if ( pFret != 0 ) // object transported? - { - IOWriteObject(file, pFret, "CreateFret"); - } - - if ( pPower != 0 ) // battery transported? - { - IOWriteObject(file, pPower, "CreatePower"); - } - - IOWriteObject(file, pObj, "CreateObject"); - - SaveFileScript(pObj, filename, objRank++); - } - fclose(file); - -#if CBOT_STACK - // Writes the file of stacks of execution. - file = fOpen(filecbot, "wb"); - if ( file == NULL ) return FALSE; - - version = 1; - fWrite(&version, sizeof(long), 1, file); // version of COLOBOT - version = CBotProgram::GivVersion(); - fWrite(&version, sizeof(long), 1, file); // version of CBOT - - objRank = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj->RetType() == OBJECT_TOTO ) continue; - if ( pObj->RetType() == OBJECT_FIX ) continue; - if ( pObj->RetTruck() != 0 ) continue; - if ( pObj->RetBurn() ) continue; - if ( pObj->RetDead() ) continue; - - if ( !SaveFileStack(pObj, file, objRank++) ) break; - } - CBotClass::SaveStaticState(file); - fClose(file); -#endif - - m_delayWriteMessage = 4; // displays message in 3 frames - return TRUE; -} - -// Resumes the game. - -CObject* CRobotMain::IOReadObject(char *line, char* filename, int objRank) -{ - CObject* pObj; -//? CBrain* pBrain; - CAuto* pAuto; - D3DVECTOR pos, dir, zoom; - ObjectType type; - int id, run, trainer, toy, option, i; - char op[10]; - - pos = OpDir(line, "pos")*g_unit; - dir = OpDir(line, "angle")*(PI/180.0f); - zoom = OpDir(line, "zoom"); - type = OpTypeObject(line, "type", OBJECT_NULL); - id = OpInt(line, "id", 0); - if ( type == OBJECT_NULL ) return 0; - trainer = OpInt(line, "trainer", 0); - toy = OpInt(line, "toy", 0); - option = OpInt(line, "option", 0); - pObj = CreateObject(pos, dir.y, 1.0f, 0.0f, type, 0.0f, trainer, toy, option); - pObj->SetDefRank(objRank); - pObj->SetPosition(0, pos); - pObj->SetAngle(0, dir); - pObj->SetID(id); - if ( g_id < id ) g_id = id; - - if ( zoom.x != 0.0f || zoom.y != 0.0f || zoom.z != 0.0f ) - { - pObj->SetZoom(0, zoom); - } - - for ( i=1 ; iRetObjectRank(i) == -1 ) continue; - - sprintf(op, "p%d", i); - pos = OpDir(line, op); - if ( pos.x != 0.0f || pos.y != 0.0f || pos.z != 0.0f ) - { - pObj->SetPosition(i, pos*g_unit); - } - - sprintf(op, "a%d", i); - dir = OpDir(line, op); - if ( dir.x != 0.0f || dir.y != 0.0f || dir.z != 0.0f ) - { - pObj->SetAngle(i, dir*(PI/180.0f)); - } - - sprintf(op, "z%d", i); - zoom = OpDir(line, op); - if ( zoom.x != 0.0f || zoom.y != 0.0f || zoom.z != 0.0f ) - { - pObj->SetZoom(i, zoom); - } - } - - if ( type == OBJECT_BASE ) m_bBase = TRUE; - - pObj->Read(line); - -#if CBOT_STACK -#else - LoadFileScript(pObj, filename, objRank, i); -#endif - - run = OpInt(line, "run", -1); - if ( run != -1 ) - { -#if CBOT_STACK -#else - pBrain = pObj->RetBrain(); - if ( pBrain != 0 ) - { - pBrain->RunProgram(run-1); // starts the program - } -#endif - - pAuto = pObj->RetAuto(); - if ( pAuto != 0 ) - { - pAuto->Start(run); // starts the film - } - } - - return pObj; -} - -// Resumes some part of the game. - -CObject* CRobotMain::IOReadScene(char *filename, char *filecbot) -{ - FILE* file; - CObject *pObj, *pPower, *pFret, *pSel; - char line[3000]; - float sleep, delay, progress, magnetic; - int i, objRank, nbError, lastError; - long version; - - m_bBase = FALSE; - - file = fopen(filename, "r"); - if ( file == NULL ) return 0; - - pFret = 0; - pPower = 0; - pSel = 0; - objRank = 0; - while ( fgets(line, 3000, file) != NULL ) - { - for ( i=0 ; i<3000 ; i++ ) - { - if ( line[i] == '\t' ) line[i] = ' '; // replace tab by space - if ( line[i] == '/' && line[i+1] == '/' ) - { - line[i] = 0; - break; - } - } - - if ( Cmd(line, "Map") ) - { - m_map->ZoomMap(OpFloat(line, "zoom", 1.0f)); - } - - if ( Cmd(line, "DoneResearch") ) - { - g_researchDone = OpInt(line, "bits", 0); - } - - if ( Cmd(line, "BlitzMode") ) - { - sleep = OpFloat(line, "sleep", 0.0f); - delay = OpFloat(line, "delay", 3.0f); - magnetic = OpFloat(line, "magnetic", 50.0f)*g_unit; - progress = OpFloat(line, "progress", 0.0f); - m_blitz->SetStatus(sleep, delay, magnetic, progress); - } - - if ( Cmd(line, "CreateFret") ) - { - pFret = IOReadObject(line, filename, -1); - } - - if ( Cmd(line, "CreatePower") ) - { - pPower = IOReadObject(line, filename, -1); - } - - if ( Cmd(line, "CreateObject") ) - { - pObj = IOReadObject(line, filename, objRank++); - - if ( OpInt(line, "select", 0) ) - { - pSel = pObj; - } - - if ( pFret != 0 ) - { - CTaskManip* task; - - pObj->SetFret(pFret); - task = new CTaskManip(m_iMan, pObj); - task->Start(TMO_AUTO, TMA_GRAB); // holds the object! - delete task; - } - - if ( pPower != 0 ) - { - pObj->SetPower(pPower); - pPower->SetTruck(pObj); - } - - pFret = 0; - pPower = 0; - } - } - fclose(file); - -#if CBOT_STACK - // Compiles scripts. - nbError = 0; - do - { - lastError = nbError; - nbError = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - if ( pObj->RetTruck() != 0 ) continue; - - objRank = pObj->RetDefRank(); - if ( objRank == -1 ) continue; - - LoadFileScript(pObj, filename, objRank, nbError); - } - } - while ( nbError > 0 && nbError != lastError ); - - // Reads the file of stacks of execution. - file = fOpen(filecbot, "rb"); - if ( file != NULL ) - { - fRead(&version, sizeof(long), 1, file); // version of COLOBOT - if ( version == 1 ) - { - fRead(&version, sizeof(long), 1, file); // version of CBOT - if ( version == CBotProgram::GivVersion() ) - { - objRank = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj->RetType() == OBJECT_TOTO ) continue; - if ( pObj->RetType() == OBJECT_FIX ) continue; - if ( pObj->RetTruck() != 0 ) continue; - if ( pObj->RetBurn() ) continue; - if ( pObj->RetDead() ) continue; - - if ( !ReadFileStack(pObj, file, objRank++) ) break; - } - } - } - CBotClass::RestoreStaticState(file); - fClose(file); - } -#endif - - return pSel; -} - - -// Writes the global parameters for free play. - -void CRobotMain::WriteFreeParam() -{ - FILE* file; - char filename[_MAX_FNAME]; - char line[100]; - - m_freeResearch |= g_researchDone; - m_freeBuild |= g_build; - - if ( m_gamerName[0] == 0 ) return; - - sprintf(filename, "%s\\%s\\research.gam", RetSavegameDir(), m_gamerName); - file = fopen(filename, "w"); - if ( file == NULL ) return; - - sprintf(line, "research=%d build=%d\n", m_freeResearch, m_freeBuild); - fputs(line, file); - fclose(file); -} - -// Reads the global parameters for free play. - -void CRobotMain::ReadFreeParam() -{ - FILE* file; - char filename[_MAX_FNAME]; - char line[100]; - - m_freeResearch = 0; - m_freeBuild = 0; - - if ( m_gamerName[0] == 0 ) return; - - sprintf(filename, "%s\\%s\\research.gam", RetSavegameDir(), m_gamerName); - file = fopen(filename, "r"); - if ( file == NULL ) return; - - if ( fgets(line, 100, file) != NULL ) - { - sscanf(line, "research=%d build=%d\n", &m_freeResearch, &m_freeBuild); - } - - fclose(file); -} - - -// Resets all objects to their original position. - -void CRobotMain::ResetObject() -{ -#if 0 - CObject* pObj; - CObject* pTruck; - CAuto* pAuto; - CBrain* brain; - CPyro* pyro; - ResetCap cap; - D3DVECTOR pos, angle; - int i; - - // Removes all pyrotechnic effects in progress. - while ( TRUE ) - { - pyro = (CPyro*)m_iMan->SearchInstance(CLASS_PYRO, 0); - if ( pyro == 0 ) break; - - pyro->DeleteObject(); - delete pyro; - } - - // Removes all bullets in progress. - m_particule->DeleteParticule(PARTIGUN1); - m_particule->DeleteParticule(PARTIGUN2); - m_particule->DeleteParticule(PARTIGUN3); - m_particule->DeleteParticule(PARTIGUN4); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - cap = pObj->RetResetCap(); - if ( cap == RESET_NONE ) continue; - - if ( cap == RESET_DELETE ) - { - pTruck = pObj->RetTruck(); - if ( pTruck != 0 ) - { - pTruck->SetFret(0); - pObj->SetTruck(0); - } - pObj->DeleteObject(); - delete pObj; - i --; - continue; - } - - pAuto = pObj->RetAuto(); - if ( pAuto != 0 ) - { - pAuto->Abort(); - } - - if ( pObj->RetEnable() ) // object still active? - { - brain = pObj->RetBrain(); - if ( brain != 0 ) - { - pos = pObj->RetResetPosition(); - angle = pObj->RetResetAngle(); - - if ( pos == pObj->RetPosition(0) && - angle == pObj->RetAngle(0) ) continue; - brain->StartTaskReset(pos, angle); - continue; - } - } - - pObj->SetEnable(TRUE); // active again - - pos = pObj->RetResetPosition(); - angle = pObj->RetResetAngle(); - - if ( pos == pObj->RetPosition(0) && - angle == pObj->RetAngle(0) ) continue; - - pyro = new CPyro(m_iMan); - pyro->Create(PT_RESET, pObj); - - brain = pObj->RetBrain(); - if ( brain != 0 ) - { - brain->RunProgram(pObj->RetResetRun()); - } - } -#else - m_bResetCreate = TRUE; -#endif -} - -// Resets all objects to their original position. - -void CRobotMain::ResetCreate() -{ - CObject* pObj; - CPyro* pyro; - ResetCap cap; - int i; - - SaveAllScript(); - - // Removes all bullets in progress. - m_particule->DeleteParticule(PARTIGUN1); - m_particule->DeleteParticule(PARTIGUN2); - m_particule->DeleteParticule(PARTIGUN3); - m_particule->DeleteParticule(PARTIGUN4); - - DeselectAll(); // removes the control buttons - DeleteAllObjects(); // removes all the current 3D Scene - - m_particule->FlushParticule(); - m_terrain->FlushBuildingLevel(); - m_iMan->Flush(CLASS_OBJECT); - m_iMan->Flush(CLASS_PHYSICS); - m_iMan->Flush(CLASS_BRAIN); - m_iMan->Flush(CLASS_PYRO); - m_camera->SetType(CAMERA_DIALOG); - - CreateScene(m_dialog->RetSceneSoluce(), FALSE, TRUE); - - if ( !RetNiceReset() ) return; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - cap = pObj->RetResetCap(); - if ( cap == RESET_NONE ) continue; - - pyro = new CPyro(m_iMan); - pyro->Create(PT_RESET, pObj); - } -} - -// Checks if the mission is over. - -Error CRobotMain::CheckEndMission(BOOL bFrame) -{ - CObject* pObj; - D3DVECTOR bPos, oPos; - ObjectType type; - int t, i, nb; - - for ( t=0 ; tSearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - // Do not use RetActif () because an invisible worm (underground) - // should be regarded as existing here! - if ( pObj->RetLock() ) continue; - if ( pObj->RetRuin() ) continue; - if ( !pObj->RetEnable() ) continue; - - type = pObj->RetType(); - if ( type == OBJECT_SCRAP2 || - type == OBJECT_SCRAP3 || - type == OBJECT_SCRAP4 || - type == OBJECT_SCRAP5 ) // wastes? - { - type = OBJECT_SCRAP1; - } - if ( type != m_endTake[t].type ) continue; - - if ( pObj->RetTruck() == 0 ) - { - oPos = pObj->RetPosition(0); - } - else - { - oPos = pObj->RetTruck()->RetPosition(0); - } - oPos.y = 0.0f; - if ( Length2d(oPos, bPos) <= m_endTake[t].dist ) - { - nb ++; - } - } - - if ( nb <= m_endTake[t].lost ) - { - if ( m_endTake[t].type == OBJECT_HUMAN ) - { - if ( m_lostDelay == 0.0f ) - { - m_lostDelay = 0.1f; // lost immediately - m_winDelay = 0.0f; - } - m_displayText->SetEnable(FALSE); - return INFO_LOSTq; - } - else - { - if ( m_lostDelay == 0.0f ) - { - m_displayText->DisplayError(INFO_LOST, D3DVECTOR(0.0f,0.0f,0.0f)); - m_lostDelay = m_endTakeLostDelay; // lost in 6 seconds - m_winDelay = 0.0f; - } - m_displayText->SetEnable(FALSE); - return INFO_LOST; - } - } - if ( nb < m_endTake[t].min || - nb > m_endTake[t].max ) - { - m_displayText->SetEnable(TRUE); - return ERR_MISSION_NOTERM; - } - if ( m_endTake[t].bImmediat ) - { - if ( m_winDelay == 0.0f ) - { - m_winDelay = m_endTakeWinDelay; // wins in x seconds - m_lostDelay = 0.0f; - } - m_displayText->SetEnable(FALSE); - return ERR_OK; // mission ended - } - } - - if ( m_endTakeResearch != 0 ) - { - if ( m_endTakeResearch != (m_endTakeResearch&g_researchDone) ) - { - m_displayText->SetEnable(TRUE); - return ERR_MISSION_NOTERM; - } - } - - if ( m_endTakeWinDelay == -1.0f ) - { - m_winDelay = 1.0f; // wins in one second - m_lostDelay = 0.0f; - m_displayText->SetEnable(FALSE); - return ERR_OK; // mission ended - } - - if ( bFrame && m_bBase ) return ERR_MISSION_NOTERM; - - if ( m_winDelay == 0.0f ) - { - m_displayText->DisplayError(INFO_WIN, D3DVECTOR(0.0f,0.0f,0.0f)); - m_winDelay = m_endTakeWinDelay; // wins in two seconds - m_lostDelay = 0.0f; - } - m_displayText->SetEnable(FALSE); - return ERR_OK; // mission ended -} - -// Checks if the mission is finished after displaying a message. - -void CRobotMain::CheckEndMessage(char *message) -{ - int t; - - for ( t=0 ; tDisplayError(INFO_WIN, D3DVECTOR(0.0f,0.0f,0.0f)); - m_winDelay = m_endTakeWinDelay; // wins in 2 seconds - m_lostDelay = 0.0f; - } - } -} - - -// Returns the number of instructions required. - -int CRobotMain::RetObligatoryToken() -{ - return m_obligatoryTotal; -} - -// Returns the name of a required instruction. - -char* CRobotMain::RetObligatoryToken(int i) -{ - return m_obligatoryToken[i]; -} - -// Checks if an instruction is part of the obligatory list. - -int CRobotMain::IsObligatoryToken(char *token) -{ - int i; - - for ( i=0 ; iRetGlint(); -} - -BOOL CRobotMain::RetSoluce4() -{ - return m_dialog->RetSoluce4(); -} - -BOOL CRobotMain::RetMovies() -{ - return m_dialog->RetMovies(); -} - -BOOL CRobotMain::RetNiceReset() -{ - return m_dialog->RetNiceReset(); -} - -BOOL CRobotMain::RetHimselfDamage() -{ - return m_dialog->RetHimselfDamage(); -} - -BOOL CRobotMain::RetShowSoluce() -{ - return m_bShowSoluce; -} - -BOOL CRobotMain::RetSceneSoluce() -{ - if ( m_infoFilename[SATCOM_SOLUCE][0] == 0 ) return FALSE; - return m_dialog->RetSceneSoluce(); -} - -BOOL CRobotMain::RetShowAll() -{ - return m_bShowAll; -} - -BOOL CRobotMain::RetCheatRadar() -{ - return m_bCheatRadar; -} - -char* CRobotMain::RetSavegameDir() -{ - return m_dialog->RetSavegameDir(); -} - -char* CRobotMain::RetPublicDir() -{ - return m_dialog->RetPublicDir(); -} - -char* CRobotMain::RetFilesDir() -{ - return m_dialog->RetFilesDir(); -} - - -// Change the player's name. - -void CRobotMain::SetGamerName(char *name) -{ - strcpy(m_gamerName, name); - SetGlobalGamerName(m_gamerName); - ReadFreeParam(); -} - -// Gives the player's name. - -char* CRobotMain::RetGamerName() -{ - return m_gamerName; -} - - -// Returns the representation to use for the player. - -int CRobotMain::RetGamerFace() -{ - return m_dialog->RetGamerFace(); -} - -// Returns the representation to use for the player. - -int CRobotMain::RetGamerGlasses() -{ - return m_dialog->RetGamerGlasses(); -} - -// Returns the mode with just the head. - -BOOL CRobotMain::RetGamerOnlyHead() -{ - return m_dialog->RetGamerOnlyHead(); -} - -// Returns the angle of presentation. - -float CRobotMain::RetPersoAngle() -{ - return m_dialog->RetPersoAngle(); -} - - -// Changes on the pause mode. - -void CRobotMain::ChangePause(BOOL bPause) -{ - m_bPause = bPause; - m_engine->SetPause(m_bPause); - - m_sound->MuteAll(m_bPause); - CreateShortcuts(); - if ( m_bPause ) HiliteClear(); -} - - -// Changes game speed - -void CRobotMain::SetSpeed(float speed) -{ - CButton* pb; - char text[10]; - - m_engine->SetSpeed(speed); - - pb = (CButton*)m_interface->SearchControl(EVENT_SPEED); - if ( pb != 0 ) - { - if ( speed == 1.0f ) - { - pb->ClearState(STATE_VISIBLE); - } - else - { - sprintf(text, "x%.1f", speed); - pb->SetName(text); - pb->SetState(STATE_VISIBLE); - } - } -} - -float CRobotMain::RetSpeed() -{ - return m_engine->RetSpeed(); -} - - -// Creates interface shortcuts to the units. - -BOOL CRobotMain::CreateShortcuts() -{ - if ( m_phase != PHASE_SIMUL ) return FALSE; - if ( !m_bShortCut ) return FALSE; - return m_short->CreateShortcuts(); -} - -// Updates the map. - -void CRobotMain::UpdateMap() -{ - m_map->UpdateMap(); -} - -// Indicates whether the mini-map is visible. - -BOOL CRobotMain::RetShowMap() -{ - return m_map->RetShowMap() && m_bMapShow; -} - - -// Management of the lock mode for movies. - -void CRobotMain::SetMovieLock(BOOL bLock) -{ - m_bMovieLock = bLock; - m_engine->SetMovieLock(m_bMovieLock); - - CreateShortcuts(); - m_map->ShowMap(!m_bMovieLock && m_bMapShow); - if ( m_bMovieLock ) HiliteClear(); - m_engine->SetMouseHide(m_bMovieLock); -} - -BOOL CRobotMain::RetMovieLock() -{ - return m_bMovieLock; -} - -BOOL CRobotMain::RetInfoLock() -{ - return ( m_displayInfo != 0 ); // info in progress? -} - -// Management of the blocking of the call of SatCom. - -void CRobotMain::SetSatComLock(BOOL bLock) -{ - m_bSatComLock = bLock; -} - -BOOL CRobotMain::RetSatComLock() -{ - return m_bSatComLock; -} - -// Management of the lock mode for the edition. - -void CRobotMain::SetEditLock(BOOL bLock, BOOL bEdit) -{ - m_bEditLock = bLock; - - CreateShortcuts(); - - // Do not remove the card if it contains a still image. - if ( !bLock || !m_map->RetFixImage() ) - { - m_map->ShowMap(!m_bEditLock && m_bMapShow); - } - - m_displayText->HideText(bLock); - m_engine->FlushPressKey(); - - if ( m_bEditLock ) - { - HiliteClear(); - } - else - { - m_bEditFull = FALSE; - } -} - -BOOL CRobotMain::RetEditLock() -{ - return m_bEditLock; -} - -// Management of the fullscreen mode during editing. - -void CRobotMain::SetEditFull(BOOL bFull) -{ - m_bEditFull = bFull; -} - -BOOL CRobotMain::RetEditFull() -{ - return m_bEditFull; -} - - -BOOL CRobotMain::RetFreePhoto() -{ - return m_bFreePhoto; -} - - -// Indicates whether mouse is on an friend object, on which we should not shoot. - -void CRobotMain::SetFriendAim(BOOL bFriend) -{ - m_bFriendAim = bFriend; -} - -BOOL CRobotMain::RetFriendAim() -{ - return m_bFriendAim; -} - - -// Management of the precision of drawing the ground. - -void CRobotMain::SetTracePrecision(float factor) -{ - m_engine->SetTracePrecision(factor); -} - -float CRobotMain::RetTracePrecision() -{ - return m_engine->RetTracePrecision(); -} - - -// Starts music with a mission. - -void CRobotMain::StartMusic() -{ - if ( m_audioTrack != 0 ) - { - m_sound->StopMusic(); - m_sound->PlayMusic(m_audioTrack, m_bAudioRepeat); - } -} - -// Removes hilite and tooltip. - -void CRobotMain::ClearInterface() -{ - HiliteClear(); // removes setting evidence - m_tooltipName[0] = 0; // really removes the tooltip -} - - diff --git a/src/robotmain.h b/src/robotmain.h deleted file mode 100644 index bafa62a..0000000 --- a/src/robotmain.h +++ /dev/null @@ -1,463 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// robotmain.h - -#ifndef _ROBOTMAIN_H_ -#define _ROBOTMAIN_H_ - - -#include "d3dengine.h" -#include "struct.h" -#include "object.h" -#include "mainmovie.h" -#include "camera.h" -#include "particule.h" - - -enum Phase -{ - PHASE_INIT, - PHASE_TERM, - PHASE_NAME, - PHASE_PERSO, - PHASE_TRAINER, - PHASE_DEFI, - PHASE_MISSION, - PHASE_FREE, - PHASE_TEEN, - PHASE_USER, - PHASE_PROTO, - PHASE_LOADING, - PHASE_SIMUL, - PHASE_MODEL, - PHASE_SETUPd, - PHASE_SETUPg, - PHASE_SETUPp, - PHASE_SETUPc, - PHASE_SETUPs, - PHASE_SETUPds, - PHASE_SETUPgs, - PHASE_SETUPps, - PHASE_SETUPcs, - PHASE_SETUPss, - PHASE_WRITE, - PHASE_READ, - PHASE_WRITEs, - PHASE_READs, - PHASE_WIN, - PHASE_LOST, - PHASE_WELCOME1, - PHASE_WELCOME2, - PHASE_WELCOME3, - PHASE_GENERIC, -}; - - -class CInstanceManager; -class CMainDialog; -class CMainShort; -class CMainMap; -class CEvent; -class CD3DEngine; -class CLight; -class CWater; -class CCloud; -class CBlitz; -class CPlanet; -class CTerrain; -class CModel; -class CInterface; -class CWindow; -class CControl; -class CDisplayText; -class CDisplayInfo; -class CSound; - - -typedef struct -{ - D3DVECTOR pos; - float dist; - ObjectType type; - int min; // wins if> - int max; // wins if < - int lost; // lost if <= - BOOL bImmediat; - char message[100]; -} -EndTake; - - -#define MAXNEWSCRIPTNAME 20 - -typedef struct -{ - BOOL bUsed; - ObjectType type; - char name[40]; -} -NewScriptName; - - -#define MAXSHOWLIMIT 5 -#define MAXSHOWPARTI 200 -#define SHOWLIMITTIME 20.0f - -typedef struct -{ - BOOL bUsed; - D3DVECTOR pos; - float radius; - int total; - int parti[MAXSHOWPARTI]; - CObject* link; - float duration; - float time; -} -ShowLimit; - - -#define SATCOM_HUSTON 0 -#define SATCOM_SAT 1 -#define SATCOM_OBJECT 2 -#define SATCOM_LOADING 3 -#define SATCOM_PROG 4 -#define SATCOM_SOLUCE 5 -#define SATCOM_MAX 6 - - - -class CRobotMain -{ -public: - CRobotMain(CInstanceManager* iMan); - ~CRobotMain(); - - void CreateIni(); - - void ChangePhase(Phase phase); - BOOL EventProcess(const Event &event); - - BOOL CreateShortcuts(); - void ScenePerso(); - - void SetMovieLock(BOOL bLock); - BOOL RetMovieLock(); - BOOL RetInfoLock(); - void SetSatComLock(BOOL bLock); - BOOL RetSatComLock(); - void SetEditLock(BOOL bLock, BOOL bEdit); - BOOL RetEditLock(); - void SetEditFull(BOOL bFull); - BOOL RetEditFull(); - BOOL RetFreePhoto(); - void SetFriendAim(BOOL bFriend); - BOOL RetFriendAim(); - - void SetTracePrecision(float factor); - float RetTracePrecision(); - - void ChangePause(BOOL bPause); - - void SetSpeed(float speed); - float RetSpeed(); - - void UpdateShortcuts(); - void SelectHuman(); - CObject* SearchHuman(); - CObject* SearchToto(); - CObject* SearchNearest(D3DVECTOR pos, CObject* pExclu); - BOOL SelectObject(CObject* pObj, BOOL bDisplayError=TRUE); - CObject* RetSelectObject(); - CObject* DeselectAll(); - BOOL DeleteObject(); - - void ResetObject(); - void ResetCreate(); - Error CheckEndMission(BOOL bFrame); - void CheckEndMessage(char *message); - int RetObligatoryToken(); - char* RetObligatoryToken(int i); - int IsObligatoryToken(char *token); - BOOL IsProhibitedToken(char *token); - void UpdateMap(); - BOOL RetShowMap(); - - MainMovieType RetMainMovie(); - - void FlushDisplayInfo(); - void StartDisplayInfo(int index, BOOL bMovie); - void StartDisplayInfo(char *filename, int index); - void StopDisplayInfo(); - char* RetDisplayInfoName(int index); - int RetDisplayInfoPosition(int index); - void SetDisplayInfoPosition(int index, int pos); - - void StartSuspend(); - void StopSuspend(); - - float RetGameTime(); - - void SetFontSize(float size); - float RetFontSize(); - void SetWindowPos(FPOINT pos); - FPOINT RetWindowPos(); - void SetWindowDim(FPOINT dim); - FPOINT RetWindowDim(); - - void SetIOPublic(BOOL bMode); - BOOL RetIOPublic(); - void SetIOPos(FPOINT pos); - FPOINT RetIOPos(); - void SetIODim(FPOINT dim); - FPOINT RetIODim(); - - char* RetTitle(); - char* RetResume(); - char* RetScriptName(); - char* RetScriptFile(); - BOOL RetTrainerPilot(); - BOOL RetFixScene(); - BOOL RetGlint(); - BOOL RetSoluce4(); - BOOL RetMovies(); - BOOL RetNiceReset(); - BOOL RetHimselfDamage(); - BOOL RetShowSoluce(); - BOOL RetSceneSoluce(); - BOOL RetShowAll(); - BOOL RetCheatRadar(); - char* RetSavegameDir(); - char* RetPublicDir(); - char* RetFilesDir(); - - void SetGamerName(char *name); - char* RetGamerName(); - int RetGamerFace(); - int RetGamerGlasses(); - BOOL RetGamerOnlyHead(); - float RetPersoAngle(); - - void StartMusic(); - void ClearInterface(); - void ChangeColor(); - - float SearchNearestObject(D3DVECTOR center, CObject *exclu); - BOOL FreeSpace(D3DVECTOR ¢er, float minRadius, float maxRadius, float space, CObject *exclu); - float RetFlatZoneRadius(D3DVECTOR center, float maxRadius, CObject *exclu); - void HideDropZone(CObject* metal); - void ShowDropZone(CObject* metal, CObject* truck); - void FlushShowLimit(int i); - void SetShowLimit(int i, ParticuleType parti, CObject *pObj, D3DVECTOR pos, float radius, float duration=SHOWLIMITTIME); - void AdjustShowLimit(int i, D3DVECTOR pos); - void StartShowLimit(); - void FrameShowLimit(float rTime); - - void CompileScript(BOOL bSoluce); - void LoadOneScript(CObject *pObj, int &nbError); - void LoadFileScript(CObject *pObj, char* filename, int objRank, int &nbError); - void SaveAllScript(); - void SaveOneScript(CObject *pObj); - void SaveFileScript(CObject *pObj, char* filename, int objRank); - BOOL SaveFileStack(CObject *pObj, FILE *file, int objRank); - BOOL ReadFileStack(CObject *pObj, FILE *file, int objRank); - - BOOL FlushNewScriptName(); - BOOL AddNewScriptName(ObjectType type, char *name); - char* RetNewScriptName(ObjectType type, int rank); - - void WriteFreeParam(); - void ReadFreeParam(); - - BOOL IsBusy(); - BOOL IOWriteScene(char *filename, char *filecbot, char *info); - CObject* IOReadScene(char *filename, char *filecbot); - void IOWriteObject(FILE *file, CObject* pObj, char *cmd); - CObject* IOReadObject(char *line, char* filename, int objRank); - - int CreateSpot(D3DVECTOR pos, D3DCOLORVALUE color); - -protected: - BOOL EventFrame(const Event &event); - BOOL EventObject(const Event &event); - void InitEye(); - - void Convert(); - void CreateScene(BOOL bSoluce, BOOL bFixScene, BOOL bResetObject); - - void CreateModel(); - D3DVECTOR LookatPoint( D3DVECTOR eye, float angleH, float angleV, float length ); - CObject* CreateObject(D3DVECTOR pos, float angle, float zoom, float height, ObjectType type, float power=1.0f, BOOL bTrainer=FALSE, BOOL bToy=FALSE, int option=0); - int CreateLight(D3DVECTOR direction, D3DCOLORVALUE color); - void HiliteClear(); - void HiliteObject(FPOINT pos); - void HiliteFrame(float rTime); - void CreateTooltip(FPOINT pos, char* text); - void ClearTooltip(); - CObject* DetectObject(FPOINT pos); - void ChangeCamera(); - void RemoteCamera(float pan, float zoom, float rTime); - void KeyCamera(EventMsg event, long param); - void AbortMovie(); - BOOL IsSelectable(CObject* pObj); - void SelectOneObject(CObject* pObj, BOOL bDisplayError=TRUE); - void HelpObject(); - BOOL DeselectObject(); - void DeleteAllObjects(); - void UpdateInfoText(); - CObject* SearchObject(ObjectType type); - CObject* RetSelect(); - void StartDisplayVisit(EventMsg event); - void FrameVisit(float rTime); - void StopDisplayVisit(); - void ExecuteCmd(char *cmd); - BOOL TestGadgetQuantity(int rank); - -protected: - CInstanceManager* m_iMan; - CMainMovie* m_movie; - CMainDialog* m_dialog; - CMainShort* m_short; - CMainMap* m_map; - CEvent* m_event; - CD3DEngine* m_engine; - CParticule* m_particule; - CWater* m_water; - CCloud* m_cloud; - CBlitz* m_blitz; - CPlanet* m_planet; - CLight* m_light; - CTerrain* m_terrain; - CModel* m_model; - CInterface* m_interface; - CCamera* m_camera; - CDisplayText* m_displayText; - CDisplayInfo* m_displayInfo; - CSound* m_sound; - - float m_time; - float m_gameTime; - float m_checkEndTime; - float m_winDelay; - float m_lostDelay; - BOOL m_bFixScene; // scene fixed, no interraction - BOOL m_bBase; // OBJECT_BASE exists in mission - FPOINT m_lastMousePos; - CObject* m_selectObject; - - Phase m_phase; - int m_cameraRank; - D3DCOLORVALUE m_color; - BOOL m_bFreePhoto; - BOOL m_bCmdEdit; - BOOL m_bShowPos; - BOOL m_bSelectInsect; - BOOL m_bShowSoluce; - BOOL m_bShowAll; - BOOL m_bCheatRadar; - BOOL m_bAudioRepeat; - BOOL m_bShortCut; - int m_audioTrack; - int m_delayWriteMessage; - int m_movieInfoIndex; - - BOOL m_bImmediatSatCom; // SatCom immediately? - BOOL m_bBeginSatCom; // messages SatCom poster? - BOOL m_bMovieLock; // movie in progress? - BOOL m_bSatComLock; // call of SatCom is possible? - BOOL m_bEditLock; // edition in progress? - BOOL m_bEditFull; // edition in full screen? - BOOL m_bPause; // simulation paused - BOOL m_bHilite; - BOOL m_bTrainerPilot; // remote trainer? - BOOL m_bSuspend; - BOOL m_bFriendAim; - BOOL m_bResetCreate; - BOOL m_bMapShow; - BOOL m_bMapImage; - char m_mapFilename[100]; - - FPOINT m_tooltipPos; - char m_tooltipName[100]; - float m_tooltipTime; - - char m_infoFilename[SATCOM_MAX][100]; // names of text files - CObject* m_infoObject; - int m_infoIndex; - int m_infoPos[SATCOM_MAX]; - int m_infoUsed; - - char m_title[100]; - char m_resume[500]; - char m_scriptName[100]; - char m_scriptFile[100]; - int m_endingWinRank; - int m_endingLostRank; - BOOL m_bWinTerminate; - - float m_fontSize; - FPOINT m_windowPos; - FPOINT m_windowDim; - - BOOL m_IOPublic; - FPOINT m_IOPos; - FPOINT m_IODim; - - NewScriptName m_newScriptName[MAXNEWSCRIPTNAME]; - - float m_cameraPan; - float m_cameraZoom; - - EventMsg m_visitLast; - CObject* m_visitObject; - CObject* m_visitArrow; - float m_visitTime; - float m_visitParticule; - D3DVECTOR m_visitPos; - D3DVECTOR m_visitPosArrow; - - int m_endTakeTotal; - EndTake m_endTake[10]; - long m_endTakeResearch; - float m_endTakeWinDelay; - float m_endTakeLostDelay; - - int m_obligatoryTotal; - char m_obligatoryToken[100][20]; - int m_prohibitedTotal; - char m_prohibitedToken[100][20]; - - char m_gamerName[100]; - - long m_freeBuild; // constructible buildings - long m_freeResearch; // researches possible - - ShowLimit m_showLimit[MAXSHOWLIMIT]; - - D3DCOLORVALUE m_colorRefBot; - D3DCOLORVALUE m_colorNewBot; - D3DCOLORVALUE m_colorRefAlien; - D3DCOLORVALUE m_colorNewAlien; - D3DCOLORVALUE m_colorRefGreen; - D3DCOLORVALUE m_colorNewGreen; - D3DCOLORVALUE m_colorRefWater; - D3DCOLORVALUE m_colorNewWater; - float m_colorShiftWater; -}; - - -#endif //_ROBOTMAIN_H_ diff --git a/src/script.cpp b/src/script.cpp deleted file mode 100644 index 62b2d25..0000000 --- a/src/script.cpp +++ /dev/null @@ -1,3777 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// script.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "CBot/CBotDll.h" -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "global.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "restext.h" -#include "math3d.h" -#include "robotmain.h" -#include "terrain.h" -#include "water.h" -#include "object.h" -#include "physics.h" -#include "interface.h" -#include "edit.h" -#include "list.h" -#include "text.h" -#include "displaytext.h" -#include "taskmanager.h" -#include "task.h" -#include "taskmanip.h" -#include "taskgoto.h" -#include "taskshield.h" -#include "cbottoken.h" -#include "script.h" - - - -#define CBOT_IPF 100 // CBOT: number of instructions / frame - -#define ERM_CONT 0 // if error -> continue -#define ERM_STOP 1 // if error -> stop - - - - -// Compiling a procedure without any parameters. - -CBotTypResult cNull(CBotVar* &var, void* user) -{ - if ( var != 0 ) return CBotErrOverParam; - return CBotTypResult(CBotTypFloat); -} - -// Compiling a procedure with a single real number. - -CBotTypResult cOneFloat(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Compiling a procedure with two real numbers. - -CBotTypResult cTwoFloat(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Compiling a procedure with a "dot". - -CBotTypResult cPoint(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - - if ( var->GivType() <= CBotTypDouble ) - { - var = var->GivNext(); - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); -//? if ( var == 0 ) return CBotTypResult(CBotErrLowParam); -//? if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); -//? var = var->GivNext(); - return CBotTypResult(0); - } - - if ( var->GivType() == CBotTypClass ) - { - if ( !var->IsElemOfClass("point") ) return CBotTypResult(CBotErrBadParam); - var = var->GivNext(); - return CBotTypResult(0); - } - - return CBotTypResult(CBotErrBadParam); -} - -// Compiling a procedure with a single "point". - -CBotTypResult cOnePoint(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Compiling a procedure with a single string. - -CBotTypResult cString(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() != CBotTypString && - var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - - -// Seeking value in an array of integers. - -BOOL FindList(CBotVar* array, int type) -{ - while ( array != 0 ) - { - if ( type == array->GivValInt() ) return TRUE; - array = array->GivNext(); - } - return FALSE; -} - - -// Gives a parameter of type "point". - -BOOL GetPoint(CBotVar* &var, int& exception, D3DVECTOR& pos) -{ - CBotVar *pX, *pY, *pZ; - - if ( var->GivType() <= CBotTypDouble ) - { - pos.x = var->GivValFloat()*g_unit; - var = var->GivNext(); - - pos.z = var->GivValFloat()*g_unit; - var = var->GivNext(); - - pos.y = 0.0f; - } - else - { - pX = var->GivItem("x"); - if ( pX == NULL ) - { - exception = CBotErrUndefItem; return TRUE; - } - pos.x = pX->GivValFloat()*g_unit; - - pY = var->GivItem("y"); - if ( pY == NULL ) - { - exception = CBotErrUndefItem; return TRUE; - } - pos.z = pY->GivValFloat()*g_unit; // attention y -> z ! - - pZ = var->GivItem("z"); - if ( pZ == NULL ) - { - exception = CBotErrUndefItem; return TRUE; - } - pos.y = pZ->GivValFloat()*g_unit; // attention z -> y ! - - var = var->GivNext(); - } - return TRUE; -} - - -// Instruction "sin(degrees)". - -BOOL rSin(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GivValFloat(); - result->SetValFloat(sinf(value*PI/180.0f)); - return TRUE; -} - -// Instruction "cos(degrees)". - -BOOL rCos(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GivValFloat(); - result->SetValFloat(cosf(value*PI/180.0f)); - return TRUE; -} - -// Instruction "tan(degrees)". - -BOOL rTan(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GivValFloat(); - result->SetValFloat(tanf(value*PI/180.0f)); - return TRUE; -} - -// Instruction "asin(degrees)". - -BOOL raSin(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GivValFloat(); - result->SetValFloat(asinf(value)*180.0f/PI); - return TRUE; -} - -// Instruction "acos(degrees)". - -BOOL raCos(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GivValFloat(); - result->SetValFloat(acosf(value)*180.0f/PI); - return TRUE; -} - -// Instruction "atan(degrees)". - -BOOL raTan(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GivValFloat(); - result->SetValFloat(atanf(value)*180.0f/PI); - return TRUE; -} - -// Instruction "sqrt(value)". - -BOOL rSqrt(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GivValFloat(); - result->SetValFloat(sqrtf(value)); - return TRUE; -} - -// Instruction "pow(x, y)". - -BOOL rPow(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float x, y; - - x = var->GivValFloat(); - var = var->GivNext(); - y = var->GivValFloat(); - result->SetValFloat(powf(x, y)); - return TRUE; -} - -// Instruction "rand()". - -BOOL rRand(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - result->SetValFloat(Rand()); - return TRUE; -} - -// Instruction "abs()". - -BOOL rAbs(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GivValFloat(); - result->SetValFloat(Abs(value)); - return TRUE; -} - - -// Compilation of the instruction "retobject(rank)". - -CBotTypResult cRetObject(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypPointer, "object"); -} - -// Instruction "retobject(rank)". - -BOOL rRetObject(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pObj; - int rank; - - rank = var->GivValInt(); - - pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, rank); - if ( pObj == 0 ) - { - result->SetPointer(0); - } - else - { - result->SetPointer(pObj->RetBotVar()); - } - return TRUE; -} - - -// Compilation of the instruction "search(type, pos)". - -CBotTypResult cSearch(CBotVar* &var, void* user) -{ - CBotVar* array; - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() == CBotTypArrayPointer ) - { - array = var->GivItemList(); - if ( array == 0 ) return CBotTypResult(CBotTypPointer); - if ( array->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - } - else if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - if ( var != 0 ) - { - ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - } - - return CBotTypResult(CBotTypPointer, "object"); -} - -// Instruction "search(type, pos)". - -BOOL rSearch(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject *pObj, *pBest; - CBotVar* array; - D3DVECTOR pos, oPos; - BOOL bNearest = FALSE; - BOOL bArray; - float min, dist; - int type, oType, i; - - if ( var->GivType() == CBotTypArrayPointer ) - { - array = var->GivItemList(); - bArray = TRUE; - } - else - { - type = var->GivValInt(); - bArray = FALSE; - } - var = var->GivNext(); - if ( var != 0 ) - { - if ( !GetPoint(var, exception, pos) ) return TRUE; - bNearest = TRUE; - } - - min = 100000.0f; - pBest = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( !pObj->RetActif() ) continue; - - oType = pObj->RetType(); - if ( oType == OBJECT_TOTO ) continue; - - if ( oType == OBJECT_RUINmobilew2 || - oType == OBJECT_RUINmobilet1 || - oType == OBJECT_RUINmobilet2 || - oType == OBJECT_RUINmobiler1 || - oType == OBJECT_RUINmobiler2 ) - { - oType = OBJECT_RUINmobilew1; // any ruin - } - - if ( oType == OBJECT_SCRAP2 || - oType == OBJECT_SCRAP3 || - oType == OBJECT_SCRAP4 || - oType == OBJECT_SCRAP5 ) // wastes? - { - oType = OBJECT_SCRAP1; // any waste - } - - if ( oType == OBJECT_BARRIER2 || - oType == OBJECT_BARRIER3 ) // barriers? - { - oType = OBJECT_BARRIER1; // any barrier - } - - if ( bArray ) - { - if ( !FindList(array, oType) ) continue; - } - else - { - if ( type != oType && type != OBJECT_NULL ) continue; - } - - if ( bNearest ) - { - oPos = pObj->RetPosition(0); - dist = Length2d(pos, oPos); - if ( dist < min ) - { - min = dist; - pBest = pObj; - } - } - else - { - pBest = pObj; - break; - } - } - - if ( pBest == 0 ) - { - result->SetPointer(0); - } - else - { - result->SetPointer(pBest->RetBotVar()); - } - return TRUE; -} - - -// Compilation of instruction "radar(type, angle, focus, min, max, sens)". - -CBotTypResult cRadar(CBotVar* &var, void* user) -{ - CBotVar* array; - - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GivType() == CBotTypArrayPointer ) - { - array = var->GivItemList(); - if ( array == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( array->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // type - } - else if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // type - var = var->GivNext(); - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // angle - var = var->GivNext(); - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // focus - var = var->GivNext(); - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // min - var = var->GivNext(); - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // max - var = var->GivNext(); - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // sense - var = var->GivNext(); - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // filter - var = var->GivNext(); - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - return CBotTypResult(CBotErrOverParam); -} - -// Instruction "radar(type, angle, focus, min, max, sens, filter)". - -BOOL rRadar(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - CObject *pObj, *pBest; - CPhysics* physics; - CBotVar* array; - D3DVECTOR iPos, oPos; - RadarFilter filter; - float best, minDist, maxDist, sens, iAngle, angle, focus, d, a; - int type, oType, i; - BOOL bArray; - - type = OBJECT_NULL; - angle = 0.0f; - focus = PI*2.0f; - minDist = 0.0f*g_unit; - maxDist = 1000.0f*g_unit; - sens = 1.0f; - filter = FILTER_NONE; - - if ( var != 0 ) - { - if ( var->GivType() == CBotTypArrayPointer ) - { - array = var->GivItemList(); - bArray = TRUE; - } - else - { - type = var->GivValInt(); - bArray = FALSE; - } - - var = var->GivNext(); - if ( var != 0 ) - { - angle = -var->GivValFloat()*PI/180.0f; - - var = var->GivNext(); - if ( var != 0 ) - { - focus = var->GivValFloat()*PI/180.0f; - - var = var->GivNext(); - if ( var != 0 ) - { - minDist = var->GivValFloat()*g_unit; - - var = var->GivNext(); - if ( var != 0 ) - { - maxDist = var->GivValFloat()*g_unit; - - var = var->GivNext(); - if ( var != 0 ) - { - sens = var->GivValFloat(); - - var = var->GivNext(); - if ( var != 0 ) - { - filter = (RadarFilter)var->GivValInt(); - } - } - } - } - } - } - } - - iPos = pThis->RetPosition(0); - iAngle = pThis->RetAngleY(0)+angle; - iAngle = NormAngle(iAngle); // 0..2*PI - - if ( sens >= 0.0f ) best = 100000.0f; - else best = 0.0f; - pBest = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - if ( pObj == pThis ) continue; - - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( !pObj->RetActif() ) continue; - if ( pObj->RetProxyActivate() ) continue; - - oType = pObj->RetType(); - if ( oType == OBJECT_TOTO ) continue; - - if ( oType == OBJECT_RUINmobilew2 || - oType == OBJECT_RUINmobilet1 || - oType == OBJECT_RUINmobilet2 || - oType == OBJECT_RUINmobiler1 || - oType == OBJECT_RUINmobiler2 ) - { - oType = OBJECT_RUINmobilew1; // any ruin - } - - if ( oType == OBJECT_SCRAP2 || - oType == OBJECT_SCRAP3 || - oType == OBJECT_SCRAP4 || - oType == OBJECT_SCRAP5 ) // wastes? - { - oType = OBJECT_SCRAP1; // any waste - } - - if ( oType == OBJECT_BARRIER2 || - oType == OBJECT_BARRIER3 ) // barriers? - { - oType = OBJECT_BARRIER1; // any barrier - } - - if ( filter == FILTER_ONLYLANDING ) - { - physics = pObj->RetPhysics(); - if ( physics != 0 && !physics->RetLand() ) continue; - } - if ( filter == FILTER_ONLYFLYING ) - { - physics = pObj->RetPhysics(); - if ( physics != 0 && physics->RetLand() ) continue; - } - - if ( bArray ) - { - if ( !FindList(array, oType) ) continue; - } - else - { - if ( type != oType && type != OBJECT_NULL ) continue; - } - - oPos = pObj->RetPosition(0); - d = Length2d(iPos, oPos); - if ( d < minDist || d > maxDist ) continue; // too close or too far? - - if ( focus >= PI*2.0f ) - { - if ( (sens >= 0.0f && d < best) || - (sens < 0.0f && d > best) ) - { - best = d; - pBest = pObj; - } - continue; - } - - a = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! - if ( TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) ) - { - if ( (sens >= 0.0f && d < best) || - (sens < 0.0f && d > best) ) - { - best = d; - pBest = pObj; - } - } - } - - if ( pBest == 0 ) - { - result->SetPointer(0); - } - else - { - result->SetPointer(pBest->RetBotVar()); - } - return TRUE; -} - - -// Monitoring a task. - -BOOL Process(CScript* script, CBotVar* result, int &exception) -{ - Error err; - - err = script->m_primaryTask->IsEnded(); - if ( err != ERR_CONTINUE ) // task terminated? - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - - script->m_bContinue = FALSE; - - if ( err == ERR_STOP ) err = ERR_OK; - result->SetValInt(err); // indicates the error or ok - if ( err != ERR_OK && script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; // it's all over - } - - script->m_primaryTask->EventProcess(script->m_event); - script->m_bContinue = TRUE; - return FALSE; // not done -} - - -// Compilation of the instruction "detect(type)". - -CBotTypResult cDetect(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypBoolean); -} - -// Instruction "detect(type)". - -BOOL rDetect(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - CObject *pObj, *pGoal, *pBest; - CPhysics* physics; - CBotVar* array; - D3DVECTOR iPos, oPos; - RadarFilter filter; - float bGoal, best, minDist, maxDist, sens, iAngle, angle, focus, d, a; - int type, oType, i; - BOOL bArray; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - type = OBJECT_NULL; - angle = 0.0f; - focus = 45.0f*PI/180.0f; - minDist = 0.0f*g_unit; - maxDist = 20.0f*g_unit; - sens = 1.0f; - filter = FILTER_NONE; - - if ( var != 0 ) - { - if ( var->GivType() == CBotTypArrayPointer ) - { - array = var->GivItemList(); - bArray = TRUE; - } - else - { - type = var->GivValInt(); - bArray = FALSE; - } - } - - iPos = pThis->RetPosition(0); - iAngle = pThis->RetAngleY(0)+angle; - iAngle = NormAngle(iAngle); // 0..2*PI - - bGoal = 100000.0f; - pGoal = 0; - if ( sens >= 0.0f ) best = 100000.0f; - else best = 0.0f; - pBest = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - if ( pObj == pThis ) continue; - - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( !pObj->RetActif() ) continue; - if ( pObj->RetProxyActivate() ) continue; - - oType = pObj->RetType(); - if ( oType == OBJECT_TOTO ) continue; - - if ( oType == OBJECT_RUINmobilew2 || - oType == OBJECT_RUINmobilet1 || - oType == OBJECT_RUINmobilet2 || - oType == OBJECT_RUINmobiler1 || - oType == OBJECT_RUINmobiler2 ) - { - oType = OBJECT_RUINmobilew1; // any ruin - } - - if ( oType == OBJECT_SCRAP2 || - oType == OBJECT_SCRAP3 || - oType == OBJECT_SCRAP4 || - oType == OBJECT_SCRAP5 ) // wastes? - { - oType = OBJECT_SCRAP1; // any waste - } - - if ( oType == OBJECT_BARRIER2 || - oType == OBJECT_BARRIER3 ) // barriers? - { - oType = OBJECT_BARRIER1; // any barrier - } - - if ( filter == FILTER_ONLYLANDING ) - { - physics = pObj->RetPhysics(); - if ( physics != 0 && !physics->RetLand() ) continue; - } - if ( filter == FILTER_ONLYFLYING ) - { - physics = pObj->RetPhysics(); - if ( physics != 0 && physics->RetLand() ) continue; - } - - if ( bArray ) - { - if ( !FindList(array, oType) ) continue; - } - else - { - if ( type != oType && type != OBJECT_NULL ) continue; - } - - oPos = pObj->RetPosition(0); - d = Length2d(iPos, oPos); - a = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! - - if ( d < bGoal && - TestAngle(a, iAngle-(5.0f*PI/180.0f)/2.0f, iAngle+(5.0f*PI/180.0f)/2.0f) ) - { - bGoal = d; - pGoal = pObj; - } - - if ( d < minDist || d > maxDist ) continue; // too close or too far? - - if ( focus >= PI*2.0f ) - { - if ( (sens >= 0.0f && d < best) || - (sens < 0.0f && d > best) ) - { - best = d; - pBest = pObj; - } - continue; - } - - if ( TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) ) - { - if ( (sens >= 0.0f && d < best) || - (sens < 0.0f && d > best) ) - { - best = d; - pBest = pObj; - } - } - } - - pThis->StartDetectEffect(pGoal, pBest!=0); - - if ( pBest == 0 ) - { - script->m_returnValue = 0.0f; - } - else - { - script->m_returnValue = 1.0f; - } - - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - err = script->m_primaryTask->StartTaskWait(0.3f); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; - } - } - if ( !Process(script, result, exception) ) return FALSE; // not finished - result->SetValFloat(script->m_returnValue); - return TRUE; -} - - -// Compilation of the instruction "direction(pos)". - -CBotTypResult cDirection(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypFloat); -} - -// Instruction "direction(pos)". - -BOOL rDirection(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - D3DVECTOR iPos, oPos; - float a, g; - - if ( !GetPoint(var, exception, oPos) ) return TRUE; - - iPos = pThis->RetPosition(0); - - a = pThis->RetAngleY(0); - g = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! - - result->SetValFloat(-Direction(a, g)*180.0f/PI); - return TRUE; -} - - -// Compilation of the instruction "produce(pos, angle, type, scriptName)". - -CBotTypResult cProduce(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() != CBotTypString ) return CBotTypResult(CBotErrBadString); - var = var->GivNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypFloat); -} - -// Instruction "produce(pos, angle, type, scriptName)". - -BOOL rProduce(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* object; - CBotString cbs; - const char* name; - D3DVECTOR pos; - float angle; - ObjectType type; - - if ( !GetPoint(var, exception, pos) ) return TRUE; - - angle = var->GivValFloat()*PI/180.0f; - var = var->GivNext(); - - type = (ObjectType)var->GivValInt(); - var = var->GivNext(); - - cbs = var->GivValString(); - name = cbs; - - if ( type == OBJECT_FRET || - type == OBJECT_STONE || - type == OBJECT_URANIUM || - type == OBJECT_METAL || - type == OBJECT_POWER || - type == OBJECT_ATOMIC || - type == OBJECT_BULLET || - type == OBJECT_BBOX || - type == OBJECT_KEYa || - type == OBJECT_KEYb || - type == OBJECT_KEYc || - type == OBJECT_KEYd || - type == OBJECT_TNT || - type == OBJECT_SCRAP1 || - type == OBJECT_SCRAP2 || - type == OBJECT_SCRAP3 || - type == OBJECT_SCRAP4 || - type == OBJECT_SCRAP5 || - type == OBJECT_BOMB || - type == OBJECT_WAYPOINT || - type == OBJECT_SHOW || - type == OBJECT_WINFIRE ) - { - object = new CObject(script->m_iMan); - if ( !object->CreateResource(pos, angle, type) ) - { - delete object; - result->SetValInt(1); // error - return TRUE; - } - } - else - if ( type == OBJECT_MOTHER || - type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_BEE || - type == OBJECT_WORM ) - { - CObject* egg; - - object = new CObject(script->m_iMan); - if ( !object->CreateInsect(pos, angle, type) ) - { - delete object; - result->SetValInt(1); // error - return TRUE; - } - - egg = new CObject(script->m_iMan); - if ( !egg->CreateResource(pos, angle, OBJECT_EGG, 0.0f) ) - { - delete egg; - } - } - else - { - result->SetValInt(1); // impossible - return TRUE; - } - object->SetActivity(FALSE); - object->ReadProgram(0, (char*)name); - object->RunProgram(0); - - result->SetValInt(0); // no error - return TRUE; -} - - -// Compilation of the instruction "distance(p1, p2)". - -CBotTypResult cDistance(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypFloat); -} - -// Instruction "distance(p1, p2)". - -BOOL rDistance(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - D3DVECTOR p1, p2; - float value; - - if ( !GetPoint(var, exception, p1) ) return TRUE; - if ( !GetPoint(var, exception, p2) ) return TRUE; - - value = Length(p1, p2); - result->SetValFloat(value/g_unit); - return TRUE; -} - -// Instruction "distance2d(p1, p2)". - -BOOL rDistance2d(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - D3DVECTOR p1, p2; - float value; - - if ( !GetPoint(var, exception, p1) ) return TRUE; - if ( !GetPoint(var, exception, p2) ) return TRUE; - - value = Length2d(p1, p2); - result->SetValFloat(value/g_unit); - return TRUE; -} - - -// Compilation of the instruction "space(center, rMin, rMax, dist)". - -CBotTypResult cSpace(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); - ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; - - if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypIntrinsic, "point"); -} - -// Instruction "space(center, rMin, rMax, dist)". - -BOOL rSpace(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - CBotVar* pSub; - D3DVECTOR center; - float rMin, rMax, dist; - - rMin = 10.0f*g_unit; - rMax = 50.0f*g_unit; - dist = 4.0f*g_unit; - - if ( var == 0 ) - { - center = pThis->RetPosition(0); - } - else - { - if ( !GetPoint(var, exception, center) ) return TRUE; - - if ( var != 0 ) - { - rMin = var->GivValFloat()*g_unit; - var = var->GivNext(); - - if ( var != 0 ) - { - rMax = var->GivValFloat()*g_unit; - var = var->GivNext(); - - if ( var != 0 ) - { - dist = var->GivValFloat()*g_unit; - var = var->GivNext(); - } - } - } - } - script->m_main->FreeSpace(center, rMin, rMax, dist, pThis); - - if ( result != 0 ) - { - pSub = result->GivItemList(); - if ( pSub != 0 ) - { - pSub->SetValFloat(center.x/g_unit); - pSub = pSub->GivNext(); // "y" - pSub->SetValFloat(center.z/g_unit); - pSub = pSub->GivNext(); // "z" - pSub->SetValFloat(center.y/g_unit); - } - } - return TRUE; -} - - -// Compilation of the instruction "flatground(center, rMax)". - -CBotTypResult cFlatGround(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypFloat); -} - -// Instruction "flatground(center, rMax)". - -BOOL rFlatGround(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - D3DVECTOR center; - float rMax, dist; - - if ( !GetPoint(var, exception, center) ) return TRUE; - rMax = var->GivValFloat()*g_unit; - var = var->GivNext(); - - dist = script->m_main->RetFlatZoneRadius(center, rMax, pThis); - result->SetValFloat(dist/g_unit); - - return TRUE; -} - - -// Instruction "wait(t)". - -BOOL rWait(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - float value; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - value = var->GivValFloat(); - err = script->m_primaryTask->StartTaskWait(value); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; - } - } - return Process(script, result, exception); -} - -// Instruction "move(dist)". - -BOOL rMove(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - float value; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - value = var->GivValFloat(); - err = script->m_primaryTask->StartTaskAdvance(value*g_unit); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; - } - } - return Process(script, result, exception); -} - -// Instruction "turn(angle)". - -BOOL rTurn(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - float value; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - value = var->GivValFloat(); - err = script->m_primaryTask->StartTaskTurn(-value*PI/180.0f); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; - } - } - return Process(script, result, exception); -} - -// Compilation of the instruction "goto(pos, altitude, crash, goal)". - -CBotTypResult cGoto(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - return CBotTypResult(CBotErrOverParam); -} - -// Instruction "goto(pos, altitude, mode)". - -BOOL rGoto(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - D3DVECTOR pos; - TaskGotoGoal goal; - TaskGotoCrash crash; - float altitude; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - if ( !GetPoint(var, exception, pos) ) return TRUE; - - goal = TGG_DEFAULT; - crash = TGC_DEFAULT; - altitude = 0.0f*g_unit; - - if ( var != 0 ) - { - altitude = var->GivValFloat()*g_unit; - - var = var->GivNext(); - if ( var != 0 ) - { - goal = (TaskGotoGoal)var->GivValInt(); - - var = var->GivNext(); - if ( var != 0 ) - { - crash = (TaskGotoCrash)var->GivValInt(); - } - } - } - - err = script->m_primaryTask->StartTaskGoto(pos, altitude, goal, crash); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; - } - } - return Process(script, result, exception); -} - -// Instruction "find(type)". - -BOOL rFind(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - D3DVECTOR pos; - TaskGotoGoal goal; - TaskGotoCrash crash; - float altitude; - Error err; - CObject* pThis = (CObject*)user; - CObject *pObj, *pBest; - CBotVar* array; - D3DVECTOR iPos, oPos; - float best, minDist, maxDist, sens, iAngle, angle, focus, d, a; - int type, oType, i; - BOOL bArray; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - type = OBJECT_NULL; - angle = 0.0f; - focus = PI*2.0f; - minDist = 0.0f*g_unit; - maxDist = 1000.0f*g_unit; - sens = 1.0f; - - if ( var->GivType() == CBotTypArrayPointer ) - { - array = var->GivItemList(); - bArray = TRUE; - } - else - { - type = var->GivValInt(); - bArray = FALSE; - } - - best = 100000.0f; - pBest = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - if ( pObj == pThis ) continue; - - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( !pObj->RetActif() ) continue; - if ( pObj->RetProxyActivate() ) continue; - - oType = pObj->RetType(); - if ( oType == OBJECT_TOTO ) continue; - - if ( oType == OBJECT_RUINmobilew2 || - oType == OBJECT_RUINmobilet1 || - oType == OBJECT_RUINmobilet2 || - oType == OBJECT_RUINmobiler1 || - oType == OBJECT_RUINmobiler2 ) - { - oType = OBJECT_RUINmobilew1; // any ruin - } - - if ( oType == OBJECT_SCRAP2 || - oType == OBJECT_SCRAP3 || - oType == OBJECT_SCRAP4 || - oType == OBJECT_SCRAP5 ) // wastes? - { - oType = OBJECT_SCRAP1; // any waste - } - - if ( oType == OBJECT_BARRIER2 || - oType == OBJECT_BARRIER3 ) // barriers? - { - oType = OBJECT_BARRIER1; // any barrier - } - - if ( bArray ) - { - if ( !FindList(array, oType) ) continue; - } - else - { - if ( type != oType && type != OBJECT_NULL ) continue; - } - - oPos = pObj->RetPosition(0); - d = Length2d(iPos, oPos); - if ( d < minDist || d > maxDist ) continue; // too close or too far? - - if ( focus >= PI*2.0f ) - { - if ( d < best ) - { - best = d; - pBest = pObj; - } - continue; - } - - a = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! - if ( TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) ) - { - if ( d < best ) - { - best = d; - pBest = pObj; - } - } - } - - if ( pBest == 0 ) - { - exception = ERR_FIND_IMPOSSIBLE; - return FALSE; - } - - pos = pBest->RetPosition(0); - goal = TGG_DEFAULT; - crash = TGC_DEFAULT; - altitude = 0.0f*g_unit; - - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - err = script->m_primaryTask->StartTaskGoto(pos, altitude, goal, crash); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; - } - } - return Process(script, result, exception); -} - -// Compilation "grab/drop(oper)". - -CBotTypResult cGrabDrop(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Instruction "grab(oper)". - -BOOL rGrab(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - ObjectType oType; - TaskManipArm type; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - if ( var == 0 ) type = TMA_FFRONT; - else type = (TaskManipArm)var->GivValInt(); - - oType = pThis->RetType(); - if ( oType == OBJECT_HUMAN || - oType == OBJECT_TECH ) - { - err = script->m_primaryTask->StartTaskTake(); - } - else - { - err = script->m_primaryTask->StartTaskManip(TMO_GRAB, type); - } - - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; - } - } - return Process(script, result, exception); -} - -// Instruction "drop(oper)". - -BOOL rDrop(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - ObjectType oType; - TaskManipArm type; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - if ( var == 0 ) type = TMA_FFRONT; - else type = (TaskManipArm)var->GivValInt(); - - oType = pThis->RetType(); - if ( oType == OBJECT_HUMAN || - oType == OBJECT_TECH ) - { - err = script->m_primaryTask->StartTaskTake(); - } - else - { - err = script->m_primaryTask->StartTaskManip(TMO_DROP, type); - } - - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; - } - } - return Process(script, result, exception); -} - -// Instruction "sniff()". - -BOOL rSniff(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - err = script->m_primaryTask->StartTaskSearch(); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; - } - } - return Process(script, result, exception); -} - -// Compilation of the instruction "receive(nom, power)". - -CBotTypResult cReceive(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() != CBotTypString ) return CBotTypResult(CBotErrBadString); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Instruction "receive(nom, power)". - -BOOL rReceive(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - CBotString cbs; - Error err; - const char* p; - float value, power; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - - cbs = var->GivValString(); - p = cbs; - var = var->GivNext(); - - power = 10.0f*g_unit; - if ( var != 0 ) - { - power = var->GivValFloat()*g_unit; - var = var->GivNext(); - } - - err = script->m_primaryTask->StartTaskInfo((char*)p, 0.0f, power, FALSE); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetInit(IS_NAN); - return TRUE; - } - } - if ( !Process(script, result, exception) ) return FALSE; // not finished - - value = pThis->RetInfoReturn(); - if ( value == NAN ) - { - result->SetInit(IS_NAN); - } - else - { - result->SetValFloat(value); - } - return TRUE; -} - -// Compilation of the instruction "send(nom, value, power)". - -CBotTypResult cSend(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() != CBotTypString ) return CBotTypResult(CBotErrBadString); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Instruction "send(nom, value, power)". - -BOOL rSend(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - CBotString cbs; - Error err; - const char* p; - float value, power; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - - cbs = var->GivValString(); - p = cbs; - var = var->GivNext(); - - value = var->GivValFloat(); - var = var->GivNext(); - - power = 10.0f*g_unit; - if ( var != 0 ) - { - power = var->GivValFloat()*g_unit; - var = var->GivNext(); - } - - err = script->m_primaryTask->StartTaskInfo((char*)p, value, power, TRUE); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; - } - } - return Process(script, result, exception); -} - -// Seeks the nearest information terminal. - -CObject* SearchInfo(CScript* script, CObject* object, float power) -{ - CObject *pObj, *pBest; - D3DVECTOR iPos, oPos; - ObjectType type; - float dist, min; - int i; - - iPos = object->RetPosition(0); - - min = 100000.0f; - pBest = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type != OBJECT_INFO ) continue; - - if ( !pObj->RetActif() ) continue; - - oPos = pObj->RetPosition(0); - dist = Length(oPos, iPos); - if ( dist > power ) continue; // too far? - if ( dist < min ) - { - min = dist; - pBest = pObj; - } - } - - return pBest; -} - -// Compilation of the instruction "deleteinfo(nom, power)". - -CBotTypResult cDeleteInfo(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() != CBotTypString ) return CBotTypResult(CBotErrBadString); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Instruction "deleteinfo(nom, power)". - -BOOL rDeleteInfo(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - CObject* pInfo; - CBotString cbs; - Info info; - const char* p; - float power; - int i, total; - - exception = 0; - - cbs = var->GivValString(); - p = cbs; - var = var->GivNext(); - - power = 10.0f*g_unit; - if ( var != 0 ) - { - power = var->GivValFloat()*g_unit; - var = var->GivNext(); - } - - pInfo = SearchInfo(script, pThis, power); - if ( pInfo == 0 ) - { - result->SetValFloat(0.0f); // false - return TRUE; - } - - total = pInfo->RetInfoTotal(); - for ( i=0 ; iRetInfo(i); - if ( strcmp(info.name, p) == 0 ) - { - pInfo->DeleteInfo(i); - result->SetValFloat(1.0f); // true - return TRUE; - } - } - result->SetValFloat(0.0f); // false - return TRUE; -} - -// Compilation of the instruction "testinfo(nom, power)". - -CBotTypResult cTestInfo(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() != CBotTypString ) return CBotTypResult(CBotErrBadString); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypBoolean); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypBoolean); -} - -// Instruction "testinfo(nom, power)". - -BOOL rTestInfo(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - CObject* pInfo; - CBotString cbs; - Info info; - const char* p; - float power; - int i, total; - - exception = 0; - - cbs = var->GivValString(); - p = cbs; - var = var->GivNext(); - - power = 10.0f*g_unit; - if ( var != 0 ) - { - power = var->GivValFloat()*g_unit; - var = var->GivNext(); - } - - pInfo = SearchInfo(script, pThis, power); - if ( pInfo == 0 ) - { - result->SetValInt(FALSE); - return TRUE; - } - - total = pInfo->RetInfoTotal(); - for ( i=0 ; iRetInfo(i); - if ( strcmp(info.name, p) == 0 ) - { - result->SetValInt(TRUE); - return TRUE; - } - } - result->SetValInt(FALSE); - return TRUE; -} - -// Instruction "thump()". - -BOOL rThump(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - err = script->m_primaryTask->StartTaskTerraform(); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; - } - } - return Process(script, result, exception); -} - -// Instruction "recycle()". - -BOOL rRecycle(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - err = script->m_primaryTask->StartTaskRecover(); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; - } - } - return Process(script, result, exception); -} - -// Compilation "shield(oper, radius)". - -CBotTypResult cShield(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypFloat); -} - -// Instruction "shield(oper, radius)". - -BOOL rShield(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - float oper, radius; - Error err; - - oper = var->GivValFloat(); // 0=down, 1=up - var = var->GivNext(); - - radius = var->GivValFloat(); - if ( radius < 10.0f ) radius = 10.0f; - if ( radius > 25.0f ) radius = 25.0f; - radius = (radius-10.0f)/15.0f; - - if ( *script->m_secondaryTask == 0 ) // shield folds? - { - if ( oper == 0.0f ) // down? - { - result->SetValInt(1); // shows the error - } - else // up ? - { - pThis->SetParam(radius); - - *script->m_secondaryTask = new CTaskManager(script->m_iMan, script->m_object); - err = (*script->m_secondaryTask)->StartTaskShield(TSM_UP, 1000.0f); - if ( err != ERR_OK ) - { - delete *script->m_secondaryTask; - *script->m_secondaryTask = 0; - result->SetValInt(err); // shows the error - } - } - } - else // shield deployed? - { - if ( oper == 0.0f ) // down? - { - (*script->m_secondaryTask)->StartTaskShield(TSM_DOWN, 0.0f); - } - else // up? - { -//? result->SetValInt(1); // shows the error - pThis->SetParam(radius); - (*script->m_secondaryTask)->StartTaskShield(TSM_UPDATE, 0.0f); - } - } - - return TRUE; -} - -// Compilation "fire(delay)". - -CBotTypResult cFire(CBotVar* &var, void* user) -{ -#if 0 - CObject* pThis = (CObject*)user; - ObjectType type; - - type = pThis->RetType(); - - if ( type == OBJECT_ANT ) - { - return cOnePoint(var, user); - } - else if ( type == OBJECT_SPIDER ) - { - return cNull(var, user); - } - else - { - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); - } -#else - return CBotTypResult(CBotTypFloat); -#endif -} - -// Instruction "fire(delay)". - -BOOL rFire(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - float delay; - D3DVECTOR impact; - Error err; - ObjectType type; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - - type = pThis->RetType(); - - if ( type == OBJECT_ANT ) - { - if ( !GetPoint(var, exception, impact) ) return TRUE; - impact.y += pThis->RetWaterLevel(); - err = script->m_primaryTask->StartTaskFireAnt(impact); - } - else if ( type == OBJECT_SPIDER ) - { - err = script->m_primaryTask->StartTaskSpiderExplo(); - } - else - { - if ( var == 0 ) delay = 0.0f; - else delay = var->GivValFloat(); - err = script->m_primaryTask->StartTaskFire(delay); - } - - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - return TRUE; - } - } - return Process(script, result, exception); -} - -// Instruction "aim(dir)". - -BOOL rAim(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - float value; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - value = var->GivValFloat(); - err = script->m_primaryTask->StartTaskGunGoal(value*PI/180.0f, 0.0f); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - return TRUE; - } - } - return Process(script, result, exception); -} - -// Compilation of the instruction "motor(left, right)". - -CBotTypResult cMotor(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypFloat); -} - -// Instruction "motor(left, right)". - -BOOL rMotor(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CObject* pThis = (CObject*)user; - CPhysics* physics = ((CObject*)user)->RetPhysics(); - float left, right, speed, turn; - - left = var->GivValFloat(); - var = var->GivNext(); - right = var->GivValFloat(); - - speed = (left+right)/2.0f; - if ( speed < -1.0f ) speed = -1.0f; - if ( speed > 1.0f ) speed = 1.0f; - - turn = left-right; - if ( turn < -1.0f ) turn = -1.0f; - if ( turn > 1.0f ) turn = 1.0f; - - if ( pThis->RetFixed() ) // ant on the back? - { - speed = 0.0f; - turn = 0.0f; - } - - physics->SetMotorSpeedX(speed); // forward/backward - physics->SetMotorSpeedZ(turn); // turns - - return TRUE; -} - -// Instruction "jet(power)". - -BOOL rJet(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CPhysics* physics = ((CObject*)user)->RetPhysics(); - float value; - - value = var->GivValFloat(); - physics->SetMotorSpeedY(value); - - return TRUE; -} - -// Compilation of the instruction "topo(pos)". - -CBotTypResult cTopo(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - return CBotTypResult(CBotErrOverParam); -} - -// Instruction "topo(pos)". - -BOOL rTopo(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - D3DVECTOR pos; - float level; - - exception = 0; - - if ( !GetPoint(var, exception, pos) ) return TRUE; - - level = script->m_terrain->RetFloorLevel(pos); - level -= script->m_water->RetLevel(); - result->SetValFloat(level/g_unit); - return TRUE; -} - -// Compilation of the instruction "message(string, type)". - -CBotTypResult cMessage(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() != CBotTypString && - var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - return CBotTypResult(CBotErrOverParam); -} - -// Instruction "message(string, type)". - -BOOL rMessage(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CBotString cbs; - const char* p; - TextType type; - - cbs = var->GivValString(); - p = cbs; - - type = TT_MESSAGE; - var = var->GivNext(); - if ( var != 0 ) - { - type = (TextType)var->GivValInt(); - } - - script->m_displayText->DisplayText((char*)p, script->m_object, 10.0f, type); - script->m_main->CheckEndMessage((char*)p); - - return TRUE; -} - -// Instruction "cmdline(rank)". - -BOOL rCmdline(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - float value; - int rank; - - rank = var->GivValInt(); - value = pThis->RetCmdLine(rank); - result->SetValFloat(value); - - return TRUE; -} - -// Instruction "ismovie()". - -BOOL rIsMovie(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - float value; - - value = script->m_main->RetMovieLock()?1.0f:0.0f; - result->SetValFloat(value); - - return TRUE; -} - -// Instruction "errmode(mode)". - -BOOL rErrMode(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - int value; - - value = var->GivValInt(); - if ( value < 0 ) value = 0; - if ( value > 1 ) value = 1; - script->m_errMode = value; - - return TRUE; -} - -// Instruction "ipf(num)". - -BOOL rIPF(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - int value; - - value = var->GivValInt(); - if ( value < 1 ) value = 1; - if ( value > 10000 ) value = 10000; - script->m_ipf = value; - - return TRUE; -} - -// Instruction "abstime()". - -BOOL rAbsTime(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - float value; - - value = script->m_main->RetGameTime(); - result->SetValFloat(value); - return TRUE; -} - - -// Prepares a file name. - -void PrepareFilename(CBotString &filename, char *dir) -{ - int pos; - - pos = filename.ReverseFind('\\'); - if ( pos > 0 ) - { - filename = filename.Mid(pos+1); // removes folders - } - - pos = filename.ReverseFind('/'); - if ( pos > 0 ) - { - filename = filename.Mid(pos+1); // also those with / - } - - pos = filename.ReverseFind(':'); - if ( pos > 0 ) - { - filename = filename.Mid(pos+1); // also removes the drive letter C: - } - - filename = CBotString(dir) + CBotString("\\") + filename; -} - -// Instruction "deletefile(filename)". - -BOOL rDeleteFile(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CBotString cbs; - const char* p; - char* dir; - - cbs = var->GivValString(); - dir = script->m_main->RetFilesDir(); - PrepareFilename(cbs, dir); - p = cbs; - DeleteFile(p); - - return TRUE; -} - -// Compilation of the instruction "pendown(color, width)". - -CBotTypResult cPenDown(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - return CBotTypResult(CBotErrOverParam); -} - -// Instruction "pendown(color, width)". - -BOOL rPenDown(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - int color; - float width; - Error err; - - if ( pThis->RetType() == OBJECT_MOBILEdr ) - { - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - if ( var != 0 ) - { - color = var->GivValInt(); - if ( color < 0 ) color = 0; - if ( color > 17 ) color = 17; - pThis->SetTraceColor(color); - - var = var->GivNext(); - if ( var != 0 ) - { - width = var->GivValFloat(); - if ( width < 0.1f ) width = 0.1f; - if ( width > 1.0f ) width = 1.0f; - pThis->SetTraceWidth(width); - } - } - pThis->SetTraceDown(TRUE); - - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - err = script->m_primaryTask->StartTaskPen(pThis->RetTraceDown(), pThis->RetTraceColor()); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; - } - } - return Process(script, result, exception); - } - else - { - if ( var != 0 ) - { - color = var->GivValInt(); - if ( color < 0 ) color = 0; - if ( color > 17 ) color = 17; - pThis->SetTraceColor(color); - - var = var->GivNext(); - if ( var != 0 ) - { - width = var->GivValFloat(); - if ( width < 0.1f ) width = 0.1f; - if ( width > 1.0f ) width = 1.0f; - pThis->SetTraceWidth(width); - } - } - pThis->SetTraceDown(TRUE); - - return TRUE; - } -} - -// Instruction "penup()". - -BOOL rPenUp(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; - Error err; - - if ( pThis->RetType() == OBJECT_MOBILEdr ) - { - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - pThis->SetTraceDown(FALSE); - - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - err = script->m_primaryTask->StartTaskPen(pThis->RetTraceDown(), pThis->RetTraceColor()); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; - } - } - return Process(script, result, exception); - } - else - { - pThis->SetTraceDown(FALSE); - return TRUE; - } -} - -// Instruction "pencolor()". - -BOOL rPenColor(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = ((CObject*)user)->RetRunScript(); - CPhysics* physics = ((CObject*)user)->RetPhysics(); - CObject* pThis = (CObject*)user; - int color; - Error err; - - if ( pThis->RetType() == OBJECT_MOBILEdr ) - { - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - color = var->GivValInt(); - if ( color < 0 ) color = 0; - if ( color > 17 ) color = 17; - pThis->SetTraceColor(color); - - script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - err = script->m_primaryTask->StartTaskPen(pThis->RetTraceDown(), pThis->RetTraceColor()); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return FALSE; - } - return TRUE; - } - } - return Process(script, result, exception); - } - else - { - color = var->GivValInt(); - if ( color < 0 ) color = 0; - if ( color > 17 ) color = 17; - pThis->SetTraceColor(color); - - return TRUE; - } -} - -// Instruction "penwidth()". - -BOOL rPenWidth(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CObject* pThis = (CObject*)user; - float width; - - width = var->GivValFloat(); - if ( width < 0.1f ) width = 0.1f; - if ( width > 1.0f ) width = 1.0f; - pThis->SetTraceWidth(width); - return TRUE; -} - - - -// Object's constructor. - -CScript::CScript(CInstanceManager* iMan, CObject* object, CTaskManager** secondaryTask) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_SCRIPT, this, 100); - - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - m_botProg = 0; - m_object = object; - m_primaryTask = 0; - m_secondaryTask = secondaryTask; - - m_ipf = CBOT_IPF; - m_errMode = ERM_STOP; - m_len = 0; - m_script = 0; - m_bRun = FALSE; - m_bStepMode = FALSE; - m_bCompile = FALSE; - m_title[0] = 0; - m_cursor1 = 0; - m_cursor2 = 0; - m_filename[0] = 0; -} - -// Initializes all functions for module CBOT. - -void CScript::InitFonctions() -{ - CBotProgram::AddFunction("sin", rSin, cOneFloat); - CBotProgram::AddFunction("cos", rCos, cOneFloat); - CBotProgram::AddFunction("tan", rTan, cOneFloat); - CBotProgram::AddFunction("asin", raSin, cOneFloat); - CBotProgram::AddFunction("acos", raCos, cOneFloat); - CBotProgram::AddFunction("atan", raTan, cOneFloat); - CBotProgram::AddFunction("sqrt", rSqrt, cOneFloat); - CBotProgram::AddFunction("pow", rPow, cTwoFloat); - CBotProgram::AddFunction("rand", rRand, cNull); - CBotProgram::AddFunction("abs", rAbs, cOneFloat); - - CBotProgram::AddFunction("retobject", rRetObject, cRetObject); - CBotProgram::AddFunction("search", rSearch, cSearch); - CBotProgram::AddFunction("radar", rRadar, cRadar); - CBotProgram::AddFunction("detect", rDetect, cDetect); - CBotProgram::AddFunction("direction", rDirection, cDirection); - CBotProgram::AddFunction("produce", rProduce, cProduce); - CBotProgram::AddFunction("distance", rDistance, cDistance); - CBotProgram::AddFunction("distance2d",rDistance2d,cDistance); - CBotProgram::AddFunction("space", rSpace, cSpace); - CBotProgram::AddFunction("flatground",rFlatGround,cFlatGround); - CBotProgram::AddFunction("wait", rWait, cOneFloat); - CBotProgram::AddFunction("move", rMove, cOneFloat); - CBotProgram::AddFunction("turn", rTurn, cOneFloat); - CBotProgram::AddFunction("goto", rGoto, cGoto); - CBotProgram::AddFunction("find", rFind, cOneFloat); - CBotProgram::AddFunction("grab", rGrab, cGrabDrop); - CBotProgram::AddFunction("drop", rDrop, cGrabDrop); - CBotProgram::AddFunction("sniff", rSniff, cNull); - CBotProgram::AddFunction("receive", rReceive, cReceive); - CBotProgram::AddFunction("send", rSend, cSend); - CBotProgram::AddFunction("deleteinfo",rDeleteInfo,cDeleteInfo); - CBotProgram::AddFunction("testinfo", rTestInfo, cTestInfo); - CBotProgram::AddFunction("thump", rThump, cNull); - CBotProgram::AddFunction("recycle", rRecycle, cNull); - CBotProgram::AddFunction("shield", rShield, cShield); - CBotProgram::AddFunction("fire", rFire, cFire); - CBotProgram::AddFunction("aim", rAim, cOneFloat); - CBotProgram::AddFunction("motor", rMotor, cMotor); - CBotProgram::AddFunction("jet", rJet, cOneFloat); - CBotProgram::AddFunction("topo", rTopo, cTopo); - CBotProgram::AddFunction("message", rMessage, cMessage); - CBotProgram::AddFunction("cmdline", rCmdline, cOneFloat); - CBotProgram::AddFunction("ismovie", rIsMovie, cNull); - CBotProgram::AddFunction("errmode", rErrMode, cOneFloat); - CBotProgram::AddFunction("ipf", rIPF, cOneFloat); - CBotProgram::AddFunction("abstime", rAbsTime, cNull); - CBotProgram::AddFunction("deletefile",rDeleteFile,cString); - CBotProgram::AddFunction("pendown", rPenDown, cPenDown); - CBotProgram::AddFunction("penup", rPenUp, cNull); - CBotProgram::AddFunction("pencolor", rPenColor, cOneFloat); - CBotProgram::AddFunction("penwidth", rPenWidth, cOneFloat); -} - -// Object's destructor. - -CScript::~CScript() -{ - delete m_botProg; - delete m_primaryTask; - delete m_script; - m_script = 0; - m_len = 0; - - m_iMan->DeleteInstance(CLASS_SCRIPT, this); -} - - -// Gives the script editable block of text. - -void CScript::PutScript(CEdit* edit, char* name) -{ - if ( m_script == 0 ) - { - New(edit, name); - } - else - { - edit->SetText(m_script); - edit->SetCursor(m_cursor2, m_cursor1); - edit->ShowSelect(); - } - edit->SetFocus(TRUE); -} - -// The script takes a paved text. - -BOOL CScript::GetScript(CEdit* edit) -{ - int len; - - delete m_script; - m_script = 0; - - len = edit->RetTextLength(); - m_script = (char*)malloc(sizeof(char)*(len+1)); - - edit->GetText(m_script, len+1); - edit->GetCursor(m_cursor2, m_cursor1); - m_len = strlen(m_script); - - if ( !CheckToken() ) - { - edit->SetCursor(m_cursor2, m_cursor1); - edit->ShowSelect(); - edit->SetFocus(TRUE); - return FALSE; - } - - if ( !Compile() ) - { - edit->SetCursor(m_cursor2, m_cursor1); - edit->ShowSelect(); - edit->SetFocus(TRUE); - return FALSE; - } - - return TRUE; -} - -// Indicates whether a program is compiled correctly. - -BOOL CScript::RetCompile() -{ - return m_bCompile; -} - -// Indicates whether the program is empty. - -BOOL CScript::IsEmpty() -{ - int i; - - for ( i=0 ; iRetCheckToken() ) return TRUE; - - m_error = 0; - m_title[0] = 0; - m_token[0] = 0; - m_bCompile = FALSE; - - for ( i=0 ; iRetObligatoryToken() ; i++ ) - { - used[i] = 0; // token not used - } - - bt = CBotToken::CompileTokens(m_script, error); - while ( bt != 0 ) - { - bs = bt->GivString(); - token = bs; - type = bt->GivType(); - - cursor1 = bt->GivStart(); - cursor2 = bt->GivEnd(); - - i = m_main->IsObligatoryToken((char*)token); - if ( i != -1 ) - { - used[i] = 1; // token used - } - - if ( !m_main->IsProhibitedToken((char*)token) ) - { - m_error = ERR_PROHIBITEDTOKEN; - m_cursor1 = cursor1; - m_cursor2 = cursor2; - strcpy(m_title, ""); - CBotToken::Delete(bt); - return FALSE; - } - - bt = bt->GivNext(); - } - - // At least once every obligatory instruction? - for ( i=0 ; iRetObligatoryToken() ; i++ ) - { - if ( used[i] == 0 ) // token not used? - { - strcpy(m_token, m_main->RetObligatoryToken(i)); - m_error = ERR_OBLIGATORYTOKEN; - strcpy(m_title, ""); - CBotToken::Delete(bt); - return FALSE; - } - } - - CBotToken::Delete(bt); - return TRUE; -} - -// Compile the script of a paved text. - -BOOL CScript::Compile() -{ - CBotStringArray liste; - int i; - const char* p; - - m_error = 0; - m_cursor1 = 0; - m_cursor2 = 0; - m_title[0] = 0; - m_bCompile = FALSE; - - if ( IsEmpty() ) // program exist? - { - delete m_botProg; - m_botProg = 0; - return TRUE; - } - - if ( m_botProg == 0 ) - { - m_botProg = new CBotProgram(m_object->RetBotVar()); - } - - if ( m_botProg->Compile(m_script, liste, this) ) - { - if ( liste.GivSize() == 0 ) - { - strcpy(m_title, ""); - } - else - { - p = liste[0]; - i = 0; - while ( TRUE ) - { - if ( p[i] == 0 || p[i] == '(' ) break; - if ( i >= 20 ) - { - m_title[i++] = '.'; - m_title[i++] = '.'; - m_title[i++] = '.'; - break; - } - m_title[i] = p[i]; - i ++; - } - m_title[i] = 0; - } - m_bCompile = TRUE; - return TRUE; - } - else - { - m_botProg->GetError(m_error, m_cursor1, m_cursor2); - if ( m_cursor1 < 0 || m_cursor1 > m_len || - m_cursor2 < 0 || m_cursor2 > m_len ) - { - m_cursor1 = 0; - m_cursor2 = 0; - } - if ( m_error == 0 ) - { - m_cursor1 = m_cursor2 = 0; - } - strcpy(m_title, ""); - return FALSE; - } -} - - -// Returns the title of the script. - -void CScript::GetTitle(char* buffer) -{ - strcpy(buffer, m_title); -} - - -// Choice of mode of execution. - -void CScript::SetStepMode(BOOL bStep) -{ - m_bStepMode = bStep; -} - - -// Runs the program from the beginning. - -BOOL CScript::Run() -{ - if( m_botProg == 0 ) return FALSE; - if ( m_script == 0 || m_len == 0 ) return FALSE; - - if ( !m_botProg->Start(m_title) ) return FALSE; - - m_object->SetRunScript(this); - m_bRun = TRUE; - m_bContinue = FALSE; - m_ipf = CBOT_IPF; - m_errMode = ERM_STOP; - - if ( m_bStepMode ) // step by step mode? - { - Event newEvent; - ZeroMemory(&newEvent, sizeof(Event)); - Step(newEvent); - } - - return TRUE; -} - -// Continues the execution of current program. -// Returns TRUE when execution is finished. - -BOOL CScript::Continue(const Event &event) -{ - if( m_botProg == 0 ) return TRUE; - if ( !m_bRun ) return TRUE; - - m_event = event; - - if ( m_bStepMode ) // step by step mode? - { - if ( m_bContinue ) // instuction "move", "goto", etc. ? - { - if ( m_botProg->Run(m_object, 0) ) - { - m_botProg->GetError(m_error, m_cursor1, m_cursor2); - if ( m_cursor1 < 0 || m_cursor1 > m_len || - m_cursor2 < 0 || m_cursor2 > m_len ) - { - m_cursor1 = 0; - m_cursor2 = 0; - } - if ( m_error == 0 ) - { - m_cursor1 = m_cursor2 = 0; - } - m_bRun = FALSE; - - if ( m_error != 0 && m_errMode == ERM_STOP ) - { - char s[100]; - GetError(s); - m_displayText->DisplayText(s, m_object, 10.0f, TT_ERROR); - } - m_engine->SetPause(TRUE); // gives pause - return TRUE; - } - if ( !m_bContinue ) - { - m_engine->SetPause(TRUE); // gives pause - } - } - - return FALSE; - } - - if ( m_botProg->Run(m_object, m_ipf) ) - { - m_botProg->GetError(m_error, m_cursor1, m_cursor2); - if ( m_cursor1 < 0 || m_cursor1 > m_len || - m_cursor2 < 0 || m_cursor2 > m_len ) - { - m_cursor1 = 0; - m_cursor2 = 0; - } - if ( m_error == 0 ) - { - m_cursor1 = m_cursor2 = 0; - } - m_bRun = FALSE; - - if ( m_error != 0 && m_errMode == ERM_STOP ) - { - char s[100]; - GetError(s); - m_displayText->DisplayText(s, m_object, 10.0f, TT_ERROR); - } - return TRUE; - } - - return FALSE; -} - -// Continues the execution of current program. -// Returns TRUE when execution is finished. - -BOOL CScript::Step(const Event &event) -{ - if( m_botProg == 0 ) return TRUE; - if ( !m_bRun ) return TRUE; - if ( !m_bStepMode ) return FALSE; - - m_engine->SetPause(FALSE); - m_engine->StepSimul(0.01f); // advance of 10ms - m_engine->SetPause(TRUE); - - m_event = event; - - if ( m_botProg->Run(m_object, 0) ) // step mode - { - m_botProg->GetError(m_error, m_cursor1, m_cursor2); - if ( m_cursor1 < 0 || m_cursor1 > m_len || - m_cursor2 < 0 || m_cursor2 > m_len ) - { - m_cursor1 = 0; - m_cursor2 = 0; - } - if ( m_error == 0 ) - { - m_cursor1 = m_cursor2 = 0; - } - m_bRun = FALSE; - - if ( m_error != 0 && m_errMode == ERM_STOP ) - { - char s[100]; - GetError(s); - m_displayText->DisplayText(s, m_object, 10.0f, TT_ERROR); - } - return TRUE; - } - - if ( m_bContinue ) // instuction "move", "goto", etc. ? - { - m_engine->SetPause(FALSE); // removes the pause - } - return FALSE; -} - -// Stops the program. - -void CScript::Stop() -{ - if ( !m_bRun ) return; - - if( m_botProg != 0 ) - { - m_botProg->Stop(); - } - - if ( m_primaryTask != 0 ) - { - m_primaryTask->Abort(); - delete m_primaryTask; - m_primaryTask = 0; - } - - m_bRun = FALSE; -} - -// Indicates whether the program runs. - -BOOL CScript::IsRunning() -{ - return m_bRun; -} - -// Indicates whether the program continues a step. - -BOOL CScript::IsContinue() -{ - return m_bContinue; -} - - -// Gives the position of the cursor during the execution. - -BOOL CScript::GetCursor(int &cursor1, int &cursor2) -{ - const char* funcName; - - cursor1 = cursor2 = 0; - - if( m_botProg == 0 ) return FALSE; - if ( !m_bRun ) return FALSE; - - m_botProg->GetRunPos(funcName, cursor1, cursor2); - if ( cursor1 < 0 || cursor1 > m_len || - cursor2 < 0 || cursor2 > m_len ) - { - cursor1 = 0; - cursor2 = 0; - } - return TRUE; -} - - -// Put of the variables in a list. - -void PutList(char *baseName, BOOL bArray, CBotVar *var, CList *list, int &rankList) -{ - CBotString bs; - CBotVar *svar, *pStatic; - char varName[100]; - char buffer[100]; - const char *p; - int index, type; - - if ( var == 0 && baseName[0] != 0 ) - { - sprintf(buffer, "%s = null;", baseName); - list->SetName(rankList++, buffer); - return; - } - - index = 0; - while ( var != 0 ) - { - var->Maj(NULL, FALSE); - pStatic = var->GivStaticVar(); // finds the static element - - bs = pStatic->GivName(); // variable name - p = bs; -//? if ( strcmp(p, "this") == 0 ) -//? { -//? var = var->GivNext(); -//? continue; -//? } - - if ( baseName[0] == 0 ) - { - sprintf(varName, "%s", p); - } - else - { - if ( bArray ) - { - sprintf(varName, "%s[%d]", baseName, index); - } - else - { - sprintf(varName, "%s.%s", baseName, p); - } - } - - type = pStatic->GivType(); - - if ( type < CBotTypBoolean ) - { - CBotString value; - value = pStatic->GivValString(); - p = value; - sprintf(buffer, "%s = %s;", varName, p); - list->SetName(rankList++, buffer); - } - else if ( type == CBotTypString ) - { - CBotString value; - value = pStatic->GivValString(); - p = value; - sprintf(buffer, "%s = \"%s\";", varName, p); - list->SetName(rankList++, buffer); - } - else if ( type == CBotTypArrayPointer ) - { - svar = pStatic->GivItemList(); - PutList(varName, TRUE, svar, list, rankList); - } - else if ( type == CBotTypClass || - type == CBotTypPointer ) - { - svar = pStatic->GivItemList(); - PutList(varName, FALSE, svar, list, rankList); - } - else - { - sprintf(buffer, "%s = ?;", varName); - list->SetName(rankList++, buffer); - } - - index ++; - var = var->GivNext(); - } -} - -// Fills a list with variables. - -void CScript::UpdateList(CList* list) -{ - CBotVar *var; - const char *progName, *funcName; - int total, select, level, cursor1, cursor2, rank; - - if( m_botProg == 0 ) return; - - total = list->RetTotal(); - select = list->RetSelect(); - - list->Flush(); // empty list - m_botProg->GetRunPos(progName, cursor1, cursor2); - if ( progName == 0 ) return; - - level = 0; - rank = 0; - while ( TRUE ) - { - var = m_botProg->GivStackVars(funcName, level--); - if ( funcName != progName ) break; - - PutList("", FALSE, var, list, rank); - } - - if ( total == list->RetTotal() ) // same total? - { - list->SetSelect(select); - } - - list->SetTooltip(""); - list->SetState(STATE_ENABLE); -} - - -// Colorize the text according to syntax. - -void CScript::ColorizeScript(CEdit* edit) -{ - CBotToken* bt; - CBotString bs; - const char* token; - int error, type, cursor1, cursor2, color; - - edit->ClearFormat(); - - bt = CBotToken::CompileTokens(edit->RetText(), error); - while ( bt != 0 ) - { - bs = bt->GivString(); - token = bs; - type = bt->GivType(); - - cursor1 = bt->GivStart(); - cursor2 = bt->GivEnd(); - - color = 0; - if ( type >= TokenKeyWord && type < TokenKeyWord+100 ) - { - color = COLOR_TOKEN; - } - if ( type >= TokenKeyDeclare && type < TokenKeyDeclare+100 ) - { - color = COLOR_TYPE; - } - if ( type >= TokenKeyVal && type < TokenKeyVal+100 ) - { - color = COLOR_CONST; - } - if ( type == TokenTypVar ) - { - if ( IsType(token) ) - { - color = COLOR_TYPE; - } - else if ( IsFunction(token) ) - { - color = COLOR_TOKEN; - } - } - if ( type == TokenTypDef ) - { - color = COLOR_CONST; - } - - if ( cursor1 < cursor2 && color != 0 ) - { - edit->SetFormat(cursor1, cursor2, color); - } - - bt = bt->GivNext(); - } - - CBotToken::Delete(bt); -} - - -// Seeks a token at random in a script. -// Returns the index of the start of the token found, or -1. - -int SearchToken(char* script, char* token) -{ - int lScript, lToken, i, iFound; - int found[100]; - char* p; - - lScript = strlen(script); - lToken = strlen(token); - iFound = 0; - for ( i=0 ; i= 100 ) break; - } - } - - if ( iFound == 0 ) return -1; - return found[rand()%iFound]; -} - -// Removes a token in a script. - -void DeleteToken(char* script, int pos, int len) -{ - while ( TRUE ) - { - script[pos] = script[pos+len]; - if ( script[pos++] == 0 ) break; - } -} - -// Inserts a token in a script. - -void InsertToken(char* script, int pos, char* token) -{ - int lScript, lToken, i; - - lScript = strlen(script); - lToken = strlen(token); - for ( i=lScript ; i>=pos ; i-- ) - { - script[i+lToken] = script[i]; - } - memcpy(script+pos, token, lToken); -} - -// Introduces a virus into a program. - -BOOL CScript::IntroduceVirus() -{ - int i, start, iFound; - int found[11*2]; - char* newScript; - - char* names[11*2] = - { - "==", "!=", - "!=", "==", - ">", "<", - "<", ">", - "true", "false", - "false", "true", - "grab", "drop", - "drop", "grab", - "InFront", "Behind", - "Behind", "EnergyCell", - "EnergyCell", "InFront", - }; - - iFound = 0; - for ( i=0 ; i<11 ; i++ ) - { - start = SearchToken(m_script, names[i*2]); - if ( start != -1 ) - { - found[iFound++] = i*2; - found[iFound++] = start; - } - } - if ( iFound == 0 ) return FALSE; - - i = (rand()%(iFound/2))*2; - start = found[i+1]; - i = found[i+0]; - - newScript = (char*)malloc(sizeof(char)*(m_len+strlen(names[i+1])+1)); - strcpy(newScript, m_script); - delete m_script; - m_script = newScript; - - DeleteToken(m_script, start, strlen(names[i])); - InsertToken(m_script, start, names[i+1]); - m_len = strlen(m_script); - Compile(); // recompile with the virus - - return TRUE; -} - - -// Returns the number of the error. - -int CScript::RetError() -{ - return m_error; -} - -// Returns the text of the error. - -void CScript::GetError(char* buffer) -{ - if ( m_error == 0 ) - { - buffer[0] = 0; - } - else - { - if ( m_error == ERR_OBLIGATORYTOKEN ) - { - char s[100]; - GetResource(RES_ERR, m_error, s); - sprintf(buffer, s, m_token); - } - else if ( m_error < 1000 ) - { - GetResource(RES_ERR, m_error, buffer); - } - else - { - GetResource(RES_CBOT, m_error, buffer); - } - } -} - - -// New program. - -void CScript::New(CEdit* edit, char* name) -{ - FILE *file = NULL; - char res[100]; - char text[100]; - char filename[100]; - char script[500]; - char buffer[500]; - char *sf; - int cursor1, cursor2, len, i, j; - - GetResource(RES_TEXT, RT_SCRIPT_NEW, res); - if ( name[0] == 0 ) strcpy(text, res); - else strcpy(text, name); - - sprintf(script, "extern void object::%s()\n{\n\t\n\t\n\t\n}\n", text); - edit->SetText(script, FALSE); - - if ( strcmp(text, res) == 0 ) - { - cursor1 = 20; - cursor2 = 20+strlen(text); // update "New" - } - else - { - if ( edit->RetAutoIndent() ) - { - cursor1 = 20+strlen(text)+6; - cursor2 = cursor1; // cursor in { } - } - else - { - cursor1 = 20+strlen(text)+8; - cursor2 = cursor1; // cursor in { } - } - } - - edit->SetCursor(cursor2, cursor1); - edit->ShowSelect(); - edit->SetFocus(TRUE); - - sf = m_main->RetScriptFile(); - if ( sf[0] != 0 ) // Load an empty program specific? - { - strcpy(filename, "script\\"); - strcat(filename, sf); - file = fopen(filename, "rb"); - if ( file != NULL ) - { - fseek(file, 0, SEEK_END); - len = ftell(file); - fseek(file, 0, SEEK_SET); - - if ( len > 500-1 ) len = 500-1; - fread(buffer, 1, len, file); - buffer[len] = 0; - fclose(file); - - cursor1 = 0; - i = 0; - j = 0; - while ( TRUE ) - { - if ( buffer[i] == 0 ) break; - - if ( buffer[i] == '\r' ) - { - i ++; - continue; - } - - if ( buffer[i] == '\t' && edit->RetAutoIndent() ) - { - i ++; - continue; - } - - if ( buffer[i+0] == '%' && - buffer[i+1] == 's' ) - { - strcpy(script+j, text); - j += strlen(text); - i += 2; - continue; - } - - if ( buffer[i] == '#' ) - { - cursor1 = j; - i ++; - continue; - } - - script[j++] = buffer[i++]; - } - script[j] = 0; - edit->SetText(script, FALSE); - - cursor2 = cursor1; - edit->SetCursor(cursor2, cursor1); - edit->ShowSelect(); - edit->SetFocus(TRUE); - } - } - - ColorizeScript(edit); -} - - -// Provided a script for all parts. - -BOOL CScript::SendScript(char* text) -{ - m_len = strlen(text); - m_script = (char*)malloc(sizeof(char)*(m_len+1)); - strcpy(m_script, text); - if ( !CheckToken() ) return FALSE; - if ( !Compile() ) return FALSE; - - return TRUE; -} - -// Reads a script as a text file. - -BOOL CScript::ReadScript(char* filename) -{ - FILE* file; - CEdit* edit; - char name[100]; - - if ( strchr(filename, '\\') == 0 ) - { - strcpy(name, "script\\"); - strcat(name, filename); - } - else - { -//? strcpy(name, filename); - UserDir(name, filename, ""); - } - - file = fopen(name, "rb"); - if ( file == NULL ) return FALSE; - fclose(file); - - delete m_script; - m_script = 0; - - edit = m_interface->CreateEdit(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), 0, EVENT_EDIT9); - edit->SetMaxChar(EDITSTUDIOMAX); - edit->SetAutoIndent(m_engine->RetEditIndentMode()); - edit->ReadText(name); - GetScript(edit); - m_interface->DeleteControl(EVENT_EDIT9); - return TRUE; -} - -// Writes a script as a text file. - -BOOL CScript::WriteScript(char* filename) -{ - CEdit* edit; - char name[100]; - - if ( strchr(filename, '\\') == 0 ) - { - strcpy(name, "script\\"); - strcat(name, filename); - } - else - { - strcpy(name, filename); - } - - if ( m_script == 0 ) - { - remove(filename); - return FALSE; - } - - edit = m_interface->CreateEdit(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), 0, EVENT_EDIT9); - edit->SetMaxChar(EDITSTUDIOMAX); - edit->SetAutoIndent(m_engine->RetEditIndentMode()); - edit->SetText(m_script); - edit->WriteText(name); - m_interface->DeleteControl(EVENT_EDIT9); - return TRUE; -} - - -// Reads a stack of script by execution as a file. - -BOOL CScript::ReadStack(FILE *file) -{ - int nb; - - fRead(&nb, sizeof(int), 1, file); - fRead(&m_ipf, sizeof(int), 1, file); - fRead(&m_errMode, sizeof(int), 1, file); - - if ( m_botProg == 0 ) return FALSE; - if ( !m_botProg->RestoreState(file) ) return FALSE; - - m_object->SetRunScript(this); - m_bRun = TRUE; - m_bContinue = FALSE; - return TRUE; -} - -// Writes a stack of script by execution as a file. - -BOOL CScript::WriteStack(FILE *file) -{ - int nb; - - nb = 2; - fWrite(&nb, sizeof(int), 1, file); - fWrite(&m_ipf, sizeof(int), 1, file); - fWrite(&m_errMode, sizeof(int), 1, file); - - return m_botProg->SaveState(file); -} - - -// Compares two scripts. - -BOOL CScript::Compare(CScript* other) -{ - if ( m_len != other->m_len ) return FALSE; - - return ( strcmp(m_script, other->m_script) == 0 ); -} - - -// Management of the file name when the script is saved. - -void CScript::SetFilename(char *filename) -{ - strcpy(m_filename, filename); -} - -char* CScript::RetFilename() -{ - return m_filename; -} - diff --git a/src/script.h b/src/script.h deleted file mode 100644 index eeb8ac8..0000000 --- a/src/script.h +++ /dev/null @@ -1,118 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// script.h - -#ifndef _SCRIPT_H_ -#define _SCRIPT_H_ - - -#include "event.h" - - -class CInstanceManager; -class CD3DEngine; -class CInterface; -class CDisplayText; -class CEdit; -class CList; -class CObject; -class CTaskManager; -class CBotProgram; -class CRobotMain; -class CTerrain; -class CWater; - - - -class CScript -{ -public: - CScript(CInstanceManager* iMan, CObject* object, CTaskManager** secondaryTask); - ~CScript(); - - static void InitFonctions(); - - void PutScript(CEdit* edit, char* name); - BOOL GetScript(CEdit* edit); - BOOL RetCompile(); - - void GetTitle(char* buffer); - - void SetStepMode(BOOL bStep); - BOOL Run(); - BOOL Continue(const Event &event); - BOOL Step(const Event &event); - void Stop(); - BOOL IsRunning(); - BOOL IsContinue(); - BOOL GetCursor(int &cursor1, int &cursor2); - void UpdateList(CList* list); - void ColorizeScript(CEdit* edit); - BOOL IntroduceVirus(); - - int RetError(); - void GetError(char* buffer); - - void New(CEdit* edit, char* name); - BOOL SendScript(char* text); - BOOL ReadScript(char* filename); - BOOL WriteScript(char* filename); - BOOL ReadStack(FILE *file); - BOOL WriteStack(FILE *file); - BOOL Compare(CScript* other); - - void SetFilename(char *filename); - char* RetFilename(); - -protected: - BOOL IsEmpty(); - BOOL CheckToken(); - BOOL Compile(); - -public: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CInterface* m_interface; - CDisplayText* m_displayText; - CBotProgram* m_botProg; - CRobotMain* m_main; - CTerrain* m_terrain; - CWater* m_water; - CTaskManager* m_primaryTask; - CTaskManager** m_secondaryTask; - CObject* m_object; - - int m_ipf; // number of instructions/second - int m_errMode; // what to do in case of error - int m_len; // length of the script (without <0>) - char* m_script; // script ends with <0> - BOOL m_bRun; // program during execution? - BOOL m_bStepMode; // step by step - BOOL m_bContinue; // external function to continue - BOOL m_bCompile; // compilation ok? - char m_title[50]; // script title - char m_filename[50]; // file name - char m_token[50]; // missing instruction - int m_error; // error (0=ok) - int m_cursor1; - int m_cursor2; - Event m_event; - float m_returnValue; -}; - - -#endif //_SCRIPT_H_ diff --git a/src/script/ClassFILE.cpp b/src/script/ClassFILE.cpp new file mode 100644 index 0000000..ef98e14 --- /dev/null +++ b/src/script/ClassFILE.cpp @@ -0,0 +1,425 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + + + +// Static variables + +static CBotClass* m_pClassFILE; +static CBotProgram* m_pFuncFile; +static int m_CompteurFileOpen = 0; +static char* m_filesDir; + + + +// Prepares a file name. + +void PrepareFilename(CBotString &filename) +{ + int pos; + + pos = filename.ReverseFind('\\'); + if ( pos > 0 ) + { + filename = filename.Mid(pos+1); // Remove files with + } + + pos = filename.ReverseFind('/'); + if ( pos > 0 ) + { + filename = filename.Mid(pos+1); // also with / + } + + pos = filename.ReverseFind(':'); + if ( pos > 0 ) + { + filename = filename.Mid(pos+1); // also removes the drive letter C: + } + + filename = CBotString(m_filesDir) + CBotString("\\") + filename; +} + + +// constructor of the class +// get the filename as a parameter + +// execution +BOOL rfconstruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + CBotString mode; + + // accepts no parameters + if ( pVar == NULL ) return TRUE; + + // must be a character string + if ( pVar->GivType() != CBotTypString ) { Exception = CBotErrBadString; return FALSE; } + + CBotString filename = pVar->GivValString(); + PrepareFilename(filename); + + // there may be a second parameter + pVar = pVar->GivNext(); + if ( pVar != NULL ) + { + // recover mode + mode = pVar->GivValString(); + if ( mode != "r" && mode != "w" ) { Exception = CBotErrBadParam; return FALSE; } + + // no third parameter + if ( pVar->GivNext() != NULL ) { Exception = CBotErrOverParam; return FALSE; } + } + + // saves the file name + pVar = pThis->GivItem("filename"); + pVar->SetValString(filename); + + if ( ! mode.IsEmpty() ) + { + // opens the requested file + FILE* pFile = fopen( filename, mode ); + if ( pFile == NULL ) { Exception = CBotErrFileOpen; return FALSE; } + + m_CompteurFileOpen ++; + + // save the channel file + pVar = pThis->GivItem("handle"); + pVar->SetValInt((long)pFile); + } + + return TRUE; +} + +// compilation +CBotTypResult cfconstruct (CBotVar* pThis, CBotVar* &pVar) +{ + // accepts no parameters + if ( pVar == NULL ) return CBotTypResult( 0 ); + + // must be a character string + if ( pVar->GivType() != CBotTypString ) + return CBotTypResult( CBotErrBadString ); + + // there may be a second parameter + pVar = pVar->GivNext(); + if ( pVar != NULL ) + { + // which must be a string + if ( pVar->GivType() != CBotTypString ) + return CBotTypResult( CBotErrBadString ); + // no third parameter + if ( pVar->GivNext() != NULL ) return CBotTypResult( CBotErrOverParam ); + } + + // the result is void (constructor) + return CBotTypResult( 0 ); +} + + +// destructor of the class + +// execution +BOOL rfdestruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + // retrieve the item "handle" + pVar = pThis->GivItem("handle"); + + // don't open? no problem :) + if ( pVar->GivInit() != IS_DEF) return TRUE; + + FILE* pFile= (FILE*)pVar->GivValInt(); + fclose(pFile); + m_CompteurFileOpen --; + + pVar->SetInit(IS_NAN); + + return TRUE; +} + + +// process FILE :: open +// get the r/w mode as a parameter + +// execution +BOOL rfopen (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + // there must be a parameter + if ( pVar == NULL ) { Exception = CBotErrLowParam; return FALSE; } + + // which must be a character string + if ( pVar->GivType() != CBotTypString ) { Exception = CBotErrBadString; return FALSE; } + + // There may be a second parameter + if ( pVar->GivNext() != NULL ) + { + // if the first parameter is the file name + CBotString filename = pVar->GivValString(); + PrepareFilename(filename); + + // saves the file name + CBotVar* pVar2 = pThis->GivItem("filename"); + pVar2->SetValString(filename); + + // next parameter is the mode + pVar = pVar -> GivNext(); + } + + CBotString mode = pVar->GivValString(); + if ( mode != "r" && mode != "w" ) { Exception = CBotErrBadParam; return FALSE; } + + // no third parameter + if ( pVar->GivNext() != NULL ) { Exception = CBotErrOverParam; return FALSE; } + + // retrieve the item "handle" + pVar = pThis->GivItem("handle"); + + // which must not be initialized + if ( pVar->GivInit() == IS_DEF) { Exception = CBotErrFileOpen; return FALSE; } + + // file contains the name + pVar = pThis->GivItem("filename"); + CBotString filename = pVar->GivValString(); + + PrepareFilename(filename); // if the name was h.filename attribute = "..."; + + // opens the requested file + FILE* pFile = fopen( filename, mode ); + if ( pFile == NULL ) + { + pResult->SetValInt(FALSE); + return TRUE; + } + + m_CompteurFileOpen ++; + + // Registered the channel file + pVar = pThis->GivItem("handle"); + pVar->SetValInt((long)pFile); + + pResult->SetValInt(TRUE); + return TRUE; +} + +// compilation +CBotTypResult cfopen (CBotVar* pThis, CBotVar* &pVar) +{ + // there must be a parameter + if ( pVar == NULL ) return CBotTypResult( CBotErrLowParam ); + + // which must be a string + if ( pVar->GivType() != CBotTypString ) + return CBotTypResult( CBotErrBadString ); + + // there may be a second parameter + pVar = pVar->GivNext(); + if ( pVar != NULL ) + { + // which must be a string + if ( pVar->GivType() != CBotTypString ) + return CBotTypResult( CBotErrBadString ); + + // no third parameter + if ( pVar->GivNext() != NULL ) return CBotTypResult( CBotErrOverParam ); + } + + // the result is bool + return CBotTypResult(CBotTypBoolean); +} + + +// process FILE :: close + +// execeution +BOOL rfclose (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + // it shouldn't be any parameters + if ( pVar != NULL ) return CBotErrOverParam; + + // retrieve the item "handle" + pVar = pThis->GivItem("handle"); + + if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return FALSE; } + + FILE* pFile= (FILE*)pVar->GivValInt(); + fclose(pFile); + m_CompteurFileOpen --; + + pVar->SetInit(IS_NAN); + + return TRUE; +} + +// compilation +CBotTypResult cfclose (CBotVar* pThis, CBotVar* &pVar) +{ + // it shouldn't be any parameters + if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam ); + + // function returns a result "void" + return CBotTypResult( 0 ); +} + +// process FILE :: writeln + +// execution +BOOL rfwrite (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + // there must be a parameter + if ( pVar == NULL ) { Exception = CBotErrLowParam; return FALSE; } + + // which must be a character string + if ( pVar->GivType() != CBotTypString ) { Exception = CBotErrBadString; return FALSE; } + + CBotString param = pVar->GivValString(); + + // retrieve the item "handle" + pVar = pThis->GivItem("handle"); + + if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return FALSE; } + + FILE* pFile= (FILE*)pVar->GivValInt(); + + int res = fputs(param+CBotString("\n"), pFile); + + // if an error occurs generate an exception + if ( res < 0 ) { Exception = CBotErrWrite; return FALSE; } + + return TRUE; +} + +// compilation +CBotTypResult cfwrite (CBotVar* pThis, CBotVar* &pVar) +{ + // there must be a parameter + if ( pVar == NULL ) return CBotTypResult( CBotErrLowParam ); + + // which must be a character string + if ( pVar->GivType() != CBotTypString ) return CBotTypResult( CBotErrBadString ); + + // no other parameter + if ( pVar->GivNext() != NULL ) return CBotTypResult( CBotErrOverParam ); + + // the function returns a void result + return CBotTypResult( 0 ); +} + +// process FILE :: readln + +// execution +BOOL rfread (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + // it shouldn't be any parameters + if ( pVar != NULL ) { Exception = CBotErrOverParam; return FALSE; } + + // retrieve the item "handle" + pVar = pThis->GivItem("handle"); + + if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return FALSE; } + + FILE* pFile= (FILE*)pVar->GivValInt(); + + char chaine[2000]; + int i; + for ( i = 0 ; i < 2000 ; i++ ) chaine[i] = 0; + + fgets(chaine, 1999, pFile); + + for ( i = 0 ; i < 2000 ; i++ ) if (chaine[i] == '\n') chaine[i] = 0; + + // if an error occurs generate an exception + if ( ferror(pFile) ) { Exception = CBotErrRead; return FALSE; } + + pResult->SetValString( chaine ); + + return TRUE; +} + +// compilation +CBotTypResult cfread (CBotVar* pThis, CBotVar* &pVar) +{ + // it should not be any parameter + if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam ); + + // function returns a result "string" + return CBotTypResult( CBotTypString ); +} +// process FILE :: readln + + +// execution +BOOL rfeof (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + // it should not be any parameter + if ( pVar != NULL ) { Exception = CBotErrOverParam; return FALSE; } + + // retrieve the item "handle" + pVar = pThis->GivItem("handle"); + + if ( pVar->GivInit() != IS_DEF) { Exception = CBotErrNotOpen; return FALSE; } + + FILE* pFile= (FILE*)pVar->GivValInt(); + + pResult->SetValInt( feof( pFile ) ); + + return TRUE; +} + +// compilation +CBotTypResult cfeof (CBotVar* pThis, CBotVar* &pVar) +{ + // it shouldn't be any parameter + if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam ); + + // the function returns a boolean result + return CBotTypResult( CBotTypBoolean ); +} + + + + + +void InitClassFILE() +{ +// create a class for file management +// the use is as follows: +// file canal( "NomFichier.txt" ) +// canal.open( "r" ); // open for read +// s = canal.readln( ); // reads a line +// canal.close(); // close the file + + // create the class FILE + m_pClassFILE = new CBotClass("file", NULL); + // adds the component ".filename" + m_pClassFILE->AddItem("filename", CBotTypString); + // adds the component ".handle" + m_pClassFILE->AddItem("handle", CBotTypInt, PR_PRIVATE); + + // define a constructor and a destructor + m_pClassFILE->AddFunction("file", rfconstruct, cfconstruct ); + m_pClassFILE->AddFunction("~file", rfdestruct, NULL ); + + // end of the methods associated + m_pClassFILE->AddFunction("open", rfopen, cfopen ); + m_pClassFILE->AddFunction("close", rfclose, cfclose ); + m_pClassFILE->AddFunction("writeln", rfwrite, cfwrite ); + m_pClassFILE->AddFunction("readln", rfread, cfread ); + m_pClassFILE->AddFunction("eof", rfeof, cfeof ); + + m_pFuncFile = new CBotProgram( ); + CBotStringArray ListFonctions; + m_pFuncFile->Compile( "public file openfile(string name, string mode) {return new file(name, mode);}", ListFonctions); + m_pFuncFile->SetIdent(-2); // restoreState in special identifier for this function +} + diff --git a/src/script/cbottoken.cpp b/src/script/cbottoken.cpp new file mode 100644 index 0000000..d97239d --- /dev/null +++ b/src/script/cbottoken.cpp @@ -0,0 +1,521 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "language.h" +#include "global.h" +#include "event.h" +#include "object.h" +#include "cbottoken.h" + + + + +// Seeking the name of an object. + +char* RetObjectName(ObjectType type) +{ + if ( type == OBJECT_PORTICO ) return "Portico"; + if ( type == OBJECT_BASE ) return "SpaceShip"; + if ( type == OBJECT_DERRICK ) return "Derrick"; + if ( type == OBJECT_FACTORY ) return "BotFactory"; + if ( type == OBJECT_STATION ) return "PowerStation"; + if ( type == OBJECT_CONVERT ) return "Converter"; + if ( type == OBJECT_REPAIR ) return "RepairCenter"; + if ( type == OBJECT_DESTROYER ) return "Destroyer"; + if ( type == OBJECT_TOWER ) return "DefenseTower"; + if ( type == OBJECT_NEST ) return "AlienNest"; + if ( type == OBJECT_RESEARCH ) return "ResearchCenter"; + if ( type == OBJECT_RADAR ) return "RadarStation"; + if ( type == OBJECT_INFO ) return "ExchangePost"; + if ( type == OBJECT_ENERGY ) return "PowerPlant"; + if ( type == OBJECT_LABO ) return "AutoLab"; + if ( type == OBJECT_NUCLEAR ) return "NuclearPlant"; + if ( type == OBJECT_PARA ) return "PowerCaptor"; + if ( type == OBJECT_SAFE ) return "Vault"; + if ( type == OBJECT_HUSTON ) return "Houston"; + if ( type == OBJECT_TARGET1 ) return "Target1"; + if ( type == OBJECT_TARGET2 ) return "Target2"; + if ( type == OBJECT_START ) return "StartArea"; + if ( type == OBJECT_END ) return "GoalArea"; + if ( type == OBJECT_TEEN34 ) return "Stone"; + if ( type == OBJECT_STONE ) return "TitaniumOre"; + if ( type == OBJECT_URANIUM ) return "UraniumOre"; + if ( type == OBJECT_METAL ) return "Titanium"; + if ( type == OBJECT_POWER ) return "PowerCell"; + if ( type == OBJECT_ATOMIC ) return "NuclearCell"; + if ( type == OBJECT_BULLET ) return "OrgaMatter"; + if ( type == OBJECT_BBOX ) return "BlackBox"; + if ( type == OBJECT_KEYa ) return "KeyA"; + if ( type == OBJECT_KEYb ) return "KeyB"; + if ( type == OBJECT_KEYc ) return "KeyC"; + if ( type == OBJECT_KEYd ) return "KeyD"; + if ( type == OBJECT_TNT ) return "TNT"; + if ( type == OBJECT_SCRAP1 ) return "Scrap"; + if ( type == OBJECT_BOMB ) return "Mine"; + if ( type == OBJECT_BARRIER1 ) return "Barrier"; + if ( type == OBJECT_WAYPOINT ) return "WayPoint"; + if ( type == OBJECT_FLAGb ) return "BlueFlag"; + if ( type == OBJECT_FLAGr ) return "RedFlag"; + if ( type == OBJECT_FLAGg ) return "GreenFlag"; + if ( type == OBJECT_FLAGy ) return "YellowFlag"; + if ( type == OBJECT_FLAGv ) return "VioletFlag"; + if ( type == OBJECT_MARKPOWER ) return "PowerSpot"; + if ( type == OBJECT_MARKSTONE ) return "TitaniumSpot"; + if ( type == OBJECT_MARKURANIUM ) return "UraniumSpot"; + if ( type == OBJECT_MARKKEYa ) return "KeyASpot"; + if ( type == OBJECT_MARKKEYb ) return "KeyBSpot"; + if ( type == OBJECT_MARKKEYc ) return "KeyCSpot"; + if ( type == OBJECT_MARKKEYd ) return "KeyDSpot"; + if ( type == OBJECT_MOBILEwt ) return "PracticeBot"; + if ( type == OBJECT_MOBILEwa ) return "WheeledGrabber"; + if ( type == OBJECT_MOBILEta ) return "TrackedGrabber"; + if ( type == OBJECT_MOBILEfa ) return "WingedGrabber"; + if ( type == OBJECT_MOBILEia ) return "LeggedGrabber"; + if ( type == OBJECT_MOBILEwc ) return "WheeledShooter"; + if ( type == OBJECT_MOBILEtc ) return "TrackedShooter"; + if ( type == OBJECT_MOBILEfc ) return "WingedShooter"; + if ( type == OBJECT_MOBILEic ) return "LeggedShooter"; + if ( type == OBJECT_MOBILEwi ) return "WheeledOrgaShooter"; + if ( type == OBJECT_MOBILEti ) return "TrackedOrgaShooter"; + if ( type == OBJECT_MOBILEfi ) return "WingedOrgaShooter"; + if ( type == OBJECT_MOBILEii ) return "LeggedOrgaShooter"; + if ( type == OBJECT_MOBILEws ) return "WheeledSniffer"; + if ( type == OBJECT_MOBILEts ) return "TrackedSniffer"; + if ( type == OBJECT_MOBILEfs ) return "WingedSniffer"; + if ( type == OBJECT_MOBILEis ) return "LeggedSniffer"; + if ( type == OBJECT_MOBILErt ) return "Thumper"; + if ( type == OBJECT_MOBILErc ) return "PhazerShooter"; + if ( type == OBJECT_MOBILErr ) return "Recycler"; + if ( type == OBJECT_MOBILErs ) return "Shielder"; + if ( type == OBJECT_MOBILEsa ) return "Subber"; + if ( type == OBJECT_MOBILEtg ) return "TargetBot"; + if ( type == OBJECT_MOBILEdr ) return "Scribbler"; + if ( type == OBJECT_HUMAN ) return "Me"; + if ( type == OBJECT_TECH ) return "Tech"; + if ( type == OBJECT_MOTHER ) return "AlienQueen"; + if ( type == OBJECT_EGG ) return "AlienEgg"; + if ( type == OBJECT_ANT ) return "AlienAnt"; + if ( type == OBJECT_SPIDER ) return "AlienSpider"; + if ( type == OBJECT_BEE ) return "AlienWasp"; + if ( type == OBJECT_WORM ) return "AlienWorm"; + if ( type == OBJECT_RUINmobilew1) return "Wreck"; + return ""; +} + +// Seeking the name of a secondary object. +// (because Otto thinks that Germans do not like nuclear power) + +char* RetObjectAlias(ObjectType type) +{ + if ( type == OBJECT_NUCLEAR ) return "FuelCellPlant"; + if ( type == OBJECT_URANIUM ) return "PlatinumOre"; + if ( type == OBJECT_ATOMIC ) return "FuelCell"; + if ( type == OBJECT_MARKURANIUM ) return "PlatinumSpot"; + if ( type == OBJECT_ENERGY ) return "Disintegrator"; // for K-CeeBot + return ""; +} + + +// Returns the help file to use for the object. + +char* RetHelpFilename(ObjectType type) +{ + if ( type == OBJECT_BASE ) return "help\\object\\base.txt"; + if ( type == OBJECT_DERRICK ) return "help\\object\\derrick.txt"; + if ( type == OBJECT_FACTORY ) return "help\\object\\factory.txt"; + if ( type == OBJECT_STATION ) return "help\\object\\station.txt"; + if ( type == OBJECT_CONVERT ) return "help\\object\\convert.txt"; + if ( type == OBJECT_REPAIR ) return "help\\object\\repair.txt"; + if ( type == OBJECT_DESTROYER ) return "help\\object\\destroy.txt"; + if ( type == OBJECT_TOWER ) return "help\\object\\tower.txt"; + if ( type == OBJECT_NEST ) return "help\\object\\nest.txt"; + if ( type == OBJECT_RESEARCH ) return "help\\object\\research.txt"; + if ( type == OBJECT_RADAR ) return "help\\object\\radar.txt"; + if ( type == OBJECT_INFO ) return "help\\object\\exchange.txt"; + if ( type == OBJECT_ENERGY ) return "help\\object\\energy.txt"; + if ( type == OBJECT_LABO ) return "help\\object\\labo.txt"; + if ( type == OBJECT_NUCLEAR ) return "help\\object\\nuclear.txt"; + if ( type == OBJECT_PARA ) return "help\\object\\captor.txt"; + if ( type == OBJECT_SAFE ) return "help\\object\\safe.txt"; + if ( type == OBJECT_HUSTON ) return "help\\object\\huston.txt"; + if ( type == OBJECT_START ) return "help\\object\\start.txt"; + if ( type == OBJECT_END ) return "help\\object\\goal.txt"; + if ( type == OBJECT_STONE ) return "help\\object\\titanore.txt"; + if ( type == OBJECT_URANIUM ) return "help\\object\\uranore.txt"; + if ( type == OBJECT_METAL ) return "help\\object\\titan.txt"; + if ( type == OBJECT_POWER ) return "help\\object\\power.txt"; + if ( type == OBJECT_ATOMIC ) return "help\\object\\atomic.txt"; + if ( type == OBJECT_BULLET ) return "help\\object\\bullet.txt"; + if ( type == OBJECT_BBOX ) return "help\\object\\bbox.txt"; + if ( type == OBJECT_KEYa ) return "help\\object\\key.txt"; + if ( type == OBJECT_KEYb ) return "help\\object\\key.txt"; + if ( type == OBJECT_KEYc ) return "help\\object\\key.txt"; + if ( type == OBJECT_KEYd ) return "help\\object\\key.txt"; + if ( type == OBJECT_TNT ) return "help\\object\\tnt.txt"; + if ( type == OBJECT_SCRAP1 ) return "help\\object\\scrap.txt"; + if ( type == OBJECT_BOMB ) return "help\\object\\mine.txt"; + if ( type == OBJECT_BARRIER1 ) return "help\\object\\barrier.txt"; + if ( type == OBJECT_WAYPOINT ) return "help\\object\\waypoint.txt"; + if ( type == OBJECT_FLAGb ) return "help\\object\\flag.txt"; + if ( type == OBJECT_FLAGr ) return "help\\object\\flag.txt"; + if ( type == OBJECT_FLAGg ) return "help\\object\\flag.txt"; + if ( type == OBJECT_FLAGy ) return "help\\object\\flag.txt"; + if ( type == OBJECT_FLAGv ) return "help\\object\\flag.txt"; + if ( type == OBJECT_MARKPOWER ) return "help\\object\\enerspot.txt"; + if ( type == OBJECT_MARKSTONE ) return "help\\object\\stonspot.txt"; + if ( type == OBJECT_MARKURANIUM ) return "help\\object\\uranspot.txt"; + if ( type == OBJECT_MOBILEwa ) return "help\\object\\botgr.txt"; + if ( type == OBJECT_MOBILEta ) return "help\\object\\botgc.txt"; + if ( type == OBJECT_MOBILEfa ) return "help\\object\\botgj.txt"; + if ( type == OBJECT_MOBILEia ) return "help\\object\\botgs.txt"; + if ( type == OBJECT_MOBILEws ) return "help\\object\\botsr.txt"; + if ( type == OBJECT_MOBILEts ) return "help\\object\\botsc.txt"; + if ( type == OBJECT_MOBILEfs ) return "help\\object\\botsj.txt"; + if ( type == OBJECT_MOBILEis ) return "help\\object\\botss.txt"; + if ( type == OBJECT_MOBILEwi ) return "help\\object\\botor.txt"; + if ( type == OBJECT_MOBILEti ) return "help\\object\\botoc.txt"; + if ( type == OBJECT_MOBILEfi ) return "help\\object\\botoj.txt"; + if ( type == OBJECT_MOBILEii ) return "help\\object\\botos.txt"; + if ( type == OBJECT_MOBILEwc ) return "help\\object\\botfr.txt"; + if ( type == OBJECT_MOBILEtc ) return "help\\object\\botfc.txt"; + if ( type == OBJECT_MOBILEfc ) return "help\\object\\botfj.txt"; + if ( type == OBJECT_MOBILEic ) return "help\\object\\botfs.txt"; + if ( type == OBJECT_MOBILErt ) return "help\\object\\bottump.txt"; + if ( type == OBJECT_MOBILErc ) return "help\\object\\botphaz.txt"; + if ( type == OBJECT_MOBILErr ) return "help\\object\\botrecy.txt"; + if ( type == OBJECT_MOBILErs ) return "help\\object\\botshld.txt"; + if ( type == OBJECT_MOBILEsa ) return "help\\object\\botsub.txt"; + if ( type == OBJECT_MOBILEwt ) return "help\\object\\bottr.txt"; + if ( type == OBJECT_MOBILEtg ) return "help\\object\\bottarg.txt"; + if ( type == OBJECT_MOBILEdr ) return "help\\object\\botdraw.txt"; + if ( type == OBJECT_APOLLO2 ) return "help\\object\\lrv.txt"; + if ( type == OBJECT_HUMAN ) return "help\\object\\human.txt"; + if ( type == OBJECT_MOTHER ) return "help\\object\\mother.txt"; + if ( type == OBJECT_EGG ) return "help\\object\\egg.txt"; + if ( type == OBJECT_ANT ) return "help\\object\\ant.txt"; + if ( type == OBJECT_SPIDER ) return "help\\object\\spider.txt"; + if ( type == OBJECT_BEE ) return "help\\object\\wasp.txt"; + if ( type == OBJECT_WORM ) return "help\\object\\worm.txt"; + if ( type == OBJECT_RUINmobilew1) return "help\\object\\wreck.txt"; + return ""; +} + + +// Returns the help file to use for instruction. + +char* RetHelpFilename(const char *token) +{ + if ( strcmp(token, "if" ) == 0 ) return "help\\cbot\\if.txt"; + if ( strcmp(token, "else" ) == 0 ) return "help\\cbot\\if.txt"; + if ( strcmp(token, "repeat" ) == 0 ) return "help\\cbot\\repeat.txt"; + if ( strcmp(token, "for" ) == 0 ) return "help\\cbot\\for.txt"; + if ( strcmp(token, "while" ) == 0 ) return "help\\cbot\\while.txt"; + if ( strcmp(token, "do" ) == 0 ) return "help\\cbot\\do.txt"; + if ( strcmp(token, "break" ) == 0 ) return "help\\cbot\\break.txt"; + if ( strcmp(token, "continue" ) == 0 ) return "help\\cbot\\continue.txt"; + if ( strcmp(token, "return" ) == 0 ) return "help\\cbot\\return.txt"; + if ( strcmp(token, "sizeof" ) == 0 ) return "help\\cbot\\sizeof.txt"; + if ( strcmp(token, "int" ) == 0 ) return "help\\cbot\\int.txt"; + if ( strcmp(token, "float" ) == 0 ) return "help\\cbot\\float.txt"; + if ( strcmp(token, "bool" ) == 0 ) return "help\\cbot\\bool.txt"; + if ( strcmp(token, "string" ) == 0 ) return "help\\cbot\\string.txt"; + if ( strcmp(token, "point" ) == 0 ) return "help\\cbot\\point.txt"; + if ( strcmp(token, "object" ) == 0 ) return "help\\cbot\\object.txt"; + if ( strcmp(token, "file" ) == 0 ) return "help\\cbot\\file.txt"; + if ( strcmp(token, "void" ) == 0 ) return "help\\cbot\\void.txt"; + if ( strcmp(token, "null" ) == 0 ) return "help\\cbot\\null.txt"; + if ( strcmp(token, "nan" ) == 0 ) return "help\\cbot\\nan.txt"; + if ( strcmp(token, "true" ) == 0 ) return "help\\cbot\\true.txt"; + if ( strcmp(token, "false" ) == 0 ) return "help\\cbot\\false.txt"; + if ( strcmp(token, "sin" ) == 0 ) return "help\\cbot\\expr.txt"; + if ( strcmp(token, "cos" ) == 0 ) return "help\\cbot\\expr.txt"; + if ( strcmp(token, "tan" ) == 0 ) return "help\\cbot\\expr.txt"; + if ( strcmp(token, "asin" ) == 0 ) return "help\\cbot\\expr.txt"; + if ( strcmp(token, "acos" ) == 0 ) return "help\\cbot\\expr.txt"; + if ( strcmp(token, "atan" ) == 0 ) return "help\\cbot\\expr.txt"; + if ( strcmp(token, "sqrt" ) == 0 ) return "help\\cbot\\expr.txt"; + if ( strcmp(token, "pow" ) == 0 ) return "help\\cbot\\expr.txt"; + if ( strcmp(token, "rand" ) == 0 ) return "help\\cbot\\expr.txt"; + if ( strcmp(token, "abs" ) == 0 ) return "help\\cbot\\expr.txt"; + if ( strcmp(token, "retobject" ) == 0 ) return "help\\cbot\\retobj.txt"; + if ( strcmp(token, "search" ) == 0 ) return "help\\cbot\\search.txt"; + if ( strcmp(token, "radar" ) == 0 ) return "help\\cbot\\radar.txt"; + if ( strcmp(token, "direction" ) == 0 ) return "help\\cbot\\direct.txt"; + if ( strcmp(token, "distance" ) == 0 ) return "help\\cbot\\dist.txt"; + if ( strcmp(token, "distance2d" ) == 0 ) return "help\\cbot\\dist2d.txt"; + if ( strcmp(token, "space" ) == 0 ) return "help\\cbot\\space.txt"; + if ( strcmp(token, "flatground" ) == 0 ) return "help\\cbot\\flatgrnd.txt"; + if ( strcmp(token, "wait" ) == 0 ) return "help\\cbot\\wait.txt"; + if ( strcmp(token, "move" ) == 0 ) return "help\\cbot\\move.txt"; + if ( strcmp(token, "turn" ) == 0 ) return "help\\cbot\\turn.txt"; + if ( strcmp(token, "goto" ) == 0 ) return "help\\cbot\\goto.txt"; + if ( strcmp(token, "find" ) == 0 ) return "help\\cbot\\find.txt"; + if ( strcmp(token, "grab" ) == 0 ) return "help\\cbot\\grab.txt"; + if ( strcmp(token, "drop" ) == 0 ) return "help\\cbot\\drop.txt"; + if ( strcmp(token, "sniff" ) == 0 ) return "help\\cbot\\sniff.txt"; + if ( strcmp(token, "receive" ) == 0 ) return "help\\cbot\\receive.txt"; + if ( strcmp(token, "send" ) == 0 ) return "help\\cbot\\send.txt"; + if ( strcmp(token, "deleteinfo" ) == 0 ) return "help\\cbot\\delinfo.txt"; + if ( strcmp(token, "testinfo" ) == 0 ) return "help\\cbot\\testinfo.txt"; + if ( strcmp(token, "thump" ) == 0 ) return "help\\cbot\\thump.txt"; + if ( strcmp(token, "recycle" ) == 0 ) return "help\\cbot\\recycle.txt"; + if ( strcmp(token, "shield" ) == 0 ) return "help\\cbot\\shield.txt"; + if ( strcmp(token, "fire" ) == 0 ) return "help\\cbot\\fire.txt"; + if ( strcmp(token, "antfire" ) == 0 ) return "help\\cbot\\antfire.txt"; + if ( strcmp(token, "aim" ) == 0 ) return "help\\cbot\\aim.txt"; + if ( strcmp(token, "motor" ) == 0 ) return "help\\cbot\\motor.txt"; + if ( strcmp(token, "jet" ) == 0 ) return "help\\cbot\\jet.txt"; + if ( strcmp(token, "topo" ) == 0 ) return "help\\cbot\\topo.txt"; + if ( strcmp(token, "message" ) == 0 ) return "help\\cbot\\message.txt"; + if ( strcmp(token, "abstime" ) == 0 ) return "help\\cbot\\abstime.txt"; + if ( strcmp(token, "BlackArrow" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "RedArrow" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "White" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "Black" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "Gray" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "LightGray" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "Red" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "Pink" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "Purple" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "Orange" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "Yellow" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "Beige" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "Brown" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "Skin" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "Green" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "LightGreen" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "Blue" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "LightBlue" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "InFront" ) == 0 ) return "help\\cbot\\grab.txt"; + if ( strcmp(token, "Behind" ) == 0 ) return "help\\cbot\\grab.txt"; + if ( strcmp(token, "EnergyCell" ) == 0 ) return "help\\cbot\\grab.txt"; + if ( strcmp(token, "DisplayError" ) == 0 ) return "help\\cbot\\message.txt"; + if ( strcmp(token, "DisplayWarning") == 0 ) return "help\\cbot\\message.txt"; + if ( strcmp(token, "DisplayInfo" ) == 0 ) return "help\\cbot\\message.txt"; + if ( strcmp(token, "DisplayMessage") == 0 ) return "help\\cbot\\message.txt"; + if ( strcmp(token, "strlen" ) == 0 ) return "help\\cbot\\string.txt"; + if ( strcmp(token, "strleft" ) == 0 ) return "help\\cbot\\string.txt"; + if ( strcmp(token, "strright" ) == 0 ) return "help\\cbot\\string.txt"; + if ( strcmp(token, "strmid" ) == 0 ) return "help\\cbot\\string.txt"; + if ( strcmp(token, "strval" ) == 0 ) return "help\\cbot\\string.txt"; + if ( strcmp(token, "strfind" ) == 0 ) return "help\\cbot\\string.txt"; + if ( strcmp(token, "strlower" ) == 0 ) return "help\\cbot\\string.txt"; + if ( strcmp(token, "strupper" ) == 0 ) return "help\\cbot\\string.txt"; + if ( strcmp(token, "open" ) == 0 ) return "help\\cbot\\open.txt"; + if ( strcmp(token, "close" ) == 0 ) return "help\\cbot\\close.txt"; + if ( strcmp(token, "writeln" ) == 0 ) return "help\\cbot\\writeln.txt"; + if ( strcmp(token, "readln " ) == 0 ) return "help\\cbot\\readln.txt"; + if ( strcmp(token, "eof" ) == 0 ) return "help\\cbot\\eof.txt"; + if ( strcmp(token, "deletefile" ) == 0 ) return "help\\cbot\\deletef.txt"; + if ( strcmp(token, "openfile" ) == 0 ) return "help\\cbot\\openfile.txt"; + if ( strcmp(token, "pendown" ) == 0 ) return "help\\cbot\\pendown.txt"; + if ( strcmp(token, "penup" ) == 0 ) return "help\\cbot\\penup.txt"; + if ( strcmp(token, "pencolor" ) == 0 ) return "help\\cbot\\pencolor.txt"; + if ( strcmp(token, "penwidth" ) == 0 ) return "help\\cbot\\penwidth.txt"; + if ( strcmp(token, "extern" ) == 0 ) return "help\\cbot\\extern.txt"; + if ( strcmp(token, "class" ) == 0 ) return "help\\cbot\\class.txt"; + if ( strcmp(token, "static" ) == 0 ) return "help\\cbot\\static.txt"; + if ( strcmp(token, "public" ) == 0 ) return "help\\cbot\\public.txt"; + if ( strcmp(token, "private" ) == 0 ) return "help\\cbot\\private.txt"; + if ( strcmp(token, "synchronized" ) == 0 ) return "help\\cbot\\synchro.txt"; + if ( strcmp(token, "new" ) == 0 ) return "help\\cbot\\new.txt"; + if ( strcmp(token, "this" ) == 0 ) return "help\\cbot\\this.txt"; + return ""; +} + + +// Test if a keyword is a type of variable. + +BOOL IsType(const char *token) +{ + if ( strcmp(token, "void" ) == 0 ) return TRUE; + if ( strcmp(token, "int" ) == 0 ) return TRUE; + if ( strcmp(token, "float" ) == 0 ) return TRUE; + if ( strcmp(token, "bool" ) == 0 ) return TRUE; + if ( strcmp(token, "string" ) == 0 ) return TRUE; + if ( strcmp(token, "point" ) == 0 ) return TRUE; + if ( strcmp(token, "object" ) == 0 ) return TRUE; + if ( strcmp(token, "file" ) == 0 ) return TRUE; + if ( strcmp(token, "this" ) == 0 ) return TRUE; + return FALSE; +} + +// Test if a keyword is a function. + +BOOL IsFunction(const char *token) +{ + if ( strcmp(token, "sin" ) == 0 ) return TRUE; + if ( strcmp(token, "cos" ) == 0 ) return TRUE; + if ( strcmp(token, "tan" ) == 0 ) return TRUE; + if ( strcmp(token, "asin" ) == 0 ) return TRUE; + if ( strcmp(token, "acos" ) == 0 ) return TRUE; + if ( strcmp(token, "atan" ) == 0 ) return TRUE; + if ( strcmp(token, "sqrt" ) == 0 ) return TRUE; + if ( strcmp(token, "pow" ) == 0 ) return TRUE; + if ( strcmp(token, "rand" ) == 0 ) return TRUE; + if ( strcmp(token, "abs" ) == 0 ) return TRUE; + if ( strcmp(token, "retobject" ) == 0 ) return TRUE; + if ( strcmp(token, "search" ) == 0 ) return TRUE; + if ( strcmp(token, "radar" ) == 0 ) return TRUE; + if ( strcmp(token, "detect" ) == 0 ) return TRUE; + if ( strcmp(token, "direction" ) == 0 ) return TRUE; + if ( strcmp(token, "distance" ) == 0 ) return TRUE; + if ( strcmp(token, "distance2d" ) == 0 ) return TRUE; + if ( strcmp(token, "space" ) == 0 ) return TRUE; + if ( strcmp(token, "flatground" ) == 0 ) return TRUE; + if ( strcmp(token, "wait" ) == 0 ) return TRUE; + if ( strcmp(token, "move" ) == 0 ) return TRUE; + if ( strcmp(token, "turn" ) == 0 ) return TRUE; + if ( strcmp(token, "goto" ) == 0 ) return TRUE; + if ( strcmp(token, "find" ) == 0 ) return TRUE; + if ( strcmp(token, "grab" ) == 0 ) return TRUE; + if ( strcmp(token, "drop" ) == 0 ) return TRUE; + if ( strcmp(token, "sniff" ) == 0 ) return TRUE; + if ( strcmp(token, "receive" ) == 0 ) return TRUE; + if ( strcmp(token, "send" ) == 0 ) return TRUE; + if ( strcmp(token, "deleteinfo" ) == 0 ) return TRUE; + if ( strcmp(token, "testinfo" ) == 0 ) return TRUE; + if ( strcmp(token, "thump" ) == 0 ) return TRUE; + if ( strcmp(token, "recycle" ) == 0 ) return TRUE; + if ( strcmp(token, "shield" ) == 0 ) return TRUE; + if ( strcmp(token, "fire" ) == 0 ) return TRUE; + if ( strcmp(token, "antfire" ) == 0 ) return TRUE; + if ( strcmp(token, "aim" ) == 0 ) return TRUE; + if ( strcmp(token, "motor" ) == 0 ) return TRUE; + if ( strcmp(token, "jet" ) == 0 ) return TRUE; + if ( strcmp(token, "topo" ) == 0 ) return TRUE; + if ( strcmp(token, "message" ) == 0 ) return TRUE; + if ( strcmp(token, "abstime" ) == 0 ) return TRUE; + if ( strcmp(token, "ismovie" ) == 0 ) return TRUE; + if ( strcmp(token, "errmode" ) == 0 ) return TRUE; + if ( strcmp(token, "ipf" ) == 0 ) return TRUE; + if ( strcmp(token, "strlen" ) == 0 ) return TRUE; + if ( strcmp(token, "strleft" ) == 0 ) return TRUE; + if ( strcmp(token, "strright" ) == 0 ) return TRUE; + if ( strcmp(token, "strmid" ) == 0 ) return TRUE; + if ( strcmp(token, "strval" ) == 0 ) return TRUE; + if ( strcmp(token, "strfind" ) == 0 ) return TRUE; + if ( strcmp(token, "strlower" ) == 0 ) return TRUE; + if ( strcmp(token, "strupper" ) == 0 ) return TRUE; + if ( strcmp(token, "open" ) == 0 ) return TRUE; + if ( strcmp(token, "close" ) == 0 ) return TRUE; + if ( strcmp(token, "writeln" ) == 0 ) return TRUE; + if ( strcmp(token, "readln" ) == 0 ) return TRUE; + if ( strcmp(token, "eof" ) == 0 ) return TRUE; + if ( strcmp(token, "deletefile" ) == 0 ) return TRUE; + if ( strcmp(token, "openfile" ) == 0 ) return TRUE; + if ( strcmp(token, "pendown" ) == 0 ) return TRUE; + if ( strcmp(token, "penup" ) == 0 ) return TRUE; + if ( strcmp(token, "pencolor" ) == 0 ) return TRUE; + if ( strcmp(token, "penwidth" ) == 0 ) return TRUE; + if ( strcmp(token, "sizeof" ) == 0 ) return TRUE; + return FALSE; +} + + +// Returns using a compact instruction. + +char* RetHelpText(const char *token) +{ + if ( strcmp(token, "if" ) == 0 ) return "if ( condition ) { bloc }"; + if ( strcmp(token, "else" ) == 0 ) return "else { bloc }"; + if ( strcmp(token, "repeat" ) == 0 ) return "repeat ( number )"; + if ( strcmp(token, "for" ) == 0 ) return "for ( before ; condition ; end )"; + if ( strcmp(token, "while" ) == 0 ) return "while ( condition ) { bloc }"; + if ( strcmp(token, "do" ) == 0 ) return "do { bloc } while ( condition );"; + if ( strcmp(token, "break" ) == 0 ) return "break;"; + if ( strcmp(token, "continue" ) == 0 ) return "continue;"; + if ( strcmp(token, "return" ) == 0 ) return "return;"; + if ( strcmp(token, "sizeof" ) == 0 ) return "sizeof( array );"; + if ( strcmp(token, "int" ) == 0 ) return "int"; + if ( strcmp(token, "sin" ) == 0 ) return "sin ( angle );"; + if ( strcmp(token, "cos" ) == 0 ) return "cos ( angle );"; + if ( strcmp(token, "tan" ) == 0 ) return "tan ( angle );"; + if ( strcmp(token, "asin" ) == 0 ) return "asin ( value );"; + if ( strcmp(token, "acos" ) == 0 ) return "acos ( value );"; + if ( strcmp(token, "atan" ) == 0 ) return "atan ( value );"; + if ( strcmp(token, "sqrt" ) == 0 ) return "sqrt ( value );"; + if ( strcmp(token, "pow" ) == 0 ) return "pow ( x, y );"; + if ( strcmp(token, "rand" ) == 0 ) return "rand ( );"; + if ( strcmp(token, "abs" ) == 0 ) return "abs ( value );"; + if ( strcmp(token, "retobject" ) == 0 ) return "retobjet ( );"; + if ( strcmp(token, "search" ) == 0 ) return "search ( );"; + if ( strcmp(token, "radar" ) == 0 ) return "radar ( cat, angle, focus, min, max, sens );"; + if ( strcmp(token, "detect" ) == 0 ) return "detect ( cat );"; + if ( strcmp(token, "direction" ) == 0 ) return "direction ( position );"; + if ( strcmp(token, "distance2d") == 0 ) return "distance2d ( p1, p2 );"; + if ( strcmp(token, "distance" ) == 0 ) return "distance ( p1, p2 );"; + if ( strcmp(token, "space" ) == 0 ) return "space ( center, rmin, rmax, dist );"; + if ( strcmp(token, "flatground") == 0 ) return "flatground ( center, rmax );"; + if ( strcmp(token, "wait" ) == 0 ) return "wait ( time );"; + if ( strcmp(token, "move" ) == 0 ) return "move ( distance );"; + if ( strcmp(token, "turn" ) == 0 ) return "turn ( angle );"; + if ( strcmp(token, "goto" ) == 0 ) return "goto ( position, altitude );"; + if ( strcmp(token, "find" ) == 0 ) return "find ( cat );"; + if ( strcmp(token, "grab" ) == 0 ) return "grab ( order );"; + if ( strcmp(token, "drop" ) == 0 ) return "drop ( order );"; + if ( strcmp(token, "sniff" ) == 0 ) return "sniff ( );"; + if ( strcmp(token, "receive" ) == 0 ) return "receive ( name, power );"; + if ( strcmp(token, "send" ) == 0 ) return "send ( name, value, power );"; + if ( strcmp(token, "deleteinfo") == 0 ) return "deleteinfo ( name, power );"; + if ( strcmp(token, "testinfo" ) == 0 ) return "testinfo ( name, power );"; + if ( strcmp(token, "thump" ) == 0 ) return "thump ( );"; + if ( strcmp(token, "recycle" ) == 0 ) return "recycle ( );"; + if ( strcmp(token, "shield" ) == 0 ) return "shield ( oper, radius );"; + if ( strcmp(token, "fire" ) == 0 ) return "fire ( time );"; + if ( strcmp(token, "antfire" ) == 0 ) return "antfire ( );"; + if ( strcmp(token, "aim" ) == 0 ) return "aim ( angle );"; + if ( strcmp(token, "motor" ) == 0 ) return "motor ( left, right );"; + if ( strcmp(token, "jet" ) == 0 ) return "jet ( power );"; + if ( strcmp(token, "topo" ) == 0 ) return "topo ( position );"; + if ( strcmp(token, "message" ) == 0 ) return "message ( string, type );"; + if ( strcmp(token, "abstime" ) == 0 ) return "abstime ( );"; + if ( strcmp(token, "ismovie" ) == 0 ) return "ismovie ( );"; + if ( strcmp(token, "errmode" ) == 0 ) return "errmode ( mdoe );"; + if ( strcmp(token, "ipf" ) == 0 ) return "ipf ( number );"; + if ( strcmp(token, "strlen" ) == 0 ) return "strlen ( string );"; + if ( strcmp(token, "strleft" ) == 0 ) return "strleft ( string, len );"; + if ( strcmp(token, "strright" ) == 0 ) return "strright ( string, len );"; + if ( strcmp(token, "strmid" ) == 0 ) return "strmid ( string, pos, len );"; + if ( strcmp(token, "strval" ) == 0 ) return "strval ( string );"; + if ( strcmp(token, "strfind" ) == 0 ) return "strfind ( string, substring );"; + if ( strcmp(token, "strlower" ) == 0 ) return "strlower ( string );"; + if ( strcmp(token, "strupper" ) == 0 ) return "strupper ( string );"; + if ( strcmp(token, "open" ) == 0 ) return "open ( filename, mode );"; + if ( strcmp(token, "close" ) == 0 ) return "close ( );"; + if ( strcmp(token, "writeln" ) == 0 ) return "writeln ( string );"; + if ( strcmp(token, "readln" ) == 0 ) return "readln ( );"; + if ( strcmp(token, "eof" ) == 0 ) return "eof ( );"; + if ( strcmp(token, "deletefile") == 0 ) return "deletefile ( filename );"; + if ( strcmp(token, "openfile" ) == 0 ) return "openfile ( filename, mode );"; + if ( strcmp(token, "pendown" ) == 0 ) return "pendown ( color, width );"; + if ( strcmp(token, "penup" ) == 0 ) return "penup ( );"; + if ( strcmp(token, "pencolor" ) == 0 ) return "pencolor ( color );"; + if ( strcmp(token, "penwidth" ) == 0 ) return "penwidth ( width );"; + return ""; +} + + diff --git a/src/script/cbottoken.h b/src/script/cbottoken.h new file mode 100644 index 0000000..0767b04 --- /dev/null +++ b/src/script/cbottoken.h @@ -0,0 +1,39 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// cbottoken.h + +#ifndef _CBOTTOKEN_H_ +#define _CBOTTOKEN_H_ + + +#include "object.h" + + + +// Procedures. + +extern char* RetObjectName(ObjectType type); +extern char* RetObjectAlias(ObjectType type); +extern char* RetHelpFilename(ObjectType type); +extern char* RetHelpFilename(const char *token); +extern BOOL IsType(const char *token); +extern BOOL IsFunction(const char *token); +extern char* RetHelpText(const char *token); + + + +#endif //_CBOTTOKEN_H_ diff --git a/src/script/cmdtoken.cpp b/src/script/cmdtoken.cpp new file mode 100644 index 0000000..d5295c5 --- /dev/null +++ b/src/script/cmdtoken.cpp @@ -0,0 +1,978 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "language.h" +#include "global.h" +#include "event.h" +#include "water.h" +#include "pyro.h" +#include "camera.h" +#include "object.h" +#include "cmdtoken.h" + + + + + +// Skips spaces. + +char* SkipSpace(char *line) +{ + while ( *line == ' ' ) + { + line ++; + } + return line; +} + +// Checks if a line contains a command. + +BOOL Cmd(char *line, char *token) +{ + char* p; + + line = SkipSpace(line); + p = strstr(line, token); + return ( p == line ); // command at the beginning? +} + +// Seeking an operator. + +char* SearchOp(char *line, char *op) +{ + char opeq[50]; + char* p; + + strcpy(opeq, " "); + strcat(opeq, op); + strcat(opeq, "="); + + p = strstr(line, opeq); + if ( p == 0 ) // not found? + { + return line+strlen(line); // point zero terminator + } + return p+strlen(opeq); // after the point "=" +} + +// Seeks the argument. + +char* SearchArg(char *line, int rank) +{ + int i; + char c; + + for ( i=0 ; i= '0' && *p <= '9' ) + { + n *= 16; + n += (*p++)-'0'; + continue; + } + if ( *p >= 'a' && *p <= 'f' ) + { + n *= 16; + n += (*p++)-'a'+10; + continue; + } + break; + } + } + else // integer? + { + sscanf(p, "%d", &n); + } + return n; +} + +// Reads a float number. + +float GetFloat(char *line, int rank, float def) +{ + char* p; + float n = 0.0f; + + p = SearchArg(line, rank); + if ( *p == 0 ) return def; + + sscanf(p, "%f", &n); + return n; +} + +// Reads a string. + +void GetString(char *line, int rank, char *buffer) +{ + char* p; + + p = SearchArg(line, rank); + *buffer = 0; + if ( *p++ != '"' ) return; + + while ( p[0] != 0 ) + { + if ( p[0] == '"' && + p[1] == '"' ) + { + *buffer++ = *p++; + p++; + continue; + } + if ( p[0] == '"' ) break; + + *buffer++ = *p++; + } + *buffer = 0; +} + +// Returns the type of an object. + +ObjectType GetTypeObject(char *line, int rank, ObjectType def) +{ + char* p; + + p = SearchArg(line, rank); + if ( *p == 0 ) return def; + + if ( Cmd(p, "All" ) ) return OBJECT_NULL; + if ( Cmd(p, "Portico" ) ) return OBJECT_PORTICO; + if ( Cmd(p, "SpaceShip" ) ) return OBJECT_BASE; + if ( Cmd(p, "PracticeBot" ) ) return OBJECT_MOBILEwt; + if ( Cmd(p, "WingedGrabber" ) ) return OBJECT_MOBILEfa; + if ( Cmd(p, "TrackedGrabber" ) ) return OBJECT_MOBILEta; + if ( Cmd(p, "WheeledGrabber" ) ) return OBJECT_MOBILEwa; + if ( Cmd(p, "LeggedGrabber" ) ) return OBJECT_MOBILEia; + if ( Cmd(p, "WingedShooter" ) ) return OBJECT_MOBILEfc; + if ( Cmd(p, "TrackedShooter" ) ) return OBJECT_MOBILEtc; + if ( Cmd(p, "WheeledShooter" ) ) return OBJECT_MOBILEwc; + if ( Cmd(p, "LeggedShooter" ) ) return OBJECT_MOBILEic; + if ( Cmd(p, "WingedOrgaShooter" ) ) return OBJECT_MOBILEfi; + if ( Cmd(p, "TrackedOrgaShooter") ) return OBJECT_MOBILEti; + if ( Cmd(p, "WheeledOrgaShooter") ) return OBJECT_MOBILEwi; + if ( Cmd(p, "LeggedOrgaShooter" ) ) return OBJECT_MOBILEii; + if ( Cmd(p, "WingedSniffer" ) ) return OBJECT_MOBILEfs; + if ( Cmd(p, "TrackedSniffer" ) ) return OBJECT_MOBILEts; + if ( Cmd(p, "WheeledSniffer" ) ) return OBJECT_MOBILEws; + if ( Cmd(p, "LeggedSniffer" ) ) return OBJECT_MOBILEis; + if ( Cmd(p, "Thumper" ) ) return OBJECT_MOBILErt; + if ( Cmd(p, "PhazerShooter" ) ) return OBJECT_MOBILErc; + if ( Cmd(p, "Recycler" ) ) return OBJECT_MOBILErr; + if ( Cmd(p, "Shielder" ) ) return OBJECT_MOBILErs; + if ( Cmd(p, "Subber" ) ) return OBJECT_MOBILEsa; + if ( Cmd(p, "TargetBot" ) ) return OBJECT_MOBILEtg; + if ( Cmd(p, "Scribbler" ) ) return OBJECT_MOBILEdr; + if ( Cmd(p, "PowerSpot" ) ) return OBJECT_MARKPOWER; + if ( Cmd(p, "TitaniumSpot" ) ) return OBJECT_MARKSTONE; + if ( Cmd(p, "UraniumSpot" ) ) return OBJECT_MARKURANIUM; + if ( Cmd(p, "PlatinumSpot" ) ) return OBJECT_MARKURANIUM; + if ( Cmd(p, "KeyASpot" ) ) return OBJECT_MARKKEYa; + if ( Cmd(p, "KeyBSpot" ) ) return OBJECT_MARKKEYb; + if ( Cmd(p, "KeyCSpot" ) ) return OBJECT_MARKKEYc; + if ( Cmd(p, "KeyDSpot" ) ) return OBJECT_MARKKEYd; + if ( Cmd(p, "WayPoint" ) ) return OBJECT_WAYPOINT; + if ( Cmd(p, "BlueFlag" ) ) return OBJECT_FLAGb; + if ( Cmd(p, "RedFlag" ) ) return OBJECT_FLAGr; + if ( Cmd(p, "GreenFlag" ) ) return OBJECT_FLAGg; + if ( Cmd(p, "YellowFlag" ) ) return OBJECT_FLAGy; + if ( Cmd(p, "VioletFlag" ) ) return OBJECT_FLAGv; + if ( Cmd(p, "PowerCell" ) ) return OBJECT_POWER; + if ( Cmd(p, "FuelCellPlant" ) ) return OBJECT_NUCLEAR; + if ( Cmd(p, "FuelCell" ) ) return OBJECT_ATOMIC; + if ( Cmd(p, "NuclearCell" ) ) return OBJECT_ATOMIC; + if ( Cmd(p, "TitaniumOre" ) ) return OBJECT_STONE; + if ( Cmd(p, "UraniumOre" ) ) return OBJECT_URANIUM; + if ( Cmd(p, "PlatinumOre" ) ) return OBJECT_URANIUM; + if ( Cmd(p, "Titanium" ) ) return OBJECT_METAL; + if ( Cmd(p, "OrgaMatter" ) ) return OBJECT_BULLET; + if ( Cmd(p, "BlackBox" ) ) return OBJECT_BBOX; + if ( Cmd(p, "KeyA" ) ) return OBJECT_KEYa; + if ( Cmd(p, "KeyB" ) ) return OBJECT_KEYb; + if ( Cmd(p, "KeyC" ) ) return OBJECT_KEYc; + if ( Cmd(p, "KeyD" ) ) return OBJECT_KEYd; + if ( Cmd(p, "TNT" ) ) return OBJECT_TNT; + if ( Cmd(p, "Scrap1" ) ) return OBJECT_SCRAP1; + if ( Cmd(p, "Scrap2" ) ) return OBJECT_SCRAP2; + if ( Cmd(p, "Scrap3" ) ) return OBJECT_SCRAP3; + if ( Cmd(p, "Scrap4" ) ) return OBJECT_SCRAP4; + if ( Cmd(p, "Scrap5" ) ) return OBJECT_SCRAP5; + if ( Cmd(p, "Mine" ) ) return OBJECT_BOMB; + if ( Cmd(p, "Firework" ) ) return OBJECT_WINFIRE; + if ( Cmd(p, "Bag" ) ) return OBJECT_BAG; + if ( Cmd(p, "Greenery10" ) ) return OBJECT_PLANT10; + if ( Cmd(p, "Greenery11" ) ) return OBJECT_PLANT11; + if ( Cmd(p, "Greenery12" ) ) return OBJECT_PLANT12; + if ( Cmd(p, "Greenery13" ) ) return OBJECT_PLANT13; + if ( Cmd(p, "Greenery14" ) ) return OBJECT_PLANT14; + if ( Cmd(p, "Greenery15" ) ) return OBJECT_PLANT15; + if ( Cmd(p, "Greenery16" ) ) return OBJECT_PLANT16; + if ( Cmd(p, "Greenery17" ) ) return OBJECT_PLANT17; + if ( Cmd(p, "Greenery18" ) ) return OBJECT_PLANT18; + if ( Cmd(p, "Greenery19" ) ) return OBJECT_PLANT19; + if ( Cmd(p, "Greenery0" ) ) return OBJECT_PLANT0; + if ( Cmd(p, "Greenery1" ) ) return OBJECT_PLANT1; + if ( Cmd(p, "Greenery2" ) ) return OBJECT_PLANT2; + if ( Cmd(p, "Greenery3" ) ) return OBJECT_PLANT3; + if ( Cmd(p, "Greenery4" ) ) return OBJECT_PLANT4; + if ( Cmd(p, "Greenery5" ) ) return OBJECT_PLANT5; + if ( Cmd(p, "Greenery6" ) ) return OBJECT_PLANT6; + if ( Cmd(p, "Greenery7" ) ) return OBJECT_PLANT7; + if ( Cmd(p, "Greenery8" ) ) return OBJECT_PLANT8; + if ( Cmd(p, "Greenery9" ) ) return OBJECT_PLANT9; + if ( Cmd(p, "Tree0" ) ) return OBJECT_TREE0; + if ( Cmd(p, "Tree1" ) ) return OBJECT_TREE1; + if ( Cmd(p, "Tree2" ) ) return OBJECT_TREE2; + if ( Cmd(p, "Tree3" ) ) return OBJECT_TREE3; + if ( Cmd(p, "Tree4" ) ) return OBJECT_TREE4; + if ( Cmd(p, "Tree5" ) ) return OBJECT_TREE5; + if ( Cmd(p, "Tree6" ) ) return OBJECT_TREE6; + if ( Cmd(p, "Tree7" ) ) return OBJECT_TREE7; + if ( Cmd(p, "Tree8" ) ) return OBJECT_TREE8; + if ( Cmd(p, "Tree9" ) ) return OBJECT_TREE9; + if ( Cmd(p, "Mushroom0" ) ) return OBJECT_MUSHROOM0; + if ( Cmd(p, "Mushroom1" ) ) return OBJECT_MUSHROOM1; + if ( Cmd(p, "Mushroom2" ) ) return OBJECT_MUSHROOM2; + if ( Cmd(p, "Mushroom3" ) ) return OBJECT_MUSHROOM3; + if ( Cmd(p, "Mushroom4" ) ) return OBJECT_MUSHROOM4; + if ( Cmd(p, "Mushroom5" ) ) return OBJECT_MUSHROOM5; + if ( Cmd(p, "Mushroom6" ) ) return OBJECT_MUSHROOM6; + if ( Cmd(p, "Mushroom7" ) ) return OBJECT_MUSHROOM7; + if ( Cmd(p, "Mushroom8" ) ) return OBJECT_MUSHROOM8; + if ( Cmd(p, "Mushroom9" ) ) return OBJECT_MUSHROOM9; + if ( Cmd(p, "Home" ) ) return OBJECT_HOME1; + if ( Cmd(p, "Derrick" ) ) return OBJECT_DERRICK; + if ( Cmd(p, "BotFactory" ) ) return OBJECT_FACTORY; + if ( Cmd(p, "PowerStation" ) ) return OBJECT_STATION; + if ( Cmd(p, "Converter" ) ) return OBJECT_CONVERT; + if ( Cmd(p, "RepairCenter" ) ) return OBJECT_REPAIR; + if ( Cmd(p, "Destroyer" ) ) return OBJECT_DESTROYER; + if ( Cmd(p, "DefenseTower" ) ) return OBJECT_TOWER; + if ( Cmd(p, "AlienNest" ) ) return OBJECT_NEST; + if ( Cmd(p, "ResearchCenter" ) ) return OBJECT_RESEARCH; + if ( Cmd(p, "RadarStation" ) ) return OBJECT_RADAR; + if ( Cmd(p, "ExchangePost" ) ) return OBJECT_INFO; + if ( Cmd(p, "PowerPlant" ) ) return OBJECT_ENERGY; + if ( Cmd(p, "AutoLab" ) ) return OBJECT_LABO; + if ( Cmd(p, "NuclearPlant" ) ) return OBJECT_NUCLEAR; + if ( Cmd(p, "PowerCaptor" ) ) return OBJECT_PARA; + if ( Cmd(p, "Vault" ) ) return OBJECT_SAFE; + if ( Cmd(p, "Houston" ) ) return OBJECT_HUSTON; + if ( Cmd(p, "Target1" ) ) return OBJECT_TARGET1; + if ( Cmd(p, "Target2" ) ) return OBJECT_TARGET2; + if ( Cmd(p, "StartArea" ) ) return OBJECT_START; + if ( Cmd(p, "GoalArea" ) ) return OBJECT_END; + if ( Cmd(p, "AlienQueen" ) ) return OBJECT_MOTHER; + if ( Cmd(p, "AlienEgg" ) ) return OBJECT_EGG; + if ( Cmd(p, "AlienAnt" ) ) return OBJECT_ANT; + if ( Cmd(p, "AlienSpider" ) ) return OBJECT_SPIDER; + if ( Cmd(p, "AlienWasp" ) ) return OBJECT_BEE; + if ( Cmd(p, "AlienWorm" ) ) return OBJECT_WORM; + if ( Cmd(p, "WreckBotw1" ) ) return OBJECT_RUINmobilew1; + if ( Cmd(p, "WreckBotw2" ) ) return OBJECT_RUINmobilew2; + if ( Cmd(p, "WreckBott1" ) ) return OBJECT_RUINmobilet1; + if ( Cmd(p, "WreckBott2" ) ) return OBJECT_RUINmobilet2; + if ( Cmd(p, "WreckBotr1" ) ) return OBJECT_RUINmobiler1; + if ( Cmd(p, "WreckBotr2" ) ) return OBJECT_RUINmobiler2; + if ( Cmd(p, "RuinBotFactory" ) ) return OBJECT_RUINfactory; + if ( Cmd(p, "RuinDoor" ) ) return OBJECT_RUINdoor; + if ( Cmd(p, "RuinSupport" ) ) return OBJECT_RUINsupport; + if ( Cmd(p, "RuinRadar" ) ) return OBJECT_RUINradar; + if ( Cmd(p, "RuinConvert" ) ) return OBJECT_RUINconvert; + if ( Cmd(p, "RuinBaseCamp" ) ) return OBJECT_RUINbase; + if ( Cmd(p, "RuinHeadCamp" ) ) return OBJECT_RUINhead; + if ( Cmd(p, "Barrier0" ) ) return OBJECT_BARRIER0; + if ( Cmd(p, "Barrier1" ) ) return OBJECT_BARRIER1; + if ( Cmd(p, "Barrier2" ) ) return OBJECT_BARRIER2; + if ( Cmd(p, "Barrier3" ) ) return OBJECT_BARRIER3; + if ( Cmd(p, "Barrier4" ) ) return OBJECT_BARRIER4; + if ( Cmd(p, "Teen40" ) ) return OBJECT_TEEN40; + if ( Cmd(p, "Teen41" ) ) return OBJECT_TEEN41; + if ( Cmd(p, "Teen42" ) ) return OBJECT_TEEN42; + if ( Cmd(p, "Teen43" ) ) return OBJECT_TEEN43; + if ( Cmd(p, "Teen44" ) ) return OBJECT_TEEN44; + if ( Cmd(p, "Teen45" ) ) return OBJECT_TEEN45; + if ( Cmd(p, "Teen46" ) ) return OBJECT_TEEN46; + if ( Cmd(p, "Teen47" ) ) return OBJECT_TEEN47; + if ( Cmd(p, "Teen48" ) ) return OBJECT_TEEN48; + if ( Cmd(p, "Teen49" ) ) return OBJECT_TEEN49; + if ( Cmd(p, "Teen30" ) ) return OBJECT_TEEN30; + if ( Cmd(p, "Teen31" ) ) return OBJECT_TEEN31; + if ( Cmd(p, "Teen32" ) ) return OBJECT_TEEN32; + if ( Cmd(p, "Teen33" ) ) return OBJECT_TEEN33; + if ( Cmd(p, "Stone" ) ) return OBJECT_TEEN34; + if ( Cmd(p, "Teen35" ) ) return OBJECT_TEEN35; + if ( Cmd(p, "Teen36" ) ) return OBJECT_TEEN36; + if ( Cmd(p, "Teen37" ) ) return OBJECT_TEEN37; + if ( Cmd(p, "Teen38" ) ) return OBJECT_TEEN38; + if ( Cmd(p, "Teen39" ) ) return OBJECT_TEEN39; + if ( Cmd(p, "Teen20" ) ) return OBJECT_TEEN20; + if ( Cmd(p, "Teen21" ) ) return OBJECT_TEEN21; + if ( Cmd(p, "Teen22" ) ) return OBJECT_TEEN22; + if ( Cmd(p, "Teen23" ) ) return OBJECT_TEEN23; + if ( Cmd(p, "Teen24" ) ) return OBJECT_TEEN24; + if ( Cmd(p, "Teen25" ) ) return OBJECT_TEEN25; + if ( Cmd(p, "Teen26" ) ) return OBJECT_TEEN26; + if ( Cmd(p, "Teen27" ) ) return OBJECT_TEEN27; + if ( Cmd(p, "Teen28" ) ) return OBJECT_TEEN28; + if ( Cmd(p, "Teen29" ) ) return OBJECT_TEEN29; + if ( Cmd(p, "Teen10" ) ) return OBJECT_TEEN10; + if ( Cmd(p, "Teen11" ) ) return OBJECT_TEEN11; + if ( Cmd(p, "Teen12" ) ) return OBJECT_TEEN12; + if ( Cmd(p, "Teen13" ) ) return OBJECT_TEEN13; + if ( Cmd(p, "Teen14" ) ) return OBJECT_TEEN14; + if ( Cmd(p, "Teen15" ) ) return OBJECT_TEEN15; + if ( Cmd(p, "Teen16" ) ) return OBJECT_TEEN16; + if ( Cmd(p, "Teen17" ) ) return OBJECT_TEEN17; + if ( Cmd(p, "Teen18" ) ) return OBJECT_TEEN18; + if ( Cmd(p, "Teen19" ) ) return OBJECT_TEEN19; + if ( Cmd(p, "Teen0" ) ) return OBJECT_TEEN0; + if ( Cmd(p, "Teen1" ) ) return OBJECT_TEEN1; + if ( Cmd(p, "Teen2" ) ) return OBJECT_TEEN2; + if ( Cmd(p, "Teen3" ) ) return OBJECT_TEEN3; + if ( Cmd(p, "Teen4" ) ) return OBJECT_TEEN4; + if ( Cmd(p, "Teen5" ) ) return OBJECT_TEEN5; + if ( Cmd(p, "Teen6" ) ) return OBJECT_TEEN6; + if ( Cmd(p, "Teen7" ) ) return OBJECT_TEEN7; + if ( Cmd(p, "Teen8" ) ) return OBJECT_TEEN8; + if ( Cmd(p, "Teen9" ) ) return OBJECT_TEEN9; + if ( Cmd(p, "Quartz0" ) ) return OBJECT_QUARTZ0; + if ( Cmd(p, "Quartz1" ) ) return OBJECT_QUARTZ1; + if ( Cmd(p, "Quartz2" ) ) return OBJECT_QUARTZ2; + if ( Cmd(p, "Quartz3" ) ) return OBJECT_QUARTZ3; + if ( Cmd(p, "Quartz4" ) ) return OBJECT_QUARTZ4; + if ( Cmd(p, "Quartz5" ) ) return OBJECT_QUARTZ5; + if ( Cmd(p, "Quartz6" ) ) return OBJECT_QUARTZ6; + if ( Cmd(p, "Quartz7" ) ) return OBJECT_QUARTZ7; + if ( Cmd(p, "Quartz8" ) ) return OBJECT_QUARTZ8; + if ( Cmd(p, "Quartz9" ) ) return OBJECT_QUARTZ9; + if ( Cmd(p, "MegaStalk0" ) ) return OBJECT_ROOT0; + if ( Cmd(p, "MegaStalk1" ) ) return OBJECT_ROOT1; + if ( Cmd(p, "MegaStalk2" ) ) return OBJECT_ROOT2; + if ( Cmd(p, "MegaStalk3" ) ) return OBJECT_ROOT3; + if ( Cmd(p, "MegaStalk4" ) ) return OBJECT_ROOT4; + if ( Cmd(p, "MegaStalk5" ) ) return OBJECT_ROOT5; + if ( Cmd(p, "MegaStalk6" ) ) return OBJECT_ROOT6; + if ( Cmd(p, "MegaStalk7" ) ) return OBJECT_ROOT7; + if ( Cmd(p, "MegaStalk8" ) ) return OBJECT_ROOT8; + if ( Cmd(p, "MegaStalk9" ) ) return OBJECT_ROOT9; + if ( Cmd(p, "ApolloLEM" ) ) return OBJECT_APOLLO1; + if ( Cmd(p, "ApolloJeep" ) ) return OBJECT_APOLLO2; + if ( Cmd(p, "ApolloFlag" ) ) return OBJECT_APOLLO3; + if ( Cmd(p, "ApolloModule" ) ) return OBJECT_APOLLO4; + if ( Cmd(p, "ApolloAntenna" ) ) return OBJECT_APOLLO5; + if ( Cmd(p, "Me" ) ) return OBJECT_HUMAN; + if ( Cmd(p, "Tech" ) ) return OBJECT_TECH; + + return def; +} + +// Returns the name of an object type. + +char* GetTypeObject(ObjectType type) +{ + if ( type == OBJECT_PORTICO ) return "Portico"; + if ( type == OBJECT_BASE ) return "SpaceShip"; + if ( type == OBJECT_MOBILEwt ) return "PracticeBot"; + if ( type == OBJECT_MOBILEfa ) return "WingedGrabber"; + if ( type == OBJECT_MOBILEta ) return "TrackedGrabber"; + if ( type == OBJECT_MOBILEwa ) return "WheeledGrabber"; + if ( type == OBJECT_MOBILEia ) return "LeggedGrabber"; + if ( type == OBJECT_MOBILEfc ) return "WingedShooter"; + if ( type == OBJECT_MOBILEtc ) return "TrackedShooter"; + if ( type == OBJECT_MOBILEwc ) return "WheeledShooter"; + if ( type == OBJECT_MOBILEic ) return "LeggedShooter"; + if ( type == OBJECT_MOBILEfi ) return "WingedOrgaShooter"; + if ( type == OBJECT_MOBILEti ) return "TrackedOrgaShooter"; + if ( type == OBJECT_MOBILEwi ) return "WheeledOrgaShooter"; + if ( type == OBJECT_MOBILEii ) return "LeggedOrgaShooter"; + if ( type == OBJECT_MOBILEfs ) return "WingedSniffer"; + if ( type == OBJECT_MOBILEts ) return "TrackedSniffer"; + if ( type == OBJECT_MOBILEws ) return "WheeledSniffer"; + if ( type == OBJECT_MOBILEis ) return "LeggedSniffer"; + if ( type == OBJECT_MOBILErt ) return "Thumper"; + if ( type == OBJECT_MOBILErc ) return "PhazerShooter"; + if ( type == OBJECT_MOBILErr ) return "Recycler"; + if ( type == OBJECT_MOBILErs ) return "Shielder"; + if ( type == OBJECT_MOBILEsa ) return "Subber"; + if ( type == OBJECT_MOBILEtg ) return "TargetBot"; + if ( type == OBJECT_MOBILEdr ) return "Scribbler"; + if ( type == OBJECT_MARKPOWER ) return "PowerSpot"; + if ( type == OBJECT_MARKSTONE ) return "TitaniumSpot"; +#if _GERMAN | _WG + if ( type == OBJECT_MARKURANIUM ) return "PlatinumSpot"; +#else + if ( type == OBJECT_MARKURANIUM ) return "UraniumSpot"; +#endif + if ( type == OBJECT_MARKKEYa ) return "KeyASpot"; + if ( type == OBJECT_MARKKEYb ) return "KeyBSpot"; + if ( type == OBJECT_MARKKEYc ) return "KeyCSpot"; + if ( type == OBJECT_MARKKEYd ) return "KeyDSpot"; + if ( type == OBJECT_WAYPOINT ) return "WayPoint"; + if ( type == OBJECT_FLAGb ) return "BlueFlag"; + if ( type == OBJECT_FLAGr ) return "RedFlag"; + if ( type == OBJECT_FLAGg ) return "GreenFlag"; + if ( type == OBJECT_FLAGy ) return "YellowFlag"; + if ( type == OBJECT_FLAGv ) return "VioletFlag"; + if ( type == OBJECT_POWER ) return "PowerCell"; +#if _GERMAN | _WG + if ( type == OBJECT_ATOMIC ) return "FuelCell"; +#else + if ( type == OBJECT_ATOMIC ) return "NuclearCell"; +#endif + if ( type == OBJECT_STONE ) return "TitaniumOre"; +#if _GERMAN | _WG + if ( type == OBJECT_URANIUM ) return "PlatinumOre"; +#else + if ( type == OBJECT_URANIUM ) return "UraniumOre"; +#endif + if ( type == OBJECT_METAL ) return "Titanium"; + if ( type == OBJECT_BULLET ) return "OrgaMatter"; + if ( type == OBJECT_BBOX ) return "BlackBox"; + if ( type == OBJECT_KEYa ) return "KeyA"; + if ( type == OBJECT_KEYb ) return "KeyB"; + if ( type == OBJECT_KEYc ) return "KeyC"; + if ( type == OBJECT_KEYd ) return "KeyD"; + if ( type == OBJECT_TNT ) return "TNT"; + if ( type == OBJECT_SCRAP1 ) return "Scrap1"; + if ( type == OBJECT_SCRAP2 ) return "Scrap2"; + if ( type == OBJECT_SCRAP3 ) return "Scrap3"; + if ( type == OBJECT_SCRAP4 ) return "Scrap4"; + if ( type == OBJECT_SCRAP5 ) return "Scrap5"; + if ( type == OBJECT_BOMB ) return "Mine"; + if ( type == OBJECT_WINFIRE ) return "Firework"; + if ( type == OBJECT_BAG ) return "Bag"; + if ( type == OBJECT_PLANT0 ) return "Greenery0"; + if ( type == OBJECT_PLANT1 ) return "Greenery1"; + if ( type == OBJECT_PLANT2 ) return "Greenery2"; + if ( type == OBJECT_PLANT3 ) return "Greenery3"; + if ( type == OBJECT_PLANT4 ) return "Greenery4"; + if ( type == OBJECT_PLANT5 ) return "Greenery5"; + if ( type == OBJECT_PLANT6 ) return "Greenery6"; + if ( type == OBJECT_PLANT7 ) return "Greenery7"; + if ( type == OBJECT_PLANT8 ) return "Greenery8"; + if ( type == OBJECT_PLANT9 ) return "Greenery9"; + if ( type == OBJECT_PLANT10 ) return "Greenery10"; + if ( type == OBJECT_PLANT11 ) return "Greenery11"; + if ( type == OBJECT_PLANT12 ) return "Greenery12"; + if ( type == OBJECT_PLANT13 ) return "Greenery13"; + if ( type == OBJECT_PLANT14 ) return "Greenery14"; + if ( type == OBJECT_PLANT15 ) return "Greenery15"; + if ( type == OBJECT_PLANT16 ) return "Greenery16"; + if ( type == OBJECT_PLANT17 ) return "Greenery17"; + if ( type == OBJECT_PLANT18 ) return "Greenery18"; + if ( type == OBJECT_PLANT19 ) return "Greenery19"; + if ( type == OBJECT_TREE0 ) return "Tree0"; + if ( type == OBJECT_TREE1 ) return "Tree1"; + if ( type == OBJECT_TREE2 ) return "Tree2"; + if ( type == OBJECT_TREE3 ) return "Tree3"; + if ( type == OBJECT_TREE4 ) return "Tree4"; + if ( type == OBJECT_TREE5 ) return "Tree5"; + if ( type == OBJECT_TREE6 ) return "Tree6"; + if ( type == OBJECT_TREE7 ) return "Tree7"; + if ( type == OBJECT_TREE8 ) return "Tree8"; + if ( type == OBJECT_TREE9 ) return "Tree9"; + if ( type == OBJECT_MUSHROOM0 ) return "Mushroom0"; + if ( type == OBJECT_MUSHROOM1 ) return "Mushroom1"; + if ( type == OBJECT_MUSHROOM2 ) return "Mushroom2"; + if ( type == OBJECT_MUSHROOM3 ) return "Mushroom3"; + if ( type == OBJECT_MUSHROOM4 ) return "Mushroom4"; + if ( type == OBJECT_MUSHROOM5 ) return "Mushroom5"; + if ( type == OBJECT_MUSHROOM6 ) return "Mushroom6"; + if ( type == OBJECT_MUSHROOM7 ) return "Mushroom7"; + if ( type == OBJECT_MUSHROOM8 ) return "Mushroom8"; + if ( type == OBJECT_MUSHROOM9 ) return "Mushroom9"; + if ( type == OBJECT_HOME1 ) return "Home"; + if ( type == OBJECT_DERRICK ) return "Derrick"; + if ( type == OBJECT_FACTORY ) return "BotFactory"; + if ( type == OBJECT_STATION ) return "PowerStation"; + if ( type == OBJECT_CONVERT ) return "Converter"; + if ( type == OBJECT_REPAIR ) return "RepairCenter"; + if ( type == OBJECT_DESTROYER ) return "Destroyer"; + if ( type == OBJECT_TOWER ) return "DefenseTower"; + if ( type == OBJECT_NEST ) return "AlienNest"; + if ( type == OBJECT_RESEARCH ) return "ResearchCenter"; + if ( type == OBJECT_RADAR ) return "RadarStation"; + if ( type == OBJECT_INFO ) return "ExchangePost"; + if ( type == OBJECT_ENERGY ) return "PowerPlant"; + if ( type == OBJECT_LABO ) return "AutoLab"; +#if _GERMAN | _WG + if ( type == OBJECT_NUCLEAR ) return "FuelCellPlant"; +#else + if ( type == OBJECT_NUCLEAR ) return "NuclearPlant"; +#endif + if ( type == OBJECT_PARA ) return "PowerCaptor"; + if ( type == OBJECT_SAFE ) return "Vault"; + if ( type == OBJECT_HUSTON ) return "Houston"; + if ( type == OBJECT_TARGET1 ) return "Target1"; + if ( type == OBJECT_TARGET2 ) return "Target2"; + if ( type == OBJECT_START ) return "StartArea"; + if ( type == OBJECT_END ) return "GoalArea"; + if ( type == OBJECT_MOTHER ) return "AlienQueen"; + if ( type == OBJECT_EGG ) return "AlienEgg"; + if ( type == OBJECT_ANT ) return "AlienAnt"; + if ( type == OBJECT_SPIDER ) return "AlienSpider"; + if ( type == OBJECT_BEE ) return "AlienWasp"; + if ( type == OBJECT_WORM ) return "AlienWorm"; + if ( type == OBJECT_RUINmobilew1 ) return "WreckBotw1"; + if ( type == OBJECT_RUINmobilew2 ) return "WreckBotw2"; + if ( type == OBJECT_RUINmobilet1 ) return "WreckBott1"; + if ( type == OBJECT_RUINmobilet2 ) return "WreckBott2"; + if ( type == OBJECT_RUINmobiler1 ) return "WreckBotr1"; + if ( type == OBJECT_RUINmobiler2 ) return "WreckBotr2"; + if ( type == OBJECT_RUINfactory ) return "RuinBotFactory"; + if ( type == OBJECT_RUINdoor ) return "RuinDoor"; + if ( type == OBJECT_RUINsupport ) return "RuinSupport"; + if ( type == OBJECT_RUINradar ) return "RuinRadar"; + if ( type == OBJECT_RUINconvert ) return "RuinConvert"; + if ( type == OBJECT_RUINbase ) return "RuinBaseCamp"; + if ( type == OBJECT_RUINhead ) return "RuinHeadCamp"; + if ( type == OBJECT_BARRIER0 ) return "Barrier0"; + if ( type == OBJECT_BARRIER1 ) return "Barrier1"; + if ( type == OBJECT_BARRIER2 ) return "Barrier2"; + if ( type == OBJECT_BARRIER3 ) return "Barrier3"; + if ( type == OBJECT_BARRIER4 ) return "Barrier4"; + if ( type == OBJECT_TEEN0 ) return "Teen0"; + if ( type == OBJECT_TEEN1 ) return "Teen1"; + if ( type == OBJECT_TEEN2 ) return "Teen2"; + if ( type == OBJECT_TEEN3 ) return "Teen3"; + if ( type == OBJECT_TEEN4 ) return "Teen4"; + if ( type == OBJECT_TEEN5 ) return "Teen5"; + if ( type == OBJECT_TEEN6 ) return "Teen6"; + if ( type == OBJECT_TEEN7 ) return "Teen7"; + if ( type == OBJECT_TEEN8 ) return "Teen8"; + if ( type == OBJECT_TEEN9 ) return "Teen9"; + if ( type == OBJECT_TEEN10 ) return "Teen10"; + if ( type == OBJECT_TEEN11 ) return "Teen11"; + if ( type == OBJECT_TEEN12 ) return "Teen12"; + if ( type == OBJECT_TEEN13 ) return "Teen13"; + if ( type == OBJECT_TEEN14 ) return "Teen14"; + if ( type == OBJECT_TEEN15 ) return "Teen15"; + if ( type == OBJECT_TEEN16 ) return "Teen16"; + if ( type == OBJECT_TEEN17 ) return "Teen17"; + if ( type == OBJECT_TEEN18 ) return "Teen18"; + if ( type == OBJECT_TEEN19 ) return "Teen19"; + if ( type == OBJECT_TEEN20 ) return "Teen20"; + if ( type == OBJECT_TEEN21 ) return "Teen21"; + if ( type == OBJECT_TEEN22 ) return "Teen22"; + if ( type == OBJECT_TEEN23 ) return "Teen23"; + if ( type == OBJECT_TEEN24 ) return "Teen24"; + if ( type == OBJECT_TEEN25 ) return "Teen25"; + if ( type == OBJECT_TEEN26 ) return "Teen26"; + if ( type == OBJECT_TEEN27 ) return "Teen27"; + if ( type == OBJECT_TEEN28 ) return "Teen28"; + if ( type == OBJECT_TEEN29 ) return "Teen29"; + if ( type == OBJECT_TEEN30 ) return "Teen30"; + if ( type == OBJECT_TEEN31 ) return "Teen31"; + if ( type == OBJECT_TEEN32 ) return "Teen32"; + if ( type == OBJECT_TEEN33 ) return "Teen33"; + if ( type == OBJECT_TEEN34 ) return "Stone"; + if ( type == OBJECT_TEEN35 ) return "Teen35"; + if ( type == OBJECT_TEEN36 ) return "Teen36"; + if ( type == OBJECT_TEEN37 ) return "Teen37"; + if ( type == OBJECT_TEEN38 ) return "Teen38"; + if ( type == OBJECT_TEEN39 ) return "Teen39"; + if ( type == OBJECT_TEEN40 ) return "Teen40"; + if ( type == OBJECT_TEEN41 ) return "Teen41"; + if ( type == OBJECT_TEEN42 ) return "Teen42"; + if ( type == OBJECT_TEEN43 ) return "Teen43"; + if ( type == OBJECT_TEEN44 ) return "Teen44"; + if ( type == OBJECT_TEEN45 ) return "Teen45"; + if ( type == OBJECT_TEEN46 ) return "Teen46"; + if ( type == OBJECT_TEEN47 ) return "Teen47"; + if ( type == OBJECT_TEEN48 ) return "Teen48"; + if ( type == OBJECT_TEEN49 ) return "Teen49"; + if ( type == OBJECT_QUARTZ0 ) return "Quartz0"; + if ( type == OBJECT_QUARTZ1 ) return "Quartz1"; + if ( type == OBJECT_QUARTZ2 ) return "Quartz2"; + if ( type == OBJECT_QUARTZ3 ) return "Quartz3"; + if ( type == OBJECT_QUARTZ4 ) return "Quartz4"; + if ( type == OBJECT_QUARTZ5 ) return "Quartz5"; + if ( type == OBJECT_QUARTZ6 ) return "Quartz6"; + if ( type == OBJECT_QUARTZ7 ) return "Quartz7"; + if ( type == OBJECT_QUARTZ8 ) return "Quartz8"; + if ( type == OBJECT_QUARTZ9 ) return "Quartz9"; + if ( type == OBJECT_ROOT0 ) return "MegaStalk0"; + if ( type == OBJECT_ROOT1 ) return "MegaStalk1"; + if ( type == OBJECT_ROOT2 ) return "MegaStalk2"; + if ( type == OBJECT_ROOT3 ) return "MegaStalk3"; + if ( type == OBJECT_ROOT4 ) return "MegaStalk4"; + if ( type == OBJECT_ROOT5 ) return "MegaStalk5"; + if ( type == OBJECT_ROOT6 ) return "MegaStalk6"; + if ( type == OBJECT_ROOT7 ) return "MegaStalk7"; + if ( type == OBJECT_ROOT8 ) return "MegaStalk8"; + if ( type == OBJECT_ROOT9 ) return "MegaStalk9"; + if ( type == OBJECT_APOLLO1 ) return "ApolloLEM"; + if ( type == OBJECT_APOLLO2 ) return "ApolloJeep"; + if ( type == OBJECT_APOLLO3 ) return "ApolloFlag"; + if ( type == OBJECT_APOLLO4 ) return "ApolloModule"; + if ( type == OBJECT_APOLLO5 ) return "ApolloAntenna"; + if ( type == OBJECT_HUMAN ) return "Me"; + if ( type == OBJECT_TECH ) return "Tech"; + return ""; +} + +// Returns the type of water. + +WaterType GetTypeWater(char *line, int rank, WaterType def) +{ + char* p; + + p = SearchArg(line, rank); + if ( *p == 0 ) return def; + + if ( Cmd(p, "NULL" ) ) return WATER_NULL; + if ( Cmd(p, "TT" ) ) return WATER_TT; + if ( Cmd(p, "TO" ) ) return WATER_TO; + if ( Cmd(p, "CT" ) ) return WATER_CT; + if ( Cmd(p, "CO" ) ) return WATER_CO; + + return def; +} + +// Returns the type of terrain. + +D3DTypeObj GetTypeTerrain(char *line, int rank, D3DTypeObj def) +{ + char* p; + + p = SearchArg(line, rank); + if ( *p == 0 ) return def; + + if ( Cmd(p, "Terrain" ) ) return TYPETERRAIN; + if ( Cmd(p, "Object" ) ) return TYPEFIX; + if ( Cmd(p, "Quartz" ) ) return TYPEQUARTZ; + if ( Cmd(p, "Metal" ) ) return TYPEMETAL; + + return def; +} + +// Returns the type of a building. + +int GetBuild(char *line, int rank) +{ + char* p; + + p = SearchArg(line, rank); + if ( *p == 0 ) return 0; + + if ( Cmd(p, "BotFactory" ) ) return BUILD_FACTORY; + if ( Cmd(p, "Derrick" ) ) return BUILD_DERRICK; + if ( Cmd(p, "Converter" ) ) return BUILD_CONVERT; + if ( Cmd(p, "RadarStation" ) ) return BUILD_RADAR; + if ( Cmd(p, "PowerPlant" ) ) return BUILD_ENERGY; + if ( Cmd(p, "NuclearPlant" ) ) return BUILD_NUCLEAR; + if ( Cmd(p, "FuelCellPlant" ) ) return BUILD_NUCLEAR; + if ( Cmd(p, "PowerStation" ) ) return BUILD_STATION; + if ( Cmd(p, "RepairCenter" ) ) return BUILD_REPAIR; + if ( Cmd(p, "DefenseTower" ) ) return BUILD_TOWER; + if ( Cmd(p, "ResearchCenter") ) return BUILD_RESEARCH; + if ( Cmd(p, "AutoLab" ) ) return BUILD_LABO; + if ( Cmd(p, "PowerCaptor" ) ) return BUILD_PARA; + if ( Cmd(p, "ExchangePost" ) ) return BUILD_INFO; + if ( Cmd(p, "FlatGround" ) ) return BUILD_GFLAT; + if ( Cmd(p, "Flag" ) ) return BUILD_FLAG; + + return 0; +} + +// Returns the type of search. + +int GetResearch(char *line, int rank) +{ + char* p; + + p = SearchArg(line, rank); + if ( *p == 0 ) return 0; + + if ( Cmd(p, "TRACKER" ) ) return RESEARCH_TANK; + if ( Cmd(p, "WINGER" ) ) return RESEARCH_FLY; + if ( Cmd(p, "THUMPER" ) ) return RESEARCH_THUMP; + if ( Cmd(p, "SHOOTER" ) ) return RESEARCH_CANON; + if ( Cmd(p, "TOWER" ) ) return RESEARCH_TOWER; + if ( Cmd(p, "PHAZER" ) ) return RESEARCH_PHAZER; + if ( Cmd(p, "SHIELDER") ) return RESEARCH_SHIELD; + if ( Cmd(p, "ATOMIC" ) ) return RESEARCH_ATOMIC; + if ( Cmd(p, "iPAW" ) ) return RESEARCH_iPAW; + if ( Cmd(p, "iGUN" ) ) return RESEARCH_iGUN; + if ( Cmd(p, "RECYCLER") ) return RESEARCH_RECYCLER; + if ( Cmd(p, "SUBBER" ) ) return RESEARCH_SUBM; + if ( Cmd(p, "SNIFFER" ) ) return RESEARCH_SNIFFER; + + return 0; +} + +// Returns the type of pyrotechnic effect. + +PyroType GetPyro(char *line, int rank) +{ + char* p; + + p = SearchArg(line, rank); + if ( *p == 0 ) return PT_NULL; + + if ( Cmd(p, "FRAGt" ) ) return PT_FRAGT; + if ( Cmd(p, "FRAGo" ) ) return PT_FRAGO; + if ( Cmd(p, "FRAGw" ) ) return PT_FRAGW; + if ( Cmd(p, "EXPLOt" ) ) return PT_EXPLOT; + if ( Cmd(p, "EXPLOo" ) ) return PT_EXPLOO; + if ( Cmd(p, "EXPLOw" ) ) return PT_EXPLOW; + if ( Cmd(p, "SHOTt" ) ) return PT_SHOTT; + if ( Cmd(p, "SHOTh" ) ) return PT_SHOTH; + if ( Cmd(p, "SHOTm" ) ) return PT_SHOTM; + if ( Cmd(p, "SHOTw" ) ) return PT_SHOTW; + if ( Cmd(p, "EGG" ) ) return PT_EGG; + if ( Cmd(p, "BURNt" ) ) return PT_BURNT; + if ( Cmd(p, "BURNo" ) ) return PT_BURNO; + if ( Cmd(p, "SPIDER" ) ) return PT_SPIDER; + if ( Cmd(p, "FALL" ) ) return PT_FALL; + if ( Cmd(p, "RESET" ) ) return PT_RESET; + if ( Cmd(p, "WIN" ) ) return PT_WIN; + if ( Cmd(p, "LOST" ) ) return PT_LOST; + + return PT_NULL; +} + +// Returns the type of camera. + +CameraType GetCamera(char *line, int rank) +{ + char* p; + + p = SearchArg(line, rank); + if ( *p == 0 ) return CAMERA_NULL; + + if ( Cmd(p, "BACK" ) ) return CAMERA_BACK; + if ( Cmd(p, "PLANE" ) ) return CAMERA_PLANE; + if ( Cmd(p, "ONBOARD" ) ) return CAMERA_ONBOARD; + if ( Cmd(p, "FIX" ) ) return CAMERA_FIX; + + return CAMERA_NULL; +} + +// Returns the name of a camera. + +char* GetCamera(CameraType type) +{ + if ( type == CAMERA_ONBOARD ) return "ONBOARD"; + if ( type == CAMERA_FIX ) return "FIX"; + return "BACK"; +} + +// Returns an integer. + +int OpInt(char *line, char *op, int def) +{ + line = SearchOp(line, op); + if ( *line == 0 ) return def; + return GetInt(line, 0, def); +} + +// Returns a float number. + +float OpFloat(char *line, char *op, float def) +{ + line = SearchOp(line, op); + if ( *line == 0 ) return def; + return GetFloat(line, 0, def); +} + +// Returns a string. + +void OpString(char *line, char *op, char *buffer) +{ + line = SearchOp(line, op); + if ( *line == 0 ) + { + buffer[0] = 0; + } + else + { + GetString(line, 0, buffer); + } +} + +// Returns the type of an object. + +ObjectType OpTypeObject(char *line, char *op, ObjectType def) +{ + line = SearchOp(line, op); + if ( *line == 0 ) return def; + return GetTypeObject(line, 0, def); +} + +// Returns the type of a water. + +WaterType OpTypeWater(char *line, char *op, WaterType def) +{ + line = SearchOp(line, op); + if ( *line == 0 ) return def; + return GetTypeWater(line, 0, def); +} + +// Returns the type of a terrain. + +D3DTypeObj OpTypeTerrain(char *line, char *op, D3DTypeObj def) +{ + line = SearchOp(line, op); + if ( *line == 0 ) return def; + return GetTypeTerrain(line, 0, def); +} + +// Returns the type of research. + +int OpResearch(char *line, char *op) +{ + line = SearchOp(line, op); + if ( *line == 0 ) return 0; + return GetResearch(line, 0); +} + +// Returns the type of pyrotechnic effect. + +PyroType OpPyro(char *line, char *op) +{ + line = SearchOp(line, op); + if ( *line == 0 ) return PT_NULL; + return GetPyro(line, 0); +} + +// Returns the type of camera. + +CameraType OpCamera(char *line, char *op) +{ + line = SearchOp(line, op); + if ( *line == 0 ) return CAMERA_NULL; + return GetCamera(line, 0); +} + +// Returns the type of a building. + +int OpBuild(char *line, char *op) +{ + line = SearchOp(line, op); + if ( *line == 0 ) return 0; + return GetBuild(line, 0); +} + +// Returns a position in the XZ plane (top view). + +D3DVECTOR OpPos(char *line, char *op) +{ + D3DVECTOR pos; + + line = SearchOp(line, op); + if ( *line == 0 ) + { + pos = D3DVECTOR(0.0f, 0.0f, 0.0f); + return pos; + } + pos.x = GetFloat(line, 0, 0.0f); + pos.y = 0.0f; + pos.z = GetFloat(line, 1, 0.0f); + return pos; +} + +// Returns a direction. + +D3DVECTOR OpDir(char *line, char *op) +{ + D3DVECTOR dir; + + line = SearchOp(line, op); + if ( *line == 0 ) + { + dir = D3DVECTOR(0.0f, 0.0f, 0.0f); + return dir; + } + dir.x = GetFloat(line, 0, 0.0f); + dir.y = GetFloat(line, 1, 0.0f); + dir.z = GetFloat(line, 2, 0.0f); + return dir; +} + +// Reads a color (0 .. 255). + +D3DCOLOR OpColor(char *line, char *op, D3DCOLOR def) +{ + D3DCOLOR color; + + line = SearchOp(line, op); + if ( *line == 0 ) return def; + + color = 0; + color |= (GetInt(line, 0, 0)&0xff)<<16; // r + color |= (GetInt(line, 1, 0)&0xff)<<8; // g + color |= (GetInt(line, 2, 0)&0xff)<<0; // b + color |= (GetInt(line, 3, 0)&0xff)<<24; // a + return color; +} + +// Reads a color (-1 .. 1). + +D3DCOLORVALUE OpColorValue(char *line, char *op, D3DCOLORVALUE def) +{ + D3DCOLORVALUE color; + + line = SearchOp(line, op); + if ( *line == 0 ) return def; + + color.r = GetFloat(line, 0, 0.0f); + color.g = GetFloat(line, 1, 0.0f); + color.b = GetFloat(line, 2, 0.0f); + color.a = GetFloat(line, 3, 0.0f); + return color; +} + + diff --git a/src/script/cmdtoken.h b/src/script/cmdtoken.h new file mode 100644 index 0000000..40fb36a --- /dev/null +++ b/src/script/cmdtoken.h @@ -0,0 +1,67 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// cmdtoken.h + +#ifndef _CMDTOKEN_H_ +#define _CMDTOKEN_H_ + + +#include "d3denum.h" +#include "d3dengine.h" +#include "object.h" +#include "water.h" +#include "pyro.h" +#include "camera.h" + + + +// Procedures. + +extern BOOL Cmd(char *line, char *token); +extern char* SearchOp(char *line, char *op); + +extern int GetInt(char *line, int rank, int def); +extern float GetFloat(char *line, int rank, float def); +extern void GetString(char *line, int rank, char *buffer); +extern ObjectType GetTypeObject(char *line, int rank, ObjectType def); +extern char* GetTypeObject(ObjectType type); +extern WaterType GetTypeWater(char *line, int rank, WaterType def); +extern D3DTypeObj GetTypeTerrain(char *line, int rank, D3DTypeObj def); +extern int GetBuild(char *line, int rank); +extern int GetResearch(char *line, int rank); +extern PyroType GetPyro(char *line, int rank); +extern CameraType GetCamera(char *line, int rank); +extern char* GetCamera(CameraType type); + +extern int OpInt(char *line, char *op, int def); +extern float OpFloat(char *line, char *op, float def); +extern void OpString(char *line, char *op, char *buffer); +extern ObjectType OpTypeObject(char *line, char *op, ObjectType def); +extern WaterType OpTypeWater(char *line, char *op, WaterType def); +extern D3DTypeObj OpTypeTerrain(char *line, char *op, D3DTypeObj def); +extern int OpResearch(char *line, char *op); +extern PyroType OpPyro(char *line, char *op); +extern CameraType OpCamera(char *line, char *op); +extern int OpBuild(char *line, char *op); +extern D3DVECTOR OpPos(char *line, char *op); +extern D3DVECTOR OpDir(char *line, char *op); +extern D3DCOLOR OpColor(char *line, char *op, D3DCOLOR def); +extern D3DCOLORVALUE OpColorValue(char *line, char *op, D3DCOLORVALUE def); + + + +#endif //_CMDTOKEN_H_ diff --git a/src/script/dd.cpp b/src/script/dd.cpp new file mode 100644 index 0000000..75e332a --- /dev/null +++ b/src/script/dd.cpp @@ -0,0 +1,175 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// Compilation of a procedure with a "dot". + +int cPoint(CBotVar* &var, CBotString& retClass, void* user) +{ + if ( var == 0 ) return CBotErrLowParam; + + if ( var->GivType() <= CBotTypDouble ) + { + var = var->GivNext(); + if ( var == 0 ) return CBotErrLowParam; + if ( var->GivType() > CBotTypDouble ) return CBotErrBadNum; + var = var->GivNext(); + if ( var == 0 ) return CBotErrLowParam; + if ( var->GivType() > CBotTypDouble ) return CBotErrBadNum; + var = var->GivNext(); + return 0; + } + + if ( var->GivType() == CBotTypClass ) + { + if ( !var->IsElemOfClass("point") ) return CBotErrBadParam; + var = var->GivNext(); + return 0; + } + + return CBotErrBadParam; +} + +// Gives a parameter of type "point". + +BOOL GetPoint(CBotVar* &var, int& exception, D3DVECTOR& pos) +{ + CBotVar *pX, *pY, *pZ; + + if ( var->GivType() <= CBotTypDouble ) + { + pos.x = var->GivValFloat()*UNIT; + var = var->GivNext(); + + pos.z = var->GivValFloat()*UNIT; + var = var->GivNext(); + + pos.y = var->GivValFloat()*UNIT; + var = var->GivNext(); + } + else + { + pX = var->GivItem("x"); + if ( pX == NULL ) + { + exception = CBotErrUndefItem; return TRUE; + } + pos.x = pX->GivValFloat()*UNIT; + + pY = var->GivItem("y"); + if ( pY == NULL ) + { + exception = CBotErrUndefItem; return TRUE; + } + pos.z = pY->GivValFloat()*UNIT; // attention y -> z ! + + pZ = var->GivItem("z"); + if ( pZ == NULL ) + { + exception = CBotErrUndefItem; return TRUE; + } + pos.y = pZ->GivValFloat()*UNIT; // attention z -> y ! + + var = var->GivNext(); + } + return TRUE; +} + + + +// Compilation of the instruction "space(center, rMin, rMax, dist)". + +int cSpace(CBotVar* &var, CBotString& retClass, void* user) +{ + int ret; + + retClass = "point"; + + if ( var == 0 ) return CBotTypIntrinsic; + ret = cPoint(var, retClass, user); + if ( ret != 0 ) return ret; + + if ( var == 0 ) return CBotTypIntrinsic; + if ( var->GivType() > CBotTypDouble ) return CBotErrBadNum; + var = var->GivNext(); + + if ( var == 0 ) return CBotTypIntrinsic; + if ( var->GivType() > CBotTypDouble ) return CBotErrBadNum; + var = var->GivNext(); + + if ( var == 0 ) return CBotTypIntrinsic; + if ( var->GivType() > CBotTypDouble ) return CBotErrBadNum; + var = var->GivNext(); + + if ( var != 0 ) return CBotErrOverParam; + return CBotTypIntrinsic; +} + +// Instruction "space(center, rMin, rMax, dist)". + +BOOL rSpace(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + CBotVar* pSub; + D3DVECTOR center; + float rMin, rMax, dist; + + rMin = 5.0f*UNIT; + rMax = 50.0f*UNIT; + dist = 4.0f*UNIT; + + if ( var == 0 ) + { + center = pThis->RetPosition(0); + } + else + { + if ( !GetPoint(var, exception, center) ) return TRUE; + + if ( var != 0 ) + { + rMin = var->GivValFloat()*UNIT; + var = var->GivNext(); + + if ( var != 0 ) + { + rMax = var->GivValFloat()*UNIT; + var = var->GivNext(); + + if ( var != 0 ) + { + dist = var->GivValFloat()*UNIT; + var = var->GivNext(); + } + } + } + } + script->m_main->FreeSpace(center, rMin, rMax, dist, pThis); + + if ( result != 0 ) + { + pSub = result->GivItemList(); + if ( pSub != 0 ) + { + pSub->SetValFloat(center.x/UNIT); + pSub = pSub->GivNext(); // "y" + pSub->SetValFloat(center.z/UNIT); + pSub = pSub->GivNext(); // "z" + pSub->SetValFloat(center.y/UNIT); + } + } + return TRUE; +} diff --git a/src/script/script.cpp b/src/script/script.cpp new file mode 100644 index 0000000..62b2d25 --- /dev/null +++ b/src/script/script.cpp @@ -0,0 +1,3777 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// script.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "CBot/CBotDll.h" +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "global.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "restext.h" +#include "math3d.h" +#include "robotmain.h" +#include "terrain.h" +#include "water.h" +#include "object.h" +#include "physics.h" +#include "interface.h" +#include "edit.h" +#include "list.h" +#include "text.h" +#include "displaytext.h" +#include "taskmanager.h" +#include "task.h" +#include "taskmanip.h" +#include "taskgoto.h" +#include "taskshield.h" +#include "cbottoken.h" +#include "script.h" + + + +#define CBOT_IPF 100 // CBOT: number of instructions / frame + +#define ERM_CONT 0 // if error -> continue +#define ERM_STOP 1 // if error -> stop + + + + +// Compiling a procedure without any parameters. + +CBotTypResult cNull(CBotVar* &var, void* user) +{ + if ( var != 0 ) return CBotErrOverParam; + return CBotTypResult(CBotTypFloat); +} + +// Compiling a procedure with a single real number. + +CBotTypResult cOneFloat(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Compiling a procedure with two real numbers. + +CBotTypResult cTwoFloat(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Compiling a procedure with a "dot". + +CBotTypResult cPoint(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + + if ( var->GivType() <= CBotTypDouble ) + { + var = var->GivNext(); + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); +//? if ( var == 0 ) return CBotTypResult(CBotErrLowParam); +//? if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); +//? var = var->GivNext(); + return CBotTypResult(0); + } + + if ( var->GivType() == CBotTypClass ) + { + if ( !var->IsElemOfClass("point") ) return CBotTypResult(CBotErrBadParam); + var = var->GivNext(); + return CBotTypResult(0); + } + + return CBotTypResult(CBotErrBadParam); +} + +// Compiling a procedure with a single "point". + +CBotTypResult cOnePoint(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + ret = cPoint(var, user); + if ( ret.GivType() != 0 ) return ret; + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Compiling a procedure with a single string. + +CBotTypResult cString(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() != CBotTypString && + var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + + +// Seeking value in an array of integers. + +BOOL FindList(CBotVar* array, int type) +{ + while ( array != 0 ) + { + if ( type == array->GivValInt() ) return TRUE; + array = array->GivNext(); + } + return FALSE; +} + + +// Gives a parameter of type "point". + +BOOL GetPoint(CBotVar* &var, int& exception, D3DVECTOR& pos) +{ + CBotVar *pX, *pY, *pZ; + + if ( var->GivType() <= CBotTypDouble ) + { + pos.x = var->GivValFloat()*g_unit; + var = var->GivNext(); + + pos.z = var->GivValFloat()*g_unit; + var = var->GivNext(); + + pos.y = 0.0f; + } + else + { + pX = var->GivItem("x"); + if ( pX == NULL ) + { + exception = CBotErrUndefItem; return TRUE; + } + pos.x = pX->GivValFloat()*g_unit; + + pY = var->GivItem("y"); + if ( pY == NULL ) + { + exception = CBotErrUndefItem; return TRUE; + } + pos.z = pY->GivValFloat()*g_unit; // attention y -> z ! + + pZ = var->GivItem("z"); + if ( pZ == NULL ) + { + exception = CBotErrUndefItem; return TRUE; + } + pos.y = pZ->GivValFloat()*g_unit; // attention z -> y ! + + var = var->GivNext(); + } + return TRUE; +} + + +// Instruction "sin(degrees)". + +BOOL rSin(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GivValFloat(); + result->SetValFloat(sinf(value*PI/180.0f)); + return TRUE; +} + +// Instruction "cos(degrees)". + +BOOL rCos(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GivValFloat(); + result->SetValFloat(cosf(value*PI/180.0f)); + return TRUE; +} + +// Instruction "tan(degrees)". + +BOOL rTan(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GivValFloat(); + result->SetValFloat(tanf(value*PI/180.0f)); + return TRUE; +} + +// Instruction "asin(degrees)". + +BOOL raSin(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GivValFloat(); + result->SetValFloat(asinf(value)*180.0f/PI); + return TRUE; +} + +// Instruction "acos(degrees)". + +BOOL raCos(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GivValFloat(); + result->SetValFloat(acosf(value)*180.0f/PI); + return TRUE; +} + +// Instruction "atan(degrees)". + +BOOL raTan(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GivValFloat(); + result->SetValFloat(atanf(value)*180.0f/PI); + return TRUE; +} + +// Instruction "sqrt(value)". + +BOOL rSqrt(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GivValFloat(); + result->SetValFloat(sqrtf(value)); + return TRUE; +} + +// Instruction "pow(x, y)". + +BOOL rPow(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float x, y; + + x = var->GivValFloat(); + var = var->GivNext(); + y = var->GivValFloat(); + result->SetValFloat(powf(x, y)); + return TRUE; +} + +// Instruction "rand()". + +BOOL rRand(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + result->SetValFloat(Rand()); + return TRUE; +} + +// Instruction "abs()". + +BOOL rAbs(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GivValFloat(); + result->SetValFloat(Abs(value)); + return TRUE; +} + + +// Compilation of the instruction "retobject(rank)". + +CBotTypResult cRetObject(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypPointer, "object"); +} + +// Instruction "retobject(rank)". + +BOOL rRetObject(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pObj; + int rank; + + rank = var->GivValInt(); + + pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, rank); + if ( pObj == 0 ) + { + result->SetPointer(0); + } + else + { + result->SetPointer(pObj->RetBotVar()); + } + return TRUE; +} + + +// Compilation of the instruction "search(type, pos)". + +CBotTypResult cSearch(CBotVar* &var, void* user) +{ + CBotVar* array; + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() == CBotTypArrayPointer ) + { + array = var->GivItemList(); + if ( array == 0 ) return CBotTypResult(CBotTypPointer); + if ( array->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + } + else if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + if ( var != 0 ) + { + ret = cPoint(var, user); + if ( ret.GivType() != 0 ) return ret; + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + } + + return CBotTypResult(CBotTypPointer, "object"); +} + +// Instruction "search(type, pos)". + +BOOL rSearch(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject *pObj, *pBest; + CBotVar* array; + D3DVECTOR pos, oPos; + BOOL bNearest = FALSE; + BOOL bArray; + float min, dist; + int type, oType, i; + + if ( var->GivType() == CBotTypArrayPointer ) + { + array = var->GivItemList(); + bArray = TRUE; + } + else + { + type = var->GivValInt(); + bArray = FALSE; + } + var = var->GivNext(); + if ( var != 0 ) + { + if ( !GetPoint(var, exception, pos) ) return TRUE; + bNearest = TRUE; + } + + min = 100000.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj->RetTruck() != 0 ) continue; // object transported? + if ( !pObj->RetActif() ) continue; + + oType = pObj->RetType(); + if ( oType == OBJECT_TOTO ) continue; + + if ( oType == OBJECT_RUINmobilew2 || + oType == OBJECT_RUINmobilet1 || + oType == OBJECT_RUINmobilet2 || + oType == OBJECT_RUINmobiler1 || + oType == OBJECT_RUINmobiler2 ) + { + oType = OBJECT_RUINmobilew1; // any ruin + } + + if ( oType == OBJECT_SCRAP2 || + oType == OBJECT_SCRAP3 || + oType == OBJECT_SCRAP4 || + oType == OBJECT_SCRAP5 ) // wastes? + { + oType = OBJECT_SCRAP1; // any waste + } + + if ( oType == OBJECT_BARRIER2 || + oType == OBJECT_BARRIER3 ) // barriers? + { + oType = OBJECT_BARRIER1; // any barrier + } + + if ( bArray ) + { + if ( !FindList(array, oType) ) continue; + } + else + { + if ( type != oType && type != OBJECT_NULL ) continue; + } + + if ( bNearest ) + { + oPos = pObj->RetPosition(0); + dist = Length2d(pos, oPos); + if ( dist < min ) + { + min = dist; + pBest = pObj; + } + } + else + { + pBest = pObj; + break; + } + } + + if ( pBest == 0 ) + { + result->SetPointer(0); + } + else + { + result->SetPointer(pBest->RetBotVar()); + } + return TRUE; +} + + +// Compilation of instruction "radar(type, angle, focus, min, max, sens)". + +CBotTypResult cRadar(CBotVar* &var, void* user) +{ + CBotVar* array; + + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( var->GivType() == CBotTypArrayPointer ) + { + array = var->GivItemList(); + if ( array == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( array->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // type + } + else if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // type + var = var->GivNext(); + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // angle + var = var->GivNext(); + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // focus + var = var->GivNext(); + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // min + var = var->GivNext(); + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // max + var = var->GivNext(); + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // sense + var = var->GivNext(); + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // filter + var = var->GivNext(); + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + return CBotTypResult(CBotErrOverParam); +} + +// Instruction "radar(type, angle, focus, min, max, sens, filter)". + +BOOL rRadar(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + CObject *pObj, *pBest; + CPhysics* physics; + CBotVar* array; + D3DVECTOR iPos, oPos; + RadarFilter filter; + float best, minDist, maxDist, sens, iAngle, angle, focus, d, a; + int type, oType, i; + BOOL bArray; + + type = OBJECT_NULL; + angle = 0.0f; + focus = PI*2.0f; + minDist = 0.0f*g_unit; + maxDist = 1000.0f*g_unit; + sens = 1.0f; + filter = FILTER_NONE; + + if ( var != 0 ) + { + if ( var->GivType() == CBotTypArrayPointer ) + { + array = var->GivItemList(); + bArray = TRUE; + } + else + { + type = var->GivValInt(); + bArray = FALSE; + } + + var = var->GivNext(); + if ( var != 0 ) + { + angle = -var->GivValFloat()*PI/180.0f; + + var = var->GivNext(); + if ( var != 0 ) + { + focus = var->GivValFloat()*PI/180.0f; + + var = var->GivNext(); + if ( var != 0 ) + { + minDist = var->GivValFloat()*g_unit; + + var = var->GivNext(); + if ( var != 0 ) + { + maxDist = var->GivValFloat()*g_unit; + + var = var->GivNext(); + if ( var != 0 ) + { + sens = var->GivValFloat(); + + var = var->GivNext(); + if ( var != 0 ) + { + filter = (RadarFilter)var->GivValInt(); + } + } + } + } + } + } + } + + iPos = pThis->RetPosition(0); + iAngle = pThis->RetAngleY(0)+angle; + iAngle = NormAngle(iAngle); // 0..2*PI + + if ( sens >= 0.0f ) best = 100000.0f; + else best = 0.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + if ( pObj == pThis ) continue; + + if ( pObj->RetTruck() != 0 ) continue; // object transported? + if ( !pObj->RetActif() ) continue; + if ( pObj->RetProxyActivate() ) continue; + + oType = pObj->RetType(); + if ( oType == OBJECT_TOTO ) continue; + + if ( oType == OBJECT_RUINmobilew2 || + oType == OBJECT_RUINmobilet1 || + oType == OBJECT_RUINmobilet2 || + oType == OBJECT_RUINmobiler1 || + oType == OBJECT_RUINmobiler2 ) + { + oType = OBJECT_RUINmobilew1; // any ruin + } + + if ( oType == OBJECT_SCRAP2 || + oType == OBJECT_SCRAP3 || + oType == OBJECT_SCRAP4 || + oType == OBJECT_SCRAP5 ) // wastes? + { + oType = OBJECT_SCRAP1; // any waste + } + + if ( oType == OBJECT_BARRIER2 || + oType == OBJECT_BARRIER3 ) // barriers? + { + oType = OBJECT_BARRIER1; // any barrier + } + + if ( filter == FILTER_ONLYLANDING ) + { + physics = pObj->RetPhysics(); + if ( physics != 0 && !physics->RetLand() ) continue; + } + if ( filter == FILTER_ONLYFLYING ) + { + physics = pObj->RetPhysics(); + if ( physics != 0 && physics->RetLand() ) continue; + } + + if ( bArray ) + { + if ( !FindList(array, oType) ) continue; + } + else + { + if ( type != oType && type != OBJECT_NULL ) continue; + } + + oPos = pObj->RetPosition(0); + d = Length2d(iPos, oPos); + if ( d < minDist || d > maxDist ) continue; // too close or too far? + + if ( focus >= PI*2.0f ) + { + if ( (sens >= 0.0f && d < best) || + (sens < 0.0f && d > best) ) + { + best = d; + pBest = pObj; + } + continue; + } + + a = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! + if ( TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) ) + { + if ( (sens >= 0.0f && d < best) || + (sens < 0.0f && d > best) ) + { + best = d; + pBest = pObj; + } + } + } + + if ( pBest == 0 ) + { + result->SetPointer(0); + } + else + { + result->SetPointer(pBest->RetBotVar()); + } + return TRUE; +} + + +// Monitoring a task. + +BOOL Process(CScript* script, CBotVar* result, int &exception) +{ + Error err; + + err = script->m_primaryTask->IsEnded(); + if ( err != ERR_CONTINUE ) // task terminated? + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + + script->m_bContinue = FALSE; + + if ( err == ERR_STOP ) err = ERR_OK; + result->SetValInt(err); // indicates the error or ok + if ( err != ERR_OK && script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; // it's all over + } + + script->m_primaryTask->EventProcess(script->m_event); + script->m_bContinue = TRUE; + return FALSE; // not done +} + + +// Compilation of the instruction "detect(type)". + +CBotTypResult cDetect(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypBoolean); +} + +// Instruction "detect(type)". + +BOOL rDetect(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + CObject *pObj, *pGoal, *pBest; + CPhysics* physics; + CBotVar* array; + D3DVECTOR iPos, oPos; + RadarFilter filter; + float bGoal, best, minDist, maxDist, sens, iAngle, angle, focus, d, a; + int type, oType, i; + BOOL bArray; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + type = OBJECT_NULL; + angle = 0.0f; + focus = 45.0f*PI/180.0f; + minDist = 0.0f*g_unit; + maxDist = 20.0f*g_unit; + sens = 1.0f; + filter = FILTER_NONE; + + if ( var != 0 ) + { + if ( var->GivType() == CBotTypArrayPointer ) + { + array = var->GivItemList(); + bArray = TRUE; + } + else + { + type = var->GivValInt(); + bArray = FALSE; + } + } + + iPos = pThis->RetPosition(0); + iAngle = pThis->RetAngleY(0)+angle; + iAngle = NormAngle(iAngle); // 0..2*PI + + bGoal = 100000.0f; + pGoal = 0; + if ( sens >= 0.0f ) best = 100000.0f; + else best = 0.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + if ( pObj == pThis ) continue; + + if ( pObj->RetTruck() != 0 ) continue; // object transported? + if ( !pObj->RetActif() ) continue; + if ( pObj->RetProxyActivate() ) continue; + + oType = pObj->RetType(); + if ( oType == OBJECT_TOTO ) continue; + + if ( oType == OBJECT_RUINmobilew2 || + oType == OBJECT_RUINmobilet1 || + oType == OBJECT_RUINmobilet2 || + oType == OBJECT_RUINmobiler1 || + oType == OBJECT_RUINmobiler2 ) + { + oType = OBJECT_RUINmobilew1; // any ruin + } + + if ( oType == OBJECT_SCRAP2 || + oType == OBJECT_SCRAP3 || + oType == OBJECT_SCRAP4 || + oType == OBJECT_SCRAP5 ) // wastes? + { + oType = OBJECT_SCRAP1; // any waste + } + + if ( oType == OBJECT_BARRIER2 || + oType == OBJECT_BARRIER3 ) // barriers? + { + oType = OBJECT_BARRIER1; // any barrier + } + + if ( filter == FILTER_ONLYLANDING ) + { + physics = pObj->RetPhysics(); + if ( physics != 0 && !physics->RetLand() ) continue; + } + if ( filter == FILTER_ONLYFLYING ) + { + physics = pObj->RetPhysics(); + if ( physics != 0 && physics->RetLand() ) continue; + } + + if ( bArray ) + { + if ( !FindList(array, oType) ) continue; + } + else + { + if ( type != oType && type != OBJECT_NULL ) continue; + } + + oPos = pObj->RetPosition(0); + d = Length2d(iPos, oPos); + a = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! + + if ( d < bGoal && + TestAngle(a, iAngle-(5.0f*PI/180.0f)/2.0f, iAngle+(5.0f*PI/180.0f)/2.0f) ) + { + bGoal = d; + pGoal = pObj; + } + + if ( d < minDist || d > maxDist ) continue; // too close or too far? + + if ( focus >= PI*2.0f ) + { + if ( (sens >= 0.0f && d < best) || + (sens < 0.0f && d > best) ) + { + best = d; + pBest = pObj; + } + continue; + } + + if ( TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) ) + { + if ( (sens >= 0.0f && d < best) || + (sens < 0.0f && d > best) ) + { + best = d; + pBest = pObj; + } + } + } + + pThis->StartDetectEffect(pGoal, pBest!=0); + + if ( pBest == 0 ) + { + script->m_returnValue = 0.0f; + } + else + { + script->m_returnValue = 1.0f; + } + + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + err = script->m_primaryTask->StartTaskWait(0.3f); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; + } + } + if ( !Process(script, result, exception) ) return FALSE; // not finished + result->SetValFloat(script->m_returnValue); + return TRUE; +} + + +// Compilation of the instruction "direction(pos)". + +CBotTypResult cDirection(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + ret = cPoint(var, user); + if ( ret.GivType() != 0 ) return ret; + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypFloat); +} + +// Instruction "direction(pos)". + +BOOL rDirection(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + D3DVECTOR iPos, oPos; + float a, g; + + if ( !GetPoint(var, exception, oPos) ) return TRUE; + + iPos = pThis->RetPosition(0); + + a = pThis->RetAngleY(0); + g = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! + + result->SetValFloat(-Direction(a, g)*180.0f/PI); + return TRUE; +} + + +// Compilation of the instruction "produce(pos, angle, type, scriptName)". + +CBotTypResult cProduce(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + ret = cPoint(var, user); + if ( ret.GivType() != 0 ) return ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() != CBotTypString ) return CBotTypResult(CBotErrBadString); + var = var->GivNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypFloat); +} + +// Instruction "produce(pos, angle, type, scriptName)". + +BOOL rProduce(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* object; + CBotString cbs; + const char* name; + D3DVECTOR pos; + float angle; + ObjectType type; + + if ( !GetPoint(var, exception, pos) ) return TRUE; + + angle = var->GivValFloat()*PI/180.0f; + var = var->GivNext(); + + type = (ObjectType)var->GivValInt(); + var = var->GivNext(); + + cbs = var->GivValString(); + name = cbs; + + if ( type == OBJECT_FRET || + type == OBJECT_STONE || + type == OBJECT_URANIUM || + type == OBJECT_METAL || + type == OBJECT_POWER || + type == OBJECT_ATOMIC || + type == OBJECT_BULLET || + type == OBJECT_BBOX || + type == OBJECT_KEYa || + type == OBJECT_KEYb || + type == OBJECT_KEYc || + type == OBJECT_KEYd || + type == OBJECT_TNT || + type == OBJECT_SCRAP1 || + type == OBJECT_SCRAP2 || + type == OBJECT_SCRAP3 || + type == OBJECT_SCRAP4 || + type == OBJECT_SCRAP5 || + type == OBJECT_BOMB || + type == OBJECT_WAYPOINT || + type == OBJECT_SHOW || + type == OBJECT_WINFIRE ) + { + object = new CObject(script->m_iMan); + if ( !object->CreateResource(pos, angle, type) ) + { + delete object; + result->SetValInt(1); // error + return TRUE; + } + } + else + if ( type == OBJECT_MOTHER || + type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_BEE || + type == OBJECT_WORM ) + { + CObject* egg; + + object = new CObject(script->m_iMan); + if ( !object->CreateInsect(pos, angle, type) ) + { + delete object; + result->SetValInt(1); // error + return TRUE; + } + + egg = new CObject(script->m_iMan); + if ( !egg->CreateResource(pos, angle, OBJECT_EGG, 0.0f) ) + { + delete egg; + } + } + else + { + result->SetValInt(1); // impossible + return TRUE; + } + object->SetActivity(FALSE); + object->ReadProgram(0, (char*)name); + object->RunProgram(0); + + result->SetValInt(0); // no error + return TRUE; +} + + +// Compilation of the instruction "distance(p1, p2)". + +CBotTypResult cDistance(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + ret = cPoint(var, user); + if ( ret.GivType() != 0 ) return ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + ret = cPoint(var, user); + if ( ret.GivType() != 0 ) return ret; + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypFloat); +} + +// Instruction "distance(p1, p2)". + +BOOL rDistance(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + D3DVECTOR p1, p2; + float value; + + if ( !GetPoint(var, exception, p1) ) return TRUE; + if ( !GetPoint(var, exception, p2) ) return TRUE; + + value = Length(p1, p2); + result->SetValFloat(value/g_unit); + return TRUE; +} + +// Instruction "distance2d(p1, p2)". + +BOOL rDistance2d(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + D3DVECTOR p1, p2; + float value; + + if ( !GetPoint(var, exception, p1) ) return TRUE; + if ( !GetPoint(var, exception, p2) ) return TRUE; + + value = Length2d(p1, p2); + result->SetValFloat(value/g_unit); + return TRUE; +} + + +// Compilation of the instruction "space(center, rMin, rMax, dist)". + +CBotTypResult cSpace(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); + ret = cPoint(var, user); + if ( ret.GivType() != 0 ) return ret; + + if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypIntrinsic, "point"); +} + +// Instruction "space(center, rMin, rMax, dist)". + +BOOL rSpace(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + CBotVar* pSub; + D3DVECTOR center; + float rMin, rMax, dist; + + rMin = 10.0f*g_unit; + rMax = 50.0f*g_unit; + dist = 4.0f*g_unit; + + if ( var == 0 ) + { + center = pThis->RetPosition(0); + } + else + { + if ( !GetPoint(var, exception, center) ) return TRUE; + + if ( var != 0 ) + { + rMin = var->GivValFloat()*g_unit; + var = var->GivNext(); + + if ( var != 0 ) + { + rMax = var->GivValFloat()*g_unit; + var = var->GivNext(); + + if ( var != 0 ) + { + dist = var->GivValFloat()*g_unit; + var = var->GivNext(); + } + } + } + } + script->m_main->FreeSpace(center, rMin, rMax, dist, pThis); + + if ( result != 0 ) + { + pSub = result->GivItemList(); + if ( pSub != 0 ) + { + pSub->SetValFloat(center.x/g_unit); + pSub = pSub->GivNext(); // "y" + pSub->SetValFloat(center.z/g_unit); + pSub = pSub->GivNext(); // "z" + pSub->SetValFloat(center.y/g_unit); + } + } + return TRUE; +} + + +// Compilation of the instruction "flatground(center, rMax)". + +CBotTypResult cFlatGround(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + ret = cPoint(var, user); + if ( ret.GivType() != 0 ) return ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypFloat); +} + +// Instruction "flatground(center, rMax)". + +BOOL rFlatGround(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + D3DVECTOR center; + float rMax, dist; + + if ( !GetPoint(var, exception, center) ) return TRUE; + rMax = var->GivValFloat()*g_unit; + var = var->GivNext(); + + dist = script->m_main->RetFlatZoneRadius(center, rMax, pThis); + result->SetValFloat(dist/g_unit); + + return TRUE; +} + + +// Instruction "wait(t)". + +BOOL rWait(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + float value; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + value = var->GivValFloat(); + err = script->m_primaryTask->StartTaskWait(value); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; + } + } + return Process(script, result, exception); +} + +// Instruction "move(dist)". + +BOOL rMove(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + float value; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + value = var->GivValFloat(); + err = script->m_primaryTask->StartTaskAdvance(value*g_unit); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; + } + } + return Process(script, result, exception); +} + +// Instruction "turn(angle)". + +BOOL rTurn(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + float value; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + value = var->GivValFloat(); + err = script->m_primaryTask->StartTaskTurn(-value*PI/180.0f); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; + } + } + return Process(script, result, exception); +} + +// Compilation of the instruction "goto(pos, altitude, crash, goal)". + +CBotTypResult cGoto(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + ret = cPoint(var, user); + if ( ret.GivType() != 0 ) return ret; + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + return CBotTypResult(CBotErrOverParam); +} + +// Instruction "goto(pos, altitude, mode)". + +BOOL rGoto(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + D3DVECTOR pos; + TaskGotoGoal goal; + TaskGotoCrash crash; + float altitude; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + if ( !GetPoint(var, exception, pos) ) return TRUE; + + goal = TGG_DEFAULT; + crash = TGC_DEFAULT; + altitude = 0.0f*g_unit; + + if ( var != 0 ) + { + altitude = var->GivValFloat()*g_unit; + + var = var->GivNext(); + if ( var != 0 ) + { + goal = (TaskGotoGoal)var->GivValInt(); + + var = var->GivNext(); + if ( var != 0 ) + { + crash = (TaskGotoCrash)var->GivValInt(); + } + } + } + + err = script->m_primaryTask->StartTaskGoto(pos, altitude, goal, crash); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; + } + } + return Process(script, result, exception); +} + +// Instruction "find(type)". + +BOOL rFind(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + D3DVECTOR pos; + TaskGotoGoal goal; + TaskGotoCrash crash; + float altitude; + Error err; + CObject* pThis = (CObject*)user; + CObject *pObj, *pBest; + CBotVar* array; + D3DVECTOR iPos, oPos; + float best, minDist, maxDist, sens, iAngle, angle, focus, d, a; + int type, oType, i; + BOOL bArray; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + type = OBJECT_NULL; + angle = 0.0f; + focus = PI*2.0f; + minDist = 0.0f*g_unit; + maxDist = 1000.0f*g_unit; + sens = 1.0f; + + if ( var->GivType() == CBotTypArrayPointer ) + { + array = var->GivItemList(); + bArray = TRUE; + } + else + { + type = var->GivValInt(); + bArray = FALSE; + } + + best = 100000.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + if ( pObj == pThis ) continue; + + if ( pObj->RetTruck() != 0 ) continue; // object transported? + if ( !pObj->RetActif() ) continue; + if ( pObj->RetProxyActivate() ) continue; + + oType = pObj->RetType(); + if ( oType == OBJECT_TOTO ) continue; + + if ( oType == OBJECT_RUINmobilew2 || + oType == OBJECT_RUINmobilet1 || + oType == OBJECT_RUINmobilet2 || + oType == OBJECT_RUINmobiler1 || + oType == OBJECT_RUINmobiler2 ) + { + oType = OBJECT_RUINmobilew1; // any ruin + } + + if ( oType == OBJECT_SCRAP2 || + oType == OBJECT_SCRAP3 || + oType == OBJECT_SCRAP4 || + oType == OBJECT_SCRAP5 ) // wastes? + { + oType = OBJECT_SCRAP1; // any waste + } + + if ( oType == OBJECT_BARRIER2 || + oType == OBJECT_BARRIER3 ) // barriers? + { + oType = OBJECT_BARRIER1; // any barrier + } + + if ( bArray ) + { + if ( !FindList(array, oType) ) continue; + } + else + { + if ( type != oType && type != OBJECT_NULL ) continue; + } + + oPos = pObj->RetPosition(0); + d = Length2d(iPos, oPos); + if ( d < minDist || d > maxDist ) continue; // too close or too far? + + if ( focus >= PI*2.0f ) + { + if ( d < best ) + { + best = d; + pBest = pObj; + } + continue; + } + + a = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! + if ( TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) ) + { + if ( d < best ) + { + best = d; + pBest = pObj; + } + } + } + + if ( pBest == 0 ) + { + exception = ERR_FIND_IMPOSSIBLE; + return FALSE; + } + + pos = pBest->RetPosition(0); + goal = TGG_DEFAULT; + crash = TGC_DEFAULT; + altitude = 0.0f*g_unit; + + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + err = script->m_primaryTask->StartTaskGoto(pos, altitude, goal, crash); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; + } + } + return Process(script, result, exception); +} + +// Compilation "grab/drop(oper)". + +CBotTypResult cGrabDrop(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Instruction "grab(oper)". + +BOOL rGrab(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + ObjectType oType; + TaskManipArm type; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + if ( var == 0 ) type = TMA_FFRONT; + else type = (TaskManipArm)var->GivValInt(); + + oType = pThis->RetType(); + if ( oType == OBJECT_HUMAN || + oType == OBJECT_TECH ) + { + err = script->m_primaryTask->StartTaskTake(); + } + else + { + err = script->m_primaryTask->StartTaskManip(TMO_GRAB, type); + } + + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; + } + } + return Process(script, result, exception); +} + +// Instruction "drop(oper)". + +BOOL rDrop(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + ObjectType oType; + TaskManipArm type; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + if ( var == 0 ) type = TMA_FFRONT; + else type = (TaskManipArm)var->GivValInt(); + + oType = pThis->RetType(); + if ( oType == OBJECT_HUMAN || + oType == OBJECT_TECH ) + { + err = script->m_primaryTask->StartTaskTake(); + } + else + { + err = script->m_primaryTask->StartTaskManip(TMO_DROP, type); + } + + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; + } + } + return Process(script, result, exception); +} + +// Instruction "sniff()". + +BOOL rSniff(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + err = script->m_primaryTask->StartTaskSearch(); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; + } + } + return Process(script, result, exception); +} + +// Compilation of the instruction "receive(nom, power)". + +CBotTypResult cReceive(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() != CBotTypString ) return CBotTypResult(CBotErrBadString); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Instruction "receive(nom, power)". + +BOOL rReceive(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + CBotString cbs; + Error err; + const char* p; + float value, power; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + + cbs = var->GivValString(); + p = cbs; + var = var->GivNext(); + + power = 10.0f*g_unit; + if ( var != 0 ) + { + power = var->GivValFloat()*g_unit; + var = var->GivNext(); + } + + err = script->m_primaryTask->StartTaskInfo((char*)p, 0.0f, power, FALSE); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetInit(IS_NAN); + return TRUE; + } + } + if ( !Process(script, result, exception) ) return FALSE; // not finished + + value = pThis->RetInfoReturn(); + if ( value == NAN ) + { + result->SetInit(IS_NAN); + } + else + { + result->SetValFloat(value); + } + return TRUE; +} + +// Compilation of the instruction "send(nom, value, power)". + +CBotTypResult cSend(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() != CBotTypString ) return CBotTypResult(CBotErrBadString); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Instruction "send(nom, value, power)". + +BOOL rSend(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + CBotString cbs; + Error err; + const char* p; + float value, power; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + + cbs = var->GivValString(); + p = cbs; + var = var->GivNext(); + + value = var->GivValFloat(); + var = var->GivNext(); + + power = 10.0f*g_unit; + if ( var != 0 ) + { + power = var->GivValFloat()*g_unit; + var = var->GivNext(); + } + + err = script->m_primaryTask->StartTaskInfo((char*)p, value, power, TRUE); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; + } + } + return Process(script, result, exception); +} + +// Seeks the nearest information terminal. + +CObject* SearchInfo(CScript* script, CObject* object, float power) +{ + CObject *pObj, *pBest; + D3DVECTOR iPos, oPos; + ObjectType type; + float dist, min; + int i; + + iPos = object->RetPosition(0); + + min = 100000.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_INFO ) continue; + + if ( !pObj->RetActif() ) continue; + + oPos = pObj->RetPosition(0); + dist = Length(oPos, iPos); + if ( dist > power ) continue; // too far? + if ( dist < min ) + { + min = dist; + pBest = pObj; + } + } + + return pBest; +} + +// Compilation of the instruction "deleteinfo(nom, power)". + +CBotTypResult cDeleteInfo(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() != CBotTypString ) return CBotTypResult(CBotErrBadString); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Instruction "deleteinfo(nom, power)". + +BOOL rDeleteInfo(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + CObject* pInfo; + CBotString cbs; + Info info; + const char* p; + float power; + int i, total; + + exception = 0; + + cbs = var->GivValString(); + p = cbs; + var = var->GivNext(); + + power = 10.0f*g_unit; + if ( var != 0 ) + { + power = var->GivValFloat()*g_unit; + var = var->GivNext(); + } + + pInfo = SearchInfo(script, pThis, power); + if ( pInfo == 0 ) + { + result->SetValFloat(0.0f); // false + return TRUE; + } + + total = pInfo->RetInfoTotal(); + for ( i=0 ; iRetInfo(i); + if ( strcmp(info.name, p) == 0 ) + { + pInfo->DeleteInfo(i); + result->SetValFloat(1.0f); // true + return TRUE; + } + } + result->SetValFloat(0.0f); // false + return TRUE; +} + +// Compilation of the instruction "testinfo(nom, power)". + +CBotTypResult cTestInfo(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() != CBotTypString ) return CBotTypResult(CBotErrBadString); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypBoolean); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypBoolean); +} + +// Instruction "testinfo(nom, power)". + +BOOL rTestInfo(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + CObject* pInfo; + CBotString cbs; + Info info; + const char* p; + float power; + int i, total; + + exception = 0; + + cbs = var->GivValString(); + p = cbs; + var = var->GivNext(); + + power = 10.0f*g_unit; + if ( var != 0 ) + { + power = var->GivValFloat()*g_unit; + var = var->GivNext(); + } + + pInfo = SearchInfo(script, pThis, power); + if ( pInfo == 0 ) + { + result->SetValInt(FALSE); + return TRUE; + } + + total = pInfo->RetInfoTotal(); + for ( i=0 ; iRetInfo(i); + if ( strcmp(info.name, p) == 0 ) + { + result->SetValInt(TRUE); + return TRUE; + } + } + result->SetValInt(FALSE); + return TRUE; +} + +// Instruction "thump()". + +BOOL rThump(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + err = script->m_primaryTask->StartTaskTerraform(); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; + } + } + return Process(script, result, exception); +} + +// Instruction "recycle()". + +BOOL rRecycle(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + err = script->m_primaryTask->StartTaskRecover(); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; + } + } + return Process(script, result, exception); +} + +// Compilation "shield(oper, radius)". + +CBotTypResult cShield(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypFloat); +} + +// Instruction "shield(oper, radius)". + +BOOL rShield(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + float oper, radius; + Error err; + + oper = var->GivValFloat(); // 0=down, 1=up + var = var->GivNext(); + + radius = var->GivValFloat(); + if ( radius < 10.0f ) radius = 10.0f; + if ( radius > 25.0f ) radius = 25.0f; + radius = (radius-10.0f)/15.0f; + + if ( *script->m_secondaryTask == 0 ) // shield folds? + { + if ( oper == 0.0f ) // down? + { + result->SetValInt(1); // shows the error + } + else // up ? + { + pThis->SetParam(radius); + + *script->m_secondaryTask = new CTaskManager(script->m_iMan, script->m_object); + err = (*script->m_secondaryTask)->StartTaskShield(TSM_UP, 1000.0f); + if ( err != ERR_OK ) + { + delete *script->m_secondaryTask; + *script->m_secondaryTask = 0; + result->SetValInt(err); // shows the error + } + } + } + else // shield deployed? + { + if ( oper == 0.0f ) // down? + { + (*script->m_secondaryTask)->StartTaskShield(TSM_DOWN, 0.0f); + } + else // up? + { +//? result->SetValInt(1); // shows the error + pThis->SetParam(radius); + (*script->m_secondaryTask)->StartTaskShield(TSM_UPDATE, 0.0f); + } + } + + return TRUE; +} + +// Compilation "fire(delay)". + +CBotTypResult cFire(CBotVar* &var, void* user) +{ +#if 0 + CObject* pThis = (CObject*)user; + ObjectType type; + + type = pThis->RetType(); + + if ( type == OBJECT_ANT ) + { + return cOnePoint(var, user); + } + else if ( type == OBJECT_SPIDER ) + { + return cNull(var, user); + } + else + { + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); + } +#else + return CBotTypResult(CBotTypFloat); +#endif +} + +// Instruction "fire(delay)". + +BOOL rFire(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + float delay; + D3DVECTOR impact; + Error err; + ObjectType type; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + + type = pThis->RetType(); + + if ( type == OBJECT_ANT ) + { + if ( !GetPoint(var, exception, impact) ) return TRUE; + impact.y += pThis->RetWaterLevel(); + err = script->m_primaryTask->StartTaskFireAnt(impact); + } + else if ( type == OBJECT_SPIDER ) + { + err = script->m_primaryTask->StartTaskSpiderExplo(); + } + else + { + if ( var == 0 ) delay = 0.0f; + else delay = var->GivValFloat(); + err = script->m_primaryTask->StartTaskFire(delay); + } + + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + return TRUE; + } + } + return Process(script, result, exception); +} + +// Instruction "aim(dir)". + +BOOL rAim(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + float value; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + value = var->GivValFloat(); + err = script->m_primaryTask->StartTaskGunGoal(value*PI/180.0f, 0.0f); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + return TRUE; + } + } + return Process(script, result, exception); +} + +// Compilation of the instruction "motor(left, right)". + +CBotTypResult cMotor(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypFloat); +} + +// Instruction "motor(left, right)". + +BOOL rMotor(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CObject* pThis = (CObject*)user; + CPhysics* physics = ((CObject*)user)->RetPhysics(); + float left, right, speed, turn; + + left = var->GivValFloat(); + var = var->GivNext(); + right = var->GivValFloat(); + + speed = (left+right)/2.0f; + if ( speed < -1.0f ) speed = -1.0f; + if ( speed > 1.0f ) speed = 1.0f; + + turn = left-right; + if ( turn < -1.0f ) turn = -1.0f; + if ( turn > 1.0f ) turn = 1.0f; + + if ( pThis->RetFixed() ) // ant on the back? + { + speed = 0.0f; + turn = 0.0f; + } + + physics->SetMotorSpeedX(speed); // forward/backward + physics->SetMotorSpeedZ(turn); // turns + + return TRUE; +} + +// Instruction "jet(power)". + +BOOL rJet(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CPhysics* physics = ((CObject*)user)->RetPhysics(); + float value; + + value = var->GivValFloat(); + physics->SetMotorSpeedY(value); + + return TRUE; +} + +// Compilation of the instruction "topo(pos)". + +CBotTypResult cTopo(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + ret = cPoint(var, user); + if ( ret.GivType() != 0 ) return ret; + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + return CBotTypResult(CBotErrOverParam); +} + +// Instruction "topo(pos)". + +BOOL rTopo(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + D3DVECTOR pos; + float level; + + exception = 0; + + if ( !GetPoint(var, exception, pos) ) return TRUE; + + level = script->m_terrain->RetFloorLevel(pos); + level -= script->m_water->RetLevel(); + result->SetValFloat(level/g_unit); + return TRUE; +} + +// Compilation of the instruction "message(string, type)". + +CBotTypResult cMessage(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GivType() != CBotTypString && + var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + return CBotTypResult(CBotErrOverParam); +} + +// Instruction "message(string, type)". + +BOOL rMessage(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CBotString cbs; + const char* p; + TextType type; + + cbs = var->GivValString(); + p = cbs; + + type = TT_MESSAGE; + var = var->GivNext(); + if ( var != 0 ) + { + type = (TextType)var->GivValInt(); + } + + script->m_displayText->DisplayText((char*)p, script->m_object, 10.0f, type); + script->m_main->CheckEndMessage((char*)p); + + return TRUE; +} + +// Instruction "cmdline(rank)". + +BOOL rCmdline(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + float value; + int rank; + + rank = var->GivValInt(); + value = pThis->RetCmdLine(rank); + result->SetValFloat(value); + + return TRUE; +} + +// Instruction "ismovie()". + +BOOL rIsMovie(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + float value; + + value = script->m_main->RetMovieLock()?1.0f:0.0f; + result->SetValFloat(value); + + return TRUE; +} + +// Instruction "errmode(mode)". + +BOOL rErrMode(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + int value; + + value = var->GivValInt(); + if ( value < 0 ) value = 0; + if ( value > 1 ) value = 1; + script->m_errMode = value; + + return TRUE; +} + +// Instruction "ipf(num)". + +BOOL rIPF(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + int value; + + value = var->GivValInt(); + if ( value < 1 ) value = 1; + if ( value > 10000 ) value = 10000; + script->m_ipf = value; + + return TRUE; +} + +// Instruction "abstime()". + +BOOL rAbsTime(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + float value; + + value = script->m_main->RetGameTime(); + result->SetValFloat(value); + return TRUE; +} + + +// Prepares a file name. + +void PrepareFilename(CBotString &filename, char *dir) +{ + int pos; + + pos = filename.ReverseFind('\\'); + if ( pos > 0 ) + { + filename = filename.Mid(pos+1); // removes folders + } + + pos = filename.ReverseFind('/'); + if ( pos > 0 ) + { + filename = filename.Mid(pos+1); // also those with / + } + + pos = filename.ReverseFind(':'); + if ( pos > 0 ) + { + filename = filename.Mid(pos+1); // also removes the drive letter C: + } + + filename = CBotString(dir) + CBotString("\\") + filename; +} + +// Instruction "deletefile(filename)". + +BOOL rDeleteFile(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CBotString cbs; + const char* p; + char* dir; + + cbs = var->GivValString(); + dir = script->m_main->RetFilesDir(); + PrepareFilename(cbs, dir); + p = cbs; + DeleteFile(p); + + return TRUE; +} + +// Compilation of the instruction "pendown(color, width)". + +CBotTypResult cPenDown(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GivNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + return CBotTypResult(CBotErrOverParam); +} + +// Instruction "pendown(color, width)". + +BOOL rPenDown(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + int color; + float width; + Error err; + + if ( pThis->RetType() == OBJECT_MOBILEdr ) + { + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + if ( var != 0 ) + { + color = var->GivValInt(); + if ( color < 0 ) color = 0; + if ( color > 17 ) color = 17; + pThis->SetTraceColor(color); + + var = var->GivNext(); + if ( var != 0 ) + { + width = var->GivValFloat(); + if ( width < 0.1f ) width = 0.1f; + if ( width > 1.0f ) width = 1.0f; + pThis->SetTraceWidth(width); + } + } + pThis->SetTraceDown(TRUE); + + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + err = script->m_primaryTask->StartTaskPen(pThis->RetTraceDown(), pThis->RetTraceColor()); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; + } + } + return Process(script, result, exception); + } + else + { + if ( var != 0 ) + { + color = var->GivValInt(); + if ( color < 0 ) color = 0; + if ( color > 17 ) color = 17; + pThis->SetTraceColor(color); + + var = var->GivNext(); + if ( var != 0 ) + { + width = var->GivValFloat(); + if ( width < 0.1f ) width = 0.1f; + if ( width > 1.0f ) width = 1.0f; + pThis->SetTraceWidth(width); + } + } + pThis->SetTraceDown(TRUE); + + return TRUE; + } +} + +// Instruction "penup()". + +BOOL rPenUp(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CObject* pThis = (CObject*)user; + Error err; + + if ( pThis->RetType() == OBJECT_MOBILEdr ) + { + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + pThis->SetTraceDown(FALSE); + + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + err = script->m_primaryTask->StartTaskPen(pThis->RetTraceDown(), pThis->RetTraceColor()); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; + } + } + return Process(script, result, exception); + } + else + { + pThis->SetTraceDown(FALSE); + return TRUE; + } +} + +// Instruction "pencolor()". + +BOOL rPenColor(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = ((CObject*)user)->RetRunScript(); + CPhysics* physics = ((CObject*)user)->RetPhysics(); + CObject* pThis = (CObject*)user; + int color; + Error err; + + if ( pThis->RetType() == OBJECT_MOBILEdr ) + { + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + color = var->GivValInt(); + if ( color < 0 ) color = 0; + if ( color > 17 ) color = 17; + pThis->SetTraceColor(color); + + script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); + err = script->m_primaryTask->StartTaskPen(pThis->RetTraceDown(), pThis->RetTraceColor()); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return FALSE; + } + return TRUE; + } + } + return Process(script, result, exception); + } + else + { + color = var->GivValInt(); + if ( color < 0 ) color = 0; + if ( color > 17 ) color = 17; + pThis->SetTraceColor(color); + + return TRUE; + } +} + +// Instruction "penwidth()". + +BOOL rPenWidth(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CObject* pThis = (CObject*)user; + float width; + + width = var->GivValFloat(); + if ( width < 0.1f ) width = 0.1f; + if ( width > 1.0f ) width = 1.0f; + pThis->SetTraceWidth(width); + return TRUE; +} + + + +// Object's constructor. + +CScript::CScript(CInstanceManager* iMan, CObject* object, CTaskManager** secondaryTask) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_SCRIPT, this, 100); + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); + m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); + m_botProg = 0; + m_object = object; + m_primaryTask = 0; + m_secondaryTask = secondaryTask; + + m_ipf = CBOT_IPF; + m_errMode = ERM_STOP; + m_len = 0; + m_script = 0; + m_bRun = FALSE; + m_bStepMode = FALSE; + m_bCompile = FALSE; + m_title[0] = 0; + m_cursor1 = 0; + m_cursor2 = 0; + m_filename[0] = 0; +} + +// Initializes all functions for module CBOT. + +void CScript::InitFonctions() +{ + CBotProgram::AddFunction("sin", rSin, cOneFloat); + CBotProgram::AddFunction("cos", rCos, cOneFloat); + CBotProgram::AddFunction("tan", rTan, cOneFloat); + CBotProgram::AddFunction("asin", raSin, cOneFloat); + CBotProgram::AddFunction("acos", raCos, cOneFloat); + CBotProgram::AddFunction("atan", raTan, cOneFloat); + CBotProgram::AddFunction("sqrt", rSqrt, cOneFloat); + CBotProgram::AddFunction("pow", rPow, cTwoFloat); + CBotProgram::AddFunction("rand", rRand, cNull); + CBotProgram::AddFunction("abs", rAbs, cOneFloat); + + CBotProgram::AddFunction("retobject", rRetObject, cRetObject); + CBotProgram::AddFunction("search", rSearch, cSearch); + CBotProgram::AddFunction("radar", rRadar, cRadar); + CBotProgram::AddFunction("detect", rDetect, cDetect); + CBotProgram::AddFunction("direction", rDirection, cDirection); + CBotProgram::AddFunction("produce", rProduce, cProduce); + CBotProgram::AddFunction("distance", rDistance, cDistance); + CBotProgram::AddFunction("distance2d",rDistance2d,cDistance); + CBotProgram::AddFunction("space", rSpace, cSpace); + CBotProgram::AddFunction("flatground",rFlatGround,cFlatGround); + CBotProgram::AddFunction("wait", rWait, cOneFloat); + CBotProgram::AddFunction("move", rMove, cOneFloat); + CBotProgram::AddFunction("turn", rTurn, cOneFloat); + CBotProgram::AddFunction("goto", rGoto, cGoto); + CBotProgram::AddFunction("find", rFind, cOneFloat); + CBotProgram::AddFunction("grab", rGrab, cGrabDrop); + CBotProgram::AddFunction("drop", rDrop, cGrabDrop); + CBotProgram::AddFunction("sniff", rSniff, cNull); + CBotProgram::AddFunction("receive", rReceive, cReceive); + CBotProgram::AddFunction("send", rSend, cSend); + CBotProgram::AddFunction("deleteinfo",rDeleteInfo,cDeleteInfo); + CBotProgram::AddFunction("testinfo", rTestInfo, cTestInfo); + CBotProgram::AddFunction("thump", rThump, cNull); + CBotProgram::AddFunction("recycle", rRecycle, cNull); + CBotProgram::AddFunction("shield", rShield, cShield); + CBotProgram::AddFunction("fire", rFire, cFire); + CBotProgram::AddFunction("aim", rAim, cOneFloat); + CBotProgram::AddFunction("motor", rMotor, cMotor); + CBotProgram::AddFunction("jet", rJet, cOneFloat); + CBotProgram::AddFunction("topo", rTopo, cTopo); + CBotProgram::AddFunction("message", rMessage, cMessage); + CBotProgram::AddFunction("cmdline", rCmdline, cOneFloat); + CBotProgram::AddFunction("ismovie", rIsMovie, cNull); + CBotProgram::AddFunction("errmode", rErrMode, cOneFloat); + CBotProgram::AddFunction("ipf", rIPF, cOneFloat); + CBotProgram::AddFunction("abstime", rAbsTime, cNull); + CBotProgram::AddFunction("deletefile",rDeleteFile,cString); + CBotProgram::AddFunction("pendown", rPenDown, cPenDown); + CBotProgram::AddFunction("penup", rPenUp, cNull); + CBotProgram::AddFunction("pencolor", rPenColor, cOneFloat); + CBotProgram::AddFunction("penwidth", rPenWidth, cOneFloat); +} + +// Object's destructor. + +CScript::~CScript() +{ + delete m_botProg; + delete m_primaryTask; + delete m_script; + m_script = 0; + m_len = 0; + + m_iMan->DeleteInstance(CLASS_SCRIPT, this); +} + + +// Gives the script editable block of text. + +void CScript::PutScript(CEdit* edit, char* name) +{ + if ( m_script == 0 ) + { + New(edit, name); + } + else + { + edit->SetText(m_script); + edit->SetCursor(m_cursor2, m_cursor1); + edit->ShowSelect(); + } + edit->SetFocus(TRUE); +} + +// The script takes a paved text. + +BOOL CScript::GetScript(CEdit* edit) +{ + int len; + + delete m_script; + m_script = 0; + + len = edit->RetTextLength(); + m_script = (char*)malloc(sizeof(char)*(len+1)); + + edit->GetText(m_script, len+1); + edit->GetCursor(m_cursor2, m_cursor1); + m_len = strlen(m_script); + + if ( !CheckToken() ) + { + edit->SetCursor(m_cursor2, m_cursor1); + edit->ShowSelect(); + edit->SetFocus(TRUE); + return FALSE; + } + + if ( !Compile() ) + { + edit->SetCursor(m_cursor2, m_cursor1); + edit->ShowSelect(); + edit->SetFocus(TRUE); + return FALSE; + } + + return TRUE; +} + +// Indicates whether a program is compiled correctly. + +BOOL CScript::RetCompile() +{ + return m_bCompile; +} + +// Indicates whether the program is empty. + +BOOL CScript::IsEmpty() +{ + int i; + + for ( i=0 ; iRetCheckToken() ) return TRUE; + + m_error = 0; + m_title[0] = 0; + m_token[0] = 0; + m_bCompile = FALSE; + + for ( i=0 ; iRetObligatoryToken() ; i++ ) + { + used[i] = 0; // token not used + } + + bt = CBotToken::CompileTokens(m_script, error); + while ( bt != 0 ) + { + bs = bt->GivString(); + token = bs; + type = bt->GivType(); + + cursor1 = bt->GivStart(); + cursor2 = bt->GivEnd(); + + i = m_main->IsObligatoryToken((char*)token); + if ( i != -1 ) + { + used[i] = 1; // token used + } + + if ( !m_main->IsProhibitedToken((char*)token) ) + { + m_error = ERR_PROHIBITEDTOKEN; + m_cursor1 = cursor1; + m_cursor2 = cursor2; + strcpy(m_title, ""); + CBotToken::Delete(bt); + return FALSE; + } + + bt = bt->GivNext(); + } + + // At least once every obligatory instruction? + for ( i=0 ; iRetObligatoryToken() ; i++ ) + { + if ( used[i] == 0 ) // token not used? + { + strcpy(m_token, m_main->RetObligatoryToken(i)); + m_error = ERR_OBLIGATORYTOKEN; + strcpy(m_title, ""); + CBotToken::Delete(bt); + return FALSE; + } + } + + CBotToken::Delete(bt); + return TRUE; +} + +// Compile the script of a paved text. + +BOOL CScript::Compile() +{ + CBotStringArray liste; + int i; + const char* p; + + m_error = 0; + m_cursor1 = 0; + m_cursor2 = 0; + m_title[0] = 0; + m_bCompile = FALSE; + + if ( IsEmpty() ) // program exist? + { + delete m_botProg; + m_botProg = 0; + return TRUE; + } + + if ( m_botProg == 0 ) + { + m_botProg = new CBotProgram(m_object->RetBotVar()); + } + + if ( m_botProg->Compile(m_script, liste, this) ) + { + if ( liste.GivSize() == 0 ) + { + strcpy(m_title, ""); + } + else + { + p = liste[0]; + i = 0; + while ( TRUE ) + { + if ( p[i] == 0 || p[i] == '(' ) break; + if ( i >= 20 ) + { + m_title[i++] = '.'; + m_title[i++] = '.'; + m_title[i++] = '.'; + break; + } + m_title[i] = p[i]; + i ++; + } + m_title[i] = 0; + } + m_bCompile = TRUE; + return TRUE; + } + else + { + m_botProg->GetError(m_error, m_cursor1, m_cursor2); + if ( m_cursor1 < 0 || m_cursor1 > m_len || + m_cursor2 < 0 || m_cursor2 > m_len ) + { + m_cursor1 = 0; + m_cursor2 = 0; + } + if ( m_error == 0 ) + { + m_cursor1 = m_cursor2 = 0; + } + strcpy(m_title, ""); + return FALSE; + } +} + + +// Returns the title of the script. + +void CScript::GetTitle(char* buffer) +{ + strcpy(buffer, m_title); +} + + +// Choice of mode of execution. + +void CScript::SetStepMode(BOOL bStep) +{ + m_bStepMode = bStep; +} + + +// Runs the program from the beginning. + +BOOL CScript::Run() +{ + if( m_botProg == 0 ) return FALSE; + if ( m_script == 0 || m_len == 0 ) return FALSE; + + if ( !m_botProg->Start(m_title) ) return FALSE; + + m_object->SetRunScript(this); + m_bRun = TRUE; + m_bContinue = FALSE; + m_ipf = CBOT_IPF; + m_errMode = ERM_STOP; + + if ( m_bStepMode ) // step by step mode? + { + Event newEvent; + ZeroMemory(&newEvent, sizeof(Event)); + Step(newEvent); + } + + return TRUE; +} + +// Continues the execution of current program. +// Returns TRUE when execution is finished. + +BOOL CScript::Continue(const Event &event) +{ + if( m_botProg == 0 ) return TRUE; + if ( !m_bRun ) return TRUE; + + m_event = event; + + if ( m_bStepMode ) // step by step mode? + { + if ( m_bContinue ) // instuction "move", "goto", etc. ? + { + if ( m_botProg->Run(m_object, 0) ) + { + m_botProg->GetError(m_error, m_cursor1, m_cursor2); + if ( m_cursor1 < 0 || m_cursor1 > m_len || + m_cursor2 < 0 || m_cursor2 > m_len ) + { + m_cursor1 = 0; + m_cursor2 = 0; + } + if ( m_error == 0 ) + { + m_cursor1 = m_cursor2 = 0; + } + m_bRun = FALSE; + + if ( m_error != 0 && m_errMode == ERM_STOP ) + { + char s[100]; + GetError(s); + m_displayText->DisplayText(s, m_object, 10.0f, TT_ERROR); + } + m_engine->SetPause(TRUE); // gives pause + return TRUE; + } + if ( !m_bContinue ) + { + m_engine->SetPause(TRUE); // gives pause + } + } + + return FALSE; + } + + if ( m_botProg->Run(m_object, m_ipf) ) + { + m_botProg->GetError(m_error, m_cursor1, m_cursor2); + if ( m_cursor1 < 0 || m_cursor1 > m_len || + m_cursor2 < 0 || m_cursor2 > m_len ) + { + m_cursor1 = 0; + m_cursor2 = 0; + } + if ( m_error == 0 ) + { + m_cursor1 = m_cursor2 = 0; + } + m_bRun = FALSE; + + if ( m_error != 0 && m_errMode == ERM_STOP ) + { + char s[100]; + GetError(s); + m_displayText->DisplayText(s, m_object, 10.0f, TT_ERROR); + } + return TRUE; + } + + return FALSE; +} + +// Continues the execution of current program. +// Returns TRUE when execution is finished. + +BOOL CScript::Step(const Event &event) +{ + if( m_botProg == 0 ) return TRUE; + if ( !m_bRun ) return TRUE; + if ( !m_bStepMode ) return FALSE; + + m_engine->SetPause(FALSE); + m_engine->StepSimul(0.01f); // advance of 10ms + m_engine->SetPause(TRUE); + + m_event = event; + + if ( m_botProg->Run(m_object, 0) ) // step mode + { + m_botProg->GetError(m_error, m_cursor1, m_cursor2); + if ( m_cursor1 < 0 || m_cursor1 > m_len || + m_cursor2 < 0 || m_cursor2 > m_len ) + { + m_cursor1 = 0; + m_cursor2 = 0; + } + if ( m_error == 0 ) + { + m_cursor1 = m_cursor2 = 0; + } + m_bRun = FALSE; + + if ( m_error != 0 && m_errMode == ERM_STOP ) + { + char s[100]; + GetError(s); + m_displayText->DisplayText(s, m_object, 10.0f, TT_ERROR); + } + return TRUE; + } + + if ( m_bContinue ) // instuction "move", "goto", etc. ? + { + m_engine->SetPause(FALSE); // removes the pause + } + return FALSE; +} + +// Stops the program. + +void CScript::Stop() +{ + if ( !m_bRun ) return; + + if( m_botProg != 0 ) + { + m_botProg->Stop(); + } + + if ( m_primaryTask != 0 ) + { + m_primaryTask->Abort(); + delete m_primaryTask; + m_primaryTask = 0; + } + + m_bRun = FALSE; +} + +// Indicates whether the program runs. + +BOOL CScript::IsRunning() +{ + return m_bRun; +} + +// Indicates whether the program continues a step. + +BOOL CScript::IsContinue() +{ + return m_bContinue; +} + + +// Gives the position of the cursor during the execution. + +BOOL CScript::GetCursor(int &cursor1, int &cursor2) +{ + const char* funcName; + + cursor1 = cursor2 = 0; + + if( m_botProg == 0 ) return FALSE; + if ( !m_bRun ) return FALSE; + + m_botProg->GetRunPos(funcName, cursor1, cursor2); + if ( cursor1 < 0 || cursor1 > m_len || + cursor2 < 0 || cursor2 > m_len ) + { + cursor1 = 0; + cursor2 = 0; + } + return TRUE; +} + + +// Put of the variables in a list. + +void PutList(char *baseName, BOOL bArray, CBotVar *var, CList *list, int &rankList) +{ + CBotString bs; + CBotVar *svar, *pStatic; + char varName[100]; + char buffer[100]; + const char *p; + int index, type; + + if ( var == 0 && baseName[0] != 0 ) + { + sprintf(buffer, "%s = null;", baseName); + list->SetName(rankList++, buffer); + return; + } + + index = 0; + while ( var != 0 ) + { + var->Maj(NULL, FALSE); + pStatic = var->GivStaticVar(); // finds the static element + + bs = pStatic->GivName(); // variable name + p = bs; +//? if ( strcmp(p, "this") == 0 ) +//? { +//? var = var->GivNext(); +//? continue; +//? } + + if ( baseName[0] == 0 ) + { + sprintf(varName, "%s", p); + } + else + { + if ( bArray ) + { + sprintf(varName, "%s[%d]", baseName, index); + } + else + { + sprintf(varName, "%s.%s", baseName, p); + } + } + + type = pStatic->GivType(); + + if ( type < CBotTypBoolean ) + { + CBotString value; + value = pStatic->GivValString(); + p = value; + sprintf(buffer, "%s = %s;", varName, p); + list->SetName(rankList++, buffer); + } + else if ( type == CBotTypString ) + { + CBotString value; + value = pStatic->GivValString(); + p = value; + sprintf(buffer, "%s = \"%s\";", varName, p); + list->SetName(rankList++, buffer); + } + else if ( type == CBotTypArrayPointer ) + { + svar = pStatic->GivItemList(); + PutList(varName, TRUE, svar, list, rankList); + } + else if ( type == CBotTypClass || + type == CBotTypPointer ) + { + svar = pStatic->GivItemList(); + PutList(varName, FALSE, svar, list, rankList); + } + else + { + sprintf(buffer, "%s = ?;", varName); + list->SetName(rankList++, buffer); + } + + index ++; + var = var->GivNext(); + } +} + +// Fills a list with variables. + +void CScript::UpdateList(CList* list) +{ + CBotVar *var; + const char *progName, *funcName; + int total, select, level, cursor1, cursor2, rank; + + if( m_botProg == 0 ) return; + + total = list->RetTotal(); + select = list->RetSelect(); + + list->Flush(); // empty list + m_botProg->GetRunPos(progName, cursor1, cursor2); + if ( progName == 0 ) return; + + level = 0; + rank = 0; + while ( TRUE ) + { + var = m_botProg->GivStackVars(funcName, level--); + if ( funcName != progName ) break; + + PutList("", FALSE, var, list, rank); + } + + if ( total == list->RetTotal() ) // same total? + { + list->SetSelect(select); + } + + list->SetTooltip(""); + list->SetState(STATE_ENABLE); +} + + +// Colorize the text according to syntax. + +void CScript::ColorizeScript(CEdit* edit) +{ + CBotToken* bt; + CBotString bs; + const char* token; + int error, type, cursor1, cursor2, color; + + edit->ClearFormat(); + + bt = CBotToken::CompileTokens(edit->RetText(), error); + while ( bt != 0 ) + { + bs = bt->GivString(); + token = bs; + type = bt->GivType(); + + cursor1 = bt->GivStart(); + cursor2 = bt->GivEnd(); + + color = 0; + if ( type >= TokenKeyWord && type < TokenKeyWord+100 ) + { + color = COLOR_TOKEN; + } + if ( type >= TokenKeyDeclare && type < TokenKeyDeclare+100 ) + { + color = COLOR_TYPE; + } + if ( type >= TokenKeyVal && type < TokenKeyVal+100 ) + { + color = COLOR_CONST; + } + if ( type == TokenTypVar ) + { + if ( IsType(token) ) + { + color = COLOR_TYPE; + } + else if ( IsFunction(token) ) + { + color = COLOR_TOKEN; + } + } + if ( type == TokenTypDef ) + { + color = COLOR_CONST; + } + + if ( cursor1 < cursor2 && color != 0 ) + { + edit->SetFormat(cursor1, cursor2, color); + } + + bt = bt->GivNext(); + } + + CBotToken::Delete(bt); +} + + +// Seeks a token at random in a script. +// Returns the index of the start of the token found, or -1. + +int SearchToken(char* script, char* token) +{ + int lScript, lToken, i, iFound; + int found[100]; + char* p; + + lScript = strlen(script); + lToken = strlen(token); + iFound = 0; + for ( i=0 ; i= 100 ) break; + } + } + + if ( iFound == 0 ) return -1; + return found[rand()%iFound]; +} + +// Removes a token in a script. + +void DeleteToken(char* script, int pos, int len) +{ + while ( TRUE ) + { + script[pos] = script[pos+len]; + if ( script[pos++] == 0 ) break; + } +} + +// Inserts a token in a script. + +void InsertToken(char* script, int pos, char* token) +{ + int lScript, lToken, i; + + lScript = strlen(script); + lToken = strlen(token); + for ( i=lScript ; i>=pos ; i-- ) + { + script[i+lToken] = script[i]; + } + memcpy(script+pos, token, lToken); +} + +// Introduces a virus into a program. + +BOOL CScript::IntroduceVirus() +{ + int i, start, iFound; + int found[11*2]; + char* newScript; + + char* names[11*2] = + { + "==", "!=", + "!=", "==", + ">", "<", + "<", ">", + "true", "false", + "false", "true", + "grab", "drop", + "drop", "grab", + "InFront", "Behind", + "Behind", "EnergyCell", + "EnergyCell", "InFront", + }; + + iFound = 0; + for ( i=0 ; i<11 ; i++ ) + { + start = SearchToken(m_script, names[i*2]); + if ( start != -1 ) + { + found[iFound++] = i*2; + found[iFound++] = start; + } + } + if ( iFound == 0 ) return FALSE; + + i = (rand()%(iFound/2))*2; + start = found[i+1]; + i = found[i+0]; + + newScript = (char*)malloc(sizeof(char)*(m_len+strlen(names[i+1])+1)); + strcpy(newScript, m_script); + delete m_script; + m_script = newScript; + + DeleteToken(m_script, start, strlen(names[i])); + InsertToken(m_script, start, names[i+1]); + m_len = strlen(m_script); + Compile(); // recompile with the virus + + return TRUE; +} + + +// Returns the number of the error. + +int CScript::RetError() +{ + return m_error; +} + +// Returns the text of the error. + +void CScript::GetError(char* buffer) +{ + if ( m_error == 0 ) + { + buffer[0] = 0; + } + else + { + if ( m_error == ERR_OBLIGATORYTOKEN ) + { + char s[100]; + GetResource(RES_ERR, m_error, s); + sprintf(buffer, s, m_token); + } + else if ( m_error < 1000 ) + { + GetResource(RES_ERR, m_error, buffer); + } + else + { + GetResource(RES_CBOT, m_error, buffer); + } + } +} + + +// New program. + +void CScript::New(CEdit* edit, char* name) +{ + FILE *file = NULL; + char res[100]; + char text[100]; + char filename[100]; + char script[500]; + char buffer[500]; + char *sf; + int cursor1, cursor2, len, i, j; + + GetResource(RES_TEXT, RT_SCRIPT_NEW, res); + if ( name[0] == 0 ) strcpy(text, res); + else strcpy(text, name); + + sprintf(script, "extern void object::%s()\n{\n\t\n\t\n\t\n}\n", text); + edit->SetText(script, FALSE); + + if ( strcmp(text, res) == 0 ) + { + cursor1 = 20; + cursor2 = 20+strlen(text); // update "New" + } + else + { + if ( edit->RetAutoIndent() ) + { + cursor1 = 20+strlen(text)+6; + cursor2 = cursor1; // cursor in { } + } + else + { + cursor1 = 20+strlen(text)+8; + cursor2 = cursor1; // cursor in { } + } + } + + edit->SetCursor(cursor2, cursor1); + edit->ShowSelect(); + edit->SetFocus(TRUE); + + sf = m_main->RetScriptFile(); + if ( sf[0] != 0 ) // Load an empty program specific? + { + strcpy(filename, "script\\"); + strcat(filename, sf); + file = fopen(filename, "rb"); + if ( file != NULL ) + { + fseek(file, 0, SEEK_END); + len = ftell(file); + fseek(file, 0, SEEK_SET); + + if ( len > 500-1 ) len = 500-1; + fread(buffer, 1, len, file); + buffer[len] = 0; + fclose(file); + + cursor1 = 0; + i = 0; + j = 0; + while ( TRUE ) + { + if ( buffer[i] == 0 ) break; + + if ( buffer[i] == '\r' ) + { + i ++; + continue; + } + + if ( buffer[i] == '\t' && edit->RetAutoIndent() ) + { + i ++; + continue; + } + + if ( buffer[i+0] == '%' && + buffer[i+1] == 's' ) + { + strcpy(script+j, text); + j += strlen(text); + i += 2; + continue; + } + + if ( buffer[i] == '#' ) + { + cursor1 = j; + i ++; + continue; + } + + script[j++] = buffer[i++]; + } + script[j] = 0; + edit->SetText(script, FALSE); + + cursor2 = cursor1; + edit->SetCursor(cursor2, cursor1); + edit->ShowSelect(); + edit->SetFocus(TRUE); + } + } + + ColorizeScript(edit); +} + + +// Provided a script for all parts. + +BOOL CScript::SendScript(char* text) +{ + m_len = strlen(text); + m_script = (char*)malloc(sizeof(char)*(m_len+1)); + strcpy(m_script, text); + if ( !CheckToken() ) return FALSE; + if ( !Compile() ) return FALSE; + + return TRUE; +} + +// Reads a script as a text file. + +BOOL CScript::ReadScript(char* filename) +{ + FILE* file; + CEdit* edit; + char name[100]; + + if ( strchr(filename, '\\') == 0 ) + { + strcpy(name, "script\\"); + strcat(name, filename); + } + else + { +//? strcpy(name, filename); + UserDir(name, filename, ""); + } + + file = fopen(name, "rb"); + if ( file == NULL ) return FALSE; + fclose(file); + + delete m_script; + m_script = 0; + + edit = m_interface->CreateEdit(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), 0, EVENT_EDIT9); + edit->SetMaxChar(EDITSTUDIOMAX); + edit->SetAutoIndent(m_engine->RetEditIndentMode()); + edit->ReadText(name); + GetScript(edit); + m_interface->DeleteControl(EVENT_EDIT9); + return TRUE; +} + +// Writes a script as a text file. + +BOOL CScript::WriteScript(char* filename) +{ + CEdit* edit; + char name[100]; + + if ( strchr(filename, '\\') == 0 ) + { + strcpy(name, "script\\"); + strcat(name, filename); + } + else + { + strcpy(name, filename); + } + + if ( m_script == 0 ) + { + remove(filename); + return FALSE; + } + + edit = m_interface->CreateEdit(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), 0, EVENT_EDIT9); + edit->SetMaxChar(EDITSTUDIOMAX); + edit->SetAutoIndent(m_engine->RetEditIndentMode()); + edit->SetText(m_script); + edit->WriteText(name); + m_interface->DeleteControl(EVENT_EDIT9); + return TRUE; +} + + +// Reads a stack of script by execution as a file. + +BOOL CScript::ReadStack(FILE *file) +{ + int nb; + + fRead(&nb, sizeof(int), 1, file); + fRead(&m_ipf, sizeof(int), 1, file); + fRead(&m_errMode, sizeof(int), 1, file); + + if ( m_botProg == 0 ) return FALSE; + if ( !m_botProg->RestoreState(file) ) return FALSE; + + m_object->SetRunScript(this); + m_bRun = TRUE; + m_bContinue = FALSE; + return TRUE; +} + +// Writes a stack of script by execution as a file. + +BOOL CScript::WriteStack(FILE *file) +{ + int nb; + + nb = 2; + fWrite(&nb, sizeof(int), 1, file); + fWrite(&m_ipf, sizeof(int), 1, file); + fWrite(&m_errMode, sizeof(int), 1, file); + + return m_botProg->SaveState(file); +} + + +// Compares two scripts. + +BOOL CScript::Compare(CScript* other) +{ + if ( m_len != other->m_len ) return FALSE; + + return ( strcmp(m_script, other->m_script) == 0 ); +} + + +// Management of the file name when the script is saved. + +void CScript::SetFilename(char *filename) +{ + strcpy(m_filename, filename); +} + +char* CScript::RetFilename() +{ + return m_filename; +} + diff --git a/src/script/script.h b/src/script/script.h new file mode 100644 index 0000000..eeb8ac8 --- /dev/null +++ b/src/script/script.h @@ -0,0 +1,118 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// script.h + +#ifndef _SCRIPT_H_ +#define _SCRIPT_H_ + + +#include "event.h" + + +class CInstanceManager; +class CD3DEngine; +class CInterface; +class CDisplayText; +class CEdit; +class CList; +class CObject; +class CTaskManager; +class CBotProgram; +class CRobotMain; +class CTerrain; +class CWater; + + + +class CScript +{ +public: + CScript(CInstanceManager* iMan, CObject* object, CTaskManager** secondaryTask); + ~CScript(); + + static void InitFonctions(); + + void PutScript(CEdit* edit, char* name); + BOOL GetScript(CEdit* edit); + BOOL RetCompile(); + + void GetTitle(char* buffer); + + void SetStepMode(BOOL bStep); + BOOL Run(); + BOOL Continue(const Event &event); + BOOL Step(const Event &event); + void Stop(); + BOOL IsRunning(); + BOOL IsContinue(); + BOOL GetCursor(int &cursor1, int &cursor2); + void UpdateList(CList* list); + void ColorizeScript(CEdit* edit); + BOOL IntroduceVirus(); + + int RetError(); + void GetError(char* buffer); + + void New(CEdit* edit, char* name); + BOOL SendScript(char* text); + BOOL ReadScript(char* filename); + BOOL WriteScript(char* filename); + BOOL ReadStack(FILE *file); + BOOL WriteStack(FILE *file); + BOOL Compare(CScript* other); + + void SetFilename(char *filename); + char* RetFilename(); + +protected: + BOOL IsEmpty(); + BOOL CheckToken(); + BOOL Compile(); + +public: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CInterface* m_interface; + CDisplayText* m_displayText; + CBotProgram* m_botProg; + CRobotMain* m_main; + CTerrain* m_terrain; + CWater* m_water; + CTaskManager* m_primaryTask; + CTaskManager** m_secondaryTask; + CObject* m_object; + + int m_ipf; // number of instructions/second + int m_errMode; // what to do in case of error + int m_len; // length of the script (without <0>) + char* m_script; // script ends with <0> + BOOL m_bRun; // program during execution? + BOOL m_bStepMode; // step by step + BOOL m_bContinue; // external function to continue + BOOL m_bCompile; // compilation ok? + char m_title[50]; // script title + char m_filename[50]; // file name + char m_token[50]; // missing instruction + int m_error; // error (0=ok) + int m_cursor1; + int m_cursor2; + Event m_event; + float m_returnValue; +}; + + +#endif //_SCRIPT_H_ diff --git a/src/scroll.cpp b/src/scroll.cpp deleted file mode 100644 index 1122ac5..0000000 --- a/src/scroll.cpp +++ /dev/null @@ -1,471 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// scroll.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "button.h" -#include "scroll.h" - - - - -// Object's constructor. - -CScroll::CScroll(CInstanceManager* iMan) : CControl(iMan) -{ - m_buttonUp = 0; - m_buttonDown = 0; - - m_visibleValue = 0.0f; - m_visibleRatio = 1.0f; - m_step = 0.0f; - - m_eventUp = EVENT_NULL; - m_eventDown = EVENT_NULL; - - m_bCapture = FALSE; -} - -// Object's destructor. - -CScroll::~CScroll() -{ - delete m_buttonUp; - delete m_buttonDown; -} - - -// Creates a new button. - -BOOL CScroll::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - CControl::Create(pos, dim, icon, eventMsg); - - MoveAdjust(); - return TRUE; -} - - -void CScroll::SetPos(FPOINT pos) -{ - CControl::SetPos(pos); - MoveAdjust(); -} - -void CScroll::SetDim(FPOINT dim) -{ - CControl::SetDim(dim); - MoveAdjust(); -} - -// Adjust both buttons. - -void CScroll::MoveAdjust() -{ - CButton* pc; - FPOINT pos, dim; - - if ( m_dim.y < m_dim.x*2.0f ) // very short lift? - { - delete m_buttonUp; - m_buttonUp = 0; - - delete m_buttonDown; - m_buttonDown = 0; - } - else - { - if ( m_buttonUp == 0 ) - { - m_buttonUp = new CButton(m_iMan); - pc = (CButton*)m_buttonUp; - pc->Create(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), 49, EVENT_NULL); - pc->SetRepeat(TRUE); - m_eventUp = pc->RetEventMsg(); - } - - if ( m_buttonDown == 0 ) - { - m_buttonDown = new CButton(m_iMan); - pc = (CButton*)m_buttonDown; - pc->Create(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), 50, EVENT_NULL); - pc->SetRepeat(TRUE); - m_eventDown = pc->RetEventMsg(); - } - } - - if ( m_buttonUp != 0 ) - { - pos.x = m_pos.x; - pos.y = m_pos.y+m_dim.y-m_dim.x/0.75f; - dim.x = m_dim.x; - dim.y = m_dim.x/0.75f; - m_buttonUp->SetPos(pos); - m_buttonUp->SetDim(dim); - } - - if ( m_buttonDown != 0 ) - { - pos.x = m_pos.x; - pos.y = m_pos.y; - dim.x = m_dim.x; - dim.y = m_dim.x/0.75f; - m_buttonDown->SetPos(pos); - m_buttonDown->SetDim(dim); - } - - AdjustGlint(); -} - -// Adjusts the position of reflection. - -void CScroll::AdjustGlint() -{ - FPOINT ref; - float hButton, h; - - hButton = m_buttonUp?m_dim.x/0.75f:0.0f; - h = m_dim.y-hButton*2.0f; - - ref.x = m_pos.x; - ref.y = m_pos.y+hButton+h*m_visibleRatio+0.003f; - ref.y += h*(1.0f-m_visibleRatio)*(1.0f-m_visibleValue); - - GlintCreate(ref); -} - - - -BOOL CScroll::SetState(int state, BOOL bState) -{ - if ( state & STATE_ENABLE ) - { - if ( m_buttonUp != 0 ) m_buttonUp->SetState(state, bState); - if ( m_buttonDown != 0 ) m_buttonDown->SetState(state, bState); - } - - return CControl::SetState(state, bState); -} - -BOOL CScroll::SetState(int state) -{ - if ( state & STATE_ENABLE ) - { - if ( m_buttonUp != 0 ) m_buttonUp->SetState(state); - if ( m_buttonDown != 0 ) m_buttonDown->SetState(state); - } - - return CControl::SetState(state); -} - -BOOL CScroll::ClearState(int state) -{ - if ( state & STATE_ENABLE ) - { - if ( m_buttonUp != 0 ) m_buttonUp->ClearState(state); - if ( m_buttonDown != 0 ) m_buttonDown->ClearState(state); - } - - return CControl::ClearState(state); -} - - -// Management of an event. - -BOOL CScroll::EventProcess(const Event &event) -{ - FPOINT pos, dim; - float hButton, h, value; - - CControl::EventProcess(event); - - if ( m_buttonUp != 0 && !m_bCapture ) - { - if ( !m_buttonUp->EventProcess(event) ) return FALSE; - } - if ( m_buttonDown != 0 && !m_bCapture ) - { - if ( !m_buttonDown->EventProcess(event) ) return FALSE; - } - - if ( event.event == m_eventUp && m_step > 0.0f ) - { - m_visibleValue -= m_step; - if ( m_visibleValue < 0.0f ) m_visibleValue = 0.0f; - AdjustGlint(); - - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - } - - if ( event.event == m_eventDown && m_step > 0.0f ) - { - m_visibleValue += m_step; - if ( m_visibleValue > 1.0f ) m_visibleValue = 1.0f; - AdjustGlint(); - - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - } - - hButton = m_buttonUp?m_dim.x/0.75f:0.0f; - - if ( event.event == EVENT_LBUTTONDOWN && - (m_state & STATE_VISIBLE) && - (m_state & STATE_ENABLE) ) - { - if ( CControl::Detect(event.pos) ) - { - pos.y = m_pos.y+hButton; - dim.y = m_dim.y-hButton*2.0f; - pos.y += dim.y*(1.0f-m_visibleRatio)*(1.0f-m_visibleValue); - dim.y *= m_visibleRatio; - if ( event.pos.y < pos.y || - event.pos.y > pos.y+dim.y ) // click outside cabin? - { - h = (m_dim.y-hButton*2.0f)*(1.0f-m_visibleRatio); - value = 1.0f-(event.pos.y-(m_pos.y+hButton+dim.y*0.5f))/h; - if ( value < 0.0f ) value = 0.0f; - if ( value > 1.0f ) value = 1.0f; - m_visibleValue = value; - AdjustGlint(); - - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - } - m_bCapture = TRUE; - m_pressPos = event.pos; - m_pressValue = m_visibleValue; - } - } - - if ( event.event == EVENT_MOUSEMOVE && m_bCapture ) - { - h = (m_dim.y-hButton*2.0f)*(1.0f-m_visibleRatio); - if ( h != 0 ) - { - value = m_pressValue - (event.pos.y-m_pressPos.y)/h; - if ( value < 0.0f ) value = 0.0f; - if ( value > 1.0f ) value = 1.0f; - - if ( value != m_visibleValue ) - { - m_visibleValue = value; - AdjustGlint(); - - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - } - } - } - - if ( event.event == EVENT_LBUTTONUP && m_bCapture ) - { - m_bCapture = FALSE; - } - - if ( event.event == EVENT_KEYDOWN && - event.param == VK_WHEELUP && - Detect(event.pos) && - m_buttonUp != 0 ) - { - Event newEvent = event; - newEvent.event = m_buttonUp->RetEventMsg(); - m_event->AddEvent(newEvent); - } - if ( event.event == EVENT_KEYDOWN && - event.param == VK_WHEELDOWN && - Detect(event.pos) && - m_buttonDown != 0 ) - { - Event newEvent = event; - newEvent.event = m_buttonDown->RetEventMsg(); - m_event->AddEvent(newEvent); - } - - return TRUE; -} - - -// Draws the button. - -void CScroll::Draw() -{ - FPOINT pos, dim, ppos, ddim; - float hButton; - int icon, n, i; - - hButton = m_buttonUp?m_dim.x/0.75f:0.0f; - - // Draws the bottom. - pos.x = m_pos.x; - pos.y = m_pos.y+hButton; - dim.x = m_dim.x; - dim.y = m_dim.y-hButton*2.0f; - if ( m_state & STATE_ENABLE ) icon = 0; - else icon = 1; - DrawVertex(pos, dim, icon); - - // Draws the cabin. - if ( m_visibleRatio < 1.0f && (m_state & STATE_ENABLE) ) - { - pos.x += 0.003f; // ch'tite(?) margin - pos.y += 0.003f; - dim.x -= 0.006f; - dim.y -= 0.006f; - pos.y += dim.y*(1.0f-m_visibleRatio)*(1.0f-m_visibleValue); - dim.y *= m_visibleRatio; - DrawVertex(pos, dim, 2); - - n = (int)(dim.y*0.8f/0.012f); - if ( n < 1 ) n = 1; - if ( n > 5 ) n = 5; - - ppos.x = pos.x+0.003f; - ppos.y = pos.y+(dim.y-(n-1)*0.012f-0.008f)/2.0f; - ddim.x = dim.x-0.006f; - ddim.y = 0.008f; - for ( i=0 ; iDraw(); - } - if ( m_buttonDown != 0 ) - { - m_buttonDown->Draw(); - } -} - -// Draws a rectangle. - -void CScroll::DrawVertex(FPOINT pos, FPOINT dim, int icon) -{ - FPOINT uv1, uv2; - float ex, dp; - - if ( icon == 0 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 0.0f/256.0f; // yellow rectangle - uv1.y = 32.0f/256.0f; - uv2.x = 32.0f/256.0f; - uv2.y = 64.0f/256.0f; - ex = 8.0f/256.0f; - } - else if ( icon == 1 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 128.0f/256.0f; // gray rectangle - uv1.y = 32.0f/256.0f; - uv2.x = 160.0f/256.0f; - uv2.y = 64.0f/256.0f; - ex = 8.0f/256.0f; - } - else if ( icon == 2 ) - { - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 64.0f/256.0f; // blue rectangle - uv1.y = 0.0f/256.0f; - uv2.x = 96.0f/256.0f; - uv2.y = 32.0f/256.0f; - ex = 8.0f/256.0f; - } - else - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 104.0f/256.0f; // blue line - - uv1.y = 32.0f/256.0f; - uv2.x = 128.0f/256.0f; - uv2.y = 40.0f/256.0f; - ex = 0.0f; - } - - dp = 0.5f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - DrawIcon(pos, dim, uv1, uv2, ex); -} - - -void CScroll::SetVisibleValue(float value) -{ - if ( value < 0.0 ) value = 0.0f; - if ( value > 1.0 ) value = 1.0f; - m_visibleValue = value; - AdjustGlint(); -} - -float CScroll::RetVisibleValue() -{ - return m_visibleValue; -} - - -void CScroll::SetVisibleRatio(float value) -{ - if ( value < 0.1 ) value = 0.1f; - if ( value > 1.0 ) value = 1.0f; - m_visibleRatio = value; - AdjustGlint(); -} - -float CScroll::RetVisibleRatio() -{ - return m_visibleRatio; -} - - -void CScroll::SetArrowStep(float step) -{ - m_step = step; -} - -float CScroll::RetArrowStep() -{ - return m_step; -} - diff --git a/src/scroll.h b/src/scroll.h deleted file mode 100644 index 6c08a19..0000000 --- a/src/scroll.h +++ /dev/null @@ -1,84 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// scroll.h - -#ifndef _SCROLL_H_ -#define _SCROLL_H_ - - -#include "control.h" -#include "struct.h" - - -class CD3DEngine; -class CButton; - - -#define SCROLL_WIDTH (15.0f/640.0f) - - - -class CScroll : public CControl -{ -public: - CScroll(CInstanceManager* iMan); - ~CScroll(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - - void SetPos(FPOINT pos); - void SetDim(FPOINT dim); - - BOOL SetState(int state, BOOL bState); - BOOL SetState(int state); - BOOL ClearState(int state); - - BOOL EventProcess(const Event &event); - void Draw(); - - void SetVisibleValue(float value); - float RetVisibleValue(); - - void SetVisibleRatio(float value); - float RetVisibleRatio(); - - void SetArrowStep(float step); - float RetArrowStep(); - -protected: - void MoveAdjust(); - void AdjustGlint(); - void DrawVertex(FPOINT pos, FPOINT dim, int icon); - -protected: - CButton* m_buttonUp; - CButton* m_buttonDown; - - float m_visibleValue; - float m_visibleRatio; - float m_step; - - BOOL m_bCapture; - FPOINT m_pressPos; - float m_pressValue; - - EventMsg m_eventUp; - EventMsg m_eventDown; -}; - - -#endif //_SCROLL_H_ diff --git a/src/shortcut.cpp b/src/shortcut.cpp deleted file mode 100644 index 21a6191..0000000 --- a/src/shortcut.cpp +++ /dev/null @@ -1,243 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// shortcut.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "shortcut.h" - - - - -// Object's constructor. - -CShortcut::CShortcut(CInstanceManager* iMan) : CControl(iMan) -{ - m_time = 0.0f; -} - -// Object's destructor. - -CShortcut::~CShortcut() -{ -} - - -// Creates a new button. - -BOOL CShortcut::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - CControl::Create(pos, dim, icon, eventMsg); - return TRUE; -} - - -// Management of an event. - -BOOL CShortcut::EventProcess(const Event &event) -{ - CControl::EventProcess(event); - - if ( event.event == EVENT_FRAME ) - { - m_time += event.rTime; - } - - if ( event.event == EVENT_LBUTTONDOWN ) - { - if ( CControl::Detect(event.pos) ) - { - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - return FALSE; - } - } - - return TRUE; -} - - -// Draws the button. - -void CShortcut::Draw() -{ - float zoom; - int icon, mode; - - icon = 0; - zoom = 0.8f; - mode = D3DSTATETTw; - if ( m_state & STATE_HILIGHT ) - { - icon = 4; - zoom = 0.9f; - mode = D3DSTATENORMAL; - } - if ( m_state & STATE_CHECK ) - { - icon = 1; - zoom = 0.8f; - mode = D3DSTATENORMAL; - } - if ( m_state & STATE_PRESS ) - { - icon = 1; - zoom = 1.0f; - mode = D3DSTATENORMAL; - } - if ( m_icon == 6 || m_icon == 7 ) // pause or film? - { - icon = -1; // no bottom - zoom = 1.0f; - } - - m_engine->SetTexture("button3.tga"); - - if ( icon != -1 ) - { - m_engine->SetState(mode); - DrawVertex(icon, 0.95f); - } - - m_engine->SetState(D3DSTATETTb); - DrawVertex(m_icon, zoom); - - if ( m_state & STATE_FRAME ) - { - FPOINT p1, p2, c, uv1, uv2; - float zoom, dp; - - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTw); - - zoom = 0.9f+sinf(m_time*8.0f)*0.1f; - - p1.x = m_pos.x; - p1.y = m_pos.y; - p2.x = m_pos.x + m_dim.x; - p2.y = m_pos.y + m_dim.y; - - c.x = (p1.x+p2.x)/2.0f; - c.y = (p1.y+p2.y)/2.0f; // center - - p1.x = (p1.x-c.x)*zoom + c.x; - p1.y = (p1.y-c.y)*zoom + c.y; - p2.x = (p2.x-c.x)*zoom + c.x; - p2.y = (p2.y-c.y)*zoom + c.y; - - p2.x -= p1.x; - p2.y -= p1.y; - - uv1.x = 176.0f/256.0f; - uv1.y = 224.0f/256.0f; - uv2.x = 192.0f/256.0f; - uv2.y = 240.0f/256.0f; - - dp = 0.5f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - DrawIcon(p1, p2, uv1, uv2); - } - - if ( (m_state & STATE_RUN) && Mod(m_time, 0.7f) >= 0.3f ) - { - FPOINT uv1, uv2; - float dp; - - m_engine->SetTexture("button3.tga"); - m_engine->SetState(D3DSTATETTw); - - uv1.x = 160.0f/256.0f; - uv1.y = 0.0f/256.0f; - uv2.x = 192.0f/256.0f; - uv2.y = 32.0f/256.0f; - - dp = 0.5f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - DrawIcon(m_pos, m_dim, uv1, uv2); - } -} - -// Draw the vertex array. - -void CShortcut::DrawVertex(int icon, float zoom) -{ - LPDIRECT3DDEVICE7 device; - D3DVERTEX2 vertex[4]; // 2 triangles - FPOINT p1, p2, c; - D3DVECTOR n; - float u1, u2, v1, v2, dp; - - device = m_engine->RetD3DDevice(); - - p1.x = m_pos.x; - p1.y = m_pos.y; - p2.x = m_pos.x + m_dim.x; - p2.y = m_pos.y + m_dim.y; - - c.x = (p1.x+p2.x)/2.0f; - c.y = (p1.y+p2.y)/2.0f; // center - - p1.x = (p1.x-c.x)*zoom + c.x; - p1.y = (p1.y-c.y)*zoom + c.y; - - p2.x = (p2.x-c.x)*zoom + c.x; - p2.y = (p2.y-c.y)*zoom + c.y; - - u1 = (32.0f/256.0f)*(icon%8); - v1 = (32.0f/256.0f)*(icon/8); // u-v texture - u2 = (32.0f/256.0f)+u1; - v2 = (32.0f/256.0f)+v1; - - dp = 0.5f/256.0f; - u1 += dp; - v1 += dp; - u2 -= dp; - v2 -= dp; - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal - - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); - vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); - vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); - - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); -} - diff --git a/src/shortcut.h b/src/shortcut.h deleted file mode 100644 index e76402b..0000000 --- a/src/shortcut.h +++ /dev/null @@ -1,50 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// shortcut.h - -#ifndef _SHORTCUT_H_ -#define _SHORTCUT_H_ - - -#include "control.h" - - -class CD3DEngine; - - - -class CShortcut : public CControl -{ -public: - CShortcut(CInstanceManager* iMan); - ~CShortcut(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - - BOOL EventProcess(const Event &event); - - void Draw(); - -protected: - void DrawVertex(int icon, float zoom); - -protected: - float m_time; -}; - - -#endif //_SHORTCUT_H_ diff --git a/src/slider.cpp b/src/slider.cpp deleted file mode 100644 index 95bd3a4..0000000 --- a/src/slider.cpp +++ /dev/null @@ -1,582 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// slider.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "text.h" -#include "button.h" -#include "slider.h" - - - -#define CURSOR_WIDTH (10.0f/640.0f) -#define HOLE_WIDTH (5.0f/480.0f) - - - - -// Object's constructor. - -CSlider::CSlider(CInstanceManager* iMan) : CControl(iMan) -{ - m_buttonLeft = 0; - m_buttonRight = 0; - - m_min = 0.0f; - m_max = 1.0f; - m_visibleValue = 0.0f; - m_step = 0.0f; - - m_marginButton = 0.0f; - m_bHoriz = FALSE; - - m_eventUp = EVENT_NULL; - m_eventDown = EVENT_NULL; - - m_bCapture = FALSE; -} - -// Object's destructor. - -CSlider::~CSlider() -{ - delete m_buttonLeft; - delete m_buttonRight; -} - - -// Creates a new button. - -BOOL CSlider::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - CControl::Create(pos, dim, icon, eventMsg); - - MoveAdjust(); - return TRUE; -} - - -void CSlider::SetPos(FPOINT pos) -{ - CControl::SetPos(pos); - MoveAdjust(); -} - -void CSlider::SetDim(FPOINT dim) -{ - CControl::SetDim(dim); - MoveAdjust(); -} - -void CSlider::MoveAdjust() -{ - FPOINT pos, dim; - - m_bHoriz = ( m_dim.x > m_dim.y ); - - if ( ( m_bHoriz && m_dim.x < m_dim.y*4.0f) || - (!m_bHoriz && m_dim.y < m_dim.x*4.0f) ) // very short slider? - { - delete m_buttonLeft; - m_buttonLeft = 0; - - delete m_buttonRight; - m_buttonRight = 0; - - m_marginButton = 0.0f; - } - else - { -#if 1 - if ( m_buttonLeft == 0 ) - { - m_buttonLeft = new CButton(m_iMan); - m_buttonLeft->Create(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), m_bHoriz?55:49, EVENT_NULL); // SetRepeat(TRUE); - if ( m_state & STATE_SHADOW ) m_buttonLeft->SetState(STATE_SHADOW); - m_eventUp = m_buttonLeft->RetEventMsg(); - } - - if ( m_buttonRight == 0 ) - { - m_buttonRight = new CButton(m_iMan); - m_buttonRight->Create(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), m_bHoriz?48:50, EVENT_NULL); // >/v - m_buttonRight->SetRepeat(TRUE); - if ( m_state & STATE_SHADOW ) m_buttonRight->SetState(STATE_SHADOW); - m_eventDown = m_buttonRight->RetEventMsg(); - } - - m_marginButton = m_bHoriz?(m_dim.y*0.75f):(m_dim.x/0.75f); -#endif - } - - if ( m_buttonLeft != 0 ) - { - if ( m_bHoriz ) - { - pos.x = m_pos.x; - pos.y = m_pos.y; - dim.x = m_dim.y*0.75f; - dim.y = m_dim.y; - } - else - { - pos.x = m_pos.x; - pos.y = m_pos.y+m_dim.y-m_dim.x/0.75f; - dim.x = m_dim.x; - dim.y = m_dim.x/0.75f; - } - m_buttonLeft->SetPos(pos); - m_buttonLeft->SetDim(dim); - } - - if ( m_buttonRight != 0 ) - { - if ( m_bHoriz ) - { - pos.x = m_pos.x+m_dim.x-m_dim.y*0.75f; - pos.y = m_pos.y; - dim.x = m_dim.y*0.75f; - dim.y = m_dim.y; - } - else - { - pos.x = m_pos.x; - pos.y = m_pos.y; - dim.x = m_dim.x; - dim.y = m_dim.x/0.75f; - } - m_buttonRight->SetPos(pos); - m_buttonRight->SetDim(dim); - } - - AdjustGlint(); -} - -// Adjusts the position of reflection. - -void CSlider::AdjustGlint() -{ - FPOINT ref; - float w; - - if ( m_bHoriz ) - { - w = m_dim.x-m_marginButton*0.75f; - ref.x = m_pos.x+m_marginButton; - ref.x += (w-CURSOR_WIDTH)*m_visibleValue; - ref.y = m_pos.y+m_dim.y; - } - else - { - w = m_dim.y-m_marginButton*2.0f; - ref.y = m_pos.y+m_marginButton+CURSOR_WIDTH; - ref.y += (w-CURSOR_WIDTH)*m_visibleValue; - ref.x = m_pos.x; - } - - GlintCreate(ref); -} - - -BOOL CSlider::SetState(int state, BOOL bState) -{ - if ( (state & STATE_ENABLE) || - (state & STATE_SHADOW) ) - { - if ( m_buttonLeft != 0 ) m_buttonLeft->SetState(state, bState); - if ( m_buttonRight != 0 ) m_buttonRight->SetState(state, bState); - } - - return CControl::SetState(state, bState); -} - -BOOL CSlider::SetState(int state) -{ - if ( (state & STATE_ENABLE) || - (state & STATE_SHADOW) ) - { - if ( m_buttonLeft != 0 ) m_buttonLeft->SetState(state); - if ( m_buttonRight != 0 ) m_buttonRight->SetState(state); - } - - return CControl::SetState(state); -} - -BOOL CSlider::ClearState(int state) -{ - if ( (state & STATE_ENABLE) || - (state & STATE_SHADOW) ) - { - if ( m_buttonLeft != 0 ) m_buttonLeft->ClearState(state); - if ( m_buttonRight != 0 ) m_buttonRight->ClearState(state); - } - - return CControl::ClearState(state); -} - - -// Management of an event. - -BOOL CSlider::EventProcess(const Event &event) -{ - FPOINT pos, dim; - float value; - - if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; - - CControl::EventProcess(event); - - if ( m_buttonLeft != 0 && !m_bCapture ) - { - if ( !m_buttonLeft->EventProcess(event) ) return FALSE; - } - if ( m_buttonRight != 0 && !m_bCapture ) - { - if ( !m_buttonRight->EventProcess(event) ) return FALSE; - } - - if ( event.event == m_eventUp && m_step > 0.0f ) - { - m_visibleValue -= m_bHoriz?m_step:-m_step; - if ( m_visibleValue < 0.0f ) m_visibleValue = 0.0f; - if ( m_visibleValue > 1.0f ) m_visibleValue = 1.0f; - AdjustGlint(); - - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - } - - if ( event.event == m_eventDown && m_step > 0.0f ) - { - m_visibleValue += m_bHoriz?m_step:-m_step; - if ( m_visibleValue < 0.0f ) m_visibleValue = 0.0f; - if ( m_visibleValue > 1.0f ) m_visibleValue = 1.0f; - AdjustGlint(); - - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - } - - if ( event.event == EVENT_LBUTTONDOWN && - (m_state & STATE_VISIBLE) && - (m_state & STATE_ENABLE) ) - { - if ( CControl::Detect(event.pos) ) - { - if ( m_bHoriz ) - { - pos.x = m_pos.x+m_marginButton; - dim.x = m_dim.x-m_marginButton*2.0f; - value = (event.pos.x-pos.x-CURSOR_WIDTH/2.0f); - value /= (dim.x-CURSOR_WIDTH); - } - else - { - pos.y = m_pos.y+m_marginButton; - dim.y = m_dim.y-m_marginButton*2.0f; - value = (event.pos.y-pos.y-CURSOR_WIDTH/2.0f); - value /= (dim.y-CURSOR_WIDTH); - } - if ( value < 0.0f ) value = 0.0f; - if ( value > 1.0f ) value = 1.0f; - m_visibleValue = value; - AdjustGlint(); - - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - - m_bCapture = TRUE; - m_pressPos = event.pos; - m_pressValue = m_visibleValue; - } - } - - if ( event.event == EVENT_MOUSEMOVE && m_bCapture ) - { - if ( m_bHoriz ) - { - pos.x = m_pos.x+m_marginButton; - dim.x = m_dim.x-m_marginButton*2.0f; - value = (event.pos.x-pos.x-CURSOR_WIDTH/2.0f); - value /= (dim.x-CURSOR_WIDTH); - } - else - { - pos.y = m_pos.y+m_marginButton; - dim.y = m_dim.y-m_marginButton*2.0f; - value = (event.pos.y-pos.y-CURSOR_WIDTH/2.0f); - value /= (dim.y-CURSOR_WIDTH); - } - if ( value < 0.0f ) value = 0.0f; - if ( value > 1.0f ) value = 1.0f; - - if ( value != m_visibleValue ) - { - m_visibleValue = value; - AdjustGlint(); - - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - } - } - - if ( event.event == EVENT_LBUTTONUP && m_bCapture ) - { - m_bCapture = FALSE; - } - - if ( event.event == EVENT_KEYDOWN && - event.param == VK_WHEELUP && - Detect(event.pos) && - m_buttonLeft != 0 ) - { - Event newEvent = event; - newEvent.event = m_buttonLeft->RetEventMsg(); - m_event->AddEvent(newEvent); - } - if ( event.event == EVENT_KEYDOWN && - event.param == VK_WHEELDOWN && - Detect(event.pos) && - m_buttonRight != 0 ) - { - Event newEvent = event; - newEvent.event = m_buttonRight->RetEventMsg(); - m_event->AddEvent(newEvent); - } - - return TRUE; -} - - -// Draws button. - -void CSlider::Draw() -{ - FPOINT pos, dim, ppos, ddim, spos; - int icon; - float h; - char text[100]; - - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - if ( m_buttonLeft != 0 ) - { - m_buttonLeft->Draw(); - } - - if ( m_bHoriz ) - { - pos.x = m_pos.x+m_marginButton; - pos.y = m_pos.y; - dim.x = m_dim.x-m_marginButton*2.0f; - dim.y = m_dim.y; - } - else - { - pos.x = m_pos.x; - pos.y = m_pos.y+m_marginButton; - dim.x = m_dim.x; - dim.y = m_dim.y-m_marginButton*2.0f; - } - - // Draws the bottom. - if ( m_bHoriz ) - { - ppos.x = pos.x + CURSOR_WIDTH/2.0f; - ppos.y = pos.y + (dim.y-HOLE_WIDTH)/2.0f; - ddim.x = dim.x - CURSOR_WIDTH; - ddim.y = HOLE_WIDTH; - } - else - { - ppos.x = pos.x + (dim.x-HOLE_WIDTH*0.75f)/2.0f; - ppos.y = pos.y + CURSOR_WIDTH/2.0f; - ddim.x = HOLE_WIDTH*0.75f; - ddim.y = dim.y - CURSOR_WIDTH; - } - - if ( m_state & STATE_SHADOW ) - { - spos = ppos; - spos.x -= 0.005f*0.75f; - spos.y += 0.005f; - DrawShadow(spos, ddim); - } - - if ( m_state & STATE_ENABLE ) icon = 0; - else icon = 1; - DrawVertex(ppos, ddim, icon); - - // Draws the cabin. - if ( m_state & STATE_ENABLE ) - { - if ( m_bHoriz ) - { - ppos.x = pos.x + (dim.x-CURSOR_WIDTH)*m_visibleValue; - ppos.y = pos.y; - ddim.x = CURSOR_WIDTH; - ddim.y = dim.y; - } - else - { - ppos.x = pos.x; - ppos.y = pos.y + (dim.y-CURSOR_WIDTH)*m_visibleValue; - ddim.x = dim.x; - ddim.y = CURSOR_WIDTH; - } - DrawShadow(ppos, ddim, 0.7f); - DrawVertex(ppos, ddim, 2); - } - - if ( m_buttonRight != 0 ) - { - m_buttonRight->Draw(); - } - - if ( m_bHoriz ) - { - sprintf(text, "%d", (int)(m_min+m_visibleValue*(m_max-m_min))); - h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType); - pos.x = m_pos.x+m_dim.x+(10.0f/640.0f); - pos.y = m_pos.y+(m_dim.y-h)/2.0f; - m_engine->RetText()->DrawText(text, pos, m_dim.x, 1, m_fontSize, m_fontStretch, m_fontType, 0); - } - else - { - if ( m_state & STATE_VALUE ) - { - pos.x = m_pos.x+m_dim.x+4.0f/640.0f; - h = m_dim.y-m_marginButton*2.0f; - pos.y = m_pos.y+m_marginButton-4.0f/480.0f; - pos.y += (h-CURSOR_WIDTH)*m_visibleValue; - dim.x = 50.0f/640.0f; - dim.y = 16.0f/480.0f; - sprintf(text, "%d", (int)(m_min+(m_visibleValue*(m_max-m_min)))); - m_engine->RetText()->DrawText(text, pos, dim.x, 1, m_fontSize, m_fontStretch, m_fontType, 0); - } - } -} - -// Draws a rectangle. - -void CSlider::DrawVertex(FPOINT pos, FPOINT dim, int icon) -{ - FPOINT uv1, uv2, corner; - float ex, dp; - - if ( icon == 0 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 0.0f/256.0f; // yellow rectangle - uv1.y = 32.0f/256.0f; - uv2.x = 32.0f/256.0f; - uv2.y = 64.0f/256.0f; - corner.x = 2.0f/640.0f; - corner.y = 2.0f/480.0f; - ex = 4.0f/256.0f; - } - else if ( icon == 1 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 128.0f/256.0f; // gray rectangle - uv1.y = 32.0f/256.0f; - uv2.x = 160.0f/256.0f; - uv2.y = 64.0f/256.0f; - corner.x = 2.0f/640.0f; - corner.y = 2.0f/480.0f; - ex = 4.0f/256.0f; - } - else - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 224.0f/256.0f; // cursor - uv1.y = 32.0f/256.0f; - uv2.x = 256.0f/256.0f; - uv2.y = 64.0f/256.0f; - if ( !m_bHoriz ) - { - uv1.y += 64.0f/256.0f; - uv2.y += 64.0f/256.0f; - } - corner.x = 2.0f/640.0f; - corner.y = 2.0f/480.0f; - ex = 4.0f/256.0f; - } - - dp = 0.5f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - DrawIcon(pos, dim, uv1, uv2, corner, ex); -} - - -void CSlider::SetLimit(float min, float max) -{ - m_min = min; - m_max = max; -} - -void CSlider::SetVisibleValue(float value) -{ - value = (value-m_min)/(m_max-m_min); - if ( value < 0.0 ) value = 0.0f; - if ( value > 1.0 ) value = 1.0f; - m_visibleValue = value; - AdjustGlint(); -} - -float CSlider::RetVisibleValue() -{ - return m_min+m_visibleValue*(m_max-m_min); -} - - -void CSlider::SetArrowStep(float step) -{ - m_step = step/(m_max-m_min); -} - -float CSlider::RetArrowStep() -{ - return m_step*(m_max-m_min); -} - - diff --git a/src/slider.h b/src/slider.h deleted file mode 100644 index c254254..0000000 --- a/src/slider.h +++ /dev/null @@ -1,84 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// slider.h - -#ifndef _SLIDER_H_ -#define _SLIDER_H_ - - -#include "control.h" -#include "struct.h" - - -class CD3DEngine; -class CButton; - - - -class CSlider : public CControl -{ -public: - CSlider(CInstanceManager* iMan); - ~CSlider(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - - void SetPos(FPOINT pos); - void SetDim(FPOINT dim); - - BOOL SetState(int state, BOOL bState); - BOOL SetState(int state); - BOOL ClearState(int state); - - BOOL EventProcess(const Event &event); - void Draw(); - - void SetLimit(float min, float max); - - void SetVisibleValue(float value); - float RetVisibleValue(); - - void SetArrowStep(float step); - float RetArrowStep(); - -protected: - void MoveAdjust(); - void AdjustGlint(); - void DrawVertex(FPOINT pos, FPOINT dim, int icon); - -protected: - CButton* m_buttonLeft; - CButton* m_buttonRight; - - float m_min; - float m_max; - float m_visibleValue; - float m_step; - - BOOL m_bHoriz; - float m_marginButton; - - BOOL m_bCapture; - FPOINT m_pressPos; - float m_pressValue; - - EventMsg m_eventUp; - EventMsg m_eventDown; -}; - - -#endif //_SLIDER_H_ diff --git a/src/sound.cpp b/src/sound.cpp deleted file mode 100644 index 333eba0..0000000 --- a/src/sound.cpp +++ /dev/null @@ -1,1658 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// sound.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include -#include -#include -#include "language.h" -#include "struct.h" -#include "iman.h" -#include "math3d.h" -#include "sound.h" - - -///////////////////////////////////////////////////////////////////////////// - - -#define LXIMAGE 640 -#define LYIMAGE 480 - - - -// Header .WAV file. - -struct WaveHeader -{ - BYTE RIFF[4]; // "RIFF" - DWORD dwSize; // size of data to follow - BYTE WAVE[4]; // "WAVE" - BYTE fmt_[4]; // "fmt " - DWORD dw16; // 16 - WORD wOne_0; // 1 - WORD wChnls; // number of Channels - DWORD dwSRate; // sample Rate - DWORD BytesPerSec; // sample Rate - WORD wBlkAlign; // 1 - WORD BitsPerSample; // sample size - BYTE DATA[4]; // "DATA" - DWORD dwDSize; // number of Samples -}; - - - - -// Displays an error DirectSound. - -void DisplayError(char *name, Sound sound, HRESULT err) -{ - char s[100]; - unsigned int i = err; - if ( err == DS_OK ) return; - sprintf(s, "SoundError in %s, sound=%d err=%d\n", name, sound, i); - OutputDebugString(s); - - if ( err == DSERR_ALLOCATED ) OutputDebugString("DSERR_ALLOCATED\n"); - if ( err == DSERR_CONTROLUNAVAIL ) OutputDebugString("DSERR_CONTROLUNAVAIL\n"); - if ( err == DSERR_INVALIDPARAM ) OutputDebugString("DSERR_INVALIDPARAM\n"); - if ( err == DSERR_INVALIDCALL ) OutputDebugString("DSERR_INVALIDCALL\n"); - if ( err == DSERR_GENERIC ) OutputDebugString("DSERR_GENERIC\n"); - if ( err == DSERR_PRIOLEVELNEEDED ) OutputDebugString("DSERR_PRIOLEVELNEEDED\n"); - if ( err == DSERR_OUTOFMEMORY ) OutputDebugString("DSERR_OUTOFMEMORY\n"); - if ( err == DSERR_BADFORMAT ) OutputDebugString("DSERR_BADFORMAT\n"); - if ( err == DSERR_UNSUPPORTED ) OutputDebugString("DSERR_UNSUPPORTED\n"); - if ( err == DSERR_NODRIVER ) OutputDebugString("DSERR_NODRIVER\n"); - if ( err == DSERR_ALREADYINITIALIZED ) OutputDebugString("DSERR_ALREADYINITIALIZED\n"); - if ( err == DSERR_NOAGGREGATION ) OutputDebugString("DSERR_NOAGGREGATION\n"); - if ( err == DSERR_BUFFERLOST ) OutputDebugString("DSERR_BUFFERLOST\n"); - if ( err == DSERR_OTHERAPPHASPRIO ) OutputDebugString("DSERR_OTHERAPPHASPRIO\n"); - if ( err == DSERR_UNINITIALIZED ) OutputDebugString("DSERR_UNINITIALIZED\n"); - if ( err == DSERR_NOINTERFACE ) OutputDebugString("DSERR_NOINTERFACE\n"); - if ( err == DSERR_ACCESSDENIED ) OutputDebugString("DSERR_ACCESSDENIED\n"); -} - -// Returns the name of the current folder. - -void GetCurrentDir(char *pName, int lg) -{ - int i; - - strncpy(pName, _pgmptr, lg-1); - pName[lg-1] = 0; - - lg = strlen(pName); - if ( lg == 0 ) return; - - for ( i=0 ; i 0 ) - { - lg --; - if ( pName[lg] == '\\' ) - { - pName[lg+1] = 0; - break; - } - } - - if ( lg > 6 && strcmp(pName+lg-6, "\\debug\\") == 0 ) - { - pName[lg-5] = 0; // ignores the folder \debug! - } - - if ( lg > 6 && strcmp(pName+lg-6, "\\release\\") == 0 ) - { - pName[lg-7] = 0; // ignores the folder \release ! - } -} - - - - -///////////////////////////////////////////////////////////////////////////// - - -// Changes the volume of midi. -// The volume is between 0 and 20! - -void InitMidiVolume(int volume) -{ - int nb, i, n; - MMRESULT result; - HMIDIOUT hmo = 0; - - static int table[21] = - { - 0x00000000, - 0x11111111, - 0x22222222, - 0x33333333, - 0x44444444, - 0x55555555, - 0x66666666, - 0x77777777, - 0x88888888, - 0x99999999, - 0xAAAAAAAA, - 0xBBBBBBBB, - 0xCCCCCCCC, - 0xDDDDDDDD, - 0xEEEEEEEE, - 0xF222F222, - 0xF555F555, - 0xF777F777, - 0xFAAAFAAA, - 0xFDDDFDDD, - 0xFFFFFFFF, - }; - - if ( volume < 0 ) volume = 0; - if ( volume > MAXVOLUME ) volume = MAXVOLUME; - - nb = midiOutGetNumDevs(); - for ( i=0 ; i MAXVOLUME ) volume = MAXVOLUME; - - // Open the mixer. This opens the mixer with a deviceID of 0. If you - // have a single sound card/mixer, then this will open it. If you have - // multiple sound cards/mixers, the deviceIDs will be 0, 1, 2, and - // so on. - rc = mixerOpen(&hMixer, 0,0,0,0); - if ( rc != MMSYSERR_NOERROR ) - { - return FALSE; // Couldn't open the mixer. - } - - // Initialize MIXERLINE structure. - ZeroMemory(&mxl,sizeof(mxl)); - mxl.cbStruct = sizeof(mxl); - - // Specify the line you want to get. You are getting the input line - // here. If you want to get the output line, you need to use - // MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT. - mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC; - - rc = mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl, - MIXER_GETLINEINFOF_COMPONENTTYPE); - if ( rc != MMSYSERR_NOERROR ) - { - return FALSE; // Couldn't get the mixer line. - } - - // Get the control. - ZeroMemory(&mxlc, sizeof(mxlc)); - mxlc.cbStruct = sizeof(mxlc); - mxlc.dwLineID = mxl.dwLineID; -//? mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_PEAKMETER; -//? mxlc.dwControlType = MIXERCONTROL_CONTROLF_UNIFORM; - mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; - mxlc.cControls = 1; - mxlc.cbmxctrl = sizeof(mxc); - mxlc.pamxctrl = &mxc; - ZeroMemory(&mxc, sizeof(mxc)); - mxc.cbStruct = sizeof(mxc); - rc = mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc, - MIXER_GETLINECONTROLSF_ONEBYTYPE); -//? MIXER_GETLINECONTROLSF_ALL); - if ( rc != MMSYSERR_NOERROR ) - { - return FALSE; // Couldn't get the control. - } - - // After successfully getting the peakmeter control, the volume range - // will be specified by mxc.Bounds.lMinimum to mxc.Bounds.lMaximum. - - MIXERCONTROLDETAILS mxcd; // Gets the control values. - MIXERCONTROLDETAILS_SIGNED volStruct; // Gets the control values. - - volStruct.lValue = volume*(mxc.Bounds.lMaximum-mxc.Bounds.lMinimum); - volStruct.lValue /= MAXVOLUME; - volStruct.lValue += mxc.Bounds.lMinimum; - - // Initialize the MIXERCONTROLDETAILS structure - ZeroMemory(&mxcd, sizeof(mxcd)); - mxcd.cbStruct = sizeof(mxcd); - mxcd.cbDetails = sizeof(volStruct); - mxcd.dwControlID = mxc.dwControlID; - mxcd.paDetails = &volStruct; - mxcd.cChannels = 1; - - // Get the current value of the peakmeter control. Typically, you - // would set a timer in your program to query the volume every 10th - // of a second or so. - rc = mixerSetControlDetails((HMIXEROBJ)hMixer, &mxcd, - MIXER_SETCONTROLDETAILSF_VALUE); - if ( rc != MMSYSERR_NOERROR ) - { - return FALSE; // Couldn't get the current volume. - } -#endif - - return TRUE; -} - - -///////////////////////////////////////////////////////////////////////////// - - -// Constructor. - -CSound::CSound(CInstanceManager* iMan) -{ - int i; - - m_iMan = iMan; - m_iMan->AddInstance(CLASS_SOUND, this); - - m_bEnable = FALSE; - m_bState = FALSE; - m_bAudioTrack = TRUE; - m_ctrl3D = TRUE; - m_bDebugMode = FALSE; - m_MidiDeviceID = 0; - m_MIDIMusic = 0; - m_audioVolume = 20; - m_midiVolume = 15; - m_lastMidiVolume = 0; - m_listener = 0; - m_lastTime = 0.0f; - m_playTime = 0.0f; - m_uniqueStamp = 0; - m_maxSound = MAXSOUND; - m_eye = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_hWnd = 0; - - m_lpDS = NULL; - - ZeroMemory(m_channel, sizeof(SoundChannel)*MAXSOUND); - for ( i=0 ; iStop(); - m_channel[i].soundBuffer->Release(); - m_channel[i].soundBuffer = 0; - m_channel[i].bUsed = FALSE; - } - } - - if ( m_listener != NULL ) - { - m_listener->Release(); - m_listener = NULL; - } - - if ( m_lpDS != NULL ) - { - m_lpDS->Release(); - m_lpDS = NULL; - } -} - - -// Specifies whether you are in debug mode. - -void CSound::SetDebugMode(BOOL bMode) -{ - m_bDebugMode = bMode; -} - - -// Initializes DirectSound. - -BOOL CSound::Create(HWND hWnd, BOOL b3D) -{ - LPDIRECTSOUNDBUFFER primary; - DSBUFFERDESC dsbdesc; - DSCAPS dscaps; - WAVEFORMATEX wfx; - HRESULT hr; - - if ( !DirectSoundCreate(NULL, &m_lpDS, NULL) == DS_OK ) - { - OutputDebugString("Fatal error: DirectSoundCreate\n"); - m_bEnable = FALSE; - return FALSE; - } - -//? m_lpDS->SetCooperativeLevel(hWnd, DSSCL_NORMAL); - m_lpDS->SetCooperativeLevel(hWnd, DSSCL_PRIORITY); - - if ( !RetSound3DCap() ) b3D = FALSE; - - m_ctrl3D = FALSE; - if ( b3D ) - { - // Obtain primary buffer, asking it for 3D control. - ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) ); - dsbdesc.dwSize = sizeof(DSBUFFERDESC); - dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D; - hr = m_lpDS->CreateSoundBuffer( &dsbdesc, &primary, NULL ); - if ( hr == S_OK ) - { - m_ctrl3D = TRUE; - } - } - - if ( !m_ctrl3D ) - { - // Obtain primary buffer, without 3D control. - ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) ); - dsbdesc.dwSize = sizeof(DSBUFFERDESC); - dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; - hr = m_lpDS->CreateSoundBuffer( &dsbdesc, &primary, NULL ); - if ( hr != S_OK ) - { - return FALSE; - } - m_ctrl3D = FALSE; - } - - if ( m_ctrl3D ) - { - hr = primary->QueryInterface( IID_IDirectSound3DListener, - (VOID**)&m_listener ); - if ( hr != S_OK ) - { - primary->Release(); - return FALSE; - } - } - - // Set primary buffer format to 44kHz and 16-bit output. - ZeroMemory( &wfx, sizeof(WAVEFORMATEX) ); - wfx.wFormatTag = WAVE_FORMAT_PCM; - wfx.nChannels = 2; - wfx.nSamplesPerSec = 22050; -//? wfx.nSamplesPerSec = 44100; - wfx.wBitsPerSample = 16; - wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels; - wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; - hr = primary->SetFormat(&wfx); - if ( hr != S_OK ) - { - DisplayError("SetFormat", SOUND_CLICK, hr); - } - - // Release the primary buffer, since it is not need anymore. - primary->Release(); - - // Search the maximum possible voices. - if ( m_ctrl3D ) - { - ZeroMemory( &dscaps, sizeof(DSCAPS) ); - dscaps.dwSize = sizeof(DSCAPS); - hr = m_lpDS->GetCaps(&dscaps); - if ( hr == DS_OK ) - { - m_maxSound = dscaps.dwMaxHwMixingAllBuffers; - if ( dscaps.dwMaxHw3DAllBuffers > 0 && - m_maxSound > (int)dscaps.dwMaxHw3DAllBuffers ) - { - m_maxSound = dscaps.dwMaxHw3DAllBuffers; - } - if ( m_maxSound > MAXSOUND ) m_maxSound = MAXSOUND; - } - } - - m_bEnable = TRUE; - m_hWnd = hWnd; - return TRUE; -} - - -// Indicates whether to play sounds in 3D or not. - -void CSound::SetSound3D(BOOL bMode) -{ - StopAll(); - - if ( m_listener != NULL ) - { - m_listener->Release(); - m_listener = NULL; - } - - if ( m_lpDS != NULL ) - { - m_lpDS->Release(); - m_lpDS = NULL; - } - - Create(m_hWnd, bMode); -} - -BOOL CSound::RetSound3D() -{ - return m_ctrl3D; -} - -// Indicates whether it is possible to play sounds in 3D. - -BOOL CSound::RetSound3DCap() -{ - DSCAPS dscaps; - HRESULT hr; - - ZeroMemory( &dscaps, sizeof(DSCAPS) ); - dscaps.dwSize = sizeof(DSCAPS); - hr = m_lpDS->GetCaps(&dscaps); - if ( hr != DS_OK ) return FALSE; - - return ( dscaps.dwMaxHw3DAllBuffers > 0 ); -} - - - -// Returns the state of DirectSound. - -BOOL CSound::RetEnable() -{ - return m_bEnable; -} - - -// Switches on or off the sound. - -void CSound::SetState(BOOL bState) -{ - m_bState = bState; -} - -// Specifies the pathname to the CD. - -void CSound::SetCDpath(char *path) -{ - strcpy(m_CDpath, path); -} - -// Switches on or off the CD-audio music. - -void CSound::SetAudioTrack(BOOL bAudio) -{ - m_bAudioTrack = bAudio; -} - - -// Manages volumes of audio (. Wav) and midi (. Mid). - -void CSound::SetAudioVolume(int volume) -{ - m_audioVolume = volume; -} - -int CSound::RetAudioVolume() -{ - if ( !m_bEnable ) return 0; - return m_audioVolume; -} - -void CSound::SetMidiVolume(int volume) -{ - m_midiVolume = volume; - - if ( m_bAudioTrack ) - { - InitAudioTrackVolume(m_midiVolume); - } -} - -int CSound::RetMidiVolume() -{ - if ( !m_bEnable ) return 0; - return m_midiVolume; -} - - -// Reads a file. - -BOOL CSound::ReadFile(Sound sound, char *metaname, char *filename) -{ - WaveHeader wavHdr; - DWORD size; - int err; - - // Open the wave file. - err = g_metafile.Open(metaname, filename); - if ( err != 0 ) return FALSE; - - // Read in the wave header. - g_metafile.Read(&wavHdr, sizeof(wavHdr)); - - // Figure out the size of the data region. - size = wavHdr.dwDSize; - - if ( m_files[sound] != 0 ) - { - free(m_files[sound]); - } - m_files[sound] = (char*)malloc(sizeof(WaveHeader)+size); - - memcpy(m_files[sound], &wavHdr, sizeof(WaveHeader)); - g_metafile.Read(m_files[sound]+sizeof(WaveHeader), size); - - // Close out the wave file. - g_metafile.Close(); - return TRUE; -} - -// Hides all sound files (. Wav). - -void CSound::CacheAll() -{ - int i; - char meta[50]; - char name[50]; - - if ( !m_bEnable ) return; - - if ( m_bDebugMode ) - { - strcpy(meta, ""); - } - else - { -#if _SCHOOL - strcpy(meta, "ceebot3.dat"); -#else - strcpy(meta, "colobot3.dat"); -#endif - } - - for ( i=0 ; iGetStatus(&status); - if ( (status&DSBSTATUS_PLAYING) == 0 ) - { - m_channel[i].priority = priority; - m_channel[i].uniqueStamp = m_uniqueStamp++; - channel = i; - bAlreadyLoaded = TRUE; - return TRUE; - } - } -#endif - - // Seeks a channel completely free. - for ( i=0 ; iGetStatus(&status); - if ( (status&DSBSTATUS_PLAYING) == 0 ) - { - m_channel[i].soundBuffer->Release(); - m_channel[i].soundBuffer = 0; - m_channel[i].priority = priority; - m_channel[i].uniqueStamp = m_uniqueStamp++; - - channel = i; - bAlreadyLoaded = FALSE; - return TRUE; - } - } - - // Seeks a lower priority channel used. - for ( i=0 ; i= priority ) continue; - - m_channel[i].soundBuffer->Stop(); - m_channel[i].soundBuffer->Release(); - m_channel[i].soundBuffer = 0; - m_channel[i].priority = priority; - m_channel[i].uniqueStamp = m_uniqueStamp++; - - channel = i; - bAlreadyLoaded = FALSE; - return TRUE; - } - - // Seeks a channel used the same or lower priority. - for ( i=0 ; i priority ) continue; - - m_channel[i].soundBuffer->Stop(); - m_channel[i].soundBuffer->Release(); - m_channel[i].soundBuffer = 0; - m_channel[i].priority = priority; - m_channel[i].uniqueStamp = m_uniqueStamp++; - - channel = i; - bAlreadyLoaded = FALSE; - return TRUE; - } - - char s[100]; - sprintf(s, "Sound %d forget (priority=%d)\n", sound, priority); - OutputDebugString(s); - - return FALSE; -} - -// Reads in data from a wave file. - -BOOL CSound::ReadData(LPDIRECTSOUNDBUFFER lpDSB, Sound sound, DWORD size) -{ - LPVOID pData1; - DWORD dwData1Size; - LPVOID pData2; - DWORD dwData2Size; - HRESULT hr; - - // Lock data in buffer for writing. - hr = lpDSB->Lock(0, size, &pData1, &dwData1Size, &pData2, &dwData2Size, DSBLOCK_FROMWRITECURSOR); - if ( hr != DS_OK ) - { - return FALSE; - } - - // Read in first chunk of data. - if ( dwData1Size > 0 ) - { - memcpy(pData1, m_files[sound]+sizeof(WaveHeader), dwData1Size); - } - - // Read in second chunk if necessary. - if ( dwData2Size > 0 ) - { - memcpy(pData2, m_files[sound]+sizeof(WaveHeader)+dwData1Size, dwData2Size); - } - - // Unlock data in buffer. - hr = lpDSB->Unlock(pData1, dwData1Size, pData2, dwData2Size); - if ( hr != DS_OK ) - { - return FALSE; - } - - return TRUE; -} - -// Creates a DirectSound buffer. - -BOOL CSound::CreateSoundBuffer(int channel, DWORD size, DWORD freq, - DWORD bitsPerSample, DWORD blkAlign, - BOOL bStereo) -{ - PCMWAVEFORMAT pcmwf; - DSBUFFERDESC dsbdesc; - DS3DBUFFER bufferParams; // 3D buffer properties - HRESULT hr; - - // Set up wave format structure. - memset( &pcmwf, 0, sizeof(PCMWAVEFORMAT) ); - pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; - pcmwf.wf.nChannels = bStereo ? 2 : 1; - pcmwf.wf.nSamplesPerSec = freq; - pcmwf.wf.nBlockAlign = (WORD)blkAlign; - pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign; - pcmwf.wBitsPerSample = (WORD)bitsPerSample; - - // Set up DSBUFFERDESC structure. - memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); // Zero it out. - dsbdesc.dwSize = sizeof(DSBUFFERDESC); - if ( m_ctrl3D ) - { - dsbdesc.dwFlags = DSBCAPS_CTRL3D|DSBCAPS_MUTE3DATMAXDISTANCE| - DSBCAPS_LOCDEFER| - DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLFREQUENCY; - } - else - { - dsbdesc.dwFlags = DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN|DSBCAPS_CTRLFREQUENCY; - } - dsbdesc.dwBufferBytes = size; - dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf; - - hr = m_lpDS->CreateSoundBuffer(&dsbdesc, &m_channel[channel].soundBuffer, NULL); - if ( hr != DS_OK ) return FALSE; - - if ( m_ctrl3D ) - { - hr = m_channel[channel].soundBuffer->QueryInterface - ( - IID_IDirectSound3DBuffer, - (VOID**)&m_channel[channel].soundBuffer3D - ); - if ( hr != DS_OK ) return FALSE; - } - - m_channel[channel].bUsed = TRUE; - m_channel[channel].bMute = FALSE; - return TRUE; -} - -// Creates a DirectSound buffer from a wave file. - -BOOL CSound::CreateBuffer(int channel, Sound sound) -{ - WaveHeader* wavHdr; - DWORD size; - BOOL bStereo; - - if ( m_files[sound] == 0 ) return FALSE; - - wavHdr = (WaveHeader*)m_files[sound]; - size = wavHdr->dwDSize; - bStereo = wavHdr->wChnls > 1 ? TRUE : FALSE; - - // Create the sound buffer for the wave file. - if ( !CreateSoundBuffer(channel, size, wavHdr->dwSRate, - wavHdr->BitsPerSample, wavHdr->wBlkAlign, bStereo) ) - { - return FALSE; - } - - // Read the data for the wave file into the sound buffer. - if ( !ReadData(m_channel[channel].soundBuffer, sound, size) ) - { - return FALSE; - } - - m_channel[channel].type = sound; - - // Close out the wave file. - return TRUE; -} - -// Calculates the volume and pan of a sound, non-3D mode. - -void CSound::ComputeVolumePan2D(int channel, const D3DVECTOR &pos) -{ - float dist, a, g; - - if ( pos.x == m_eye.x && - pos.y == m_eye.y && - pos.z == m_eye.z ) - { - m_channel[channel].volume = 1.0f; // maximum volume - m_channel[channel].pan = 0.0f; // at the center - return; - } - -#if _TEEN - dist = Length(pos, m_eye); - if ( dist >= 210.0f ) // very far? - { - m_channel[channel].volume = 0.0f; // silence - m_channel[channel].pan = 0.0f; // at the center - return; - } - if ( dist <= 10.0f ) // very close? - { - m_channel[channel].volume = 1.0f; // maximum volume - m_channel[channel].pan = 0.0f; // at the center - return; - } - m_channel[channel].volume = 1.0f-((dist-10.0f)/200.0f); -#else - dist = Length(pos, m_eye); - if ( dist >= 110.0f ) // very far? - { - m_channel[channel].volume = 0.0f; // silence - m_channel[channel].pan = 0.0f; // at the center - return; - } - if ( dist <= 10.0f ) // very close? - { - m_channel[channel].volume = 1.0f; // maximum volume - m_channel[channel].pan = 0.0f; // at the center - return; - } - m_channel[channel].volume = 1.0f-((dist-10.0f)/100.0f); -#endif - - a = RotateAngle(m_lookat.x-m_eye.x, m_eye.z-m_lookat.z); - g = RotateAngle(pos.x-m_eye.x, m_eye.z-pos.z); - m_channel[channel].pan = sinf(Direction(a, g)); -} - -// Sounds in the middle. -// Returns the associated channel or -1. - -int CSound::Play(Sound sound, float amplitude, float frequency, BOOL bLoop) -{ - return Play(sound, m_lookat, amplitude, frequency, bLoop); -} - -// Sounds at a given position. -// Returns the associated channel or -1. - -int CSound::Play(Sound sound, D3DVECTOR pos, - float amplitude, float frequency, BOOL bLoop) -{ - DS3DBUFFER sb; - int channel, iVolume, iPan, iFreq, uniqueStamp; - BOOL bAlreadyLoaded; - DWORD flag, freq; - HRESULT err; - - if ( !m_bEnable ) return -1; - if ( !m_bState || m_audioVolume == 0 ) return -1; - -//? if ( Length(pos, m_eye) > 100.0f ) return -1; - - if ( !SearchFreeBuffer(sound, channel, bAlreadyLoaded) ) return -1; - - if ( !bAlreadyLoaded ) - { - if ( !CreateBuffer(channel, sound) ) - { - if ( m_channel[channel].bUsed && - m_channel[channel].soundBuffer != 0 ) - { - m_channel[channel].soundBuffer->Release(); - m_channel[channel].soundBuffer = 0; - } - m_channel[channel].bUsed = FALSE; - return -1; - } - } - - m_channel[channel].pos = pos; - - if ( m_ctrl3D ) - { - m_channel[channel].volume = 1.0f; - m_channel[channel].pan = 0.0f; - } - else - { - ComputeVolumePan2D(channel, pos); - } - -#if 0 - DWORD status; - m_channel[channel].soundBuffer->GetStatus(&status); - char s[100]; - sprintf(s, "Play sound=%d status=%d channel=%d flag=%d\n", sound, status, channel, bAlreadyLoaded); - OutputDebugString(s); -#endif - - m_channel[channel].oper[0].bUsed = FALSE; - m_channel[channel].startAmplitude = amplitude; - m_channel[channel].startFrequency = frequency; - m_channel[channel].changeFrequency = 1.0f; - - if ( m_ctrl3D ) - { - sb.dwSize = sizeof(DS3DBUFFER); - err = m_channel[channel].soundBuffer3D->GetAllParameters(&sb); - DisplayError("GetAllParameters", sound, err); - - sb.vPosition = pos; -//? sb.dwInsideConeAngle = 90; -//? sb.dwOutsideConeAngle = 180; -//? sb.vConeOrientation = D3DVECTOR(0.0f, 1.0f, 0.0f); - sb.lConeOutsideVolume = DSBVOLUME_MIN; -#if _TEEN - sb.flMinDistance = 50.0f; -#else - sb.flMinDistance = 20.0f; -#endif - sb.flMaxDistance = DS3D_DEFAULTMAXDISTANCE; - - err = m_channel[channel].soundBuffer3D->SetAllParameters(&sb, DS3D_IMMEDIATE); - DisplayError("SetAllParameters", sound, err); - } - - amplitude *= m_channel[channel].volume; - amplitude *= (float)m_audioVolume/MAXVOLUME; - iVolume = (int)((powf(amplitude, 0.2f)-1.0f)*10000.0f); - if ( iVolume > 0 ) iVolume = 0; - err = m_channel[channel].soundBuffer->SetVolume(iVolume); - DisplayError("SetVolume", sound, err); - - if ( !m_ctrl3D ) - { - iPan = (int)(m_channel[channel].pan*10000.0f); - err = m_channel[channel].soundBuffer->SetPan(iPan); - DisplayError("SetPan", sound, err); - } - - if ( !bAlreadyLoaded ) - { - err = m_channel[channel].soundBuffer->GetFrequency(&freq); - DisplayError("GetFrequency", sound, err); - m_channel[channel].initFrequency = freq; - } - iFreq = (int)(frequency*m_channel[channel].initFrequency); - err = m_channel[channel].soundBuffer->SetFrequency(iFreq); - DisplayError("SetFrequency", sound, err); - - err = m_channel[channel].soundBuffer->SetCurrentPosition(0); - DisplayError("SetCurrentPosition", sound, err); - - flag = bLoop?DSBPLAY_LOOPING:0; -//? flag |= DSBPLAY_LOCHARDWARE|DSBPLAY_TERMINATEBY_DISTANCE; -//? flag |= DSBPLAY_TERMINATEBY_DISTANCE; - err = m_channel[channel].soundBuffer->Play(0, 0, flag); - DisplayError("Play", sound, err); - if ( err == DSERR_BADFORMAT ) - { - iFreq = m_channel[channel].initFrequency; - err = m_channel[channel].soundBuffer->SetFrequency(iFreq); - DisplayError("SetFrequency (repeat)", sound, err); - - err = m_channel[channel].soundBuffer->Play(0, 0, flag); - DisplayError("Play (repeat)", sound, err); - } - - uniqueStamp = m_channel[channel].uniqueStamp; - return channel | ((uniqueStamp&0xffff)<<16); -} - -// Check a channel number. -// Adapts the channel, so it can be used as an offset in m_channel. - -BOOL CSound::CheckChannel(int &channel) -{ - int uniqueStamp; - - uniqueStamp = (channel>>16)&0xffff; - channel &= 0xffff; - - if ( !m_bEnable ) return FALSE; - if ( !m_bState || m_audioVolume == 0 ) return FALSE; - - if ( channel < 0 || channel >= m_maxSound ) return FALSE; - if ( !m_channel[channel].bUsed ) return FALSE; - - if ( m_channel[channel].uniqueStamp != uniqueStamp ) return FALSE; - - return TRUE; -} - -// Removes all envelopes. - -BOOL CSound::FlushEnvelope(int channel) -{ - if ( !CheckChannel(channel) ) return FALSE; - - m_channel[channel].oper[0].bUsed = FALSE; - return TRUE; -} - -// Adds an operation envelope. - -BOOL CSound::AddEnvelope(int channel, float amplitude, float frequency, - float time, SoundNext oper) -{ - int i; - - if ( !CheckChannel(channel) ) return FALSE; - - for ( i=0 ; iSetPosition(pos.x, pos.y, pos.z, DS3D_DEFERRED); - } - else - { - ComputeVolumePan2D(channel, pos); - - if ( !m_channel[channel].oper[0].bUsed ) - { - amplitude = m_channel[channel].startAmplitude; - amplitude *= m_channel[channel].volume; - amplitude *= (float)m_audioVolume/MAXVOLUME; - iVolume = (int)((powf(amplitude, 0.2f)-1.0f)*10000.0f); - if ( iVolume > 0 ) iVolume = 0; - err = m_channel[channel].soundBuffer->SetVolume(iVolume); - DisplayError("SetVolume", m_channel[channel].type, err); - } - - pan = m_channel[channel].pan; - iPan = (int)(pan*10000.0f); - err = m_channel[channel].soundBuffer->SetPan(iPan); - DisplayError("SetPan", m_channel[channel].type, err); - } - return TRUE; -} - -// Changes the frequency of a sound. -// 0.5 down of an octave and 2.0 up of an octave. - -BOOL CSound::Frequency(int channel, float frequency) -{ - HRESULT err; - int iFreq; - - if ( !CheckChannel(channel) ) return FALSE; - - m_channel[channel].changeFrequency = frequency; - - if ( !m_channel[channel].oper[0].bUsed ) - { - iFreq = (int)(frequency*m_channel[channel].initFrequency); - err = m_channel[channel].soundBuffer->SetFrequency(iFreq); - DisplayError("Frequency", m_channel[channel].type, err); - } - - return TRUE; -} - -// Stops sound. - -BOOL CSound::Stop(int channel) -{ - if ( !CheckChannel(channel) ) return FALSE; - - m_channel[channel].soundBuffer->Stop(); - return TRUE; -} - -// Stops all sounds. - -BOOL CSound::StopAll() -{ - DWORD status; - int i; - - for ( i=0 ; iGetStatus(&status); - if ( (status&DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING ) - { - m_channel[i].soundBuffer->Stop(); - } - m_channel[i].soundBuffer->Stop(); - m_channel[i].soundBuffer->Release(); - m_channel[i].soundBuffer = 0; - - m_channel[i].bUsed = FALSE; - } - return TRUE; -} - -// Silent all sounds. - -BOOL CSound::MuteAll(BOOL bMute) -{ - int i; - - for ( i=0 ; iSetVolume(-10000); // silence - continue; - } - - m_channel[i].oper[0].currentTime += rTime; - - progress = m_channel[i].oper[0].currentTime / m_channel[i].oper[0].totalTime; - if ( progress > 1.0f ) progress = 1.0f; - - volume = progress; - volume *= m_channel[i].oper[0].finalAmplitude-m_channel[i].startAmplitude; - volume += m_channel[i].startAmplitude; - volume *= m_channel[i].volume; - volume *= (float)m_audioVolume/MAXVOLUME; - iVolume = (int)((powf(volume, 0.2f)-1.0f)*10000.0f); - if ( iVolume > 0 ) iVolume = 0; - m_channel[i].soundBuffer->SetVolume(iVolume); - - freq = progress; - freq *= m_channel[i].oper[0].finalFrequency-m_channel[i].startFrequency; - freq += m_channel[i].startFrequency; - freq *= m_channel[i].changeFrequency; - iFreq = (int)(freq*m_channel[i].initFrequency); - err = m_channel[i].soundBuffer->SetFrequency(iFreq); - DisplayError("FrameMove::Frequency", m_channel[i].type, err); - - if ( m_channel[i].oper[0].currentTime >= - m_channel[i].oper[0].totalTime ) - { - next = m_channel[i].oper[0].nextOper; - - if ( next == SOPER_LOOP ) - { - m_channel[i].oper[0].currentTime = 0.0f; - } - else - { - OperNext(i); - - if ( next == SOPER_STOP ) - { - m_channel[i].soundBuffer->Stop(); - } - } - } - } - - m_lastTime += rTime; - if ( m_lastTime >= 0.05f && m_listener != 0 ) - { - m_lastTime = 0.0f; - m_listener->CommitDeferredSettings(); - } -} - -// Specifies the position of the listener. -// Must be called whenever the camera moves. - -void CSound::SetListener(D3DVECTOR eye, D3DVECTOR lookat) -{ - DS3DLISTENER listenerParams; - HRESULT err; - float amplitude, pan; - int i, iVolume, iPan; - - m_eye = eye; - m_lookat = lookat; - - if ( m_listener == 0 ) - { - if ( m_ctrl3D ) return; - - for ( i=0 ; i 0 ) iVolume = 0; - err = m_channel[i].soundBuffer->SetVolume(iVolume); - DisplayError("SetVolume", m_channel[i].type, err); - } - - pan = m_channel[i].pan; - iPan = (int)(pan*10000.0f); - err = m_channel[i].soundBuffer->SetPan(iPan); - DisplayError("SetPan", m_channel[i].type, err); - } - return; - } - - // Get listener parameters. - listenerParams.dwSize = sizeof(DS3DLISTENER); - m_listener->GetAllParameters(&listenerParams); - - listenerParams.vPosition = eye; - listenerParams.vOrientFront = lookat-eye; - listenerParams.vOrientTop = D3DVECTOR(0.0f, 1.0f, 0.0f); - listenerParams.flDistanceFactor = 10.0f; - listenerParams.flRolloffFactor = 1.0f; - - m_listener->SetAllParameters(&listenerParams, DS3D_DEFERRED); -} - - - - -// Uses MCI to play a MIDI file. The window procedure -// is notified when playback is complete. - -BOOL CSound::PlayMusic(int rank, BOOL bRepeat) -{ - MCI_OPEN_PARMS mciOpenParms; - MCI_PLAY_PARMS mciPlayParms; - DWORD dwReturn; - char filename[MAX_PATH]; - - m_bRepeatMusic = bRepeat; - m_playTime = 0.0f; - - if ( m_midiVolume == 0 ) return TRUE; - - if ( m_bAudioTrack ) - { - return PlayAudioTrack(rank); - } - - if ( !m_bEnable ) return TRUE; - InitMidiVolume(m_midiVolume); - m_lastMidiVolume = m_midiVolume; - - GetCurrentDir(filename, MAX_PATH-30); - sprintf(filename+strlen(filename), "sound\\music%.3d.blp", rank-1); - - // Open the device by specifying the device and filename. - // MCI will attempt to choose the MIDI mapper as the output port. - mciOpenParms.lpstrDeviceType = "sequencer"; - mciOpenParms.lpstrElementName = filename; - dwReturn = mciSendCommand(NULL, - MCI_OPEN, - MCI_OPEN_TYPE|MCI_OPEN_ELEMENT, - (DWORD)(LPVOID)&mciOpenParms); - if ( dwReturn != 0 ) - { - mciGetErrorString(dwReturn, filename, 128); - // Failed to open device. Don't close it; just return error. - return FALSE; - } - - // The device opened successfully; get the device ID. - m_MidiDeviceID = mciOpenParms.wDeviceID; - - // Begin playback. - mciPlayParms.dwCallback = (DWORD)m_hWnd; - dwReturn = mciSendCommand(m_MidiDeviceID, - MCI_PLAY, - MCI_NOTIFY, - (DWORD)(LPVOID)&mciPlayParms); - if ( dwReturn != 0 ) - { - mciGetErrorString(dwReturn, filename, 128); - StopMusic(); - return FALSE; - } - - m_MIDIMusic = rank; - return TRUE; -} - -// Uses MCI to play a CD-audio track. The window procedure -// is notified when playback is complete. -// The rank parameter is in space [1..n] ! -// For CD mix (data/audio), it will be [2..n] ! - -BOOL CSound::PlayAudioTrack(int rank) -{ -#if _SOUNDTRACKS - MCI_OPEN_PARMS mciOpenParms; - MCI_PLAY_PARMS mciPlayParms; - MCI_SET_PARMS mciSetParms; - DWORD dwReturn; - char filename[MAX_PATH]; - char device[10]; - - if ( !m_bEnable ) return TRUE; -//? if ( m_midiVolume == 0 ) return TRUE; - InitAudioTrackVolume(m_midiVolume); - m_lastMidiVolume = m_midiVolume; - - // Open the device by specifying the device and filename. - // MCI will attempt to choose the MIDI mapper as the output port. - memset(&mciOpenParms, 0, sizeof(MCI_OPEN_PARMS)); -//? mciOpenParms.lpstrDeviceType = (LPCTSTR)MCI_DEVTYPE_CD_AUDIO; -//? dwReturn = mciSendCommand(NULL, -//? MCI_OPEN, -//? MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID, -//? (DWORD)(LPVOID)&mciOpenParms); - mciOpenParms.lpstrDeviceType = (LPCTSTR)MCI_DEVTYPE_CD_AUDIO; - if ( m_CDpath[0] == 0 ) - { - dwReturn = mciSendCommand(NULL, - MCI_OPEN, - MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID, - (DWORD)(LPVOID)&mciOpenParms); - } - else - { - device[0] = m_CDpath[0]; - device[1] = ':'; - device[2] = 0; - mciOpenParms.lpstrElementName = device; - dwReturn = mciSendCommand(NULL, - MCI_OPEN, - MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_OPEN_ELEMENT, - (DWORD)(LPVOID)&mciOpenParms); - } - if ( dwReturn != 0 ) - { - mciGetErrorString(dwReturn, filename, 128); - // Failed to open device. Don't close it; just return error. - return FALSE; - } - - // The device opened successfully; get the device ID. - m_MidiDeviceID = mciOpenParms.wDeviceID; - - // Set the time format to track/minute/second/frame (TMSF). - memset(&mciSetParms, 0, sizeof(MCI_SET_PARMS)); - mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF; - dwReturn = mciSendCommand(m_MidiDeviceID, - MCI_SET, - MCI_SET_TIME_FORMAT, - (DWORD)&mciSetParms); - if ( dwReturn != 0 ) - { - mciGetErrorString(dwReturn, filename, 128); - StopMusic(); - return FALSE; - } - - // Begin playback. - memset(&mciPlayParms, 0, sizeof(MCI_PLAY_PARMS)); - mciPlayParms.dwCallback = (DWORD)m_hWnd; - mciPlayParms.dwFrom = MCI_MAKE_TMSF(rank+0, 0, 0, 0); - mciPlayParms.dwTo = MCI_MAKE_TMSF(rank+1, 0, 0, 0); - dwReturn = mciSendCommand(m_MidiDeviceID, - MCI_PLAY, - MCI_NOTIFY|MCI_FROM|MCI_TO, - (DWORD)(LPVOID)&mciPlayParms); - if ( dwReturn != 0 ) - { - mciGetErrorString(dwReturn, filename, 128); - StopMusic(); - return FALSE; - } - - m_MIDIMusic = rank; -#endif - return TRUE; -} - -// Restart the MIDI player. - -BOOL CSound::RestartMusic() -{ - if ( !m_bRepeatMusic ) return FALSE; - - OutputDebugString("RestartMusic\n"); - if ( !m_bEnable ) return TRUE; -//? if ( m_midiVolume == 0 ) return TRUE; - if ( m_MIDIMusic == 0 ) return FALSE; - if ( m_playTime < 5.0f ) return FALSE; - - return PlayMusic(m_MIDIMusic, TRUE); -} - -// Shuts down the MIDI player. - -void CSound::SuspendMusic() -{ - if ( !m_bEnable ) return; - -//? if ( m_MidiDeviceID && m_midiVolume != 0 ) - if ( m_MidiDeviceID ) - { - if ( m_bAudioTrack ) mciSendCommand(m_MidiDeviceID, MCI_STOP, 0, NULL); - mciSendCommand(m_MidiDeviceID, MCI_CLOSE, 0, NULL); - } - m_MidiDeviceID = 0; -} - -// Shuts down the MIDI player. - -void CSound::StopMusic() -{ - SuspendMusic(); - m_MIDIMusic = 0; -} - -// Returns TRUE if the music is in progress. - -BOOL CSound::IsPlayingMusic() -{ - return (m_MIDIMusic != 0); -} - -// Adjusts the volume of currently music, if necessary. - -void CSound::AdaptVolumeMusic() -{ - if ( m_midiVolume != m_lastMidiVolume ) - { - if ( m_bAudioTrack ) - { - InitAudioTrackVolume(m_midiVolume); - } - else - { - InitMidiVolume(m_midiVolume); - } - m_lastMidiVolume = m_midiVolume; - RestartMusic(); - } -} - diff --git a/src/sound.h b/src/sound.h deleted file mode 100644 index 16e1be5..0000000 --- a/src/sound.h +++ /dev/null @@ -1,245 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// sound.h - -#ifndef SOUND_H -#define SOUND_H - - -#include - - -#define MAXFILES 200 -#define MAXSOUND 32 -#define MAXVOLUME 20 -#define MAXOPER 4 - -class CInstanceManager; - - -enum Sound -{ - SOUND_CLICK = 0, - SOUND_BOUM = 1, - SOUND_EXPLO = 2, - SOUND_FLYh = 3, // human - SOUND_FLY = 4, - SOUND_STEPs = 5, // smooth - SOUND_MOTORw = 6, // wheel - SOUND_MOTORt = 7, // tank - SOUND_MOTORr = 8, // roller - SOUND_ERROR = 9, - SOUND_CONVERT = 10, - SOUND_ENERGY = 11, - SOUND_PLOUF = 12, - SOUND_BLUP = 13, - SOUND_WARNING = 14, - SOUND_DERRICK = 15, - SOUND_LABO = 16, - SOUND_STATION = 17, - SOUND_REPAIR = 18, - SOUND_RESEARCH = 19, - SOUND_INSECTs = 20, // spider - SOUND_BURN = 21, - SOUND_TZOING = 22, - SOUND_GGG = 23, - SOUND_MANIP = 24, - SOUND_FIRE = 25, // shooting with fireball - SOUND_HUMAN1 = 26, // breathing - SOUND_STEPw = 27, // water - SOUND_SWIM = 28, - SOUND_RADAR = 29, - SOUND_BUILD = 30, - SOUND_ALARM = 31, // energy alarm - SOUND_SLIDE = 32, - SOUND_EXPLOi = 33, // insect - SOUND_INSECTa = 34, // ant - SOUND_INSECTb = 35, // bee - SOUND_INSECTw = 36, // worm - SOUND_INSECTm = 37, // mother - SOUND_TREMBLE = 38, - SOUND_PSHHH = 39, - SOUND_NUCLEAR = 40, - SOUND_INFO = 41, - SOUND_OPEN = 42, - SOUND_CLOSE = 43, - SOUND_FACTORY = 44, - SOUND_EGG = 45, - SOUND_MOTORs = 46, // submarine - SOUND_MOTORi = 47, // insect (legs) - SOUND_SHIELD = 48, - SOUND_FIREi = 49, // shooting with orgaball (insect) - SOUND_GUNDEL = 50, - SOUND_PSHHH2 = 51, // shield - SOUND_MESSAGE = 52, - SOUND_BOUMm = 53, // metal - SOUND_BOUMv = 54, // plant - SOUND_BOUMs = 55, // smooth - SOUND_EXPLOl = 56, // little - SOUND_EXPLOlp = 57, // little power - SOUND_EXPLOp = 58, // power - SOUND_STEPh = 59, // hard - SOUND_STEPm = 60, // metal - SOUND_POWERON = 61, - SOUND_POWEROFF = 62, - SOUND_AIE = 63, - SOUND_WAYPOINT = 64, - SOUND_RECOVER = 65, - SOUND_DEADi = 66, - SOUND_JOSTLE = 67, - SOUND_GFLAT = 68, - SOUND_DEADg = 69, // shooting death - SOUND_DEADw = 70, // drowning - SOUND_FLYf = 71, // reactor fail - SOUND_ALARMt = 72, // temperature alarm - SOUND_FINDING = 73, // finds a cache object - SOUND_THUMP = 74, - SOUND_TOUCH = 75, - SOUND_BLITZ = 76, - SOUND_MUSHROOM = 77, - SOUND_FIREp = 78, // shooting with phazer - SOUND_EXPLOg1 = 79, // impact gun 1 - SOUND_EXPLOg2 = 80, // impact gun 2 - SOUND_MOTORd = 81, // engine friction -}; - -enum SoundNext -{ - SOPER_CONTINUE = 1, - SOPER_STOP = 2, - SOPER_LOOP = 3, -}; - -typedef struct -{ - char bUsed; - float finalAmplitude; - float finalFrequency; - float totalTime; - float currentTime; - SoundNext nextOper; -} -SoundOper; - -typedef struct -{ - char bUsed; // buffer used? - char bMute; // silence? - Sound type; // SOUND_* - int priority; // so great -> important - D3DVECTOR pos; // position in space - unsigned short uniqueStamp; // unique marker - LPDIRECTSOUNDBUFFER soundBuffer; - LPDIRECTSOUND3DBUFFER soundBuffer3D; - float startAmplitude; - float startFrequency; - float changeFrequency; - int initFrequency; - float volume; // 2D: volume 1..0 depending on position - float pan; // 2D: pan -1..+1 depending on position - SoundOper oper[MAXOPER]; -} -SoundChannel; - - - -class CSound -{ -public: - CSound(CInstanceManager* iMan); - ~CSound(); - - void SetDebugMode(BOOL bMode); - BOOL Create(HWND hWnd, BOOL b3D); - void CacheAll(); - - void SetState(BOOL bState); - BOOL RetEnable(); - - void SetCDpath(char *path); - void SetAudioTrack(BOOL bAudio); - - void SetSound3D(BOOL bMode); - BOOL RetSound3D(); - BOOL RetSound3DCap(); - - void SetAudioVolume(int volume); - int RetAudioVolume(); - void SetMidiVolume(int volume); - int RetMidiVolume(); - - void SetListener(D3DVECTOR eye, D3DVECTOR lookat); - void FrameMove(float rTime); - - int Play(Sound sound, float amplitude=1.0f, float frequency=1.0f, BOOL bLoop=FALSE); - int Play(Sound sound, D3DVECTOR pos, float amplitude=1.0f, float frequency=1.0f, BOOL bLoop=FALSE); - BOOL FlushEnvelope(int channel); - BOOL AddEnvelope(int channel, float amplitude, float frequency, float time, SoundNext oper); - BOOL Position(int channel, D3DVECTOR pos); - BOOL Frequency(int channel, float frequency); - BOOL Stop(int channel); - BOOL StopAll(); - BOOL MuteAll(BOOL bMute); - - BOOL PlayMusic(int rank, BOOL bRepeat); - BOOL RestartMusic(); - void SuspendMusic(); - void StopMusic(); - BOOL IsPlayingMusic(); - void AdaptVolumeMusic(); - -protected: - BOOL CheckChannel(int &channel); - BOOL CreateSoundBuffer(int channel, DWORD size, DWORD freq, DWORD bitsPerSample, DWORD blkAlign, BOOL bStereo); - BOOL ReadData(LPDIRECTSOUNDBUFFER lpDSB, Sound sound, DWORD size); - BOOL CreateBuffer(int channel, Sound sound); - void ComputeVolumePan2D(int channel, const D3DVECTOR &pos); - BOOL ReadFile(Sound sound, char *metaname, char *filename); - int RetPriority(Sound sound); - BOOL SearchFreeBuffer(Sound sound, int &channel, BOOL &bAlreadyLoaded); - void OperNext(int channel); - BOOL PlayAudioTrack(int rank); - -protected: - CInstanceManager* m_iMan; - - HWND m_hWnd; - BOOL m_bEnable; - BOOL m_bState; - BOOL m_bAudioTrack; - BOOL m_ctrl3D; - BOOL m_bDebugMode; - LPDIRECTSOUND m_lpDS; - LPDIRECTSOUND3DLISTENER m_listener; - SoundChannel m_channel[MAXSOUND]; - char* m_files[MAXFILES]; - UINT m_MidiDeviceID; - int m_MIDIMusic; - BOOL m_bRepeatMusic; - int m_audioVolume; - int m_midiVolume; - int m_lastMidiVolume; - D3DVECTOR m_eye; - D3DVECTOR m_lookat; - float m_lastTime; - float m_playTime; - int m_uniqueStamp; - int m_maxSound; - char m_CDpath[100]; -}; - -#endif // SOUND_H diff --git a/src/sound/README.txt b/src/sound/README.txt new file mode 100644 index 0000000..d6ac0bd --- /dev/null +++ b/src/sound/README.txt @@ -0,0 +1,3 @@ +src/sound + +Contains the sound module - for playing sounds and music. diff --git a/src/sound/sound.cpp b/src/sound/sound.cpp new file mode 100644 index 0000000..333eba0 --- /dev/null +++ b/src/sound/sound.cpp @@ -0,0 +1,1658 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// sound.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include +#include +#include +#include "language.h" +#include "struct.h" +#include "iman.h" +#include "math3d.h" +#include "sound.h" + + +///////////////////////////////////////////////////////////////////////////// + + +#define LXIMAGE 640 +#define LYIMAGE 480 + + + +// Header .WAV file. + +struct WaveHeader +{ + BYTE RIFF[4]; // "RIFF" + DWORD dwSize; // size of data to follow + BYTE WAVE[4]; // "WAVE" + BYTE fmt_[4]; // "fmt " + DWORD dw16; // 16 + WORD wOne_0; // 1 + WORD wChnls; // number of Channels + DWORD dwSRate; // sample Rate + DWORD BytesPerSec; // sample Rate + WORD wBlkAlign; // 1 + WORD BitsPerSample; // sample size + BYTE DATA[4]; // "DATA" + DWORD dwDSize; // number of Samples +}; + + + + +// Displays an error DirectSound. + +void DisplayError(char *name, Sound sound, HRESULT err) +{ + char s[100]; + unsigned int i = err; + if ( err == DS_OK ) return; + sprintf(s, "SoundError in %s, sound=%d err=%d\n", name, sound, i); + OutputDebugString(s); + + if ( err == DSERR_ALLOCATED ) OutputDebugString("DSERR_ALLOCATED\n"); + if ( err == DSERR_CONTROLUNAVAIL ) OutputDebugString("DSERR_CONTROLUNAVAIL\n"); + if ( err == DSERR_INVALIDPARAM ) OutputDebugString("DSERR_INVALIDPARAM\n"); + if ( err == DSERR_INVALIDCALL ) OutputDebugString("DSERR_INVALIDCALL\n"); + if ( err == DSERR_GENERIC ) OutputDebugString("DSERR_GENERIC\n"); + if ( err == DSERR_PRIOLEVELNEEDED ) OutputDebugString("DSERR_PRIOLEVELNEEDED\n"); + if ( err == DSERR_OUTOFMEMORY ) OutputDebugString("DSERR_OUTOFMEMORY\n"); + if ( err == DSERR_BADFORMAT ) OutputDebugString("DSERR_BADFORMAT\n"); + if ( err == DSERR_UNSUPPORTED ) OutputDebugString("DSERR_UNSUPPORTED\n"); + if ( err == DSERR_NODRIVER ) OutputDebugString("DSERR_NODRIVER\n"); + if ( err == DSERR_ALREADYINITIALIZED ) OutputDebugString("DSERR_ALREADYINITIALIZED\n"); + if ( err == DSERR_NOAGGREGATION ) OutputDebugString("DSERR_NOAGGREGATION\n"); + if ( err == DSERR_BUFFERLOST ) OutputDebugString("DSERR_BUFFERLOST\n"); + if ( err == DSERR_OTHERAPPHASPRIO ) OutputDebugString("DSERR_OTHERAPPHASPRIO\n"); + if ( err == DSERR_UNINITIALIZED ) OutputDebugString("DSERR_UNINITIALIZED\n"); + if ( err == DSERR_NOINTERFACE ) OutputDebugString("DSERR_NOINTERFACE\n"); + if ( err == DSERR_ACCESSDENIED ) OutputDebugString("DSERR_ACCESSDENIED\n"); +} + +// Returns the name of the current folder. + +void GetCurrentDir(char *pName, int lg) +{ + int i; + + strncpy(pName, _pgmptr, lg-1); + pName[lg-1] = 0; + + lg = strlen(pName); + if ( lg == 0 ) return; + + for ( i=0 ; i 0 ) + { + lg --; + if ( pName[lg] == '\\' ) + { + pName[lg+1] = 0; + break; + } + } + + if ( lg > 6 && strcmp(pName+lg-6, "\\debug\\") == 0 ) + { + pName[lg-5] = 0; // ignores the folder \debug! + } + + if ( lg > 6 && strcmp(pName+lg-6, "\\release\\") == 0 ) + { + pName[lg-7] = 0; // ignores the folder \release ! + } +} + + + + +///////////////////////////////////////////////////////////////////////////// + + +// Changes the volume of midi. +// The volume is between 0 and 20! + +void InitMidiVolume(int volume) +{ + int nb, i, n; + MMRESULT result; + HMIDIOUT hmo = 0; + + static int table[21] = + { + 0x00000000, + 0x11111111, + 0x22222222, + 0x33333333, + 0x44444444, + 0x55555555, + 0x66666666, + 0x77777777, + 0x88888888, + 0x99999999, + 0xAAAAAAAA, + 0xBBBBBBBB, + 0xCCCCCCCC, + 0xDDDDDDDD, + 0xEEEEEEEE, + 0xF222F222, + 0xF555F555, + 0xF777F777, + 0xFAAAFAAA, + 0xFDDDFDDD, + 0xFFFFFFFF, + }; + + if ( volume < 0 ) volume = 0; + if ( volume > MAXVOLUME ) volume = MAXVOLUME; + + nb = midiOutGetNumDevs(); + for ( i=0 ; i MAXVOLUME ) volume = MAXVOLUME; + + // Open the mixer. This opens the mixer with a deviceID of 0. If you + // have a single sound card/mixer, then this will open it. If you have + // multiple sound cards/mixers, the deviceIDs will be 0, 1, 2, and + // so on. + rc = mixerOpen(&hMixer, 0,0,0,0); + if ( rc != MMSYSERR_NOERROR ) + { + return FALSE; // Couldn't open the mixer. + } + + // Initialize MIXERLINE structure. + ZeroMemory(&mxl,sizeof(mxl)); + mxl.cbStruct = sizeof(mxl); + + // Specify the line you want to get. You are getting the input line + // here. If you want to get the output line, you need to use + // MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT. + mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC; + + rc = mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl, + MIXER_GETLINEINFOF_COMPONENTTYPE); + if ( rc != MMSYSERR_NOERROR ) + { + return FALSE; // Couldn't get the mixer line. + } + + // Get the control. + ZeroMemory(&mxlc, sizeof(mxlc)); + mxlc.cbStruct = sizeof(mxlc); + mxlc.dwLineID = mxl.dwLineID; +//? mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_PEAKMETER; +//? mxlc.dwControlType = MIXERCONTROL_CONTROLF_UNIFORM; + mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; + mxlc.cControls = 1; + mxlc.cbmxctrl = sizeof(mxc); + mxlc.pamxctrl = &mxc; + ZeroMemory(&mxc, sizeof(mxc)); + mxc.cbStruct = sizeof(mxc); + rc = mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc, + MIXER_GETLINECONTROLSF_ONEBYTYPE); +//? MIXER_GETLINECONTROLSF_ALL); + if ( rc != MMSYSERR_NOERROR ) + { + return FALSE; // Couldn't get the control. + } + + // After successfully getting the peakmeter control, the volume range + // will be specified by mxc.Bounds.lMinimum to mxc.Bounds.lMaximum. + + MIXERCONTROLDETAILS mxcd; // Gets the control values. + MIXERCONTROLDETAILS_SIGNED volStruct; // Gets the control values. + + volStruct.lValue = volume*(mxc.Bounds.lMaximum-mxc.Bounds.lMinimum); + volStruct.lValue /= MAXVOLUME; + volStruct.lValue += mxc.Bounds.lMinimum; + + // Initialize the MIXERCONTROLDETAILS structure + ZeroMemory(&mxcd, sizeof(mxcd)); + mxcd.cbStruct = sizeof(mxcd); + mxcd.cbDetails = sizeof(volStruct); + mxcd.dwControlID = mxc.dwControlID; + mxcd.paDetails = &volStruct; + mxcd.cChannels = 1; + + // Get the current value of the peakmeter control. Typically, you + // would set a timer in your program to query the volume every 10th + // of a second or so. + rc = mixerSetControlDetails((HMIXEROBJ)hMixer, &mxcd, + MIXER_SETCONTROLDETAILSF_VALUE); + if ( rc != MMSYSERR_NOERROR ) + { + return FALSE; // Couldn't get the current volume. + } +#endif + + return TRUE; +} + + +///////////////////////////////////////////////////////////////////////////// + + +// Constructor. + +CSound::CSound(CInstanceManager* iMan) +{ + int i; + + m_iMan = iMan; + m_iMan->AddInstance(CLASS_SOUND, this); + + m_bEnable = FALSE; + m_bState = FALSE; + m_bAudioTrack = TRUE; + m_ctrl3D = TRUE; + m_bDebugMode = FALSE; + m_MidiDeviceID = 0; + m_MIDIMusic = 0; + m_audioVolume = 20; + m_midiVolume = 15; + m_lastMidiVolume = 0; + m_listener = 0; + m_lastTime = 0.0f; + m_playTime = 0.0f; + m_uniqueStamp = 0; + m_maxSound = MAXSOUND; + m_eye = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_hWnd = 0; + + m_lpDS = NULL; + + ZeroMemory(m_channel, sizeof(SoundChannel)*MAXSOUND); + for ( i=0 ; iStop(); + m_channel[i].soundBuffer->Release(); + m_channel[i].soundBuffer = 0; + m_channel[i].bUsed = FALSE; + } + } + + if ( m_listener != NULL ) + { + m_listener->Release(); + m_listener = NULL; + } + + if ( m_lpDS != NULL ) + { + m_lpDS->Release(); + m_lpDS = NULL; + } +} + + +// Specifies whether you are in debug mode. + +void CSound::SetDebugMode(BOOL bMode) +{ + m_bDebugMode = bMode; +} + + +// Initializes DirectSound. + +BOOL CSound::Create(HWND hWnd, BOOL b3D) +{ + LPDIRECTSOUNDBUFFER primary; + DSBUFFERDESC dsbdesc; + DSCAPS dscaps; + WAVEFORMATEX wfx; + HRESULT hr; + + if ( !DirectSoundCreate(NULL, &m_lpDS, NULL) == DS_OK ) + { + OutputDebugString("Fatal error: DirectSoundCreate\n"); + m_bEnable = FALSE; + return FALSE; + } + +//? m_lpDS->SetCooperativeLevel(hWnd, DSSCL_NORMAL); + m_lpDS->SetCooperativeLevel(hWnd, DSSCL_PRIORITY); + + if ( !RetSound3DCap() ) b3D = FALSE; + + m_ctrl3D = FALSE; + if ( b3D ) + { + // Obtain primary buffer, asking it for 3D control. + ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) ); + dsbdesc.dwSize = sizeof(DSBUFFERDESC); + dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D; + hr = m_lpDS->CreateSoundBuffer( &dsbdesc, &primary, NULL ); + if ( hr == S_OK ) + { + m_ctrl3D = TRUE; + } + } + + if ( !m_ctrl3D ) + { + // Obtain primary buffer, without 3D control. + ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) ); + dsbdesc.dwSize = sizeof(DSBUFFERDESC); + dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; + hr = m_lpDS->CreateSoundBuffer( &dsbdesc, &primary, NULL ); + if ( hr != S_OK ) + { + return FALSE; + } + m_ctrl3D = FALSE; + } + + if ( m_ctrl3D ) + { + hr = primary->QueryInterface( IID_IDirectSound3DListener, + (VOID**)&m_listener ); + if ( hr != S_OK ) + { + primary->Release(); + return FALSE; + } + } + + // Set primary buffer format to 44kHz and 16-bit output. + ZeroMemory( &wfx, sizeof(WAVEFORMATEX) ); + wfx.wFormatTag = WAVE_FORMAT_PCM; + wfx.nChannels = 2; + wfx.nSamplesPerSec = 22050; +//? wfx.nSamplesPerSec = 44100; + wfx.wBitsPerSample = 16; + wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels; + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + hr = primary->SetFormat(&wfx); + if ( hr != S_OK ) + { + DisplayError("SetFormat", SOUND_CLICK, hr); + } + + // Release the primary buffer, since it is not need anymore. + primary->Release(); + + // Search the maximum possible voices. + if ( m_ctrl3D ) + { + ZeroMemory( &dscaps, sizeof(DSCAPS) ); + dscaps.dwSize = sizeof(DSCAPS); + hr = m_lpDS->GetCaps(&dscaps); + if ( hr == DS_OK ) + { + m_maxSound = dscaps.dwMaxHwMixingAllBuffers; + if ( dscaps.dwMaxHw3DAllBuffers > 0 && + m_maxSound > (int)dscaps.dwMaxHw3DAllBuffers ) + { + m_maxSound = dscaps.dwMaxHw3DAllBuffers; + } + if ( m_maxSound > MAXSOUND ) m_maxSound = MAXSOUND; + } + } + + m_bEnable = TRUE; + m_hWnd = hWnd; + return TRUE; +} + + +// Indicates whether to play sounds in 3D or not. + +void CSound::SetSound3D(BOOL bMode) +{ + StopAll(); + + if ( m_listener != NULL ) + { + m_listener->Release(); + m_listener = NULL; + } + + if ( m_lpDS != NULL ) + { + m_lpDS->Release(); + m_lpDS = NULL; + } + + Create(m_hWnd, bMode); +} + +BOOL CSound::RetSound3D() +{ + return m_ctrl3D; +} + +// Indicates whether it is possible to play sounds in 3D. + +BOOL CSound::RetSound3DCap() +{ + DSCAPS dscaps; + HRESULT hr; + + ZeroMemory( &dscaps, sizeof(DSCAPS) ); + dscaps.dwSize = sizeof(DSCAPS); + hr = m_lpDS->GetCaps(&dscaps); + if ( hr != DS_OK ) return FALSE; + + return ( dscaps.dwMaxHw3DAllBuffers > 0 ); +} + + + +// Returns the state of DirectSound. + +BOOL CSound::RetEnable() +{ + return m_bEnable; +} + + +// Switches on or off the sound. + +void CSound::SetState(BOOL bState) +{ + m_bState = bState; +} + +// Specifies the pathname to the CD. + +void CSound::SetCDpath(char *path) +{ + strcpy(m_CDpath, path); +} + +// Switches on or off the CD-audio music. + +void CSound::SetAudioTrack(BOOL bAudio) +{ + m_bAudioTrack = bAudio; +} + + +// Manages volumes of audio (. Wav) and midi (. Mid). + +void CSound::SetAudioVolume(int volume) +{ + m_audioVolume = volume; +} + +int CSound::RetAudioVolume() +{ + if ( !m_bEnable ) return 0; + return m_audioVolume; +} + +void CSound::SetMidiVolume(int volume) +{ + m_midiVolume = volume; + + if ( m_bAudioTrack ) + { + InitAudioTrackVolume(m_midiVolume); + } +} + +int CSound::RetMidiVolume() +{ + if ( !m_bEnable ) return 0; + return m_midiVolume; +} + + +// Reads a file. + +BOOL CSound::ReadFile(Sound sound, char *metaname, char *filename) +{ + WaveHeader wavHdr; + DWORD size; + int err; + + // Open the wave file. + err = g_metafile.Open(metaname, filename); + if ( err != 0 ) return FALSE; + + // Read in the wave header. + g_metafile.Read(&wavHdr, sizeof(wavHdr)); + + // Figure out the size of the data region. + size = wavHdr.dwDSize; + + if ( m_files[sound] != 0 ) + { + free(m_files[sound]); + } + m_files[sound] = (char*)malloc(sizeof(WaveHeader)+size); + + memcpy(m_files[sound], &wavHdr, sizeof(WaveHeader)); + g_metafile.Read(m_files[sound]+sizeof(WaveHeader), size); + + // Close out the wave file. + g_metafile.Close(); + return TRUE; +} + +// Hides all sound files (. Wav). + +void CSound::CacheAll() +{ + int i; + char meta[50]; + char name[50]; + + if ( !m_bEnable ) return; + + if ( m_bDebugMode ) + { + strcpy(meta, ""); + } + else + { +#if _SCHOOL + strcpy(meta, "ceebot3.dat"); +#else + strcpy(meta, "colobot3.dat"); +#endif + } + + for ( i=0 ; iGetStatus(&status); + if ( (status&DSBSTATUS_PLAYING) == 0 ) + { + m_channel[i].priority = priority; + m_channel[i].uniqueStamp = m_uniqueStamp++; + channel = i; + bAlreadyLoaded = TRUE; + return TRUE; + } + } +#endif + + // Seeks a channel completely free. + for ( i=0 ; iGetStatus(&status); + if ( (status&DSBSTATUS_PLAYING) == 0 ) + { + m_channel[i].soundBuffer->Release(); + m_channel[i].soundBuffer = 0; + m_channel[i].priority = priority; + m_channel[i].uniqueStamp = m_uniqueStamp++; + + channel = i; + bAlreadyLoaded = FALSE; + return TRUE; + } + } + + // Seeks a lower priority channel used. + for ( i=0 ; i= priority ) continue; + + m_channel[i].soundBuffer->Stop(); + m_channel[i].soundBuffer->Release(); + m_channel[i].soundBuffer = 0; + m_channel[i].priority = priority; + m_channel[i].uniqueStamp = m_uniqueStamp++; + + channel = i; + bAlreadyLoaded = FALSE; + return TRUE; + } + + // Seeks a channel used the same or lower priority. + for ( i=0 ; i priority ) continue; + + m_channel[i].soundBuffer->Stop(); + m_channel[i].soundBuffer->Release(); + m_channel[i].soundBuffer = 0; + m_channel[i].priority = priority; + m_channel[i].uniqueStamp = m_uniqueStamp++; + + channel = i; + bAlreadyLoaded = FALSE; + return TRUE; + } + + char s[100]; + sprintf(s, "Sound %d forget (priority=%d)\n", sound, priority); + OutputDebugString(s); + + return FALSE; +} + +// Reads in data from a wave file. + +BOOL CSound::ReadData(LPDIRECTSOUNDBUFFER lpDSB, Sound sound, DWORD size) +{ + LPVOID pData1; + DWORD dwData1Size; + LPVOID pData2; + DWORD dwData2Size; + HRESULT hr; + + // Lock data in buffer for writing. + hr = lpDSB->Lock(0, size, &pData1, &dwData1Size, &pData2, &dwData2Size, DSBLOCK_FROMWRITECURSOR); + if ( hr != DS_OK ) + { + return FALSE; + } + + // Read in first chunk of data. + if ( dwData1Size > 0 ) + { + memcpy(pData1, m_files[sound]+sizeof(WaveHeader), dwData1Size); + } + + // Read in second chunk if necessary. + if ( dwData2Size > 0 ) + { + memcpy(pData2, m_files[sound]+sizeof(WaveHeader)+dwData1Size, dwData2Size); + } + + // Unlock data in buffer. + hr = lpDSB->Unlock(pData1, dwData1Size, pData2, dwData2Size); + if ( hr != DS_OK ) + { + return FALSE; + } + + return TRUE; +} + +// Creates a DirectSound buffer. + +BOOL CSound::CreateSoundBuffer(int channel, DWORD size, DWORD freq, + DWORD bitsPerSample, DWORD blkAlign, + BOOL bStereo) +{ + PCMWAVEFORMAT pcmwf; + DSBUFFERDESC dsbdesc; + DS3DBUFFER bufferParams; // 3D buffer properties + HRESULT hr; + + // Set up wave format structure. + memset( &pcmwf, 0, sizeof(PCMWAVEFORMAT) ); + pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; + pcmwf.wf.nChannels = bStereo ? 2 : 1; + pcmwf.wf.nSamplesPerSec = freq; + pcmwf.wf.nBlockAlign = (WORD)blkAlign; + pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign; + pcmwf.wBitsPerSample = (WORD)bitsPerSample; + + // Set up DSBUFFERDESC structure. + memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); // Zero it out. + dsbdesc.dwSize = sizeof(DSBUFFERDESC); + if ( m_ctrl3D ) + { + dsbdesc.dwFlags = DSBCAPS_CTRL3D|DSBCAPS_MUTE3DATMAXDISTANCE| + DSBCAPS_LOCDEFER| + DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLFREQUENCY; + } + else + { + dsbdesc.dwFlags = DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN|DSBCAPS_CTRLFREQUENCY; + } + dsbdesc.dwBufferBytes = size; + dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf; + + hr = m_lpDS->CreateSoundBuffer(&dsbdesc, &m_channel[channel].soundBuffer, NULL); + if ( hr != DS_OK ) return FALSE; + + if ( m_ctrl3D ) + { + hr = m_channel[channel].soundBuffer->QueryInterface + ( + IID_IDirectSound3DBuffer, + (VOID**)&m_channel[channel].soundBuffer3D + ); + if ( hr != DS_OK ) return FALSE; + } + + m_channel[channel].bUsed = TRUE; + m_channel[channel].bMute = FALSE; + return TRUE; +} + +// Creates a DirectSound buffer from a wave file. + +BOOL CSound::CreateBuffer(int channel, Sound sound) +{ + WaveHeader* wavHdr; + DWORD size; + BOOL bStereo; + + if ( m_files[sound] == 0 ) return FALSE; + + wavHdr = (WaveHeader*)m_files[sound]; + size = wavHdr->dwDSize; + bStereo = wavHdr->wChnls > 1 ? TRUE : FALSE; + + // Create the sound buffer for the wave file. + if ( !CreateSoundBuffer(channel, size, wavHdr->dwSRate, + wavHdr->BitsPerSample, wavHdr->wBlkAlign, bStereo) ) + { + return FALSE; + } + + // Read the data for the wave file into the sound buffer. + if ( !ReadData(m_channel[channel].soundBuffer, sound, size) ) + { + return FALSE; + } + + m_channel[channel].type = sound; + + // Close out the wave file. + return TRUE; +} + +// Calculates the volume and pan of a sound, non-3D mode. + +void CSound::ComputeVolumePan2D(int channel, const D3DVECTOR &pos) +{ + float dist, a, g; + + if ( pos.x == m_eye.x && + pos.y == m_eye.y && + pos.z == m_eye.z ) + { + m_channel[channel].volume = 1.0f; // maximum volume + m_channel[channel].pan = 0.0f; // at the center + return; + } + +#if _TEEN + dist = Length(pos, m_eye); + if ( dist >= 210.0f ) // very far? + { + m_channel[channel].volume = 0.0f; // silence + m_channel[channel].pan = 0.0f; // at the center + return; + } + if ( dist <= 10.0f ) // very close? + { + m_channel[channel].volume = 1.0f; // maximum volume + m_channel[channel].pan = 0.0f; // at the center + return; + } + m_channel[channel].volume = 1.0f-((dist-10.0f)/200.0f); +#else + dist = Length(pos, m_eye); + if ( dist >= 110.0f ) // very far? + { + m_channel[channel].volume = 0.0f; // silence + m_channel[channel].pan = 0.0f; // at the center + return; + } + if ( dist <= 10.0f ) // very close? + { + m_channel[channel].volume = 1.0f; // maximum volume + m_channel[channel].pan = 0.0f; // at the center + return; + } + m_channel[channel].volume = 1.0f-((dist-10.0f)/100.0f); +#endif + + a = RotateAngle(m_lookat.x-m_eye.x, m_eye.z-m_lookat.z); + g = RotateAngle(pos.x-m_eye.x, m_eye.z-pos.z); + m_channel[channel].pan = sinf(Direction(a, g)); +} + +// Sounds in the middle. +// Returns the associated channel or -1. + +int CSound::Play(Sound sound, float amplitude, float frequency, BOOL bLoop) +{ + return Play(sound, m_lookat, amplitude, frequency, bLoop); +} + +// Sounds at a given position. +// Returns the associated channel or -1. + +int CSound::Play(Sound sound, D3DVECTOR pos, + float amplitude, float frequency, BOOL bLoop) +{ + DS3DBUFFER sb; + int channel, iVolume, iPan, iFreq, uniqueStamp; + BOOL bAlreadyLoaded; + DWORD flag, freq; + HRESULT err; + + if ( !m_bEnable ) return -1; + if ( !m_bState || m_audioVolume == 0 ) return -1; + +//? if ( Length(pos, m_eye) > 100.0f ) return -1; + + if ( !SearchFreeBuffer(sound, channel, bAlreadyLoaded) ) return -1; + + if ( !bAlreadyLoaded ) + { + if ( !CreateBuffer(channel, sound) ) + { + if ( m_channel[channel].bUsed && + m_channel[channel].soundBuffer != 0 ) + { + m_channel[channel].soundBuffer->Release(); + m_channel[channel].soundBuffer = 0; + } + m_channel[channel].bUsed = FALSE; + return -1; + } + } + + m_channel[channel].pos = pos; + + if ( m_ctrl3D ) + { + m_channel[channel].volume = 1.0f; + m_channel[channel].pan = 0.0f; + } + else + { + ComputeVolumePan2D(channel, pos); + } + +#if 0 + DWORD status; + m_channel[channel].soundBuffer->GetStatus(&status); + char s[100]; + sprintf(s, "Play sound=%d status=%d channel=%d flag=%d\n", sound, status, channel, bAlreadyLoaded); + OutputDebugString(s); +#endif + + m_channel[channel].oper[0].bUsed = FALSE; + m_channel[channel].startAmplitude = amplitude; + m_channel[channel].startFrequency = frequency; + m_channel[channel].changeFrequency = 1.0f; + + if ( m_ctrl3D ) + { + sb.dwSize = sizeof(DS3DBUFFER); + err = m_channel[channel].soundBuffer3D->GetAllParameters(&sb); + DisplayError("GetAllParameters", sound, err); + + sb.vPosition = pos; +//? sb.dwInsideConeAngle = 90; +//? sb.dwOutsideConeAngle = 180; +//? sb.vConeOrientation = D3DVECTOR(0.0f, 1.0f, 0.0f); + sb.lConeOutsideVolume = DSBVOLUME_MIN; +#if _TEEN + sb.flMinDistance = 50.0f; +#else + sb.flMinDistance = 20.0f; +#endif + sb.flMaxDistance = DS3D_DEFAULTMAXDISTANCE; + + err = m_channel[channel].soundBuffer3D->SetAllParameters(&sb, DS3D_IMMEDIATE); + DisplayError("SetAllParameters", sound, err); + } + + amplitude *= m_channel[channel].volume; + amplitude *= (float)m_audioVolume/MAXVOLUME; + iVolume = (int)((powf(amplitude, 0.2f)-1.0f)*10000.0f); + if ( iVolume > 0 ) iVolume = 0; + err = m_channel[channel].soundBuffer->SetVolume(iVolume); + DisplayError("SetVolume", sound, err); + + if ( !m_ctrl3D ) + { + iPan = (int)(m_channel[channel].pan*10000.0f); + err = m_channel[channel].soundBuffer->SetPan(iPan); + DisplayError("SetPan", sound, err); + } + + if ( !bAlreadyLoaded ) + { + err = m_channel[channel].soundBuffer->GetFrequency(&freq); + DisplayError("GetFrequency", sound, err); + m_channel[channel].initFrequency = freq; + } + iFreq = (int)(frequency*m_channel[channel].initFrequency); + err = m_channel[channel].soundBuffer->SetFrequency(iFreq); + DisplayError("SetFrequency", sound, err); + + err = m_channel[channel].soundBuffer->SetCurrentPosition(0); + DisplayError("SetCurrentPosition", sound, err); + + flag = bLoop?DSBPLAY_LOOPING:0; +//? flag |= DSBPLAY_LOCHARDWARE|DSBPLAY_TERMINATEBY_DISTANCE; +//? flag |= DSBPLAY_TERMINATEBY_DISTANCE; + err = m_channel[channel].soundBuffer->Play(0, 0, flag); + DisplayError("Play", sound, err); + if ( err == DSERR_BADFORMAT ) + { + iFreq = m_channel[channel].initFrequency; + err = m_channel[channel].soundBuffer->SetFrequency(iFreq); + DisplayError("SetFrequency (repeat)", sound, err); + + err = m_channel[channel].soundBuffer->Play(0, 0, flag); + DisplayError("Play (repeat)", sound, err); + } + + uniqueStamp = m_channel[channel].uniqueStamp; + return channel | ((uniqueStamp&0xffff)<<16); +} + +// Check a channel number. +// Adapts the channel, so it can be used as an offset in m_channel. + +BOOL CSound::CheckChannel(int &channel) +{ + int uniqueStamp; + + uniqueStamp = (channel>>16)&0xffff; + channel &= 0xffff; + + if ( !m_bEnable ) return FALSE; + if ( !m_bState || m_audioVolume == 0 ) return FALSE; + + if ( channel < 0 || channel >= m_maxSound ) return FALSE; + if ( !m_channel[channel].bUsed ) return FALSE; + + if ( m_channel[channel].uniqueStamp != uniqueStamp ) return FALSE; + + return TRUE; +} + +// Removes all envelopes. + +BOOL CSound::FlushEnvelope(int channel) +{ + if ( !CheckChannel(channel) ) return FALSE; + + m_channel[channel].oper[0].bUsed = FALSE; + return TRUE; +} + +// Adds an operation envelope. + +BOOL CSound::AddEnvelope(int channel, float amplitude, float frequency, + float time, SoundNext oper) +{ + int i; + + if ( !CheckChannel(channel) ) return FALSE; + + for ( i=0 ; iSetPosition(pos.x, pos.y, pos.z, DS3D_DEFERRED); + } + else + { + ComputeVolumePan2D(channel, pos); + + if ( !m_channel[channel].oper[0].bUsed ) + { + amplitude = m_channel[channel].startAmplitude; + amplitude *= m_channel[channel].volume; + amplitude *= (float)m_audioVolume/MAXVOLUME; + iVolume = (int)((powf(amplitude, 0.2f)-1.0f)*10000.0f); + if ( iVolume > 0 ) iVolume = 0; + err = m_channel[channel].soundBuffer->SetVolume(iVolume); + DisplayError("SetVolume", m_channel[channel].type, err); + } + + pan = m_channel[channel].pan; + iPan = (int)(pan*10000.0f); + err = m_channel[channel].soundBuffer->SetPan(iPan); + DisplayError("SetPan", m_channel[channel].type, err); + } + return TRUE; +} + +// Changes the frequency of a sound. +// 0.5 down of an octave and 2.0 up of an octave. + +BOOL CSound::Frequency(int channel, float frequency) +{ + HRESULT err; + int iFreq; + + if ( !CheckChannel(channel) ) return FALSE; + + m_channel[channel].changeFrequency = frequency; + + if ( !m_channel[channel].oper[0].bUsed ) + { + iFreq = (int)(frequency*m_channel[channel].initFrequency); + err = m_channel[channel].soundBuffer->SetFrequency(iFreq); + DisplayError("Frequency", m_channel[channel].type, err); + } + + return TRUE; +} + +// Stops sound. + +BOOL CSound::Stop(int channel) +{ + if ( !CheckChannel(channel) ) return FALSE; + + m_channel[channel].soundBuffer->Stop(); + return TRUE; +} + +// Stops all sounds. + +BOOL CSound::StopAll() +{ + DWORD status; + int i; + + for ( i=0 ; iGetStatus(&status); + if ( (status&DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING ) + { + m_channel[i].soundBuffer->Stop(); + } + m_channel[i].soundBuffer->Stop(); + m_channel[i].soundBuffer->Release(); + m_channel[i].soundBuffer = 0; + + m_channel[i].bUsed = FALSE; + } + return TRUE; +} + +// Silent all sounds. + +BOOL CSound::MuteAll(BOOL bMute) +{ + int i; + + for ( i=0 ; iSetVolume(-10000); // silence + continue; + } + + m_channel[i].oper[0].currentTime += rTime; + + progress = m_channel[i].oper[0].currentTime / m_channel[i].oper[0].totalTime; + if ( progress > 1.0f ) progress = 1.0f; + + volume = progress; + volume *= m_channel[i].oper[0].finalAmplitude-m_channel[i].startAmplitude; + volume += m_channel[i].startAmplitude; + volume *= m_channel[i].volume; + volume *= (float)m_audioVolume/MAXVOLUME; + iVolume = (int)((powf(volume, 0.2f)-1.0f)*10000.0f); + if ( iVolume > 0 ) iVolume = 0; + m_channel[i].soundBuffer->SetVolume(iVolume); + + freq = progress; + freq *= m_channel[i].oper[0].finalFrequency-m_channel[i].startFrequency; + freq += m_channel[i].startFrequency; + freq *= m_channel[i].changeFrequency; + iFreq = (int)(freq*m_channel[i].initFrequency); + err = m_channel[i].soundBuffer->SetFrequency(iFreq); + DisplayError("FrameMove::Frequency", m_channel[i].type, err); + + if ( m_channel[i].oper[0].currentTime >= + m_channel[i].oper[0].totalTime ) + { + next = m_channel[i].oper[0].nextOper; + + if ( next == SOPER_LOOP ) + { + m_channel[i].oper[0].currentTime = 0.0f; + } + else + { + OperNext(i); + + if ( next == SOPER_STOP ) + { + m_channel[i].soundBuffer->Stop(); + } + } + } + } + + m_lastTime += rTime; + if ( m_lastTime >= 0.05f && m_listener != 0 ) + { + m_lastTime = 0.0f; + m_listener->CommitDeferredSettings(); + } +} + +// Specifies the position of the listener. +// Must be called whenever the camera moves. + +void CSound::SetListener(D3DVECTOR eye, D3DVECTOR lookat) +{ + DS3DLISTENER listenerParams; + HRESULT err; + float amplitude, pan; + int i, iVolume, iPan; + + m_eye = eye; + m_lookat = lookat; + + if ( m_listener == 0 ) + { + if ( m_ctrl3D ) return; + + for ( i=0 ; i 0 ) iVolume = 0; + err = m_channel[i].soundBuffer->SetVolume(iVolume); + DisplayError("SetVolume", m_channel[i].type, err); + } + + pan = m_channel[i].pan; + iPan = (int)(pan*10000.0f); + err = m_channel[i].soundBuffer->SetPan(iPan); + DisplayError("SetPan", m_channel[i].type, err); + } + return; + } + + // Get listener parameters. + listenerParams.dwSize = sizeof(DS3DLISTENER); + m_listener->GetAllParameters(&listenerParams); + + listenerParams.vPosition = eye; + listenerParams.vOrientFront = lookat-eye; + listenerParams.vOrientTop = D3DVECTOR(0.0f, 1.0f, 0.0f); + listenerParams.flDistanceFactor = 10.0f; + listenerParams.flRolloffFactor = 1.0f; + + m_listener->SetAllParameters(&listenerParams, DS3D_DEFERRED); +} + + + + +// Uses MCI to play a MIDI file. The window procedure +// is notified when playback is complete. + +BOOL CSound::PlayMusic(int rank, BOOL bRepeat) +{ + MCI_OPEN_PARMS mciOpenParms; + MCI_PLAY_PARMS mciPlayParms; + DWORD dwReturn; + char filename[MAX_PATH]; + + m_bRepeatMusic = bRepeat; + m_playTime = 0.0f; + + if ( m_midiVolume == 0 ) return TRUE; + + if ( m_bAudioTrack ) + { + return PlayAudioTrack(rank); + } + + if ( !m_bEnable ) return TRUE; + InitMidiVolume(m_midiVolume); + m_lastMidiVolume = m_midiVolume; + + GetCurrentDir(filename, MAX_PATH-30); + sprintf(filename+strlen(filename), "sound\\music%.3d.blp", rank-1); + + // Open the device by specifying the device and filename. + // MCI will attempt to choose the MIDI mapper as the output port. + mciOpenParms.lpstrDeviceType = "sequencer"; + mciOpenParms.lpstrElementName = filename; + dwReturn = mciSendCommand(NULL, + MCI_OPEN, + MCI_OPEN_TYPE|MCI_OPEN_ELEMENT, + (DWORD)(LPVOID)&mciOpenParms); + if ( dwReturn != 0 ) + { + mciGetErrorString(dwReturn, filename, 128); + // Failed to open device. Don't close it; just return error. + return FALSE; + } + + // The device opened successfully; get the device ID. + m_MidiDeviceID = mciOpenParms.wDeviceID; + + // Begin playback. + mciPlayParms.dwCallback = (DWORD)m_hWnd; + dwReturn = mciSendCommand(m_MidiDeviceID, + MCI_PLAY, + MCI_NOTIFY, + (DWORD)(LPVOID)&mciPlayParms); + if ( dwReturn != 0 ) + { + mciGetErrorString(dwReturn, filename, 128); + StopMusic(); + return FALSE; + } + + m_MIDIMusic = rank; + return TRUE; +} + +// Uses MCI to play a CD-audio track. The window procedure +// is notified when playback is complete. +// The rank parameter is in space [1..n] ! +// For CD mix (data/audio), it will be [2..n] ! + +BOOL CSound::PlayAudioTrack(int rank) +{ +#if _SOUNDTRACKS + MCI_OPEN_PARMS mciOpenParms; + MCI_PLAY_PARMS mciPlayParms; + MCI_SET_PARMS mciSetParms; + DWORD dwReturn; + char filename[MAX_PATH]; + char device[10]; + + if ( !m_bEnable ) return TRUE; +//? if ( m_midiVolume == 0 ) return TRUE; + InitAudioTrackVolume(m_midiVolume); + m_lastMidiVolume = m_midiVolume; + + // Open the device by specifying the device and filename. + // MCI will attempt to choose the MIDI mapper as the output port. + memset(&mciOpenParms, 0, sizeof(MCI_OPEN_PARMS)); +//? mciOpenParms.lpstrDeviceType = (LPCTSTR)MCI_DEVTYPE_CD_AUDIO; +//? dwReturn = mciSendCommand(NULL, +//? MCI_OPEN, +//? MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID, +//? (DWORD)(LPVOID)&mciOpenParms); + mciOpenParms.lpstrDeviceType = (LPCTSTR)MCI_DEVTYPE_CD_AUDIO; + if ( m_CDpath[0] == 0 ) + { + dwReturn = mciSendCommand(NULL, + MCI_OPEN, + MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID, + (DWORD)(LPVOID)&mciOpenParms); + } + else + { + device[0] = m_CDpath[0]; + device[1] = ':'; + device[2] = 0; + mciOpenParms.lpstrElementName = device; + dwReturn = mciSendCommand(NULL, + MCI_OPEN, + MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_OPEN_ELEMENT, + (DWORD)(LPVOID)&mciOpenParms); + } + if ( dwReturn != 0 ) + { + mciGetErrorString(dwReturn, filename, 128); + // Failed to open device. Don't close it; just return error. + return FALSE; + } + + // The device opened successfully; get the device ID. + m_MidiDeviceID = mciOpenParms.wDeviceID; + + // Set the time format to track/minute/second/frame (TMSF). + memset(&mciSetParms, 0, sizeof(MCI_SET_PARMS)); + mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF; + dwReturn = mciSendCommand(m_MidiDeviceID, + MCI_SET, + MCI_SET_TIME_FORMAT, + (DWORD)&mciSetParms); + if ( dwReturn != 0 ) + { + mciGetErrorString(dwReturn, filename, 128); + StopMusic(); + return FALSE; + } + + // Begin playback. + memset(&mciPlayParms, 0, sizeof(MCI_PLAY_PARMS)); + mciPlayParms.dwCallback = (DWORD)m_hWnd; + mciPlayParms.dwFrom = MCI_MAKE_TMSF(rank+0, 0, 0, 0); + mciPlayParms.dwTo = MCI_MAKE_TMSF(rank+1, 0, 0, 0); + dwReturn = mciSendCommand(m_MidiDeviceID, + MCI_PLAY, + MCI_NOTIFY|MCI_FROM|MCI_TO, + (DWORD)(LPVOID)&mciPlayParms); + if ( dwReturn != 0 ) + { + mciGetErrorString(dwReturn, filename, 128); + StopMusic(); + return FALSE; + } + + m_MIDIMusic = rank; +#endif + return TRUE; +} + +// Restart the MIDI player. + +BOOL CSound::RestartMusic() +{ + if ( !m_bRepeatMusic ) return FALSE; + + OutputDebugString("RestartMusic\n"); + if ( !m_bEnable ) return TRUE; +//? if ( m_midiVolume == 0 ) return TRUE; + if ( m_MIDIMusic == 0 ) return FALSE; + if ( m_playTime < 5.0f ) return FALSE; + + return PlayMusic(m_MIDIMusic, TRUE); +} + +// Shuts down the MIDI player. + +void CSound::SuspendMusic() +{ + if ( !m_bEnable ) return; + +//? if ( m_MidiDeviceID && m_midiVolume != 0 ) + if ( m_MidiDeviceID ) + { + if ( m_bAudioTrack ) mciSendCommand(m_MidiDeviceID, MCI_STOP, 0, NULL); + mciSendCommand(m_MidiDeviceID, MCI_CLOSE, 0, NULL); + } + m_MidiDeviceID = 0; +} + +// Shuts down the MIDI player. + +void CSound::StopMusic() +{ + SuspendMusic(); + m_MIDIMusic = 0; +} + +// Returns TRUE if the music is in progress. + +BOOL CSound::IsPlayingMusic() +{ + return (m_MIDIMusic != 0); +} + +// Adjusts the volume of currently music, if necessary. + +void CSound::AdaptVolumeMusic() +{ + if ( m_midiVolume != m_lastMidiVolume ) + { + if ( m_bAudioTrack ) + { + InitAudioTrackVolume(m_midiVolume); + } + else + { + InitMidiVolume(m_midiVolume); + } + m_lastMidiVolume = m_midiVolume; + RestartMusic(); + } +} + diff --git a/src/sound/sound.h b/src/sound/sound.h new file mode 100644 index 0000000..16e1be5 --- /dev/null +++ b/src/sound/sound.h @@ -0,0 +1,245 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// sound.h + +#ifndef SOUND_H +#define SOUND_H + + +#include + + +#define MAXFILES 200 +#define MAXSOUND 32 +#define MAXVOLUME 20 +#define MAXOPER 4 + +class CInstanceManager; + + +enum Sound +{ + SOUND_CLICK = 0, + SOUND_BOUM = 1, + SOUND_EXPLO = 2, + SOUND_FLYh = 3, // human + SOUND_FLY = 4, + SOUND_STEPs = 5, // smooth + SOUND_MOTORw = 6, // wheel + SOUND_MOTORt = 7, // tank + SOUND_MOTORr = 8, // roller + SOUND_ERROR = 9, + SOUND_CONVERT = 10, + SOUND_ENERGY = 11, + SOUND_PLOUF = 12, + SOUND_BLUP = 13, + SOUND_WARNING = 14, + SOUND_DERRICK = 15, + SOUND_LABO = 16, + SOUND_STATION = 17, + SOUND_REPAIR = 18, + SOUND_RESEARCH = 19, + SOUND_INSECTs = 20, // spider + SOUND_BURN = 21, + SOUND_TZOING = 22, + SOUND_GGG = 23, + SOUND_MANIP = 24, + SOUND_FIRE = 25, // shooting with fireball + SOUND_HUMAN1 = 26, // breathing + SOUND_STEPw = 27, // water + SOUND_SWIM = 28, + SOUND_RADAR = 29, + SOUND_BUILD = 30, + SOUND_ALARM = 31, // energy alarm + SOUND_SLIDE = 32, + SOUND_EXPLOi = 33, // insect + SOUND_INSECTa = 34, // ant + SOUND_INSECTb = 35, // bee + SOUND_INSECTw = 36, // worm + SOUND_INSECTm = 37, // mother + SOUND_TREMBLE = 38, + SOUND_PSHHH = 39, + SOUND_NUCLEAR = 40, + SOUND_INFO = 41, + SOUND_OPEN = 42, + SOUND_CLOSE = 43, + SOUND_FACTORY = 44, + SOUND_EGG = 45, + SOUND_MOTORs = 46, // submarine + SOUND_MOTORi = 47, // insect (legs) + SOUND_SHIELD = 48, + SOUND_FIREi = 49, // shooting with orgaball (insect) + SOUND_GUNDEL = 50, + SOUND_PSHHH2 = 51, // shield + SOUND_MESSAGE = 52, + SOUND_BOUMm = 53, // metal + SOUND_BOUMv = 54, // plant + SOUND_BOUMs = 55, // smooth + SOUND_EXPLOl = 56, // little + SOUND_EXPLOlp = 57, // little power + SOUND_EXPLOp = 58, // power + SOUND_STEPh = 59, // hard + SOUND_STEPm = 60, // metal + SOUND_POWERON = 61, + SOUND_POWEROFF = 62, + SOUND_AIE = 63, + SOUND_WAYPOINT = 64, + SOUND_RECOVER = 65, + SOUND_DEADi = 66, + SOUND_JOSTLE = 67, + SOUND_GFLAT = 68, + SOUND_DEADg = 69, // shooting death + SOUND_DEADw = 70, // drowning + SOUND_FLYf = 71, // reactor fail + SOUND_ALARMt = 72, // temperature alarm + SOUND_FINDING = 73, // finds a cache object + SOUND_THUMP = 74, + SOUND_TOUCH = 75, + SOUND_BLITZ = 76, + SOUND_MUSHROOM = 77, + SOUND_FIREp = 78, // shooting with phazer + SOUND_EXPLOg1 = 79, // impact gun 1 + SOUND_EXPLOg2 = 80, // impact gun 2 + SOUND_MOTORd = 81, // engine friction +}; + +enum SoundNext +{ + SOPER_CONTINUE = 1, + SOPER_STOP = 2, + SOPER_LOOP = 3, +}; + +typedef struct +{ + char bUsed; + float finalAmplitude; + float finalFrequency; + float totalTime; + float currentTime; + SoundNext nextOper; +} +SoundOper; + +typedef struct +{ + char bUsed; // buffer used? + char bMute; // silence? + Sound type; // SOUND_* + int priority; // so great -> important + D3DVECTOR pos; // position in space + unsigned short uniqueStamp; // unique marker + LPDIRECTSOUNDBUFFER soundBuffer; + LPDIRECTSOUND3DBUFFER soundBuffer3D; + float startAmplitude; + float startFrequency; + float changeFrequency; + int initFrequency; + float volume; // 2D: volume 1..0 depending on position + float pan; // 2D: pan -1..+1 depending on position + SoundOper oper[MAXOPER]; +} +SoundChannel; + + + +class CSound +{ +public: + CSound(CInstanceManager* iMan); + ~CSound(); + + void SetDebugMode(BOOL bMode); + BOOL Create(HWND hWnd, BOOL b3D); + void CacheAll(); + + void SetState(BOOL bState); + BOOL RetEnable(); + + void SetCDpath(char *path); + void SetAudioTrack(BOOL bAudio); + + void SetSound3D(BOOL bMode); + BOOL RetSound3D(); + BOOL RetSound3DCap(); + + void SetAudioVolume(int volume); + int RetAudioVolume(); + void SetMidiVolume(int volume); + int RetMidiVolume(); + + void SetListener(D3DVECTOR eye, D3DVECTOR lookat); + void FrameMove(float rTime); + + int Play(Sound sound, float amplitude=1.0f, float frequency=1.0f, BOOL bLoop=FALSE); + int Play(Sound sound, D3DVECTOR pos, float amplitude=1.0f, float frequency=1.0f, BOOL bLoop=FALSE); + BOOL FlushEnvelope(int channel); + BOOL AddEnvelope(int channel, float amplitude, float frequency, float time, SoundNext oper); + BOOL Position(int channel, D3DVECTOR pos); + BOOL Frequency(int channel, float frequency); + BOOL Stop(int channel); + BOOL StopAll(); + BOOL MuteAll(BOOL bMute); + + BOOL PlayMusic(int rank, BOOL bRepeat); + BOOL RestartMusic(); + void SuspendMusic(); + void StopMusic(); + BOOL IsPlayingMusic(); + void AdaptVolumeMusic(); + +protected: + BOOL CheckChannel(int &channel); + BOOL CreateSoundBuffer(int channel, DWORD size, DWORD freq, DWORD bitsPerSample, DWORD blkAlign, BOOL bStereo); + BOOL ReadData(LPDIRECTSOUNDBUFFER lpDSB, Sound sound, DWORD size); + BOOL CreateBuffer(int channel, Sound sound); + void ComputeVolumePan2D(int channel, const D3DVECTOR &pos); + BOOL ReadFile(Sound sound, char *metaname, char *filename); + int RetPriority(Sound sound); + BOOL SearchFreeBuffer(Sound sound, int &channel, BOOL &bAlreadyLoaded); + void OperNext(int channel); + BOOL PlayAudioTrack(int rank); + +protected: + CInstanceManager* m_iMan; + + HWND m_hWnd; + BOOL m_bEnable; + BOOL m_bState; + BOOL m_bAudioTrack; + BOOL m_ctrl3D; + BOOL m_bDebugMode; + LPDIRECTSOUND m_lpDS; + LPDIRECTSOUND3DLISTENER m_listener; + SoundChannel m_channel[MAXSOUND]; + char* m_files[MAXFILES]; + UINT m_MidiDeviceID; + int m_MIDIMusic; + BOOL m_bRepeatMusic; + int m_audioVolume; + int m_midiVolume; + int m_lastMidiVolume; + D3DVECTOR m_eye; + D3DVECTOR m_lookat; + float m_lastTime; + float m_playTime; + int m_uniqueStamp; + int m_maxSound; + char m_CDpath[100]; +}; + +#endif // SOUND_H diff --git a/src/struct.h b/src/struct.h deleted file mode 100644 index 8b90288..0000000 --- a/src/struct.h +++ /dev/null @@ -1,73 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// struct.h - -#ifndef _STRUCT_H_ -#define _STRUCT_H_ - -#include - - -#define NAN 999999 - -#define D3DFVF_VERTEX2 (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX2) - -struct D3DVERTEX2 -{ - float x,y,z; - float nx,ny,nz; - float tu, tv; - float tu2, tv2; - - D3DVERTEX2() { } - D3DVERTEX2(const D3DVECTOR& _v, const D3DVECTOR& _n, float _tu=0.0f, float _tv=0.0f, float _tu2=0.0f, float _tv2=0.0f) - { - x = _v.x; - y = _v.y; - z = _v.z; - nx = _n.x; - ny = _n.y; - nz = _n.z; - tu = _tu; - tv = _tv; - tu2 = _tu2; - tv2 = _tv2; - } -}; - - -struct FPOINT -{ - float x; - float y; - - FPOINT() { } - FPOINT(float _x, float _y) - { - x = _x; - y = _y; - } -}; - - -struct ColorHSV -{ - float h,s,v; -}; - - -#endif //_STRUCT_H_ diff --git a/src/studio.cpp b/src/studio.cpp deleted file mode 100644 index 8839f31..0000000 --- a/src/studio.cpp +++ /dev/null @@ -1,1667 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// studio.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "language.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "restext.h" -#include "math3d.h" -#include "robotmain.h" -#include "object.h" -#include "camera.h" -#include "sound.h" -#include "script.h" -#include "interface.h" -#include "button.h" -#include "check.h" -#include "slider.h" -#include "edit.h" -#include "list.h" -#include "label.h" -#include "group.h" -#include "window.h" -#include "text.h" -#include "cbottoken.h" -#include "studio.h" - - - - -// Object's constructor. - -CStudio::CStudio(CInstanceManager* iMan) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_STUDIO, this); - - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); - m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - - m_bEditMaximized = FALSE; - m_bEditMinimized = FALSE; - - m_time = 0.0f; - m_bRealTime = TRUE; - m_bRunning = FALSE; - m_fixInfoTextTime = 0.0f; - m_helpFilename[0] = 0; - m_dialog = SD_NULL; -} - -// Object's destructor. - -CStudio::~CStudio() -{ - m_iMan->DeleteInstance(CLASS_STUDIO, this); -} - - -// Management of an event. - -BOOL CStudio::EventProcess(const Event &event) -{ - CWindow* pw; - CEdit* edit; - CSlider* slider; - char res[100]; - - if ( m_dialog != SD_NULL ) // dialogue exists? - { - return EventDialog(event); - } - - if ( event.event == EVENT_FRAME ) - { - EventFrame(event); - } - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw == 0 ) return FALSE; - - edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); - if ( edit == 0 ) return FALSE; - - if ( event.event == pw->RetEventMsgClose() ) - { - Event newEvent = event; - newEvent.event = EVENT_STUDIO_OK; - m_event->AddEvent(newEvent); - } - - if ( event.event == EVENT_STUDIO_EDIT ) // text modifief? - { - ColorizeScript(edit); - } - - if ( event.event == EVENT_STUDIO_LIST ) // list clicked? - { - m_main->StartDisplayInfo(m_helpFilename, -1); - } - - if ( event.event == EVENT_STUDIO_NEW ) // new? - { - m_script->New(edit, ""); - } - - if ( event.event == EVENT_STUDIO_OPEN ) // open? - { - StartDialog(SD_OPEN); - } - if ( event.event == EVENT_STUDIO_SAVE ) // save? - { - StartDialog(SD_SAVE); - } - - if ( event.event == EVENT_STUDIO_UNDO ) // undo? - { - edit->Undo(); - } - if ( event.event == EVENT_STUDIO_CUT ) // cut? - { - edit->Cut(); - } - if ( event.event == EVENT_STUDIO_COPY ) // copy? - { - edit->Copy(); - } - if ( event.event == EVENT_STUDIO_PASTE ) // paste? - { - edit->Paste(); - } - - if ( event.event == EVENT_STUDIO_SIZE ) // size? - { - slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); - if ( slider == 0 ) return FALSE; - m_main->SetFontSize(9.0f+slider->RetVisibleValue()*6.0f); - ViewEditScript(); - } - - if ( event.event == EVENT_STUDIO_TOOL && // instructions? - m_dialog == SD_NULL ) - { - m_main->StartDisplayInfo(SATCOM_HUSTON, FALSE); - } - if ( event.event == EVENT_STUDIO_HELP && // help? - m_dialog == SD_NULL ) - { - m_main->StartDisplayInfo(SATCOM_PROG, FALSE); - } - - if ( event.event == EVENT_STUDIO_COMPILE ) // compile? - { - char buffer[100]; - - if ( m_script->GetScript(edit) ) // compile - { - GetResource(RES_TEXT, RT_STUDIO_COMPOK, res); - SetInfoText(res, FALSE); - } - else - { - m_script->GetError(buffer); - SetInfoText(buffer, FALSE); - } - } - - if ( event.event == EVENT_STUDIO_RUN ) // run/stop? - { - if ( m_script->IsRunning() ) - { - Event newEvent = event; - newEvent.event = EVENT_OBJECT_PROGSTOP; - m_event->AddEvent(newEvent); // stop - } - else - { - if ( m_script->GetScript(edit) ) // compile - { - SetInfoText("", FALSE); - - Event newEvent = event; - newEvent.event = EVENT_OBJECT_PROGSTART; - m_event->AddEvent(newEvent); // start - } - else - { - char buffer[100]; - m_script->GetError(buffer); - SetInfoText(buffer, FALSE); - } - } - } - - if ( event.event == EVENT_STUDIO_REALTIME ) // real time? - { - m_bRealTime = !m_bRealTime; - m_script->SetStepMode(!m_bRealTime); - UpdateFlux(); - UpdateButtons(); - } - - if ( event.event == EVENT_STUDIO_STEP ) // step? - { - m_script->Step(event); - } - - if ( event.event == EVENT_KEYDOWN ) - { - if ( event.param == m_engine->RetKey(KEYRANK_CBOT, 0) || - event.param == m_engine->RetKey(KEYRANK_CBOT, 1) ) - { - if ( m_helpFilename[0] != 0 ) - { - m_main->StartDisplayInfo(m_helpFilename, -1); - } - } - } - - if ( event.event == EVENT_WINDOW3 ) // window is moved? - { - m_editActualPos = m_editFinalPos = pw->RetPos(); - m_editActualDim = m_editFinalDim = pw->RetDim(); - m_main->SetWindowPos(m_editActualPos); - m_main->SetWindowDim(m_editActualDim); - AdjustEditScript(); - } - if ( event.event == pw->RetEventMsgReduce() ) - { - if ( m_bEditMinimized ) - { - m_editFinalPos = m_main->RetWindowPos(); - m_editFinalDim = m_main->RetWindowDim(); - m_bEditMinimized = FALSE; - m_bEditMaximized = FALSE; - } - else - { - m_editFinalPos.x = 0.00f; - m_editFinalPos.y = -0.44f; - m_editFinalDim.x = 1.00f; - m_editFinalDim.y = 0.50f; - m_bEditMinimized = TRUE; - m_bEditMaximized = FALSE; - } - m_main->SetEditFull(m_bEditMaximized); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw != 0 ) - { - pw->SetMaximized(m_bEditMaximized); - pw->SetMinimized(m_bEditMinimized); - } - } - if ( event.event == pw->RetEventMsgFull() ) - { - if ( m_bEditMaximized ) - { - m_editFinalPos = m_main->RetWindowPos(); - m_editFinalDim = m_main->RetWindowDim(); - m_bEditMinimized = FALSE; - m_bEditMaximized = FALSE; - } - else - { - m_editFinalPos.x = 0.00f; - m_editFinalPos.y = 0.00f; - m_editFinalDim.x = 1.00f; - m_editFinalDim.y = 1.00f; - m_bEditMinimized = FALSE; - m_bEditMaximized = TRUE; - } - m_main->SetEditFull(m_bEditMaximized); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw != 0 ) - { - pw->SetMaximized(m_bEditMaximized); - pw->SetMinimized(m_bEditMinimized); - } - } - - return TRUE; -} - - -// Evolves value with time elapsed. - -float Evolution(float final, float actual, float time) -{ - float value; - - value = actual + (final-actual)*time; - - if ( final > actual ) - { - if ( value > final ) value = final; // does not exceed - } - else - { - if ( value < final ) value = final; // does not exceed - } - - return value; -} - -// Makes the studio evolve as time elapsed. - -BOOL CStudio::EventFrame(const Event &event) -{ - CWindow* pw; - CEdit* edit; - CList* list; - float time; - int cursor1, cursor2, iCursor1, iCursor2; - char res[100]; - - m_time += event.rTime; - m_fixInfoTextTime -= event.rTime; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw == 0 ) return FALSE; - - edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); - if ( edit == 0 ) return FALSE; - - list = (CList*)pw->SearchControl(EVENT_STUDIO_LIST); - if ( list == 0 ) return FALSE; - - if ( !m_script->IsRunning() && m_bRunning ) // stop? - { - m_bRunning = FALSE; - UpdateFlux(); // stop - AdjustEditScript(); - GetResource(RES_TEXT, RT_STUDIO_PROGSTOP, res); - SetInfoText(res, FALSE); - - Event newEvent = event; - newEvent.event = EVENT_OBJECT_PROGSTOP; - m_event->AddEvent(newEvent); // stop - } - - if ( m_script->IsRunning() && !m_bRunning ) // starting? - { - m_bRunning = TRUE; - UpdateFlux(); // run - AdjustEditScript(); - } - UpdateButtons(); - - if ( m_bRunning ) - { - m_script->GetCursor(cursor1, cursor2); - edit->GetCursor(iCursor1, iCursor2); - if ( cursor1 != iCursor1 || - cursor2 != iCursor2 ) // cursors change? - { - edit->SetCursor(cursor1, cursor2); // shows it on the execution - edit->ShowSelect(); - } - - m_script->UpdateList(list); // updates the list of variables - } - else - { - SearchToken(edit); - } - - if ( m_editFinalPos.x != m_editActualPos.x || - m_editFinalPos.y != m_editActualPos.y || - m_editFinalDim.x != m_editActualDim.x || - m_editFinalDim.y != m_editActualDim.y ) - { - time = event.rTime*20.0f; - m_editActualPos.x = Evolution(m_editFinalPos.x, m_editActualPos.x, time); - m_editActualPos.y = Evolution(m_editFinalPos.y, m_editActualPos.y, time); - m_editActualDim.x = Evolution(m_editFinalDim.x, m_editActualDim.x, time); - m_editActualDim.y = Evolution(m_editFinalDim.y, m_editActualDim.y, time); - AdjustEditScript(); - } - - return TRUE; -} - - -// Indicates whether a character is part of a word. - -BOOL IsToken(int character) -{ - char c; - - c = tolower(RetNoAccent(character)); - - return ( (c >= 'a' && c <= 'z') || - (c >= '0' && c <= '9') || - c == '_' ); -} - -// Seeks if the cursor is on a keyword. - -void CStudio::SearchToken(CEdit* edit) -{ - ObjectType type; - int len, cursor1, cursor2, i, character, level; - char* text; - char token[100]; - - text = edit->RetText(); - len = edit->RetTextLength(); - edit->GetCursor(cursor1, cursor2); - - i = cursor1; - if ( i > 0 ) - { - character = (unsigned char)text[i-1]; - if ( !IsToken(character) ) - { - level = 1; - while ( i > 0 ) - { - character = (unsigned char)text[i-1]; - if ( character == ')' ) - { - level ++; - } - else if ( character == '(' ) - { - level --; - if ( level == 0 ) break; - } - i --; - } - if ( level > 0 ) - { - m_helpFilename[0] = 0; - SetInfoText("", TRUE); - return; - } - while ( i > 0 ) - { - character = (unsigned char)text[i-1]; - if ( IsToken(character) ) break; - i --; - } - } - } - - while ( i > 0 ) - { - character = (unsigned char)text[i-1]; - if ( !IsToken(character) ) break; - i --; - } - cursor2 = i; - - while ( i < len ) - { - character = (unsigned char)text[i]; - if ( !IsToken(character) ) break; - i ++; - } - cursor1 = i; - len = cursor1-cursor2; - - if ( len > 100-1 ) len = 100-1; - for ( i=0 ; iColorizeScript(edit); -} - - -// Starts editing a program. - -void CStudio::StartEditScript(CScript *script, char* name, int rank) -{ - FPOINT pos, dim; - CWindow* pw; - CEdit* edit; - CButton* button; - CSlider* slider; - CList* list; - char res[100]; - - m_script = script; - m_rank = rank; - - m_main->SetEditLock(TRUE, TRUE); - m_main->SetEditFull(FALSE); - m_bInitPause = m_engine->RetPause(); - m_main->SetSpeed(1.0f); - m_editCamera = m_camera->RetType(); - m_camera->SetType(CAMERA_EDIT); - - m_bRunning = m_script->IsRunning(); - m_bRealTime = m_bRunning; - m_script->SetStepMode(!m_bRealTime); - - button = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); - if ( button != 0 ) - { - button->ClearState(STATE_VISIBLE); - } - - pos = m_editFinalPos = m_editActualPos = m_main->RetWindowPos(); - dim = m_editFinalDim = m_editActualDim = m_main->RetWindowDim(); - pw = m_interface->CreateWindows(pos, dim, 8, EVENT_WINDOW3); - if ( pw == 0 ) return; - pw->SetState(STATE_SHADOW); - pw->SetRedim(TRUE); // before SetName! - pw->SetMovable(TRUE); - pw->SetClosable(TRUE); - GetResource(RES_TEXT, RT_STUDIO_TITLE, res); - pw->SetName(res); - pw->SetMinDim(FPOINT(0.49f, 0.50f)); - pw->SetMaximized(m_bEditMaximized); - pw->SetMinimized(m_bEditMinimized); - m_main->SetEditFull(m_bEditMaximized); - - edit = pw->CreateEdit(pos, dim, 0, EVENT_STUDIO_EDIT); - if ( edit == 0 ) return; - edit->SetState(STATE_SHADOW); - edit->SetInsideScroll(FALSE); -//? if ( m_bRunning ) edit->SetEdit(FALSE); - edit->SetMaxChar(EDITSTUDIOMAX); - edit->SetFontType(FONT_COURIER); - edit->SetFontStretch(0.7f); - edit->SetDisplaySpec(TRUE); - edit->SetAutoIndent(m_engine->RetEditIndentMode()); - m_script->PutScript(edit, name); - ColorizeScript(edit); - - ViewEditScript(); - - list = pw->CreateList(pos, dim, 1, EVENT_STUDIO_LIST, 1.2f); - list->SetState(STATE_SHADOW); - list->SetFontType(FONT_COURIER); - list->SetSelectCap(FALSE); - list->SetFontSize(SMALLFONT*0.85f); -//? list->SetFontStretch(1.0f); - - button = pw->CreateButton(pos, dim, 56, EVENT_STUDIO_NEW); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 57, EVENT_STUDIO_OPEN); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 58, EVENT_STUDIO_SAVE); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 59, EVENT_STUDIO_UNDO); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 60, EVENT_STUDIO_CUT); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 61, EVENT_STUDIO_COPY); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 62, EVENT_STUDIO_PASTE); - button->SetState(STATE_SHADOW); - slider = pw->CreateSlider(pos, dim, 0, EVENT_STUDIO_SIZE); - slider->SetState(STATE_SHADOW); - slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f); - pw->CreateGroup(pos, dim, 19, EVENT_LABEL1); // SatCom logo - button = pw->CreateButton(pos, dim, 128+57, EVENT_STUDIO_TOOL); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 128+60, EVENT_STUDIO_HELP); - button->SetState(STATE_SHADOW); - - button = pw->CreateButton(pos, dim, -1, EVENT_STUDIO_OK); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, -1, EVENT_STUDIO_CANCEL); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 64+23, EVENT_STUDIO_COMPILE); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 21, EVENT_STUDIO_RUN); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 64+22, EVENT_STUDIO_REALTIME); - button->SetState(STATE_SHADOW); - button = pw->CreateButton(pos, dim, 64+29, EVENT_STUDIO_STEP); - button->SetState(STATE_SHADOW); - - UpdateFlux(); - UpdateButtons(); - AdjustEditScript(); -} - -// Repositions all the editing controls. - -void CStudio::AdjustEditScript() -{ - CWindow* pw; - CEdit* edit; - CButton* button; - CGroup* group; - CSlider* slider; - CList* list; - FPOINT wpos, wdim, pos, dim, ppos, ddim; - float hList; - - wpos = m_editActualPos; - wdim = m_editActualDim; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw != 0 ) - { - pw->SetPos(wpos); - pw->SetDim(wdim); - wdim = pw->RetDim(); - } - - if ( m_bRunning ) hList = 80.0f/480.0f; - else hList = 20.0f/480.0f; - - pos.x = wpos.x+0.01f; - pos.y = wpos.y+0.09f+hList; - dim.x = wdim.x-0.02f; - dim.y = wdim.y-0.22f-hList; - edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); - if ( edit != 0 ) - { - edit->SetPos(pos); - edit->SetDim(dim); - } - - pos.x = wpos.x+0.01f; - pos.y = wpos.y+0.09f; - dim.x = wdim.x-0.02f; - dim.y = hList; - list = (CList*)pw->SearchControl(EVENT_STUDIO_LIST); - if ( list != 0 ) - { - list->SetPos(pos); - list->SetDim(dim); - } - - dim.x = 0.04f; - dim.y = 0.04f*1.5f; - dim.y = 25.0f/480.0f; - - pos.y = wpos.y+wdim.y-dim.y-0.06f; - pos.x = wpos.x+0.01f; - button = (CButton*)pw->SearchControl(EVENT_STUDIO_NEW); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x = wpos.x+0.05f; - button = (CButton*)pw->SearchControl(EVENT_STUDIO_OPEN); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x = wpos.x+0.09f; - button = (CButton*)pw->SearchControl(EVENT_STUDIO_SAVE); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x = wpos.x+0.14f; - button = (CButton*)pw->SearchControl(EVENT_STUDIO_UNDO); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x = wpos.x+0.19f; - button = (CButton*)pw->SearchControl(EVENT_STUDIO_CUT); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x = wpos.x+0.23f; - button = (CButton*)pw->SearchControl(EVENT_STUDIO_COPY); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x = wpos.x+0.27f; - button = (CButton*)pw->SearchControl(EVENT_STUDIO_PASTE); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x = wpos.x+0.32f; - slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); - if ( slider != 0 ) - { - ppos = pos; - ddim.x = dim.x*0.7f; - ddim.y = dim.y; - ppos.y -= 3.0f/480.0f; - ddim.y += 6.0f/480.0f; - slider->SetPos(ppos); - slider->SetDim(ddim); - } - pos.x = wpos.x+0.36f; - group = (CGroup*)pw->SearchControl(EVENT_LABEL1); - if ( group != 0 ) - { - group->SetPos(pos); - group->SetDim(dim); - } - pos.x = wpos.x+0.40f; - button = (CButton*)pw->SearchControl(EVENT_STUDIO_TOOL); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x = wpos.x+0.44f; - button = (CButton*)pw->SearchControl(EVENT_STUDIO_HELP); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - - pos.y = wpos.y+0.02f; - pos.x = wpos.x+0.01f; - dim.x = 80.0f/640.0f; - dim.y = 25.0f/480.0f; - button = (CButton*)pw->SearchControl(EVENT_STUDIO_OK); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x = wpos.x+0.14f; - button = (CButton*)pw->SearchControl(EVENT_STUDIO_CANCEL); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x = wpos.x+0.28f; - dim.x = dim.y*0.75f; - button = (CButton*)pw->SearchControl(EVENT_STUDIO_COMPILE); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x = wpos.x+0.28f+dim.x*1; - button = (CButton*)pw->SearchControl(EVENT_STUDIO_RUN); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x = wpos.x+0.28f+dim.x*2; - button = (CButton*)pw->SearchControl(EVENT_STUDIO_REALTIME); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } - pos.x = wpos.x+0.28f+dim.x*3; - button = (CButton*)pw->SearchControl(EVENT_STUDIO_STEP); - if ( button != 0 ) - { - button->SetPos(pos); - button->SetDim(dim); - } -} - -// Ends edition of a program. - -BOOL CStudio::StopEditScript(BOOL bCancel) -{ - CWindow* pw; - CEdit* edit; - CButton* button; - char buffer[100]; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw == 0 ) return FALSE; - - if ( !bCancel && !m_script->IsRunning() ) - { - edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); - if ( edit != 0 ) - { - if ( !m_script->GetScript(edit) ) // compile - { - m_script->GetError(buffer); - SetInfoText(buffer, FALSE); - return FALSE; - } - } - } - m_script->SetStepMode(FALSE); - - m_interface->DeleteControl(EVENT_WINDOW3); - - button = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); - if ( button != 0 ) - { - button->SetState(STATE_VISIBLE); - } - - if ( !m_bInitPause ) m_engine->SetPause(FALSE); - m_sound->MuteAll(FALSE); - m_main->SetEditLock(FALSE, TRUE); - m_camera->SetType(m_editCamera); - return TRUE; -} - -// Specifies the message to display. -// The messages are not clickable 8 seconds, -// even if a message was clickable poster before. - -void CStudio::SetInfoText(char *text, BOOL bClickable) -{ - CWindow* pw; - CList* list; - char res[100]; - - if ( bClickable && m_fixInfoTextTime > 0.0f ) return; - if ( !bClickable ) m_fixInfoTextTime = 8.0f; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw == 0 ) return; - - list = (CList*)pw->SearchControl(EVENT_STUDIO_LIST); - if ( list == 0 ) return; - - list->Flush(); // just text - list->SetName(0, text); - - if ( text[0] == 0 ) bClickable = FALSE; - list->SetSelectCap(bClickable); - - if ( bClickable ) - { - GetResource(RES_TEXT, RT_STUDIO_LISTTT, res); - list->SetTooltip(res); - list->SetState(STATE_ENABLE); - } - else - { - list->SetTooltip(""); -//? list->ClearState(STATE_ENABLE); - list->SetState(STATE_ENABLE, text[0] != 0); - } -} - - -// Changing the size of a editing program. - -void CStudio::ViewEditScript() -{ - CWindow* pw; - CEdit* edit; - POINT dim; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw == 0 ) return; - - edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); - if ( edit == 0 ) return; - - dim = m_engine->RetDim(); - edit->SetFontSize(m_main->RetFontSize()/(dim.x/640.0f)); -} - - -// Updates the operating mode. - -void CStudio::UpdateFlux() -{ - if ( m_bRunning ) - { -#if 1 - if ( m_bRealTime ) // run? - { - m_engine->SetPause(FALSE); - m_sound->MuteAll(FALSE); - } - else // step by step? - { - m_engine->SetPause(TRUE); - m_sound->MuteAll(TRUE); - } -#else - m_engine->SetPause(FALSE); - m_sound->MuteAll(FALSE); -#endif - } - else // stop? - { - m_engine->SetPause(TRUE); - m_sound->MuteAll(TRUE); - } -} - -// Updates the buttons. - -void CStudio::UpdateButtons() -{ - CWindow* pw; - CEdit* edit; - CButton* button; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw == 0 ) return; - - edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); - if ( edit == 0 ) return; - - if ( m_bRunning ) - { - edit->SetIcon(1); // red background - edit->SetEditCap(FALSE); // just to see - edit->SetHiliteCap(TRUE); - } - else - { - edit->SetIcon(0); // standard background - edit->SetEditCap(TRUE); - edit->SetHiliteCap(TRUE); - } - - button = (CButton*)pw->SearchControl(EVENT_STUDIO_COMPILE); - if ( button == 0 ) return; - button->SetState(STATE_ENABLE, !m_bRunning); - - button = (CButton*)pw->SearchControl(EVENT_STUDIO_RUN); - if ( button == 0 ) return; - button->SetIcon(m_bRunning?8:21); // stop/run - - button = (CButton*)pw->SearchControl(EVENT_STUDIO_REALTIME); - if ( button == 0 ) return; - button->SetIcon(m_bRealTime?64+22:64+21); - button->SetState(STATE_ENABLE, (!m_bRunning || !m_script->IsContinue())); - - button = (CButton*)pw->SearchControl(EVENT_STUDIO_STEP); - if ( button == 0 ) return; - button->SetState(STATE_ENABLE, (m_bRunning && !m_bRealTime && !m_script->IsContinue())); -} - - -// Beginning of the display of a dialogue. - -void CStudio::StartDialog(StudioDialog type) -{ - CWindow* pw; - CButton* pb; - CCheck* pc; - CLabel* pla; - CList* pli; - CEdit* pe; - FPOINT pos, dim; - char name[100]; - - m_dialog = type; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW6); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW7); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW8); - if ( pw != 0 ) pw->ClearState(STATE_ENABLE); - - if ( m_dialog == SD_OPEN || - m_dialog == SD_SAVE ) - { - pos = m_main->RetIOPos(); - dim = m_main->RetIODim(); - } -//? pw = m_interface->CreateWindows(pos, dim, 8, EVENT_WINDOW9); - pw = m_interface->CreateWindows(pos, dim, m_dialog==SD_OPEN?14:13, EVENT_WINDOW9); - pw->SetState(STATE_SHADOW); - pw->SetMovable(TRUE); - pw->SetClosable(TRUE); - pw->SetMinDim(FPOINT(320.0f/640.0f, (121.0f+18.0f*4)/480.0f)); - if ( m_dialog == SD_OPEN ) GetResource(RES_TEXT, RT_IO_OPEN, name); - if ( m_dialog == SD_SAVE ) GetResource(RES_TEXT, RT_IO_SAVE, name); - pw->SetName(name); - - pos = FPOINT(0.0f, 0.0f); - dim = FPOINT(0.0f, 0.0f); - - if ( m_dialog == SD_OPEN || - m_dialog == SD_SAVE ) - { - GetResource(RES_TEXT, RT_IO_LIST, name); - pla = pw->CreateLabel(pos, dim, 0, EVENT_DIALOG_LABEL1, name); - pla->SetJustif(1); - - pli = pw->CreateList(pos, dim, 0, EVENT_DIALOG_LIST); - pli->SetState(STATE_SHADOW); - - GetResource(RES_TEXT, RT_IO_NAME, name); - pla = pw->CreateLabel(pos, dim, 0, EVENT_DIALOG_LABEL2, name); - pla->SetJustif(1); - - pe = pw->CreateEdit(pos, dim, 0, EVENT_DIALOG_EDIT); - pe->SetState(STATE_SHADOW); - if ( m_dialog == SD_SAVE ) - { - pe->SetText(m_script->RetFilename()); - } - - GetResource(RES_TEXT, RT_IO_DIR, name); - pla = pw->CreateLabel(pos, dim, 0, EVENT_DIALOG_LABEL3, name); - pla->SetJustif(1); - - pc = pw->CreateCheck(pos, dim, 0, EVENT_DIALOG_CHECK1); - GetResource(RES_TEXT, RT_IO_PRIVATE, name); - pc->SetName(name); - pc->SetState(STATE_SHADOW); -#if _POLISH - pc->SetFontSize(8.0f); -#endif - - pc = pw->CreateCheck(pos, dim, 0, EVENT_DIALOG_CHECK2); - GetResource(RES_TEXT, RT_IO_PUBLIC, name); - pc->SetName(name); - pc->SetState(STATE_SHADOW); -#if _POLISH - pc->SetFontSize(8.0f); -#endif - - pb = pw->CreateButton(pos, dim, -1, EVENT_DIALOG_OK); - pb->SetState(STATE_SHADOW); - if ( m_dialog == SD_OPEN ) GetResource(RES_TEXT, RT_IO_OPEN, name); - if ( m_dialog == SD_SAVE ) GetResource(RES_TEXT, RT_IO_SAVE, name); - pb->SetName(name); - - pb = pw->CreateButton(pos, dim, -1, EVENT_DIALOG_CANCEL); - pb->SetState(STATE_SHADOW); - GetResource(RES_EVENT, EVENT_DIALOG_CANCEL, name); - pb->SetName(name); - - AdjustDialog(); - UpdateDialogList(); - UpdateDialogPublic(); - UpdateDialogAction(); - - pe->SetCursor(999, 0); // selects all - pe->SetFocus(TRUE); - } - - m_main->SetSatComLock(TRUE); // impossible to use the SatCom -} - -// End of the display of a dialogue. - -void CStudio::StopDialog() -{ - CWindow* pw; - - if ( m_dialog == SD_NULL ) return; - m_dialog = SD_NULL; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW6); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW7); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW8); - if ( pw != 0 ) pw->SetState(STATE_ENABLE); - - m_interface->DeleteControl(EVENT_WINDOW9); - m_main->SetSatComLock(FALSE); // possible to use the SatCom -} - -// Adjust all controls of dialogue after a change in geometry. - -void CStudio::AdjustDialog() -{ - CWindow* pw; - CButton* pb; - CCheck* pc; - CLabel* pla; - CList* pli; - CEdit* pe; - FPOINT wpos, wdim, ppos, ddim; - int nli, nch; - char name[100]; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); - if ( pw == 0 ) return; - - wpos = pw->RetPos(); - wdim = pw->RetDim(); - pw->SetPos(wpos); // to move the buttons on the titlebar - - if ( m_dialog == SD_OPEN || - m_dialog == SD_SAVE ) - { - ppos.x = wpos.x+10.0f/640.0f; - ppos.y = wpos.y+wdim.y-55.0f/480.0f; - ddim.x = wdim.x-20.0f/640.0f; - ddim.y = 20.0f/480.0f; - pla = (CLabel*)pw->SearchControl(EVENT_DIALOG_LABEL1); - if ( pla != 0 ) - { - pla->SetPos(ppos); - pla->SetDim(ddim); - } - - nli = (int)((wdim.y-120.0f/480.0f)/(18.0f/480.0f)); - ddim.y = nli*18.0f/480.0f+9.0f/480.0f; - ppos.y = wpos.y+wdim.y-48.0f/480.0f-ddim.y; - pli = (CList*)pw->SearchControl(EVENT_DIALOG_LIST); - if ( pli != 0 ) - { - pli->SetPos(ppos); - pli->SetDim(ddim); - pli->SetTabs(0, ddim.x-(50.0f+130.0f+16.0f)/640.0f); - pli->SetTabs(1, 50.0f/640.0f, -1); - pli->SetTabs(2, 130.0f/640.0f); -//? pli->ShowSelect(); - } - - ppos.y = wpos.y+30.0f/480.0f; - ddim.x = 50.0f/640.0f; - ddim.y = 20.0f/480.0f; - pla = (CLabel*)pw->SearchControl(EVENT_DIALOG_LABEL2); - if ( pla != 0 ) - { - pla->SetPos(ppos); - pla->SetDim(ddim); - } - - ppos.x += 50.0f/640.0f; - ppos.y = wpos.y+36.0f/480.0f; - ddim.x = wdim.x-170.0f/640.0f; - pe = (CEdit*)pw->SearchControl(EVENT_DIALOG_EDIT); - if ( pe != 0 ) - { - pe->SetPos(ppos); - pe->SetDim(ddim); - - nch = (int)((ddim.x*640.0f-22.0f)/8.0f); - pe->GetText(name, 100); - pe->SetMaxChar(nch); - name[nch] = 0; // truncates the text according to max - pe->SetText(name); - } - - ppos.x = wpos.x+10.0f/640.0f; - ppos.y = wpos.y+5.0f/480.0f; - ddim.x = 50.0f/640.0f; - ddim.y = 16.0f/480.0f; - pla = (CLabel*)pw->SearchControl(EVENT_DIALOG_LABEL3); - if ( pla != 0 ) - { - pla->SetPos(ppos); - pla->SetDim(ddim); - } - - ppos.x += 50.0f/640.0f; - ppos.y = wpos.y+12.0f/480.0f; - ddim.x = 70.0f/640.0f; - pc = (CCheck*)pw->SearchControl(EVENT_DIALOG_CHECK1); - if ( pc != 0 ) - { - pc->SetPos(ppos); - pc->SetDim(ddim); - } - - ppos.x += 80.0f/640.0f; - pc = (CCheck*)pw->SearchControl(EVENT_DIALOG_CHECK2); - if ( pc != 0 ) - { - pc->SetPos(ppos); - pc->SetDim(ddim); - } - - ppos.x = wpos.x+wdim.x-100.0f/640.0f; - ppos.y = wpos.y+34.0f/480.0f; - ddim.x = 90.0f/640.0f; - ddim.y = 23.0f/480.0f; - pb = (CButton*)pw->SearchControl(EVENT_DIALOG_OK); - if ( pb != 0 ) - { - pb->SetPos(ppos); - pb->SetDim(ddim); - } - - ppos.y -= 26.0f/480.0f; - pb = (CButton*)pw->SearchControl(EVENT_DIALOG_CANCEL); - if ( pb != 0 ) - { - pb->SetPos(ppos); - pb->SetDim(ddim); - } - } -} - -// Management of the event of a dialogue. - -BOOL CStudio::EventDialog(const Event &event) -{ - CWindow* pw; - FPOINT wpos, wdim; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); - if ( pw == 0 ) return FALSE; - - if ( event.event == EVENT_WINDOW9 ) // window is moved? - { - wpos = pw->RetPos(); - wdim = pw->RetDim(); - m_main->SetIOPos(wpos); - m_main->SetIODim(wdim); - AdjustDialog(); - } - - if ( m_dialog == SD_OPEN || - m_dialog == SD_SAVE ) - { - if ( event.event == EVENT_DIALOG_LIST ) - { - UpdateChangeList(); - } - if ( event.event == EVENT_DIALOG_EDIT ) - { - UpdateChangeEdit(); - } - - if ( event.event == EVENT_DIALOG_CHECK1 ) // private? - { - m_main->SetIOPublic(FALSE); - UpdateDialogPublic(); - UpdateDialogList(); - } - if ( event.event == EVENT_DIALOG_CHECK2 ) // public? - { - m_main->SetIOPublic(TRUE); - UpdateDialogPublic(); - UpdateDialogList(); - } - } - - if ( event.event == EVENT_DIALOG_OK || - (event.event == EVENT_KEYDOWN && event.param == VK_RETURN) ) - { - if ( m_dialog == SD_OPEN ) - { - if ( !ReadProgram() ) return TRUE; - } - if ( m_dialog == SD_SAVE ) - { - if ( !WriteProgram() ) return TRUE; - } - - StopDialog(); - return TRUE; - } - - if ( event.event == EVENT_DIALOG_CANCEL || - (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) || - event.event == pw->RetEventMsgClose() ) - { - StopDialog(); - return TRUE; - } - - return TRUE; -} - -// Updates the name after a click in the list. - -void CStudio::UpdateChangeList() -{ - CWindow* pw; - CList* pl; - CEdit* pe; - char name[100]; - char* p; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_DIALOG_LIST); - if ( pl == 0 ) return; - pe = (CEdit*)pw->SearchControl(EVENT_DIALOG_EDIT); - if ( pe == 0 ) return; - - strcpy(name, pl->RetName(pl->RetSelect())); - name[pe->RetMaxChar()] = 0; // truncates according lg max editable - p = strchr(name, '\t'); // seeks first tab - if ( p != 0 ) *p = 0; - pe->SetText(name); - pe->SetCursor(999, 0); // selects all - pe->SetFocus(TRUE); - - UpdateDialogAction(); -} - -// Updates the list after a change in name. - -void CStudio::UpdateChangeEdit() -{ - CWindow* pw; - CList* pl; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_DIALOG_LIST); - if ( pl == 0 ) return; - - pl->SetSelect(-1); - - UpdateDialogAction(); -} - -// Updates the action button. - -void CStudio::UpdateDialogAction() -{ - CWindow* pw; - CEdit* pe; - CButton* pb; - char name[100]; - int len, i; - BOOL bError; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); - if ( pw == 0 ) return; - pe = (CEdit*)pw->SearchControl(EVENT_DIALOG_EDIT); - if ( pe == 0 ) return; - pb = (CButton*)pw->SearchControl(EVENT_DIALOG_OK); - if ( pb == 0 ) return; - - pe->GetText(name, 100); - len = strlen(name); - if ( len == 0 ) - { - bError = TRUE; - } - else - { - bError = FALSE; - for ( i=0 ; i' || - name[i] == '"' || - name[i] == '|' || - name[i] == '/' || - name[i] == '\\' ) bError = TRUE; - } - } - - pb->SetState(STATE_ENABLE, !bError); -} - -// Updates the buttons private/public. - -void CStudio::UpdateDialogPublic() -{ - CWindow* pw; - CCheck* pc; - CLabel* pl; - char name[100]; - char dir[_MAX_FNAME]; - char text[_MAX_FNAME+100]; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); - if ( pw == 0 ) return; - - pc = (CCheck*)pw->SearchControl(EVENT_DIALOG_CHECK1); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, !m_main->RetIOPublic()); - } - - pc = (CCheck*)pw->SearchControl(EVENT_DIALOG_CHECK2); - if ( pc != 0 ) - { - pc->SetState(STATE_CHECK, m_main->RetIOPublic()); - } - - pl = (CLabel*)pw->SearchControl(EVENT_DIALOG_LABEL1); - if ( pl != 0 ) - { - GetResource(RES_TEXT, RT_IO_LIST, name); - SearchDirectory(dir, FALSE); - sprintf(text, name, dir); - pl->SetName(text, FALSE); - } -} - -// Fills the list with all programs saved. - -void CStudio::UpdateDialogList() -{ - CWindow* pw; - CList* pl; - long hFile; - struct _finddata_t fileBuffer; - struct _finddata_t* listBuffer; - BOOL bDo; - char dir[_MAX_FNAME]; - char temp[_MAX_FNAME]; - int nbFilenames, i; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); - if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_DIALOG_LIST); - if ( pl == 0 ) return; - pl->Flush(); - - nbFilenames = 0; - listBuffer = (_finddata_t*)malloc(sizeof(_finddata_t)*1000); - - SearchDirectory(dir, FALSE); - strcat(dir, "*"); // list all - hFile = _findfirst(dir, &fileBuffer); - if ( hFile != -1 ) - { - do - { - if ( (fileBuffer.attrib & _A_SUBDIR) == 0 ) - { - listBuffer[nbFilenames++] = fileBuffer; - } - } - while ( _findnext(hFile, &fileBuffer) == 0 && nbFilenames < 1000 ); - } - do // sorts all names: - { - bDo = FALSE; - for ( i=0 ; i 0 ) - { - fileBuffer = listBuffer[i]; // exchange i and i +1 - listBuffer[i] = listBuffer[i+1]; - listBuffer[i+1] = fileBuffer; - bDo = TRUE; - } - } - } - while ( bDo ); - - for ( i=0 ; iSetName(i, temp); - } - - free(listBuffer); -} - -// Constructs the name of the folder or open/save. -// If the folder does not exist, it will be created. - -void CStudio::SearchDirectory(char *dir, BOOL bCreate) -{ - if ( m_main->RetIOPublic() ) - { - sprintf(dir, "%s\\", m_main->RetPublicDir()); - } - else - { - sprintf(dir, "%s\\%s\\Program\\", m_main->RetSavegameDir(), m_main->RetGamerName()); - } - - if ( bCreate ) - { - _mkdir(dir); // if does not exist yet! - } -} - -// Reads a new program. - -BOOL CStudio::ReadProgram() -{ - CWindow* pw; - CEdit* pe; - char filename[100]; - char dir[100]; - char* p; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); - if ( pw == 0 ) return FALSE; - - pe = (CEdit*)pw->SearchControl(EVENT_DIALOG_EDIT); - if ( pe == 0 ) return FALSE; - pe->GetText(filename, 100); - if ( filename[0] == 0 ) return FALSE; - - p = strstr(filename, ".txt"); - if ( p == 0 || p != filename+strlen(filename)-4 ) - { - strcat(filename, ".txt"); - } - SearchDirectory(dir, TRUE); - strcat(dir, filename); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw == 0 ) return FALSE; - pe = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); - if ( pe == 0 ) return FALSE; - - if ( !pe->ReadText(dir) ) return FALSE; - - m_script->SetFilename(filename); - ColorizeScript(pe); - return TRUE; -} - -// Writes the current program. - -BOOL CStudio::WriteProgram() -{ - CWindow* pw; - CEdit* pe; - char filename[100]; - char dir[100]; - char* p; - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); - if ( pw == 0 ) return FALSE; - - pe = (CEdit*)pw->SearchControl(EVENT_DIALOG_EDIT); - if ( pe == 0 ) return FALSE; - pe->GetText(filename, 100); - if ( filename[0] == 0 ) return FALSE; - - p = strstr(filename, ".txt"); - if ( p == 0 || p != filename+strlen(filename)-4 ) - { - strcat(filename, ".txt"); - } - SearchDirectory(dir, TRUE); - strcat(dir, filename); - - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); - if ( pw == 0 ) return FALSE; - pe = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); - if ( pe == 0 ) return FALSE; - - if ( !pe->WriteText(dir) ) return FALSE; - - m_script->SetFilename(filename); - return TRUE; -} - diff --git a/src/studio.h b/src/studio.h deleted file mode 100644 index a19bedd..0000000 --- a/src/studio.h +++ /dev/null @@ -1,117 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// studio.h - -#ifndef _STUDIO_H_ -#define _STUDIO_H_ - - -#include "object.h" -#include "script.h" - - -class CInstanceManager; -class CD3DEngine; -class CEvent; -class CRobotMain; -class CCamera; -class CSound; -class CInterface; -class CScript; -class CList; -class CEdit; - - - -enum StudioDialog -{ - SD_NULL, - SD_OPEN, - SD_SAVE, - SD_FIND, - SD_REPLACE, -}; - - - -class CStudio -{ -public: - CStudio(CInstanceManager* iMan); - ~CStudio(); - - BOOL EventProcess(const Event &event); - - void StartEditScript(CScript *script, char* name, int rank); - BOOL StopEditScript(BOOL bCancel); - -protected: - BOOL EventFrame(const Event &event); - void SearchToken(CEdit* edit); - void ColorizeScript(CEdit* edit); - void AdjustEditScript(); - void SetInfoText(char *text, BOOL bClickable); - void ViewEditScript(); - void UpdateFlux(); - void UpdateButtons(); - - void StartDialog(StudioDialog type); - void StopDialog(); - void AdjustDialog(); - BOOL EventDialog(const Event &event); - void UpdateChangeList(); - void UpdateChangeEdit(); - void UpdateDialogAction(); - void UpdateDialogPublic(); - void UpdateDialogList(); - void SearchDirectory(char *dir, BOOL bCreate); - BOOL ReadProgram(); - BOOL WriteProgram(); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CEvent* m_event; - CRobotMain* m_main; - CCamera* m_camera; - CSound* m_sound; - CInterface* m_interface; - - int m_rank; - CScript* m_script; - - BOOL m_bEditMaximized; - BOOL m_bEditMinimized; - - CameraType m_editCamera; - FPOINT m_editActualPos; - FPOINT m_editActualDim; - FPOINT m_editFinalPos; - FPOINT m_editFinalDim; - - float m_time; - float m_fixInfoTextTime; - BOOL m_bRunning; - BOOL m_bRealTime; - BOOL m_bInitPause; - char m_helpFilename[100]; - - StudioDialog m_dialog; -}; - - -#endif //_STUDIO_H_ diff --git a/src/t.txt b/src/t.txt deleted file mode 100644 index 9dd81fb..0000000 --- a/src/t.txt +++ /dev/null @@ -1,11 +0,0 @@ -extern void object::Go() -{ -//float a = energyLevel; -//message(a); - -//object item=energyCell; -//float i = item.energyLevel; -//message(i); -float i = energyCell.energyLevel; - -} diff --git a/src/target.cpp b/src/target.cpp deleted file mode 100644 index 4a6ae43..0000000 --- a/src/target.cpp +++ /dev/null @@ -1,285 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// target.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "robotmain.h" -#include "object.h" -#include "restext.h" -#include "target.h" - - - - -// Object's constructor. - -CTarget::CTarget(CInstanceManager* iMan) : CControl(iMan) -{ -} - -// Object's destructor. - -CTarget::~CTarget() -{ -} - - -// Creates a new button. - -BOOL CTarget::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - CControl::Create(pos, dim, icon, eventMsg); - - return TRUE; -} - - -// Management of an event. - -BOOL CTarget::EventProcess(const Event &event) -{ -#if 0 - if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; - if ( m_state & STATE_DEAD ) return TRUE; - - CControl::EventProcess(event); - - if ( event.event == EVENT_MOUSEMOVE ) - { - if ( CControl::Detect(event.pos) ) - { - m_engine->SetMouseType(D3DMOUSETARGET); - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - return FALSE; - } - } - - if ( event.event == EVENT_LBUTTONDOWN && - (m_state & STATE_VISIBLE) && - (m_state & STATE_ENABLE) ) - { - if ( CControl::Detect(event.pos) ) - { - Event newEvent = event; - newEvent.event = EVENT_OBJECT_FIRE; - m_event->AddEvent(newEvent); - return FALSE; - } - } - - return TRUE; -#else - CObject* pObj; - - if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; - if ( m_state & STATE_DEAD ) return TRUE; - - CControl::EventProcess(event); - - if ( event.event == EVENT_MOUSEMOVE ) - { - m_main->SetFriendAim(FALSE); - - if ( CControl::Detect(event.pos) ) - { - pObj = DetectFriendObject(event.pos); - if ( pObj == 0 ) - { - m_engine->SetMouseType(D3DMOUSETARGET); - - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - return FALSE; - } - else - { - m_main->SetFriendAim(TRUE); - m_engine->SetMouseType(D3DMOUSENORM); - } - } - } - - if ( event.event == EVENT_LBUTTONDOWN && - (m_state & STATE_VISIBLE) && - (m_state & STATE_ENABLE) ) - { - if ( CControl::Detect(event.pos) ) - { - if ( !m_main->RetFriendAim() ) - { - Event newEvent = event; - newEvent.event = EVENT_OBJECT_FIRE; - m_event->AddEvent(newEvent); - return FALSE; - } - } - } - - return TRUE; -#endif -} - - -// Draws button. - -void CTarget::Draw() -{ - // It is completely invisible! -} - - -// Returns the tooltip. - -BOOL CTarget::GetTooltip(FPOINT pos, char* name) -{ -#if 0 - if ( (m_state&STATE_VISIBLE) && Detect(pos) ) // in the window? - { - strcpy(name, m_tooltip); - return TRUE; // does not detect objects below! - } - - return FALSE; -#else -//? CObject* pObj; - - if ( (m_state & STATE_VISIBLE) == 0 ) return FALSE; - - if ( (m_state&STATE_VISIBLE) && Detect(pos) ) // in the window? - { -//? pObj = DetectFriendObject(pos); -//? if ( pObj == 0 ) - if ( !m_main->RetFriendAim() ) - { - strcpy(name, m_tooltip); - return TRUE; // does not detect objects below! - } - } - - return FALSE; -#endif -} - - -// Detects the object aimed by the mouse. - -CObject* CTarget::DetectFriendObject(FPOINT pos) -{ - ObjectType type; - CObject *pObj, *pTarget; - int objRank, i, j, rank; - - objRank = m_engine->DetectObject(pos); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetActif() ) continue; - if ( pObj->RetProxyActivate() ) continue; - if ( pObj->RetSelect() ) continue; - - pTarget = 0; - type = pObj->RetType(); - if ( type == OBJECT_DERRICK || - type == OBJECT_FACTORY || - type == OBJECT_REPAIR || - type == OBJECT_DESTROYER || - type == OBJECT_STATION || - type == OBJECT_CONVERT || - type == OBJECT_TOWER || - type == OBJECT_RESEARCH || - type == OBJECT_RADAR || - type == OBJECT_INFO || - type == OBJECT_ENERGY || - type == OBJECT_LABO || - type == OBJECT_NUCLEAR || - type == OBJECT_PARA || - type == OBJECT_SAFE || - type == OBJECT_HUSTON || - type == OBJECT_HUMAN || - type == OBJECT_TECH || - type == OBJECT_TOTO || - type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs || - type == OBJECT_MOBILEsa || - type == OBJECT_MOBILEft || - type == OBJECT_MOBILEtt || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEit || - type == OBJECT_MOBILEdr ) - { - pTarget = pObj; - } - else if ( (type == OBJECT_POWER || - type == OBJECT_ATOMIC ) && - pObj->RetTruck() != 0 ) // battery used? - { - pTarget = pObj->RetTruck(); - if ( pTarget->RetType() == OBJECT_MOBILEtg ) - { - pTarget = 0; - } - } - - for ( j=0 ; jRetObjectRank(j); - if ( rank == -1 ) continue; - if ( rank != objRank ) continue; - return pTarget; - } - } - return 0; -} - diff --git a/src/target.h b/src/target.h deleted file mode 100644 index 632e411..0000000 --- a/src/target.h +++ /dev/null @@ -1,50 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// target.h - -#ifndef _TARGET_H_ -#define _TARGET_H_ - - -#include "control.h" - - -class CD3DEngine; -class CObject; - - - -class CTarget : public CControl -{ -public: - CTarget(CInstanceManager* iMan); - ~CTarget(); - - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - - BOOL EventProcess(const Event &event); - void Draw(); - BOOL GetTooltip(FPOINT pos, char* name); - -protected: - CObject* DetectFriendObject(FPOINT pos); - -protected: -}; - - -#endif //_TARGET_H_ diff --git a/src/task.cpp b/src/task.cpp deleted file mode 100644 index 6b8222e..0000000 --- a/src/task.cpp +++ /dev/null @@ -1,109 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// task.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "light.h" -#include "particule.h" -#include "terrain.h" -#include "water.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "motion.h" -#include "camera.h" -#include "sound.h" -#include "robotmain.h" -#include "displaytext.h" -#include "task.h" - - - - -// Object's constructor. - -CTask::CTask(CInstanceManager* iMan, CObject* object) -{ - m_iMan = iMan; - - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - - m_object = object; - m_physics = m_object->RetPhysics(); - m_brain = m_object->RetBrain(); - m_motion = m_object->RetMotion(); -} - -// Object's destructor. - -CTask::~CTask() -{ -} - - -// Management of an event. - -BOOL CTask::EventProcess(const Event &event) -{ - return TRUE; -} - - -// Indicates whether the action is finished. - -Error CTask::IsEnded() -{ - return ERR_STOP; -} - - -// Indicates whether the action is pending. - -BOOL CTask::IsBusy() -{ - return TRUE; -} - - -// Suddenly ends the current action. - -BOOL CTask::Abort() -{ - return TRUE; -} - - diff --git a/src/task.h b/src/task.h deleted file mode 100644 index f5685ef..0000000 --- a/src/task.h +++ /dev/null @@ -1,89 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// task.h - -#ifndef _TASK_H_ -#define _TASK_H_ - - -#include "misc.h" - - -class CInstanceManager; -class CD3DEngine; -class CEngine; -class CLight; -class CParticule; -class CTerrain; -class CWater; -class CCamera; -class CBrain; -class CPhysics; -class CMotion; -class CObject; -class CRobotMain; -class CDisplayText; -class CSound; - - -#define TAKE_DIST 6.0f // distance to an object to pick it -#define TAKE_DIST_OTHER 1.5f // additional distance if on friend - -//?#define ARM_NEUTRAL_ANGLE1 155.0f*PI/180.0f -//?#define ARM_NEUTRAL_ANGLE2 -125.0f*PI/180.0f -//?#define ARM_NEUTRAL_ANGLE3 -45.0f*PI/180.0f -#define ARM_NEUTRAL_ANGLE1 110.0f*PI/180.0f -#define ARM_NEUTRAL_ANGLE2 -130.0f*PI/180.0f -#define ARM_NEUTRAL_ANGLE3 -50.0f*PI/180.0f - -#define ARM_STOCK_ANGLE1 110.0f*PI/180.0f -#define ARM_STOCK_ANGLE2 -100.0f*PI/180.0f -#define ARM_STOCK_ANGLE3 -70.0f*PI/180.0f - - -class CTask -{ -public: - CTask(CInstanceManager* iMan, CObject* object); - virtual ~CTask(); - - virtual BOOL EventProcess(const Event &event); - virtual Error IsEnded(); - virtual BOOL IsBusy(); - virtual BOOL Abort(); - -protected: - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CLight* m_light; - CParticule* m_particule; - CTerrain* m_terrain; - CWater* m_water; - CCamera* m_camera; - CMotion* m_motion; - CBrain* m_brain; - CPhysics* m_physics; - CObject* m_object; - CRobotMain* m_main; - CDisplayText* m_displayText; - CSound* m_sound; -}; - - -#endif //_TASK_H_ diff --git a/src/taskadvance.cpp b/src/taskadvance.cpp deleted file mode 100644 index 7860cb2..0000000 --- a/src/taskadvance.cpp +++ /dev/null @@ -1,159 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskadvance.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "task.h" -#include "taskadvance.h" - - - - -// Object's constructor. - -CTaskAdvance::CTaskAdvance(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); -} - -// Object's destructor. - -CTaskAdvance::~CTaskAdvance() -{ -} - - -// Management of an event. - -BOOL CTaskAdvance::EventProcess(const Event &event) -{ - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_fixTime += event.rTime; - - // Momentarily stationary object (ant on the back)? - if ( m_object->RetFixed() ) - { - m_physics->SetMotorSpeedX(0.0f); // stops the advance - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - m_bError = TRUE; - return TRUE; - } - - m_timeLimit -= event.rTime; - return TRUE; -} - - -// Assigns the goal was achieved. - -Error CTaskAdvance::Start(float length) -{ - m_direction = (length>=0.0f)?1.0f:-1.0f; - m_totalLength = Abs(length); - m_advanceLength = m_physics->RetLinLength(length); - m_startPos = m_object->RetPosition(0); - m_lastDist = 0.0f; - m_fixTime = 0.0f; - - m_timeLimit = m_physics->RetLinTimeLength(m_totalLength, m_direction)*3.0f; - if ( m_timeLimit < 2.0f ) m_timeLimit = 2.0f; - - m_physics->SetMotorSpeedX(m_direction*1.0f); // forward/backward - m_physics->SetMotorSpeedY(0.0f); - m_physics->SetMotorSpeedZ(0.0f); - - m_bError = FALSE; - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskAdvance::IsEnded() -{ - D3DVECTOR pos; - float length; - - if ( m_engine->RetPause() ) return ERR_CONTINUE; - - if ( m_bError ) - { - return ERR_STOP; - } - - if ( m_timeLimit < 0.0f ) - { - m_physics->SetMotorSpeedX(0.0f); - return ERR_MOVE_IMPOSSIBLE; - } - - pos = m_object->RetPosition(0); - length = Length2d(pos, m_startPos); - - if ( length > m_lastDist ) // forward? - { - m_fixTime = 0.0f; - } - else // still stands? - { - if ( m_fixTime > 1.0f ) // for more than a second? - { - m_physics->SetMotorSpeedX(0.0f); - return ERR_MOVE_IMPOSSIBLE; - } - } - m_lastDist = length; - - if ( length >= m_totalLength ) - { - m_physics->SetMotorSpeedX(0.0f); - m_physics->SetLinMotionX(MO_CURSPEED, 0.0f); - - if ( length != 0.0f ) - { - pos = m_startPos+((pos-m_startPos)*m_totalLength/length); - m_object->SetPosition(0, pos); - } - return ERR_STOP; - } - - if ( length >= m_advanceLength ) - { - m_physics->SetMotorSpeedX(m_direction*0.1f); - } - return ERR_CONTINUE; -} - - diff --git a/src/taskadvance.h b/src/taskadvance.h deleted file mode 100644 index 284cf12..0000000 --- a/src/taskadvance.h +++ /dev/null @@ -1,59 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskadvance.h - -#ifndef _TASKADVANCE_H_ -#define _TASKADVANCE_H_ - - -#include "misc.h" -#include "d3dengine.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - -class CTaskAdvance : public CTask -{ -public: - CTaskAdvance(CInstanceManager* iMan, CObject* object); - ~CTaskAdvance(); - - BOOL EventProcess(const Event &event); - - Error Start(float length); - Error IsEnded(); - -protected: - -protected: - float m_totalLength; - float m_advanceLength; - float m_direction; - float m_timeLimit; - D3DVECTOR m_startPos; - float m_lastDist; - float m_fixTime; - BOOL m_bError; -}; - - -#endif //_TASKADVANCE_H_ diff --git a/src/taskbuild.cpp b/src/taskbuild.cpp deleted file mode 100644 index cc1303b..0000000 --- a/src/taskbuild.cpp +++ /dev/null @@ -1,822 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskbuild.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "light.h" -#include "particule.h" -#include "terrain.h" -#include "water.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "auto.h" -#include "camera.h" -#include "motion.h" -#include "motionhuman.h" -#include "robotmain.h" -#include "sound.h" -#include "displaytext.h" -#include "task.h" -#include "taskbuild.h" - - - - -// Object's constructor. - -CTaskBuild::CTaskBuild(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - int i; - - CTask::CTask(iMan, object); - - m_type = OBJECT_DERRICK; - m_time = 0.0f; - m_soundChannel = -1; - - for ( i=0 ; iFlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } - - for ( i=0 ; iDeleteLight(m_lightRank[i]); - } -} - - -// Creates a building. - -BOOL CTaskBuild::CreateBuilding(D3DVECTOR pos, float angle) -{ - m_building = new CObject(m_iMan); - if ( !m_building->CreateBuilding(pos, angle, 0.0f, m_type, 0.0f) ) - { - delete m_building; - m_building = 0; - return FALSE; - } - m_building->UpdateMapping(); - m_building->SetLock(TRUE); // not yet usable - - if ( m_type == OBJECT_DERRICK ) m_buildingHeight = 35.0f; - if ( m_type == OBJECT_FACTORY ) m_buildingHeight = 28.0f; - if ( m_type == OBJECT_REPAIR ) m_buildingHeight = 30.0f; - if ( m_type == OBJECT_STATION ) m_buildingHeight = 13.0f; - if ( m_type == OBJECT_CONVERT ) m_buildingHeight = 20.0f; - if ( m_type == OBJECT_TOWER ) m_buildingHeight = 30.0f; - if ( m_type == OBJECT_RESEARCH ) m_buildingHeight = 22.0f; - if ( m_type == OBJECT_RADAR ) m_buildingHeight = 19.0f; - if ( m_type == OBJECT_ENERGY ) m_buildingHeight = 20.0f; - if ( m_type == OBJECT_LABO ) m_buildingHeight = 16.0f; - if ( m_type == OBJECT_NUCLEAR ) m_buildingHeight = 40.0f; - if ( m_type == OBJECT_PARA ) m_buildingHeight = 68.0f; - if ( m_type == OBJECT_INFO ) m_buildingHeight = 19.0f; - m_buildingHeight *= 0.25f; - - m_buildingPos = m_building->RetPosition(0); - m_buildingPos.y -= m_buildingHeight; - m_building->SetPosition(0, m_buildingPos); - return TRUE; -} - -// Creates lights for the effects. - -void CTaskBuild::CreateLight() -{ - D3DLIGHT7 light; - D3DCOLORVALUE color; - D3DVECTOR center, pos, dir; - FPOINT c, p; - float angle; - int i; - - if ( !m_engine->RetLightMode() ) return; - - center = m_metal->RetPosition(0); - - angle = 0; - for ( i=0 ; iCreateLight(); - if ( m_lightRank[i] == -1 ) continue; - - c.x = center.x; - c.y = center.z; - p.x = center.x+40.0f; - p.y = center.z; - p = RotatePoint(c, angle, p); - pos.x = p.x; - pos.z = p.y; - pos.y = center.y+40.0f; - dir = center-pos; - - ZeroMemory( &light, sizeof(light) ); - light.dltType = D3DLIGHT_SPOT; - light.dcvDiffuse.r = 0.0f; - light.dcvDiffuse.g = 0.0f; - light.dcvDiffuse.b = 0.0f; // white (invisible) - light.dvPosition.x = pos.x; - light.dvPosition.y = pos.y; - light.dvPosition.z = pos.z; - light.dvDirection.x = dir.x; - light.dvDirection.y = dir.y; - light.dvDirection.z = dir.z; - light.dvRange = D3DLIGHT_RANGE_MAX; - light.dvFalloff = 1.0f; - light.dvAttenuation0 = 1.0f; - light.dvAttenuation1 = 0.0f; - light.dvAttenuation2 = 0.0f; - light.dvTheta = 0.0f; - light.dvPhi = PI/4.0f; - m_light->SetLight(m_lightRank[i], light); - - color.r = -1.0f; - color.g = -1.0f; - color.b = -0.5f; // violet - color.a = 0.0f; - m_light->SetLightColor(m_lightRank[i], color); - m_light->SetLightColorSpeed(m_lightRank[i], 1.0f/((1.0f/m_speed)*0.25f)); - - angle += (PI*2.0f)/TBMAXLIGHT; - } - - m_bBlack = FALSE; -} - -// Switches the lights from black to white. - -void CTaskBuild::BlackLight() -{ - D3DCOLORVALUE color; - int i; - - for ( i=0 ; iSetLightColor(m_lightRank[i], color); - m_light->SetLightColorSpeed(m_lightRank[i], 1.0f/((1.0f/m_speed)*0.75f)); - } - - m_bBlack = TRUE; -} - -// Management of an event. - -BOOL CTaskBuild::EventProcess(const Event &event) -{ - D3DMATRIX* mat; - D3DVECTOR pos, dir, speed; - FPOINT dim; - float a, g, cirSpeed, dist, linSpeed; - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_bError ) return FALSE; - - m_time += event.rTime; - - m_progress += event.rTime*m_speed; // other advance - - if ( m_phase == TBP_TURN ) // preliminary rotation? - { - a = m_object->RetAngleY(0); - g = m_angleY; - cirSpeed = Direction(a, g)*1.0f; - if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; - if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; - - m_physics->SetMotorSpeedZ(cirSpeed); // turns left/right - return TRUE; - } - - if ( m_phase == TBP_MOVE ) // preliminary forward/backward? - { - dist = Length(m_object->RetPosition(0), m_metal->RetPosition(0)); - linSpeed = 0.0f; - if ( dist > 30.0f ) linSpeed = 1.0f; - if ( dist < 30.0f ) linSpeed = -1.0f; - m_physics->SetMotorSpeedX(linSpeed); // forward/backward - return TRUE; - } - - if ( m_phase == TBP_RECEDE ) // terminal back? - { - m_physics->SetMotorSpeedX(-1.0f); // back - return TRUE; - } - - if ( m_phase == TBP_TAKE ) // takes gun? - { - return TRUE; - } - - if ( m_phase == TBP_PREP ) // prepares? - { - return TRUE; - } - - if ( m_phase == TBP_TERM ) // ends? - { - return TRUE; - } - - if ( !m_bBuild ) // building to build? - { - m_bBuild = TRUE; - - pos = m_metal->RetPosition(0); - a = m_object->RetAngleY(0); - if ( !CreateBuilding(pos, a+PI) ) - { - m_metal->SetLock(FALSE); // usable again - m_motion->SetAction(-1); - m_object->SetObjectParent(14, 0); - m_object->SetPosition(14, D3DVECTOR(-1.5f, 0.3f, -1.35f)); - m_object->SetAngleZ(14, PI); - m_camera->FlushEffect(); - Abort(); - m_bError = TRUE; - m_displayText->DisplayError(ERR_TOOMANY, m_object->RetPosition(0)); - return FALSE; - } - CreateLight(); - } - - pos = m_buildingPos; - pos.y += m_buildingHeight*m_progress; - m_building->SetPosition(0, pos); // the building rises - - m_building->SetZoom(0, m_progress*0.75f+0.25f); - m_metal->SetZoom(0, 1.0f-m_progress); - - a = (2.0f-2.0f*m_progress); - if ( a > 1.0f ) a = 1.0f; - dir.x = (Rand()-0.5f)*a*0.1f; - dir.z = (Rand()-0.5f)*a*0.1f; - dir.y = (Rand()-0.5f)*a*0.1f; - m_building->SetCirVibration(dir); - - if ( !m_bBlack && m_progress >= 0.25f ) - { - BlackLight(); - } - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_metal->RetPosition(0); - speed.x = (Rand()-0.5f)*20.0f; - speed.z = (Rand()-0.5f)*20.0f; - speed.y = Rand()*10.0f; - dim.x = Rand()*6.0f+4.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFIRE); - - pos = D3DVECTOR(0.0f, 0.5f, 0.0f); - mat = m_object->RetWorldMatrix(14); - pos = Transform(*mat, pos); - speed = m_metal->RetPosition(0); - speed.x += (Rand()-0.5f)*5.0f; - speed.z += (Rand()-0.5f)*5.0f; - speed -= pos; - dim.x = 2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ); - - if ( Rand() < 0.3f ) - { - m_sound->Play(SOUND_BUILD, m_object->RetPosition(0), 0.5f, 1.0f*Rand()*1.5f); - } - } - - return TRUE; -} - - -// Assigns the goal was achieved. - -Error CTaskBuild::Start(ObjectType type) -{ - D3DVECTOR pos, speed, pv, pm; - Error err; - float iAngle, oAngle; - - m_type = type; - m_lastParticule = 0.0f; - m_progress = 0.0f; - - iAngle = m_object->RetAngleY(0); - iAngle = NormAngle(iAngle); // 0..2*PI - oAngle = iAngle; - - m_bError = TRUE; // operation impossible - - pos = m_object->RetPosition(0); - if ( pos.y < m_water->RetLevel() ) return ERR_BUILD_WATER; - - if ( !m_physics->RetLand() ) return ERR_BUILD_FLY; - - speed = m_physics->RetMotorSpeed(); - if ( speed.x != 0.0f || - speed.z != 0.0f ) return ERR_BUILD_MOTOR; - - if ( m_object->RetFret() != 0 ) return ERR_MANIP_BUSY; - - m_metal = SearchMetalObject(oAngle, 2.0f, 100.0f, PI*0.25f, err); - if ( err == ERR_BUILD_METALNEAR && m_metal != 0 ) - { - err = FlatFloor(); - if ( err != ERR_OK ) return err; - return ERR_BUILD_METALNEAR; - } - if ( err != ERR_OK ) return err; - - err = FlatFloor(); - if ( err != ERR_OK ) return err; - - m_metal->SetLock(TRUE); // not usable - m_camera->StartCentering(m_object, PI*0.15f, 99.9f, 0.0f, 1.0f); - - m_phase = TBP_TURN; // rotation necessary preliminary - m_angleY = oAngle; // angle was reached - - pv = m_object->RetPosition(0); - pv.y += 8.3f; - pm = m_metal->RetPosition(0); - m_angleZ = RotateAngle(Length2d(pv, pm), Abs(pv.y-pm.y)); - - m_physics->SetFreeze(TRUE); // it does not move - - m_bBuild = FALSE; // not yet built - m_bError = FALSE; // ok - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskBuild::IsEnded() -{ - CAuto* automat; - float angle, dist, time; - - if ( m_engine->RetPause() ) return ERR_CONTINUE; - if ( m_bError ) return ERR_STOP; - - if ( m_phase == TBP_TURN ) // preliminary rotation? - { - angle = m_object->RetAngleY(0); - angle = NormAngle(angle); // 0..2*PI - - if ( TestAngle(angle, m_angleY-PI*0.01f, m_angleY+PI*0.01f) ) - { - m_physics->SetMotorSpeedZ(0.0f); - - dist = Length(m_object->RetPosition(0), m_metal->RetPosition(0)); - if ( dist > 30.0f ) - { - time = m_physics->RetLinTimeLength(dist-30.0f, 1.0f); - m_speed = 1.0f/time; - } - else - { - time = m_physics->RetLinTimeLength(30.0f-dist, -1.0f); - m_speed = 1.0f/time; - } - m_phase = TBP_MOVE; - m_progress = 0.0f; - } - return ERR_CONTINUE; - } - - if ( m_phase == TBP_MOVE ) // preliminary forward/backward? - { - dist = Length(m_object->RetPosition(0), m_metal->RetPosition(0)); - - if ( dist >= 25.0f && dist <= 35.0f ) - { - m_physics->SetMotorSpeedX(0.0f); - m_motion->SetAction(MHS_GUN); // takes gun - - m_phase = TBP_TAKE; - m_speed = 1.0f/1.0f; - m_progress = 0.0f; - } - else - { - if ( m_progress > 1.0f ) // timeout? - { - m_metal->SetLock(FALSE); // usable again - if ( dist < 30.0f ) return ERR_BUILD_METALNEAR; - else return ERR_BUILD_METALAWAY; - } - } - return ERR_CONTINUE; - } - - if ( m_phase == TBP_TAKE ) // takes gun - { - if ( m_progress < 1.0f ) return ERR_CONTINUE; - - m_motion->SetAction(MHS_FIRE); // shooting position - m_object->SetObjectParent(14, 4); - m_object->SetPosition(14, D3DVECTOR(0.6f, 0.1f, 0.3f)); - m_object->SetAngleZ(14, 0.0f); - - m_phase = TBP_PREP; - m_speed = 1.0f/1.0f; - m_progress = 0.0f; - } - - if ( m_phase == TBP_PREP ) // prepares? - { - if ( m_progress < 1.0f ) return ERR_CONTINUE; - - m_soundChannel = m_sound->Play(SOUND_TREMBLE, m_object->RetPosition(0), 0.0f, 1.0f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 0.7f, 1.0f, 1.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.7f, 1.5f, 7.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.5f, 2.0f, SOPER_STOP); - - m_camera->StartEffect(CE_VIBRATION, m_metal->RetPosition(0), 1.0f); - - m_phase = TBP_BUILD; - m_speed = 1.0f/10.f; // duration of 10s - m_progress = 0.0f; - } - - if ( m_phase == TBP_BUILD ) // construction? - { - if ( m_progress < 1.0f ) return ERR_CONTINUE; - - DeleteMark(m_metal->RetPosition(0), 20.0f); - - m_metal->DeleteObject(); // removes the metal - delete m_metal; - m_metal = 0; - - m_building->SetZoom(0, 1.0f); - m_building->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); - m_building->SetLock(FALSE); // building usable - m_main->CreateShortcuts(); - m_displayText->DisplayError(INFO_BUILD, m_buildingPos, 10.0f, 50.0f); - - automat = m_building->RetAuto(); - if ( automat != 0 ) - { - automat->Init(); - } - - m_motion->SetAction(MHS_GUN); // hands gun - m_phase = TBP_TERM; - m_speed = 1.0f/1.0f; - m_progress = 0.0f; - } - - if ( m_phase == TBP_TERM ) // rotation terminale ? - { - if ( m_progress < 1.0f ) return ERR_CONTINUE; - - m_motion->SetAction(-1); - m_object->SetObjectParent(14, 0); - m_object->SetPosition(14, D3DVECTOR(-1.5f, 0.3f, -1.35f)); - m_object->SetAngleZ(14, PI); - - if ( m_type == OBJECT_FACTORY || - m_type == OBJECT_RESEARCH || - m_type == OBJECT_NUCLEAR ) - { - - m_phase = TBP_RECEDE; - m_speed = 1.0f/1.5f; - m_progress = 0.0f; - } - } - - if ( m_phase == TBP_RECEDE ) // back? - { - if ( m_progress < 1.0f ) return ERR_CONTINUE; - - m_physics->SetMotorSpeedX(0.0f); - } - - Abort(); - return ERR_STOP; -} - -// Suddenly ends the current action. - -BOOL CTaskBuild::Abort() -{ - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } - - m_camera->StopCentering(m_object, 2.0f); - m_physics->SetFreeze(FALSE); // is moving again - return TRUE; -} - - -// Checks whether the terrain is fairly flat -// and if there is not too close to another object. - -Error CTaskBuild::FlatFloor() -{ - CObject *pObj; - ObjectType type; - D3DVECTOR center, pos, oPos, bPos; - FPOINT c, p; - float radius, max, oRadius, bRadius, angle, dist; - int i, j; - BOOL bLittleFlat, bBase; - - radius = 0.0f; - if ( m_type == OBJECT_DERRICK ) radius = 5.0f; - if ( m_type == OBJECT_FACTORY ) radius = 15.0f; - if ( m_type == OBJECT_REPAIR ) radius = 12.0f; - if ( m_type == OBJECT_STATION ) radius = 12.0f; - if ( m_type == OBJECT_CONVERT ) radius = 12.0f; - if ( m_type == OBJECT_TOWER ) radius = 7.0f; - if ( m_type == OBJECT_RESEARCH ) radius = 10.0f; - if ( m_type == OBJECT_RADAR ) radius = 5.0f; - if ( m_type == OBJECT_ENERGY ) radius = 8.0f; - if ( m_type == OBJECT_LABO ) radius = 12.0f; - if ( m_type == OBJECT_NUCLEAR ) radius = 20.0f; - if ( m_type == OBJECT_PARA ) radius = 20.0f; - if ( m_type == OBJECT_INFO ) radius = 5.0f; - if ( radius == 0.0f ) return ERR_GENERIC; - - center = m_metal->RetPosition(0); - angle = m_terrain->RetFineSlope(center); - bLittleFlat = ( angle < FLATLIMIT ); - - max = m_terrain->RetFlatZoneRadius(center, radius); - if ( max < radius ) // area too small? - { - if ( bLittleFlat ) - { - m_main->SetShowLimit(1, PARTILIMIT3, m_metal, center, max, 10.0f); - } - return bLittleFlat?ERR_BUILD_FLATLIT:ERR_BUILD_FLAT; - } - - max = 100000.0f; - bBase = FALSE; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetActif() ) continue; // inactive? - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( pObj == m_metal ) continue; - if ( pObj == m_object ) continue; - - type = pObj->RetType(); - if ( type == OBJECT_BASE ) - { - oPos = pObj->RetPosition(0); - dist = Length(center, oPos)-80.0f; - if ( dist < max ) - { - max = dist; - bPos = oPos; - bRadius = oRadius; - bBase = TRUE; - } - } - else - { - j = 0; - while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) - { - dist = Length(center, oPos)-oRadius; - if ( dist < max ) - { - max = dist; - bPos = oPos; - bRadius = oRadius; - bBase = FALSE; - } - } - } - } - if ( max < radius ) - { - m_main->SetShowLimit(1, PARTILIMIT2, m_metal, center, max, 10.0f); - if ( bRadius < 2.0f ) bRadius = 2.0f; - m_main->SetShowLimit(2, PARTILIMIT3, m_metal, bPos, bRadius, 10.0f); - return bBase?ERR_BUILD_BASE:ERR_BUILD_BUSY; - } - - max = 100000.0f; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetActif() ) continue; // inactive? - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( pObj == m_metal ) continue; - if ( pObj == m_object ) continue; - - type = pObj->RetType(); - if ( type == OBJECT_DERRICK || - type == OBJECT_FACTORY || - type == OBJECT_STATION || - type == OBJECT_CONVERT || - type == OBJECT_REPAIR || - type == OBJECT_TOWER || - type == OBJECT_RESEARCH || - type == OBJECT_RADAR || - type == OBJECT_ENERGY || - type == OBJECT_LABO || - type == OBJECT_NUCLEAR || - type == OBJECT_START || - type == OBJECT_END || - type == OBJECT_INFO || - type == OBJECT_PARA || - type == OBJECT_SAFE || - type == OBJECT_HUSTON ) // building? - { - j = 0; - while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) - { - dist = Length(center, oPos)-oRadius; - if ( dist < max ) - { - max = dist; - bPos = oPos; - bRadius = oRadius; - } - } - } - } - if ( max-BUILDMARGIN < radius ) - { - m_main->SetShowLimit(1, PARTILIMIT2, m_metal, center, max-BUILDMARGIN, 10.0f); - m_main->SetShowLimit(2, PARTILIMIT3, m_metal, bPos, bRadius+BUILDMARGIN, 10.0f); - return bBase?ERR_BUILD_BASE:ERR_BUILD_NARROW; - } - - return ERR_OK; -} - -// Seeks the nearest metal object. - -CObject* CTaskBuild::SearchMetalObject(float &angle, float dMin, float dMax, - float aLimit, Error &err) -{ - CObject *pObj, *pBest; - D3DVECTOR iPos, oPos; - ObjectType type; - float min, iAngle, a, aa, aBest, distance, magic; - int i; - BOOL bMetal; - - iPos = m_object->RetPosition(0); - iAngle = m_object->RetAngleY(0); - iAngle = NormAngle(iAngle); // 0..2*PI - - min = 1000000.0f; - pBest = 0; - bMetal = FALSE; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetActif() ) continue; // objet inactive? - if ( pObj->RetTruck() != 0 ) continue; // object transported? - - type = pObj->RetType(); - if ( type != OBJECT_METAL ) continue; - - bMetal = TRUE; // metal exists - - oPos = pObj->RetPosition(0); - distance = Length(oPos, iPos); - a = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW! - - if ( distance > dMax ) continue; - if ( !TestAngle(a, iAngle-aLimit, iAngle+aLimit) ) continue; - - if ( distance < dMin ) - { - err = ERR_BUILD_METALNEAR; // too close - return pObj; - } - - aa = Abs(a-iAngle); - if ( aa > PI ) aa = PI*2.0f-aa; - magic = distance*aa; - - if ( magic < min ) - { - min = magic; - aBest = a; - pBest = pObj; - } - } - - if ( pBest == 0 ) - { - if ( bMetal ) err = ERR_BUILD_METALAWAY; // too far - else err = ERR_BUILD_METALINEX; // non-existent - } - else - { - angle = aBest; - err = ERR_OK; - } - return pBest; -} - -// Destroys all the close marks. - -void CTaskBuild::DeleteMark(D3DVECTOR pos, float radius) -{ - CObject* pObj; - D3DVECTOR oPos; - ObjectType type; - float distance; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type != OBJECT_MARKSTONE && - type != OBJECT_MARKURANIUM && - type != OBJECT_MARKKEYa && - type != OBJECT_MARKKEYb && - type != OBJECT_MARKKEYc && - type != OBJECT_MARKKEYd && - type != OBJECT_MARKPOWER ) continue; - - oPos = pObj->RetPosition(0); - distance = Length(oPos, pos); - if ( distance <= radius ) - { - pObj->DeleteObject(); // removes the mark - delete pObj; - i --; - } - } -} - diff --git a/src/taskbuild.h b/src/taskbuild.h deleted file mode 100644 index 75a44f7..0000000 --- a/src/taskbuild.h +++ /dev/null @@ -1,93 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskbuild.h - -#ifndef _TASKBUILD_H_ -#define _TASKBUILD_H_ - - -#include "misc.h" -#include "object.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; - - - -#define BUILDMARGIN 16.0f -#define TBMAXLIGHT 4 - - -enum TaskBuildPhase -{ - TBP_TURN = 1, // turns - TBP_MOVE = 2, // forward/backward - TBP_TAKE = 3, // takes gun - TBP_PREP = 4, // prepares - TBP_BUILD = 5, // builds - TBP_TERM = 6, // ends - TBP_RECEDE = 7, // back terminal -}; - - - -class CTaskBuild : public CTask -{ -public: - CTaskBuild(CInstanceManager* iMan, CObject* object); - ~CTaskBuild(); - - BOOL EventProcess(const Event &event); - - Error Start(ObjectType type); - Error IsEnded(); - BOOL Abort(); - -protected: - Error FlatFloor(); - BOOL CreateBuilding(D3DVECTOR pos, float angle); - void CreateLight(); - void BlackLight(); - CObject* SearchMetalObject(float &angle, float dMin, float dMax, float aLimit, Error &err); - void DeleteMark(D3DVECTOR pos, float radius); - -protected: - ObjectType m_type; // type of construction - CObject* m_metal; // transforms metal object - CObject* m_power; // the vehicle battery - CObject* m_building; // building built - TaskBuildPhase m_phase; // phase of the operation - BOOL m_bError; // TRUE -> operation impossible - BOOL m_bBuild; // TRUE -> building built - BOOL m_bBlack; // TRUE -> lights black -> white - float m_time; // absolute time - float m_lastParticule; // time of generation last particle - float m_progress; // progression (0..1) - float m_speed; // speed of progression - float m_angleY; // rotation angle of the vehicle - float m_angleZ; // angle of rotation of the gun - D3DVECTOR m_buildingPos; // initial position of the building - float m_buildingHeight; // height of the building - int m_lightRank[TBMAXLIGHT];// lights for the effects - int m_soundChannel; -}; - - -#endif //_TASKBUILD_H_ diff --git a/src/taskfire.cpp b/src/taskfire.cpp deleted file mode 100644 index 4fc0af5..0000000 --- a/src/taskfire.cpp +++ /dev/null @@ -1,398 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskfire.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "sound.h" -#include "task.h" -#include "taskfire.h" - - - -#define ENERGY_FIRE (0.25f/2.5f) // energy consumed/shot -#define ENERGY_FIREr (0.25f/1.5f) // energy consumed/ray -#define ENERGY_FIREi (0.10f/2.5f) // energy consumed/organic - - -// Object's constructor. - -CTaskFire::CTaskFire(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); - m_soundChannel = -1; -} - -// Object's destructor. - -CTaskFire::~CTaskFire() -{ - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } -} - - -// Management of an event. - -BOOL CTaskFire::EventProcess(const Event &event) -{ - CObject* power; - CPhysics* physics; - D3DMATRIX* mat; - D3DVECTOR pos, speed, dir, vib; - ObjectType type; - FPOINT dim; - float energy, fire; - int i, channel; - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_bError ) return FALSE; - - m_time += event.rTime; - m_lastSound -= event.rTime; - m_progress += event.rTime*m_speed; - - power = m_object->RetPower(); - if ( power != 0 ) - { - energy = power->RetEnergy(); - if ( m_bOrganic ) fire = ENERGY_FIREi; - else if ( m_bRay ) fire = ENERGY_FIREr; - else fire = ENERGY_FIRE; - energy -= event.rTime*fire/power->RetCapacity(); - power->SetEnergy(energy); - } - - if ( m_lastParticule+0.05f <= m_time ) - { - m_lastParticule = m_time; - - if ( m_bOrganic ) - { - mat = m_object->RetWorldMatrix(1); // insect-cannon - - for ( i=0 ; i<6 ; i++ ) - { - pos = D3DVECTOR(0.0f, 2.5f, 0.0f); - pos = Transform(*mat, pos); - - speed = D3DVECTOR(200.0f, 0.0f, 0.0f); - - physics = m_object->RetPhysics(); - if ( physics != 0 ) - { - speed += physics->RetLinMotion(MO_REASPEED); - } - - speed.x += (Rand()-0.5f)*10.0f; - speed.y += (Rand()-0.5f)*20.0f; - speed.z += (Rand()-0.5f)*30.0f; - speed = Transform(*mat, speed); - speed -= pos; - - dim.x = Rand()*0.5f+0.5f; - dim.y = dim.x; - - channel = m_particule->CreateParticule(pos, speed, dim, PARTIGUN4, 0.8f, 0.0f, 0.0f); - m_particule->SetObjectFather(channel, m_object); - } - } - else if ( m_bRay ) - { - mat = m_object->RetWorldMatrix(2); // cannon - - for ( i=0 ; i<4 ; i++ ) - { - pos = D3DVECTOR(4.0f, 0.0f, 0.0f); - pos.y += (rand()%3-1)*1.5f; - pos.z += (rand()%3-1)*1.5f; - pos = Transform(*mat, pos); - - speed = D3DVECTOR(200.0f, 0.0f, 0.0f); - speed.x += (Rand()-0.5f)*6.0f; - speed.y += (Rand()-0.5f)*12.0f; - speed.z += (Rand()-0.5f)*12.0f; - speed = Transform(*mat, speed); - speed -= pos; - - dim.x = 1.0f; - dim.y = dim.x; - channel = m_particule->CreateTrack(pos, speed, dim, PARTITRACK11, - 2.0f, 200.0f, 0.5f, 1.0f); - m_particule->SetObjectFather(channel, m_object); - - speed = D3DVECTOR(5.0f, 0.0f, 0.0f); - speed.x += (Rand()-0.5f)*1.0f; - speed.y += (Rand()-0.5f)*2.0f; - speed.z += (Rand()-0.5f)*2.0f; - speed = Transform(*mat, speed); - speed -= pos; - speed.y += 5.0f; - - dim.x = 2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE2, 2.0f, 0.0f, 0.5f); - } - } - else - { - type = m_object->RetType(); - - if ( type == OBJECT_MOBILErc ) - { - mat = m_object->RetWorldMatrix(2); // cannon - } - else - { - mat = m_object->RetWorldMatrix(1); // cannon - } - - for ( i=0 ; i<3 ; i++ ) - { - if ( type == OBJECT_MOBILErc ) - { - pos = D3DVECTOR(0.0f, 0.0f, 0.0f); - } - else - { - pos = D3DVECTOR(3.0f, 1.0f, 0.0f); - } - pos.y += (Rand()-0.5f)*1.0f; - pos.z += (Rand()-0.5f)*1.0f; - pos = Transform(*mat, pos); - - speed = D3DVECTOR(200.0f, 0.0f, 0.0f); - - physics = m_object->RetPhysics(); - if ( physics != 0 ) - { - speed += physics->RetLinMotion(MO_REASPEED); - } - - speed.x += (Rand()-0.5f)*3.0f; - speed.y += (Rand()-0.5f)*6.0f; - speed.z += (Rand()-0.5f)*6.0f; - speed = Transform(*mat, speed); - speed -= pos; - - dim.x = Rand()*0.7f+0.7f; - dim.y = dim.x; - - channel = m_particule->CreateParticule(pos, speed, dim, PARTIGUN1, 0.8f, 0.0f, 0.0f); - m_particule->SetObjectFather(channel, m_object); - } - - if ( type != OBJECT_MOBILErc && - m_progress > 0.3f ) - { - pos = D3DVECTOR(-1.0f, 1.0f, 0.0f); - pos.y += (Rand()-0.5f)*0.4f; - pos.z += (Rand()-0.5f)*0.4f; - pos = Transform(*mat, pos); - - speed = D3DVECTOR(-4.0f, 0.0f, 0.0f); - speed.x += (Rand()-0.5f)*2.0f; - speed.y += (Rand()-0.2f)*4.0f; - speed.z += (Rand()-0.5f)*4.0f; - speed = Transform(*mat, speed); - speed -= pos; - - dim.x = Rand()*1.2f+1.2f; - dim.y = dim.x; - - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.0f); -//? m_particule->CreateParticule(pos, speed, dim, PARTISMOKE2, 4.0f, 0.0f, 0.0f); - } - } - - dir = D3DVECTOR(0.0f, 0.0f, 0.0f); - if ( m_progress < 0.1f ) - { - dir.z = (PI*0.04f)*(m_progress*10.0f); - } - else if ( m_progress < 0.9f ) - { - dir.z = (PI*0.04f); - } - else - { - dir.z = (PI*0.04f)*(1.0f-(m_progress-0.9f)*10.0f); - } - m_object->SetInclinaison(dir); - - vib.x = (Rand()-0.5f)*0.01f; - vib.y = (Rand()-0.5f)*0.02f; - vib.z = (Rand()-0.5f)*0.02f; - m_object->SetCirVibration(vib); - - vib.x = (Rand()-0.5f)*0.20f; - vib.y = (Rand()-0.5f)*0.05f; - vib.z = (Rand()-0.5f)*0.20f; - m_object->SetLinVibration(vib); - } - - if ( m_bRay && m_lastSound <= 0.0f ) - { - m_lastSound = Rand()*0.4f+0.4f; - m_sound->Play(SOUND_FIREp, m_object->RetPosition(0)); - } - - return TRUE; -} - - -// Assigns the goal was achieved. - -Error CTaskFire::Start(float delay) -{ - CObject* power; - D3DVECTOR pos, goal, speed; - float energy, fire; - ObjectType type; - - m_bError = TRUE; // operation impossible - - type = m_object->RetType(); - if ( type != OBJECT_MOBILEfc && - type != OBJECT_MOBILEtc && - type != OBJECT_MOBILEwc && - type != OBJECT_MOBILEic && - type != OBJECT_MOBILEfi && - type != OBJECT_MOBILEti && - type != OBJECT_MOBILEwi && - type != OBJECT_MOBILEii && - type != OBJECT_MOBILErc ) return ERR_FIRE_VEH; - -//? if ( !m_physics->RetLand() ) return ERR_FIRE_FLY; - - speed = m_physics->RetMotorSpeed(); -//? if ( speed.x != 0.0f || -//? speed.z != 0.0f ) return ERR_FIRE_MOTOR; - - m_bRay = (type == OBJECT_MOBILErc); - - m_bOrganic = FALSE; - if ( type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii ) - { - m_bOrganic = TRUE; - } - - if ( delay == 0.0f ) - { - if ( m_bRay ) delay = 1.2f; - else delay = 2.0f; - } - m_delay = delay; - - power = m_object->RetPower(); - if ( power == 0 ) return ERR_FIRE_ENERGY; - energy = power->RetEnergy(); - if ( m_bOrganic ) fire = m_delay*ENERGY_FIREi; - else if ( m_bRay ) fire = m_delay*ENERGY_FIREr; - else fire = m_delay*ENERGY_FIRE; - if ( energy < fire/power->RetCapacity()+0.05f ) return ERR_FIRE_ENERGY; - - m_speed = 1.0f/m_delay; - m_progress = 0.0f; - m_time = 0.0f; - m_lastParticule = 0.0f; - m_lastSound = 0.0f; - m_bError = FALSE; // ok - -//? m_camera->StartCentering(m_object, PI*0.15f, 99.9f, 0.0f, 1.0f); - - if ( m_bOrganic ) - { - m_soundChannel = m_sound->Play(SOUND_FIREi, m_object->RetPosition(0), 1.0f, 1.0f, TRUE); - if ( m_soundChannel != -1 ) - { - m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, m_delay, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 0.5f, SOPER_STOP); - } - } - else if ( m_bRay ) - { - } - else - { - m_soundChannel = m_sound->Play(SOUND_FIRE, m_object->RetPosition(0), 1.0f, 1.0f, TRUE); - if ( m_soundChannel != -1 ) - { - m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, m_delay, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 0.5f, SOPER_STOP); - } - } - - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskFire::IsEnded() -{ - if ( m_engine->RetPause() ) return ERR_CONTINUE; - if ( m_bError ) return ERR_STOP; - if ( m_progress < 1.0f ) return ERR_CONTINUE; - - Abort(); - return ERR_STOP; -} - -// Suddenly ends the current action. - -BOOL CTaskFire::Abort() -{ - m_object->SetInclinaison(D3DVECTOR(0.0f, 0.0f, 0.0f)); - m_object->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); - m_object->SetLinVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); - - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } - -//? m_camera->StopCentering(m_object, 1.0f); - return TRUE; -} - diff --git a/src/taskfire.h b/src/taskfire.h deleted file mode 100644 index af371b2..0000000 --- a/src/taskfire.h +++ /dev/null @@ -1,61 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskfire.h - -#ifndef _TASKFIRE_H_ -#define _TASKTIRE_H_ - - -#include "misc.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - -class CTaskFire : public CTask -{ -public: - CTaskFire(CInstanceManager* iMan, CObject* object); - ~CTaskFire(); - - BOOL EventProcess(const Event &event); - - Error Start(float delay); - Error IsEnded(); - BOOL Abort(); - -protected: - -protected: - float m_delay; - float m_progress; - BOOL m_bError; - BOOL m_bRay; - BOOL m_bOrganic; - float m_time; - float m_speed; - float m_lastParticule; - float m_lastSound; - int m_soundChannel; -}; - - -#endif //_TASKFIRE_H_ diff --git a/src/taskfireant.cpp b/src/taskfireant.cpp deleted file mode 100644 index 2c47adf..0000000 --- a/src/taskfireant.cpp +++ /dev/null @@ -1,227 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskfireant.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "motion.h" -#include "motionant.h" -#include "task.h" -#include "taskfireant.h" - - - - -// Object's constructor. - -CTaskFireAnt::CTaskFireAnt(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); - - m_phase = TFA_NULL; -} - -// Object's destructor. - -CTaskFireAnt::~CTaskFireAnt() -{ -} - - -// Management of an event. - -BOOL CTaskFireAnt::EventProcess(const Event &event) -{ - D3DVECTOR dir, vib; - float a, g, cirSpeed; - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_bError ) return FALSE; - - if ( m_object->RetFixed() ) // insect on its back? - { - m_bError = TRUE; - return FALSE; - } - - m_time += event.rTime; - m_progress += event.rTime*m_speed; - - if ( m_phase == TFA_TURN ) // preliminary rotation? - { - a = m_object->RetAngleY(0); - g = m_angle; - cirSpeed = Direction(a, g)*2.0f; - if ( cirSpeed > 2.0f ) cirSpeed = 2.0f; - if ( cirSpeed < -2.0f ) cirSpeed = -2.0f; - - m_physics->SetMotorSpeedZ(cirSpeed); // turns left/right - } - - return TRUE; -} - - -// Assigns the goal was achieved. - -Error CTaskFireAnt::Start(D3DVECTOR impact) -{ - D3DVECTOR pos; - ObjectType type; - - m_impact = impact; - - m_bError = TRUE; // operation impossible - if ( !m_physics->RetLand() ) return ERR_FIRE_VEH; - - type = m_object->RetType(); - if ( type != OBJECT_ANT ) return ERR_FIRE_VEH; - - // Insect on its back? - if ( m_object->RetFixed() ) return ERR_FIRE_VEH; - - m_physics->SetMotorSpeed(D3DVECTOR(0.0f, 0.0f, 0.0f)); - - pos = m_object->RetPosition(0); - m_angle = RotateAngle(m_impact.x-pos.x, pos.z-m_impact.z); // CW ! - - m_phase = TFA_TURN; - m_speed = 1.0f/1.0f; - m_progress = 0.0f; - m_time = 0.0f; - m_lastParticule = 0.0f; - m_bError = FALSE; // ok - m_bFire = FALSE; // once! - - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskFireAnt::IsEnded() -{ - D3DMATRIX* mat; - D3DVECTOR pos, speed; - FPOINT dim; - float angle, dist; - int i, channel; - - if ( m_engine->RetPause() ) return ERR_CONTINUE; - if ( m_bError ) return ERR_STOP; - if ( m_object->RetFixed() ) return ERR_STOP; // insect on its back? - - if ( m_phase == TFA_TURN ) // rotation ? - { - angle = m_object->RetAngleY(0); - angle = NormAngle(angle); // 0..2*PI - if ( !TestAngle(angle, m_angle-PI*0.05f, m_angle+PI*0.05f) ) return ERR_CONTINUE; - - m_physics->SetMotorSpeedZ(0.0f); // rotation ended - - m_phase = TFA_PREPARE; -//? m_speed = 1.0f/1.5f; - m_speed = 1.0f/0.4f; - m_progress = 0.0f; -//? m_motion->SetAction(MAS_PREPARE, 1.5f); - m_motion->SetAction(MAS_PREPARE, 0.4f); - } - - if ( m_phase == TFA_PREPARE ) // preparation? - { - if ( m_progress < 1.0f ) return ERR_CONTINUE; - - m_phase = TFA_FIRE; -//? m_speed = 1.0f/2.0f; - m_speed = 1.0f/0.5f; - m_progress = 0.0f; -//? m_motion->SetAction(MAS_FIRE, 2.0f); - m_motion->SetAction(MAS_FIRE, 0.5f); - } - - if ( m_phase == TFA_FIRE ) // shooting? - { - if ( m_progress > 0.75f && !m_bFire ) - { - m_bFire = TRUE; // once - - for ( i=0 ; i<20 ; i++ ) - { - pos = D3DVECTOR(-2.5f, -0.7f, 0.0f); - mat = m_object->RetWorldMatrix(2); - pos = Transform(*mat, pos); - dist = Length(pos, m_impact); - speed = m_impact-pos; - speed.x += (Rand()-0.5f)*dist*1.2f; - speed.y += (Rand()-0.5f)*dist*0.4f+50.0f; - speed.z += (Rand()-0.5f)*dist*1.2f; - dim.x = 1.0f; - dim.y = dim.x; - channel = m_particule->CreateParticule(pos, speed, dim, PARTIGUN2, 2.0f, 100.0f, 0.0f); - m_particule->SetObjectFather(channel, m_object); - } - } - - if ( m_progress < 1.0f ) return ERR_CONTINUE; - - m_phase = TFA_TERMINATE; -//? m_speed = 1.0f/0.9f; - m_speed = 1.0f/0.4f; - m_progress = 0.0f; -//? m_motion->SetAction(MAS_TERMINATE, 0.9f); - m_motion->SetAction(MAS_TERMINATE, 0.4f); - } - - if ( m_phase == TFA_TERMINATE ) // ends? - { - if ( m_progress < 1.0f ) return ERR_CONTINUE; - - m_phase = TFA_NULL; - m_speed = 1.0f/1.0f; - m_progress = 0.0f; - } - - Abort(); - return ERR_STOP; -} - - -// Suddenly ends the current action. - -BOOL CTaskFireAnt::Abort() -{ - m_motion->SetAction(-1); - return TRUE; -} - diff --git a/src/taskfireant.h b/src/taskfireant.h deleted file mode 100644 index 2504241..0000000 --- a/src/taskfireant.h +++ /dev/null @@ -1,72 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskfireant.h - -#ifndef _TASKFIREANT_H_ -#define _TASKTIREANT_H_ - - -#include "d3dengine.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - - -enum TaskFireAnt -{ - TFA_NULL = 0, // nothing to do - TFA_TURN = 1, // turns - TFA_PREPARE = 2, // prepares shooting position - TFA_FIRE = 3, // shooting - TFA_TERMINATE = 4, // ends shooting position -}; - - - -class CTaskFireAnt : public CTask -{ -public: - CTaskFireAnt(CInstanceManager* iMan, CObject* object); - ~CTaskFireAnt(); - - BOOL EventProcess(const Event &event); - - Error Start(D3DVECTOR impact); - Error IsEnded(); - BOOL Abort(); - -protected: - -protected: - D3DVECTOR m_impact; - TaskFireAnt m_phase; - float m_progress; - float m_speed; - float m_angle; - BOOL m_bError; - BOOL m_bFire; - float m_time; - float m_lastParticule; -}; - - -#endif //_TASKFIREANT_H_ diff --git a/src/taskflag.cpp b/src/taskflag.cpp deleted file mode 100644 index b965d08..0000000 --- a/src/taskflag.cpp +++ /dev/null @@ -1,321 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskflag.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "terrain.h" -#include "water.h" -#include "object.h" -#include "pyro.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "motion.h" -#include "motionhuman.h" -#include "sound.h" -#include "task.h" -#include "taskflag.h" - - - - - -// Object's constructor. - -CTaskFlag::CTaskFlag(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); -} - -// Object's destructor. - -CTaskFlag::~CTaskFlag() -{ -} - - -// Management of an event. - -BOOL CTaskFlag::EventProcess(const Event &event) -{ - if ( m_bError ) return TRUE; - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_time += event.rTime; - - return TRUE; -} - - - -// Assigns the goal was achieved. - -Error CTaskFlag::Start(TaskFlagOrder order, int rank) -{ - D3DVECTOR pos, speed; - Error err; - - m_order = order; - m_time = 0.0f; - - m_bError = TRUE; // operation impossible - if ( !m_physics->RetLand() ) - { - pos = m_object->RetPosition(0); - if ( pos.y < m_water->RetLevel() ) return ERR_FLAG_WATER; - return ERR_FLAG_FLY; - } - - speed = m_physics->RetMotorSpeed(); - if ( speed.x != 0.0f || - speed.z != 0.0f ) return ERR_FLAG_MOTOR; - - if ( m_object->RetFret() != 0 ) return ERR_FLAG_BUSY; - - if ( order == TFL_CREATE ) - { - err = CreateFlag(rank); - if ( err != ERR_OK ) return err; - } - - if ( order == TFL_DELETE ) - { - err = DeleteFlag(); - if ( err != ERR_OK ) return err; - } - - m_bError = FALSE; - - m_motion->SetAction(MHS_FLAG); // sets/removes flag - m_camera->StartCentering(m_object, PI*0.3f, 99.9f, 0.0f, 0.5f); - - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskFlag::IsEnded() -{ - if ( m_engine->RetPause() ) return ERR_CONTINUE; - - if ( m_bError ) return ERR_STOP; - if ( m_time < 2.0f ) return ERR_CONTINUE; - - Abort(); - return ERR_STOP; -} - -// Suddenly ends the current action. - -BOOL CTaskFlag::Abort() -{ - m_motion->SetAction(-1); - m_camera->StopCentering(m_object, 2.0f); - return TRUE; -} - - - -// Returns the closest object to a given position. - -CObject* CTaskFlag::SearchNearest(D3DVECTOR pos, ObjectType type) -{ - ObjectType oType; - CObject *pObj, *pBest; - D3DVECTOR oPos; - float min, dist; - int i; - - min = 100000.0f; - pBest = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetEnable() ) continue; - - oType = pObj->RetType(); - if ( type == OBJECT_NULL ) - { - if ( oType != OBJECT_FLAGb && - oType != OBJECT_FLAGr && - oType != OBJECT_FLAGg && - oType != OBJECT_FLAGy && - oType != OBJECT_FLAGv ) continue; - } - else - { - if ( oType != type ) continue; - } - - oPos = pObj->RetPosition(0); - dist = Length2d(oPos, pos); - if ( dist < min ) - { - min = dist; - pBest = pObj; - } - } - return pBest; -} - -// Counts the number of existing objects. - -int CTaskFlag::CountObject(ObjectType type) -{ - ObjectType oType; - CObject *pObj; - D3DVECTOR oPos; - int i, count; - - count = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetEnable() ) continue; - - oType = pObj->RetType(); - if ( type == OBJECT_NULL ) - { - if ( oType != OBJECT_FLAGb && - oType != OBJECT_FLAGr && - oType != OBJECT_FLAGg && - oType != OBJECT_FLAGy && - oType != OBJECT_FLAGv ) continue; - } - else - { - if ( oType != type ) continue; - } - - count ++; - } - return count; -} - -// Creates a color indicator. - -Error CTaskFlag::CreateFlag(int rank) -{ - CObject* pObj; - CObject* pNew; - CPyro* pyro; - D3DMATRIX* mat; - D3DVECTOR pos; - float dist; - int i; - - ObjectType table[5] = - { - OBJECT_FLAGb, - OBJECT_FLAGr, - OBJECT_FLAGg, - OBJECT_FLAGy, - OBJECT_FLAGv, - }; - - mat = m_object->RetWorldMatrix(0); - pos = Transform(*mat, D3DVECTOR(4.0f, 0.0f, 0.0f)); - - pObj = SearchNearest(pos, OBJECT_NULL); - if ( pObj != 0 ) - { - dist = Length(pos, pObj->RetPosition(0)); - if ( dist < 10.0f ) - { - return ERR_FLAG_PROXY; - } - } - - i = rank; - if ( CountObject(table[i]) >= 5 ) - { - return ERR_FLAG_CREATE; - } - - pNew = new CObject(m_iMan); - if ( !pNew->CreateFlag(pos, 0.0f, table[i]) ) - { - delete pNew; - return ERR_TOOMANY; - } - pNew->SetZoom(0, 0.0f); - - m_sound->Play(SOUND_WAYPOINT, pos); - pyro = new CPyro(m_iMan); - pyro->Create(PT_FLCREATE, pNew); - - return ERR_OK; -} - -// Deletes a color indicator. - -Error CTaskFlag::DeleteFlag() -{ - CObject* pObj; - CPyro* pyro; - D3DVECTOR iPos, oPos; - float iAngle, angle, aLimit, dist; - - iPos = m_object->RetPosition(0); - iAngle = m_object->RetAngleY(0); - iAngle = NormAngle(iAngle); // 0..2*PI - - pObj = SearchNearest(iPos, OBJECT_NULL); - if ( pObj == 0 ) - { - return ERR_FLAG_DELETE; - } - dist = Length(iPos, pObj->RetPosition(0)); - if ( dist > 10.0f ) - { - return ERR_FLAG_DELETE; - } - - oPos = pObj->RetPosition(0); - angle = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! - aLimit = 45.0f*PI/180.0f; - if ( !TestAngle(angle, iAngle-aLimit, iAngle+aLimit) ) - { - return ERR_FLAG_DELETE; - } - - m_sound->Play(SOUND_WAYPOINT, iPos); - pyro = new CPyro(m_iMan); - pyro->Create(PT_FLDELETE, pObj); - - return ERR_OK; -} - diff --git a/src/taskflag.h b/src/taskflag.h deleted file mode 100644 index aa979f8..0000000 --- a/src/taskflag.h +++ /dev/null @@ -1,66 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. -// taskflag.h - -#ifndef _TASKFLAG_H_ -#define _TASKFLAG_H_ - - -#include "misc.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - - -enum TaskFlagOrder -{ - TFL_CREATE = 0, // sets - TFL_DELETE = 1, // removes -}; - - - -class CTaskFlag : public CTask -{ -public: - CTaskFlag(CInstanceManager* iMan, CObject* object); - ~CTaskFlag(); - - BOOL EventProcess(const Event &event); - - Error Start(TaskFlagOrder order, int rank); - Error IsEnded(); - BOOL Abort(); - -protected: - Error CreateFlag(int rank); - Error DeleteFlag(); - CObject* SearchNearest(D3DVECTOR pos, ObjectType type); - int CountObject(ObjectType type); - -protected: - TaskFlagOrder m_order; - float m_time; - BOOL m_bError; -}; - - -#endif //_TASKFLAG_H_ diff --git a/src/taskgoto.cpp b/src/taskgoto.cpp deleted file mode 100644 index a6c836f..0000000 --- a/src/taskgoto.cpp +++ /dev/null @@ -1,2352 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskgoto.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "terrain.h" -#include "water.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "task.h" -#include "taskgoto.h" - - - -#define FLY_DIST_GROUND 80.0f // minimum distance to remain on the ground -#define FLY_DEF_HEIGHT 50.0f // default flying height -#define BM_DIM_STEP 5.0f - - - - -// Object's constructor. - -CTaskGoto::CTaskGoto(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); - - m_bmArray = 0; -} - -// Object's destructor. - -CTaskGoto::~CTaskGoto() -{ - BitmapClose(); -} - - -// Management of an event. - -BOOL CTaskGoto::EventProcess(const Event &event) -{ - D3DVECTOR pos, goal; - FPOINT rot, repulse; - float a, g, dist, linSpeed, cirSpeed, h, hh, factor, dir; - Error ret; - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - // Momentarily stationary object (ant on the back)? - if ( m_object->RetFixed() ) - { - m_physics->SetMotorSpeedX(0.0f); // stops the advance - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - return TRUE; - } - - if ( m_error != ERR_OK ) return FALSE; - - if ( m_bWorm ) - { - WormFrame(event.rTime); - } - - if ( m_phase == TGP_BEAMLEAK ) // leak? - { - m_leakTime += event.rTime; - - pos = m_object->RetPosition(0); - - rot.x = m_leakPos.x-pos.x; - rot.y = m_leakPos.z-pos.z; - dist = Length(rot.x, rot.y); - rot.x /= dist; - rot.y /= dist; - - a = m_object->RetAngleY(0); - g = RotateAngle(rot.x, -rot.y); // CW ! - a = Direction(a, g)*1.0f; - cirSpeed = a; - if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; - if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; - - a = NormAngle(a); - if ( a > PI*0.5f && a < PI*1.5f ) - { - linSpeed = 1.0f; // obstacle behind -> advance - cirSpeed = -cirSpeed; - } - else - { - linSpeed = -1.0f; // obstacle in front -> back - } - - if ( m_bLeakRecede ) - { - linSpeed = -1.0f; - cirSpeed = 0.0f; - } - - m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right - m_physics->SetMotorSpeedX(linSpeed); // advance - return TRUE; - } - - if ( m_phase == TGP_BEAMSEARCH ) // search path? - { - if ( m_bmStep == 0 ) - { - // Frees the area around the departure. - BitmapClearCircle(m_object->RetPosition(0), BM_DIM_STEP*1.8f); - } - - pos = m_object->RetPosition(0); - - if ( m_bmFretObject == 0 ) - { - goal = m_goal; - dist = 0.0f; - } - else - { - goal = m_goalObject; - dist = TAKE_DIST+2.0f; - if ( m_bmFretObject->RetType() == OBJECT_BASE ) dist = 12.0f; - } - - ret = BeamSearch(pos, goal, dist); - if ( ret == ERR_OK ) - { -#if 0 - D3DVECTOR min, max; - min = pos; - max = m_goal; - if ( min.x > max.x ) Swap(min.x, max.x); - if ( min.z > max.z ) Swap(min.z, max.z); - min.x -= 50.0f; - min.z -= 50.0f; - max.x += 50.0f; - max.z += 50.0f; - BitmapDebug(min, max, m_object->RetPosition(0), m_goal); -#endif - if ( m_physics->RetLand() ) m_phase = TGP_BEAMWCOLD; - else m_phase = TGP_BEAMGOTO; - m_bmIndex = 0; - m_bmWatchDogPos = m_object->RetPosition(0); - m_bmWatchDogTime = 0.0f; - } - if ( ret == ERR_GOTO_IMPOSSIBLE || ret == ERR_GOTO_ITER ) - { -#if 0 - D3DVECTOR min, max; - min = pos; - max = m_goal; - if ( min.x > max.x ) Swap(min.x, max.x); - if ( min.z > max.z ) Swap(min.z, max.z); - min.x -= 50.0f; - min.z -= 50.0f; - max.x += 50.0f; - max.z += 50.0f; - BitmapDebug(min, max, m_object->RetPosition(0), m_goal); -#endif - m_error = ret; - return FALSE; - } - return TRUE; - } - - if ( m_phase == TGP_BEAMWCOLD ) // expects cooled reactor? - { - return TRUE; - } - - if ( m_phase == TGP_BEAMUP ) // off? - { - m_physics->SetMotorSpeedY(1.0f); // up - return TRUE; - } - - if ( m_phase == TGP_BEAMGOTO ) // goto dot list? (?) - { - if ( m_physics->RetCollision() ) // collision? - { - m_physics->SetCollision(FALSE); // there's more - } - - pos = m_object->RetPosition(0); - - if ( m_physics->RetType() == TYPE_FLYING && m_altitude == 0.0f ) - { - if ( m_physics->RetLand() ) - { - m_physics->SetMotorSpeedY(0.0f); - } - else - { - m_physics->SetMotorSpeedY(-1.0f); - } - } - - if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f ) - { - goal = m_bmPoints[m_bmIndex]; - goal.y = pos.y; - h = m_terrain->RetFloorHeight(goal, TRUE, TRUE); - dist = Length2d(pos, goal); - if ( dist != 0.0f ) // anticipates? - { - linSpeed = m_physics->RetLinMotionX(MO_REASPEED); - linSpeed /= m_physics->RetLinMotionX(MO_ADVSPEED); - goal.x = pos.x + (goal.x-pos.x)*linSpeed*20.0f/dist; - goal.z = pos.z + (goal.z-pos.z)*linSpeed*20.0f/dist; - } - goal.y = pos.y; - hh = m_terrain->RetFloorHeight(goal, TRUE, TRUE); - h = Min(h, hh); - linSpeed = 0.0f; - if ( h < m_altitude-1.0f ) - { - linSpeed = 0.2f+((m_altitude-1.0f)-h)*0.1f; // up - if ( linSpeed > 1.0f ) linSpeed = 1.0f; - } - if ( h > m_altitude+1.0f ) - { - linSpeed = -0.2f; // down - } - m_physics->SetMotorSpeedY(linSpeed); - } - - rot.x = m_bmPoints[m_bmIndex].x-pos.x; - rot.y = m_bmPoints[m_bmIndex].z-pos.z; - dist = Length(rot.x, rot.y); - rot.x /= dist; - rot.y /= dist; - - a = m_object->RetAngleY(0); - g = RotateAngle(rot.x, -rot.y); // CW ! - cirSpeed = Direction(a, g)*2.0f; - if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; - if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; - if ( dist < 4.0f ) cirSpeed *= dist/4.0f; // so close -> turns less - - if ( m_bmIndex == m_bmTotal ) // last point? - { - linSpeed = dist/(m_physics->RetLinStopLength()*1.5f); - if ( linSpeed > 1.0f ) linSpeed = 1.0f; - } - else - { - linSpeed = 1.0f; // dark without stopping - } - - linSpeed *= 1.0f-(1.0f-0.3f)*Abs(cirSpeed); - -//? if ( dist < 20.0f && Abs(cirSpeed) >= 0.5f ) - if ( Abs(cirSpeed) >= 0.2f ) - { - linSpeed = 0.0f; // turns first, then advance - } - - dist = Length2d(pos, m_bmWatchDogPos); - if ( dist < 1.0f && linSpeed != 0.0f ) - { - m_bmWatchDogTime += event.rTime; - } - else - { - m_bmWatchDogTime = 0.0f; - m_bmWatchDogPos = pos; - } - - if ( m_bmWatchDogTime >= 1.0f ) // immobile for a long time? - { - m_physics->SetMotorSpeedX(0.0f); // stops the advance - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - BeamStart(); // we start all - return TRUE; - } - - m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right - m_physics->SetMotorSpeedX(linSpeed); // advance - return TRUE; - } - - if ( m_phase == TGP_BEAMDOWN ) // landed? - { - m_physics->SetMotorSpeedY(-0.5f); // tomb - return TRUE; - } - - if ( m_phase == TGP_LAND ) // landed? - { - m_physics->SetMotorSpeedY(-0.5f); // tomb - return TRUE; - } - - if ( m_goalMode == TGG_EXPRESS ) - { - if ( m_crashMode == TGC_HALT ) - { - if ( m_physics->RetCollision() ) // collision? - { - m_physics->SetCollision(FALSE); // there's more - m_error = ERR_STOP; - return TRUE; - } - } - - pos = m_object->RetPosition(0); - - if ( m_altitude > 0.0f ) - { - h = m_terrain->RetFloorHeight(pos, TRUE, TRUE); - linSpeed = 0.0f; - if ( h < m_altitude ) - { - linSpeed = 0.1f; // up - } - if ( h > m_altitude ) - { - linSpeed = -0.2f; // down - } - m_physics->SetMotorSpeedY(linSpeed); - } - - rot.x = m_goal.x-pos.x; - rot.y = m_goal.z-pos.z; - a = m_object->RetAngleY(0); - g = RotateAngle(rot.x, -rot.y); // CW ! - cirSpeed = Direction(a, g)*1.0f; - if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; - if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; - - m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right - m_physics->SetMotorSpeedX(1.0f); // advance - return TRUE; - } - - if ( m_phase != TGP_TURN && - m_physics->RetType() == TYPE_FLYING && - m_altitude > 0.0f ) - { - pos = m_object->RetPosition(0); - dist = Length2d(m_goal, pos); - factor = (dist-20.0f)/20.0f; - if ( factor < 0.0f ) factor = 0.0f; - if ( factor > 1.0f ) factor = 1.0f; - - h = m_terrain->RetFloorHeight(m_object->RetPosition(0), TRUE, TRUE); - linSpeed = 0.0f; - if ( h < (m_altitude-0.5f)*factor && factor == 1.0f ) - { - linSpeed = 0.1f; // up - } - if ( h > m_altitude*factor ) - { - linSpeed = -0.2f; // down - } - ComputeFlyingRepulse(dir); - linSpeed += dir*0.2f; - - m_physics->SetMotorSpeedY(linSpeed); - } - - if ( m_phase == TGP_ADVANCE ) // going towards the goal? - { - if ( m_physics->RetCollision() ) // collision? - { - m_physics->SetCollision(FALSE); // there's more - m_time = 0.0f; - m_phase = TGP_CRWAIT; - return TRUE; - } - -#if 0 - pos = m_object->RetPosition(0); - a = m_object->RetAngleY(0); - g = RotateAngle(m_goal.x-pos.x, pos.z-m_goal.z); // CW ! - cirSpeed = Direction(a, g)*1.0f; - if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; - if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; - - dist = Length2d(m_goal, pos); - linSpeed = dist/(m_physics->RetLinStopLength()*1.5f); - if ( linSpeed > 1.0f ) linSpeed = 1.0f; - - if ( dist < 20.0f && Abs(cirSpeed) >= 0.5f ) - { - linSpeed = 0.0f; // turns first, then advance - } -#else - pos = m_object->RetPosition(0); - - rot.x = m_goal.x-pos.x; - rot.y = m_goal.z-pos.z; - dist = Length(rot.x, rot.y); - rot.x /= dist; - rot.y /= dist; - - ComputeRepulse(repulse); - rot.x += repulse.x*2.0f; - rot.y += repulse.y*2.0f; - - a = m_object->RetAngleY(0); - g = RotateAngle(rot.x, -rot.y); // CW ! - cirSpeed = Direction(a, g)*1.0f; -//? if ( m_physics->RetType() == TYPE_FLYING && -//? m_physics->RetLand() ) // flying on the ground? -//? { -//? cirSpeed *= 4.0f; // more fishing -//? } - if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; - if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; - - dist = Length2d(m_goal, pos); - linSpeed = dist/(m_physics->RetLinStopLength()*1.5f); -//? if ( m_physics->RetType() == TYPE_FLYING && -//? m_physics->RetLand() ) // flying on the ground? -//? { -//? linSpeed *= 8.0f; // more fishing -//? } - if ( linSpeed > 1.0f ) linSpeed = 1.0f; - - linSpeed *= 1.0f-(1.0f-0.3f)*Abs(cirSpeed); - - if ( dist < 20.0f && Abs(cirSpeed) >= 0.5f ) - { - linSpeed = 0.0f; // turns first, then advance - } -#endif - - m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right - m_physics->SetMotorSpeedX(linSpeed); // advance - } - - if ( m_phase == TGP_TURN || // turns to the object? - m_phase == TGP_CRTURN || // turns after collision? - m_phase == TGP_CLTURN ) // turns after collision? - { - a = m_object->RetAngleY(0); - g = m_angle; - cirSpeed = Direction(a, g)*1.0f; - if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; - if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; - - m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right - } - - if ( m_phase == TGP_CRWAIT || // waits after collision? - m_phase == TGP_CLWAIT ) // waits after collision? - { - m_time += event.rTime; - m_physics->SetMotorSpeedX(0.0f); // stops the advance - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - } - - if ( m_phase == TGP_CRADVANCE ) // advance after collision? - { - if ( m_physics->RetCollision() ) // collision? - { - m_physics->SetCollision(FALSE); // there's more - m_time = 0.0f; - m_phase = TGP_CLWAIT; - return TRUE; - } - m_physics->SetMotorSpeedX(0.5f); // advance mollo - } - - if ( m_phase == TGP_CLADVANCE ) // advance after collision? - { - if ( m_physics->RetCollision() ) // collision? - { - m_physics->SetCollision(FALSE); // there's more - m_time = 0.0f; - m_phase = TGP_CRWAIT; - return TRUE; - } - m_physics->SetMotorSpeedX(0.5f); // advance mollo - } - - if ( m_phase == TGP_MOVE ) // final advance? - { - m_bmTimeLimit -= event.rTime; - m_physics->SetMotorSpeedX(1.0f); - } - - return TRUE; -} - - -// Sought a target for the worm. - -CObject* CTaskGoto::WormSearch(D3DVECTOR &impact) -{ - CObject* pObj; - CObject* pBest = 0; - D3DVECTOR iPos, oPos; - ObjectType oType; - float distance, min, radius; - int i; - - iPos = m_object->RetPosition(0); - min = 1000000.0f; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - oType = pObj->RetType(); - if ( oType != OBJECT_MOBILEfa && - oType != OBJECT_MOBILEta && - oType != OBJECT_MOBILEwa && - oType != OBJECT_MOBILEia && - oType != OBJECT_MOBILEfc && - oType != OBJECT_MOBILEtc && - oType != OBJECT_MOBILEwc && - oType != OBJECT_MOBILEic && - oType != OBJECT_MOBILEfi && - oType != OBJECT_MOBILEti && - oType != OBJECT_MOBILEwi && - oType != OBJECT_MOBILEii && - oType != OBJECT_MOBILEfs && - oType != OBJECT_MOBILEts && - oType != OBJECT_MOBILEws && - oType != OBJECT_MOBILEis && - oType != OBJECT_MOBILErt && - oType != OBJECT_MOBILErc && - oType != OBJECT_MOBILErr && - oType != OBJECT_MOBILErs && - oType != OBJECT_MOBILEsa && - oType != OBJECT_MOBILEtg && - oType != OBJECT_MOBILEft && - oType != OBJECT_MOBILEtt && - oType != OBJECT_MOBILEwt && - oType != OBJECT_MOBILEit && - oType != OBJECT_MOBILEdr && - oType != OBJECT_DERRICK && - oType != OBJECT_STATION && - oType != OBJECT_FACTORY && - oType != OBJECT_REPAIR && - oType != OBJECT_DESTROYER && - oType != OBJECT_CONVERT && - oType != OBJECT_TOWER && - oType != OBJECT_RESEARCH && - oType != OBJECT_RADAR && - oType != OBJECT_INFO && - oType != OBJECT_ENERGY && - oType != OBJECT_LABO && - oType != OBJECT_NUCLEAR && - oType != OBJECT_PARA && - oType != OBJECT_SAFE && - oType != OBJECT_HUSTON ) continue; - - if ( pObj->RetVirusMode() ) continue; // object infected? - - if ( !pObj->GetCrashSphere(0, oPos, radius) ) continue; - distance = Length2d(oPos, iPos); - if ( distance < min ) - { - min = distance; - pBest = pObj; - } - } - if ( pBest == 0 ) return 0; - - impact = pBest->RetPosition(0); - return pBest; -} - -// Contaminate objects near the worm. - -void CTaskGoto::WormFrame(float rTime) -{ - CObject* pObj; - D3DVECTOR impact, pos; - float dist; - - m_wormLastTime += rTime; - - if ( m_wormLastTime >= 0.5f ) - { - m_wormLastTime = 0.0f; - - pObj = WormSearch(impact); - if ( pObj != 0 ) - { - pos = m_object->RetPosition(0); - dist = Length(pos, impact); - if ( dist <= 15.0f ) - { - pObj->SetVirusMode(TRUE); // bam, infected! - } - } - } -} - - - -// Assigns the goal was achieved. -// "dist" is the distance that needs to go far to make a deposit or object. - -Error CTaskGoto::Start(D3DVECTOR goal, float altitude, - TaskGotoGoal goalMode, TaskGotoCrash crashMode) -{ - D3DVECTOR pos; - CObject* target; - ObjectType type; - float dist; - int x, y; - - type = m_object->RetType(); - - if ( goalMode == TGG_DEFAULT ) - { - goalMode = TGG_STOP; - if ( type == OBJECT_MOTHER || - type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_WORM ) - { - goalMode = TGG_EXPRESS; - } - } - - if ( crashMode == TGC_DEFAULT ) - { -//? crashMode = TGC_RIGHTLEFT; - crashMode = TGC_BEAM; - if ( type == OBJECT_MOTHER || - type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_WORM || - type == OBJECT_BEE ) - { - crashMode = TGC_HALT; - } - } - - m_altitude = altitude; - m_goalMode = goalMode; - m_crashMode = crashMode; - m_goalObject = goal; - m_goal = goal; - - m_bTake = FALSE; - m_phase = TGP_ADVANCE; - m_error = ERR_OK; - m_try = 0; - m_bmFretObject = 0; - m_bmFinalMove = 0.0f; - - pos = m_object->RetPosition(0); - dist = Length2d(pos, m_goal); - if ( dist < 10.0f && m_crashMode == TGC_BEAM ) - { - m_crashMode = TGC_RIGHTLEFT; - } - - m_bWorm = FALSE; - if ( type == OBJECT_WORM ) - { - m_bWorm = TRUE; - m_wormLastTime = 0.0f; - } - - m_bApprox = FALSE; - if ( type == OBJECT_HUMAN || - type == OBJECT_TECH || - type == OBJECT_MOTHER || - type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_BEE || - type == OBJECT_WORM || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs ) - { - m_bApprox = TRUE; - } - - if ( !m_bApprox && m_crashMode != TGC_BEAM ) - { - target = SearchTarget(goal, 1.0f); - if ( target != 0 ) - { - m_goal = target->RetPosition(0); - dist = 0.0f; - if ( !AdjustBuilding(m_goal, 1.0f, dist) ) - { - dist = 0.0f; - AdjustTarget(target, m_goal, dist); - } - m_bTake = TRUE; // object was taken on arrival (final rotation) - } - } - - m_lastDistance = 1000.0f; - m_physics->SetCollision(FALSE); - - if ( m_crashMode == TGC_BEAM ) // with the algorithm of rays? - { - target = SearchTarget(goal, 1.0f); - if ( target != 0 ) - { - m_goal = target->RetPosition(0); - dist = 4.0f; - if ( AdjustBuilding(m_goal, 1.0f, dist) ) - { - m_bmFinalMove = dist; - } - else - { - dist = 4.0f; - if ( AdjustTarget(target, m_goal, dist) ) - { - m_bmFretObject = target; // cargo on the ground - } - else - { - m_bmFinalMove = dist; - } - } - m_bTake = TRUE; // object was taken on arrival (final rotation) - } - - if ( m_physics->RetType() == TYPE_FLYING && m_altitude == 0.0f ) - { - pos = m_object->RetPosition(0); - dist = Length2d(pos, m_goal); - if ( dist > FLY_DIST_GROUND ) // over 20 meters? - { - m_altitude = FLY_DEF_HEIGHT; // default altitude - } - } - - BeamStart(); - - if ( m_bmFretObject == 0 ) - { - x = (int)((m_goal.x+1600.0f)/BM_DIM_STEP); - y = (int)((m_goal.z+1600.0f)/BM_DIM_STEP); - if ( BitmapTestDot(0, x, y) ) // arrival occupied? - { -#if 0 - D3DVECTOR min, max; - min = m_object->RetPosition(0); - max = m_goal; - if ( min.x > max.x ) Swap(min.x, max.x); - if ( min.z > max.z ) Swap(min.z, max.z); - min.x -= 50.0f; - min.z -= 50.0f; - max.x += 50.0f; - max.z += 50.0f; - BitmapDebug(min, max, m_object->RetPosition(0), m_goal); -#endif - m_error = ERR_GOTO_BUSY; - return m_error; - } - } - } - - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskGoto::IsEnded() -{ - D3DVECTOR pos; - float limit, angle, dist, h, level; - - if ( m_engine->RetPause() ) return ERR_CONTINUE; - if ( m_error != ERR_OK ) return m_error; - - pos = m_object->RetPosition(0); - - if ( m_phase == TGP_BEAMLEAK ) // leak? - { - if ( m_leakTime >= m_leakDelay ) - { - m_physics->SetMotorSpeedX(0.0f); // stops the advance - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - BeamInit(); - m_phase = TGP_BEAMSEARCH; // will seek the path - } - return ERR_CONTINUE; - } - - if ( m_phase == TGP_BEAMSEARCH ) // search path? - { - return ERR_CONTINUE; - } - - if ( m_phase == TGP_BEAMWCOLD ) // expects cool reactor? - { - if ( m_altitude != 0.0f && - m_physics->RetReactorRange() < 1.0f ) return ERR_CONTINUE; - m_phase = TGP_BEAMUP; - } - - if ( m_phase == TGP_BEAMUP ) // off? - { - if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f ) - { - level = m_terrain->RetFloorLevel(pos, TRUE, TRUE); - h = level+m_altitude-20.0f; - limit = m_terrain->RetFlyingMaxHeight(); - if ( h > limit ) h = limit; - if ( pos.y < h-1.0f ) return ERR_CONTINUE; - - m_physics->SetMotorSpeedY(0.0f); // stops the ascent - } - m_phase = TGP_BEAMGOTO; - } - - if ( m_phase == TGP_BEAMGOTO ) // goto dot list ? - { - if ( m_altitude != 0.0f && - m_physics->RetReactorRange() < 0.1f ) // overheating? - { - m_physics->SetMotorSpeedX(0.0f); // stops the advance - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - m_physics->SetMotorSpeedY(-1.0f); // tomb - m_phase = TGP_BEAMWCOLD; - return ERR_CONTINUE; - } - - if ( m_physics->RetLand() ) // on the ground? - { - limit = 1.0f; - } - else // in flight? - { - limit = 2.0f; - if ( m_bmIndex < m_bmTotal ) limit *= 2.0f; // intermediate point - } - if ( m_bApprox ) limit = 2.0f; - - if ( Abs(pos.x - m_bmPoints[m_bmIndex].x) < limit && - Abs(pos.z - m_bmPoints[m_bmIndex].z) < limit ) - { - m_physics->SetMotorSpeedX(0.0f); // stops the advance - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - - m_bmIndex = BeamShortcut(); - - if ( m_bmIndex > m_bmTotal ) - { - m_phase = TGP_BEAMDOWN; - } - } - } - - if ( m_phase == TGP_BEAMDOWN ) // landed? - { - if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f ) - { - if ( !m_physics->RetLand() ) return ERR_CONTINUE; - m_physics->SetMotorSpeedY(0.0f); // stops the descent - - m_altitude = 0.0f; - m_phase = TGP_BEAMGOTO; // advance finely on the ground to finish - m_bmIndex = m_bmTotal; - return ERR_CONTINUE; - } - - if ( m_bTake ) - { - m_angle = RotateAngle(m_goalObject.x-pos.x, pos.z-m_goalObject.z); - m_phase = TGP_TURN; - } - else - { - m_physics->SetMotorSpeedX(0.0f); // stops the advance - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - return ERR_STOP; - } - } - - if ( m_goalMode == TGG_EXPRESS ) - { - dist = Length2d(m_goal, pos); - if ( dist < 10.0f && dist > m_lastDistance ) - { - return ERR_STOP; - } - m_lastDistance = dist; - } - - if ( m_phase == TGP_ADVANCE ) // going towards the goal? - { - if ( m_physics->RetLand() ) limit = 0.1f; // on the ground - else limit = 1.0f; // flying - if ( m_bApprox ) limit = 2.0f; - - if ( Abs(pos.x - m_goal.x) < limit && - Abs(pos.z - m_goal.z) < limit ) - { - m_physics->SetMotorSpeedX(0.0f); // stops the advance - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - m_phase = TGP_LAND; - } - } - - if ( m_phase == TGP_LAND ) // landed? - { - if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f ) - { - if ( !m_physics->RetLand() ) return ERR_CONTINUE; - m_physics->SetMotorSpeedY(0.0f); - } - - if ( m_bTake ) - { - m_angle = RotateAngle(m_goalObject.x-pos.x, pos.z-m_goalObject.z); - m_phase = TGP_TURN; - } - else - { - return ERR_STOP; - } - } - - if ( m_phase == TGP_TURN ) // turns to the object? - { - angle = NormAngle(m_object->RetAngleY(0)); - limit = 0.02f; - if ( m_bApprox ) limit = 0.10f; - if ( Abs(angle-m_angle) < limit ) - { - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - if ( m_bmFinalMove == 0.0f ) return ERR_STOP; - - m_bmFinalPos = m_object->RetPosition(0); - m_bmFinalDist = m_physics->RetLinLength(m_bmFinalMove); - m_bmTimeLimit = m_physics->RetLinTimeLength(Abs(m_bmFinalMove))*1.5f; - if ( m_bmTimeLimit < 0.5f ) m_bmTimeLimit = 0.5f; - m_phase = TGP_MOVE; - } - } - - if ( m_phase == TGP_CRWAIT ) // waits after collision? - { - if ( m_crashMode == TGC_HALT ) - { - m_physics->SetMotorSpeedX(0.0f); // stops the advance - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - m_error = ERR_GENERIC; - return m_error; - } - if ( m_time >= 1.0f ) - { - if ( m_crashMode == TGC_RIGHTLEFT || - m_crashMode == TGC_RIGHT ) angle = PI/2.0f; // 90 deegres to the right - else angle = -PI/2.0f; // 90 deegres to the left - m_angle = NormAngle(m_object->RetAngleY(0)+angle); - m_phase = TGP_CRTURN; -//? m_phase = TGP_ADVANCE; - } - } - - if ( m_phase == TGP_CRTURN ) // turns after collision? - { - angle = NormAngle(m_object->RetAngleY(0)); - limit = 0.1f; - if ( Abs(angle-m_angle) < limit ) - { - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - m_pos = pos; - m_phase = TGP_CRADVANCE; - } - } - - if ( m_phase == TGP_CRADVANCE ) // advance after collision? - { - if ( Length(pos, m_pos) >= 5.0f ) - { - m_phase = TGP_ADVANCE; - } - } - - if ( m_phase == TGP_CLWAIT ) // waits after collision? - { - if ( m_time >= 1.0f ) - { - if ( m_crashMode == TGC_RIGHTLEFT ) angle = -PI; - if ( m_crashMode == TGC_LEFTRIGHT ) angle = PI; - if ( m_crashMode == TGC_RIGHT ) angle = PI/2.0f; - if ( m_crashMode == TGC_LEFT ) angle = -PI/2.0f; - m_angle = NormAngle(m_object->RetAngleY(0)+angle); - m_phase = TGP_CLTURN; - } - } - - if ( m_phase == TGP_CLTURN ) // turns after collision? - { - angle = NormAngle(m_object->RetAngleY(0)); - limit = 0.1f; - if ( Abs(angle-m_angle) < limit ) - { - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - m_pos = pos; - m_phase = TGP_CLADVANCE; - } - } - - if ( m_phase == TGP_CLADVANCE ) // advance after collision? - { - if ( Length(pos, m_pos) >= 10.0f ) - { - m_phase = TGP_ADVANCE; - m_try ++; - } - } - - if ( m_phase == TGP_MOVE ) // final advance? - { - if ( m_bmTimeLimit <= 0.0f ) - { - m_physics->SetMotorSpeedX(0.0f); // stops - Abort(); - return ERR_STOP; - } - - dist = Length(m_bmFinalPos, m_object->RetPosition(0)); - if ( dist < m_bmFinalDist ) return ERR_CONTINUE; - m_physics->SetMotorSpeedX(0.0f); // stops the advance - return ERR_STOP; - } - - return ERR_CONTINUE; -} - - -// Tries the object is the target position. - -CObject* CTaskGoto::SearchTarget(D3DVECTOR pos, float margin) -{ - CObject *pObj, *pBest; - D3DVECTOR oPos; - float dist, min; - int i; - - pBest = 0; - min = 1000000.0f; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetActif() ) continue; - if ( pObj->RetTruck() != 0 ) continue; // object transtorted? - - oPos = pObj->RetPosition(0); - dist = Length2d(pos, oPos); - - if ( dist <= margin && dist <= min ) - { - min = dist; - pBest = pObj; - } - } - - return pBest; -} - -// Adjusts the target as a function of the object. -// Returns TRUE if it is cargo laying on the ground, which can be approached from any site. - -BOOL CTaskGoto::AdjustTarget(CObject* pObj, D3DVECTOR &pos, float &distance) -{ - ObjectType type; - Character* character; - D3DMATRIX* mat; - D3DVECTOR goal; - float dist, suppl; - - type = m_object->RetType(); - if ( type == OBJECT_BEE || - type == OBJECT_WORM ) - { - pos = pObj->RetPosition(0); - return FALSE; // single approach - } - - type = pObj->RetType(); - - if ( type == OBJECT_FRET || - type == OBJECT_STONE || - type == OBJECT_URANIUM || - type == OBJECT_METAL || - type == OBJECT_POWER || - type == OBJECT_ATOMIC || - type == OBJECT_BULLET || - type == OBJECT_BBOX || - type == OBJECT_KEYa || - type == OBJECT_KEYb || - type == OBJECT_KEYc || - type == OBJECT_KEYd || - type == OBJECT_TNT || - type == OBJECT_SCRAP1 || - type == OBJECT_SCRAP2 || - type == OBJECT_SCRAP3 || - type == OBJECT_SCRAP4 || - type == OBJECT_SCRAP5 || - type == OBJECT_BOMB || - type == OBJECT_RUINmobilew1 || - type == OBJECT_RUINmobilew2 || - type == OBJECT_RUINmobilet1 || - type == OBJECT_RUINmobilet2 || - type == OBJECT_RUINmobiler1 || - type == OBJECT_RUINmobiler2 ) - { - pos = m_object->RetPosition(0); - goal = pObj->RetPosition(0); - dist = Length(goal, pos); - pos = (pos-goal)*(TAKE_DIST+distance)/dist + goal; - return TRUE; // approach from all sites - } - - if ( type == OBJECT_BASE ) - { - pos = m_object->RetPosition(0); - goal = pObj->RetPosition(0); - dist = Length(goal, pos); - pos = (pos-goal)*(TAKE_DIST+distance)/dist + goal; - return TRUE; // approach from all sites - } - - if ( type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs || - type == OBJECT_MOBILEsa || - type == OBJECT_MOBILEtg || - type == OBJECT_MOBILEft || - type == OBJECT_MOBILEtt || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEit || - type == OBJECT_MOBILEdr ) - { - character = pObj->RetCharacter(); - pos = character->posPower; - pos.x -= TAKE_DIST+TAKE_DIST_OTHER+distance; - mat = pObj->RetWorldMatrix(0); - pos = Transform(*mat, pos); - return FALSE; // single approach - } - - if ( GetHotPoint(pObj, goal, TRUE, distance, suppl) ) - { - pos = goal; - distance += suppl; - return FALSE; // single approach - } - - pos = pObj->RetPosition(0); - distance = 0.0f; - return FALSE; // single approach -} - -// If you are on an object produced by a building (ore produced by derrick), -// changes the position by report the building. - -BOOL CTaskGoto::AdjustBuilding(D3DVECTOR &pos, float margin, float &distance) -{ - CObject* pObj; - D3DVECTOR oPos; - float dist, suppl; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( !pObj->RetActif() ) continue; - if ( pObj->RetTruck() != 0 ) continue; // object transported? - - if ( !GetHotPoint(pObj, oPos, FALSE, 0.0f, suppl) ) continue; - dist = Length2d(pos, oPos); - if ( dist <= margin ) - { - GetHotPoint(pObj, pos, TRUE, distance, suppl); - distance += suppl; - return TRUE; - } - } - return FALSE; -} - -// Returns the item or product or pose is something on a building. - -BOOL CTaskGoto::GetHotPoint(CObject *pObj, D3DVECTOR &pos, - BOOL bTake, float distance, float &suppl) -{ - ObjectType type; - D3DMATRIX* mat; - - pos = D3DVECTOR(0.0f, 0.0f, 0.0f); - suppl = 0.0f; - type = pObj->RetType(); - - if ( type == OBJECT_DERRICK ) - { - mat = pObj->RetWorldMatrix(0); - pos.x += 8.0f; - if ( bTake && distance != 0.0f ) suppl = 4.0f; - if ( bTake ) pos.x += TAKE_DIST+distance+suppl; - pos = Transform(*mat, pos); - return TRUE; - } - - if ( type == OBJECT_CONVERT ) - { - mat = pObj->RetWorldMatrix(0); - pos.x += 0.0f; - if ( bTake && distance != 0.0f ) suppl = 4.0f; - if ( bTake ) pos.x += TAKE_DIST+distance+suppl; - pos = Transform(*mat, pos); - return TRUE; - } - - if ( type == OBJECT_RESEARCH ) - { - mat = pObj->RetWorldMatrix(0); - pos.x += 10.0f; - if ( bTake && distance != 0.0f ) suppl = 2.5f; - if ( bTake ) pos.x += TAKE_DIST+TAKE_DIST_OTHER+distance+suppl; - pos = Transform(*mat, pos); - return TRUE; - } - - if ( type == OBJECT_ENERGY ) - { - mat = pObj->RetWorldMatrix(0); - pos.x += 6.0f; - if ( bTake && distance != 0.0f ) suppl = 6.0f; - if ( bTake ) pos.x += TAKE_DIST+TAKE_DIST_OTHER+distance; - pos = Transform(*mat, pos); - return TRUE; - } - - if ( type == OBJECT_TOWER ) - { - mat = pObj->RetWorldMatrix(0); - pos.x += 5.0f; - if ( bTake && distance != 0.0f ) suppl = 4.0f; - if ( bTake ) pos.x += TAKE_DIST+TAKE_DIST_OTHER+distance+suppl; - pos = Transform(*mat, pos); - return TRUE; - } - - if ( type == OBJECT_LABO ) - { - mat = pObj->RetWorldMatrix(0); - pos.x += 6.0f; - if ( bTake && distance != 0.0f ) suppl = 6.0f; - if ( bTake ) pos.x += TAKE_DIST+TAKE_DIST_OTHER+distance; - pos = Transform(*mat, pos); - return TRUE; - } - - if ( type == OBJECT_NUCLEAR ) - { - mat = pObj->RetWorldMatrix(0); - pos.x += 22.0f; - if ( bTake && distance != 0.0f ) suppl = 4.0f; - if ( bTake ) pos.x += TAKE_DIST+TAKE_DIST_OTHER+distance+suppl; - pos = Transform(*mat, pos); - return TRUE; - } - - if ( type == OBJECT_FACTORY ) - { - mat = pObj->RetWorldMatrix(0); - pos.x += 4.0f; - if ( bTake && distance != 0.0f ) suppl = 6.0f; - if ( bTake ) pos.x += TAKE_DIST+distance+suppl; - pos = Transform(*mat, pos); - return TRUE; - } - - if ( type == OBJECT_STATION ) - { - mat = pObj->RetWorldMatrix(0); - pos.x += 4.0f; - if ( bTake && distance != 0.0f ) suppl = 4.0f; - if ( bTake ) pos.x += distance; - pos = Transform(*mat, pos); - return TRUE; - } - - if ( type == OBJECT_REPAIR ) - { - mat = pObj->RetWorldMatrix(0); - pos.x += 4.0f; - if ( bTake && distance != 0.0f ) suppl = 4.0f; - if ( bTake ) pos.x += distance; - pos = Transform(*mat, pos); - return TRUE; - } - - if ( type == OBJECT_DESTROYER ) - { - mat = pObj->RetWorldMatrix(0); - pos.x += 0.0f; - if ( bTake && distance != 0.0f ) suppl = 4.0f; - if ( bTake ) pos.x += TAKE_DIST+distance+suppl; - pos = Transform(*mat, pos); - return TRUE; - } - - if ( type == OBJECT_PARA && m_physics->RetType() == TYPE_FLYING ) - { - mat = pObj->RetWorldMatrix(0); - if ( bTake && distance != 0.0f ) suppl = 20.0f; - if ( bTake ) pos.x += distance+suppl; - pos = Transform(*mat, pos); - return TRUE; - } - - suppl = 0.0f; - return FALSE; -} - - -// Seeks an object too close that he must flee. - -BOOL CTaskGoto::LeakSearch(D3DVECTOR &pos, float &delay) -{ - CObject *pObj, *pObstacle; - D3DVECTOR iPos, oPos, bPos; - float iRadius, oRadius, bRadius, dist, min, dir; - int i, j; - - if ( !m_physics->RetLand() ) return FALSE; // in flight? - - m_object->GetCrashSphere(0, iPos, iRadius); - - min = 100000.0f; - bRadius = 0.0f; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj == m_object ) continue; - if ( !pObj->RetActif() ) continue; - if ( pObj->RetTruck() != 0 ) continue; // object transported? - - j = 0; - while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) - { - dist = Length2d(oPos, iPos); - if ( dist < min ) - { - min = dist; - bPos = oPos; - bRadius = oRadius; - pObstacle = pObj; - } - } - } - if ( min > iRadius+bRadius+4.0f ) return FALSE; - - m_bLeakRecede = FALSE; - - dist = 4.0f; - dir = 1.0f; - if ( pObstacle->RetType() == OBJECT_FACTORY ) - { - dist = 16.0f; - dir = -1.0f; - m_bLeakRecede = TRUE; // simply recoils - } - - pos = bPos; - delay = m_physics->RetLinTimeLength(dist, dir); - return TRUE; -} - - -// Calculates the force of repulsion due to obstacles. -// The vector length rendered is between 0 and 1. - -void CTaskGoto::ComputeRepulse(FPOINT &dir) -{ -#if 0 - D3DVECTOR iPos, oPos; - FPOINT repulse; - CObject *pObj; - float dist, iRadius, oRadius; - int i; - - dir.x = 0.0f; - dir.y = 0.0f; - - m_object->GetCrashSphere(0, iPos, iRadius); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj == m_object ) continue; - if ( pObj->RetTruck() != 0 ) continue; - - oPos = pObj->RetPosition(0); - dist = Length(oPos, m_goalObject); - if ( dist <= 1.0f ) continue; - - pObj->GetGlobalSphere(oPos, oRadius); - oRadius += iRadius+m_physics->RetLinStopLength()*1.1f; - dist = Length2d(oPos, iPos); - if ( dist <= oRadius ) - { - repulse.x = iPos.x-oPos.x; - repulse.y = iPos.z-oPos.z; - -//? dist = 0.2f-(0.2f*dist/oRadius); - dist = powf(dist/oRadius, 2.0f); - dist = 0.2f-0.2f*dist; - repulse.x *= dist; - repulse.y *= dist; -//? repulse.x /= dist; -//? repulse.y /= dist; - - dir.x += repulse.x; - dir.y += repulse.y; - } - } -#else - ObjectType iType, oType; - D3DVECTOR iPos, oPos; - FPOINT repulse; - CObject *pObj; - float gDist, add, addi, fac, dist, iRadius, oRadius; - int i, j; - BOOL bAlien; - - dir.x = 0.0f; - dir.y = 0.0f; - - // The worm goes everywhere and through everything! - iType = m_object->RetType(); - if ( iType == OBJECT_WORM ) return; - - m_object->GetCrashSphere(0, iPos, iRadius); - gDist = Length(iPos, m_goal); - - add = m_physics->RetLinStopLength()*1.1f; // braking distance - fac = 2.0f; - - if ( iType == OBJECT_MOBILEwa || - iType == OBJECT_MOBILEwc || - iType == OBJECT_MOBILEwi || - iType == OBJECT_MOBILEws || - iType == OBJECT_MOBILEwt ) // wheels? - { - add = 5.0f; - fac = 1.5f; - } - if ( iType == OBJECT_MOBILEta || - iType == OBJECT_MOBILEtc || - iType == OBJECT_MOBILEti || - iType == OBJECT_MOBILEts || - iType == OBJECT_MOBILEtt || - iType == OBJECT_MOBILEdr ) // caterpillars? - { - add = 4.0f; - fac = 1.5f; - } - if ( iType == OBJECT_MOBILEfa || - iType == OBJECT_MOBILEfc || - iType == OBJECT_MOBILEfi || - iType == OBJECT_MOBILEfs || - iType == OBJECT_MOBILEft ) // flying? - { - if ( m_physics->RetLand() ) - { - add = 5.0f; - fac = 1.5f; - } - else - { - add = 10.0f; - fac = 1.5f; - } - } - if ( iType == OBJECT_MOBILEia || - iType == OBJECT_MOBILEic || - iType == OBJECT_MOBILEii || - iType == OBJECT_MOBILEis || - iType == OBJECT_MOBILEit ) // legs? - { - add = 4.0f; - fac = 1.5f; - } - if ( iType == OBJECT_BEE ) // wasp? - { - if ( m_physics->RetLand() ) - { - add = 3.0f; - fac = 1.5f; - } - else - { - add = 5.0f; - fac = 1.5f; - } - } - - bAlien = FALSE; - if ( iType == OBJECT_MOTHER || - iType == OBJECT_ANT || - iType == OBJECT_SPIDER || - iType == OBJECT_BEE || - iType == OBJECT_WORM ) - { - bAlien = TRUE; - } - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj == m_object ) continue; - if ( pObj->RetTruck() != 0 ) continue; - - oType = pObj->RetType(); - - if ( oType == OBJECT_WORM ) continue; - - if ( bAlien ) - { - if ( oType == OBJECT_STONE || - oType == OBJECT_URANIUM || - oType == OBJECT_METAL || - oType == OBJECT_POWER || - oType == OBJECT_ATOMIC || - oType == OBJECT_BULLET || - oType == OBJECT_BBOX || - oType == OBJECT_KEYa || - oType == OBJECT_KEYb || - oType == OBJECT_KEYc || - oType == OBJECT_KEYd || - oType == OBJECT_TNT || - oType == OBJECT_SCRAP1 || - oType == OBJECT_SCRAP2 || - oType == OBJECT_SCRAP3 || - oType == OBJECT_SCRAP4 || - oType == OBJECT_SCRAP5 || - oType == OBJECT_BOMB || - (oType >= OBJECT_PLANT0 && - oType <= OBJECT_PLANT19 ) || - (oType >= OBJECT_MUSHROOM0 && - oType <= OBJECT_MUSHROOM9 ) ) continue; - } - - addi = add; - if ( iType == OBJECT_BEE && - oType == OBJECT_BEE ) - { - addi = 2.0f; // between wasps, do not annoy too much - } - - j = 0; - while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) - { - if ( oPos.y-oRadius > iPos.y+iRadius ) continue; - if ( oPos.y+oRadius < iPos.y-iRadius ) continue; - - dist = Length(oPos, m_goal); - if ( dist <= 1.0f ) continue; // on purpose? - - oRadius += iRadius+addi; - dist = Length2d(oPos, iPos); - if ( dist > gDist ) continue; // beyond the goal? - if ( dist <= oRadius ) - { - repulse.x = iPos.x-oPos.x; - repulse.y = iPos.z-oPos.z; - - dist = powf(dist/oRadius, fac); - dist = 0.2f-0.2f*dist; - repulse.x *= dist; - repulse.y *= dist; - - dir.x += repulse.x; - dir.y += repulse.y; - } - } - } -#endif -} - -// Calculates the force of vertical repulsion according to barriers. -// The vector length is made​between -1 and 1. - -void CTaskGoto::ComputeFlyingRepulse(float &dir) -{ - ObjectType oType; - D3DVECTOR iPos, oPos; - CObject *pObj; - float add, fac, dist, iRadius, oRadius, repulse; - int i, j; - - m_object->GetCrashSphere(0, iPos, iRadius); - - add = 0.0f; - fac = 1.5f; - dir = 0.0f; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj == m_object ) continue; - if ( pObj->RetTruck() != 0 ) continue; - - oType = pObj->RetType(); - - if ( oType == OBJECT_WORM ) continue; - - j = 0; - while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) - { - oRadius += iRadius+add; - dist = Length2d(oPos, iPos); - if ( dist <= oRadius ) - { - repulse = iPos.y-oPos.y; - - dist = powf(dist/oRadius, fac); - dist = 0.2f-0.2f*dist; - repulse *= dist; - - dir += repulse; - } - } - } - - if ( dir < -1.0f ) dir = -1.0f; - if ( dir > 1.0f ) dir = 1.0f; -} - - - -// Among all of the following, seek if there is one allowing to go directly to the crow flies. -// If yes, skip all the unnecessary intermediate points. - -int CTaskGoto::BeamShortcut() -{ - int i; - - for ( i=m_bmTotal ; i>=m_bmIndex+2 ; i-- ) // tries from the last - { - if ( BitmapTestLine(m_bmPoints[m_bmIndex], m_bmPoints[i], 0.0f, FALSE) ) - { - return i; // bingo, found - } - } - - return m_bmIndex+1; // simply goes to the next -} - -// That's the big start. - -void CTaskGoto::BeamStart() -{ - D3DVECTOR min, max; - - BitmapOpen(); - BitmapObject(); - - min = m_object->RetPosition(0); - max = m_goal; - if ( min.x > max.x ) Swap(min.x, max.x); - if ( min.z > max.z ) Swap(min.z, max.z); - min.x -= 10.0f*BM_DIM_STEP; - min.z -= 10.0f*BM_DIM_STEP; - max.x += 10.0f*BM_DIM_STEP; - max.z += 10.0f*BM_DIM_STEP; - BitmapTerrain(min, max); - - if ( LeakSearch(m_leakPos, m_leakDelay) ) - { - m_phase = TGP_BEAMLEAK; // must first leak - m_leakTime = 0.0f; - } - else - { - m_physics->SetMotorSpeedX(0.0f); // stops the advance - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - BeamInit(); - m_phase = TGP_BEAMSEARCH; // will seek the path - } -} - -// Initialization before the first BeamSearch. - -void CTaskGoto::BeamInit() -{ - int i; - - for ( i=0 ; i 20.0f ) step = 20.0f; - nbIter = 200; // in order not to lower the framerate - m_bmIterCounter = 0; - return BeamExplore(start, start, goal, goalRadius, 165.0f*PI/180.0f, 22, step, 0, nbIter); -} - -// prevPos: previous position -// curPos: current position -// goalPos: position that seeks to achieve -// angle: angle to the goal we explores -// nbDiv: number of subdivisions being done with angle -// step length of a step -// i number of recursions made -// nbIter maximum number of iterations you have the right to make before temporarily interrupt - -Error CTaskGoto::BeamExplore(const D3DVECTOR &prevPos, const D3DVECTOR &curPos, - const D3DVECTOR &goalPos, float goalRadius, - float angle, int nbDiv, float step, - int i, int nbIter) -{ - D3DVECTOR newPos; - Error ret; - int iDiv, iClear, iLar; - - iLar = 0; - if ( i >= MAXPOINTS ) return ERR_GOTO_ITER; // too many recursions - - if ( m_bmIter[i] == -1 ) - { - m_bmIter[i] = 0; - - if ( i == 0 ) - { - m_bmPoints[i] = curPos; - } - else - { - if ( !BitmapTestLine(prevPos, curPos, angle/nbDiv, TRUE) ) return ERR_GOTO_IMPOSSIBLE; - - m_bmPoints[i] = curPos; - - if ( Length2d(curPos, goalPos)-goalRadius <= step ) - { - if ( goalRadius == 0.0f ) - { - newPos = goalPos; - } - else - { - newPos = BeamPoint(curPos, goalPos, 0, Length2d(curPos, goalPos)-goalRadius); - } - if ( BitmapTestLine(curPos, newPos, angle/nbDiv, FALSE) ) - { - m_bmPoints[i+1] = newPos; - m_bmTotal = i+1; - return ERR_OK; - } - } - } - } - - if ( iLar >= m_bmIter[i] ) - { - newPos = BeamPoint(curPos, goalPos, 0, step); - ret = BeamExplore(curPos, newPos, goalPos, goalRadius, angle, nbDiv, step, i+1, nbIter); - if ( ret != ERR_GOTO_IMPOSSIBLE ) return ret; - m_bmIter[i] = iLar+1; - for ( iClear=i+1 ; iClear<=MAXPOINTS ; iClear++ ) m_bmIter[iClear] = -1; - m_bmIterCounter ++; - if ( m_bmIterCounter >= nbIter ) return ERR_CONTINUE; - } - iLar ++; - - for ( iDiv=1 ; iDiv<=nbDiv ; iDiv++ ) - { - if ( iLar >= m_bmIter[i] ) - { - newPos = BeamPoint(curPos, goalPos, angle*iDiv/nbDiv, step); - ret = BeamExplore(curPos, newPos, goalPos, goalRadius, angle, nbDiv, step, i+1, nbIter); - if ( ret != ERR_GOTO_IMPOSSIBLE ) return ret; - m_bmIter[i] = iLar+1; - for ( iClear=i+1 ; iClear<=MAXPOINTS ; iClear++ ) m_bmIter[iClear] = -1; - m_bmIterCounter ++; - if ( m_bmIterCounter >= nbIter ) return ERR_CONTINUE; - } - iLar ++; - - if ( iLar >= m_bmIter[i] ) - { - newPos = BeamPoint(curPos, goalPos, -angle*iDiv/nbDiv, step); - ret = BeamExplore(curPos, newPos, goalPos, goalRadius, angle, nbDiv, step, i+1, nbIter); - if ( ret != ERR_GOTO_IMPOSSIBLE ) return ret; - m_bmIter[i] = iLar+1; - for ( iClear=i+1 ; iClear<=MAXPOINTS ; iClear++ ) m_bmIter[iClear] = -1; - m_bmIterCounter ++; - if ( m_bmIterCounter >= nbIter ) return ERR_CONTINUE; - } - iLar ++; - } - - return ERR_GOTO_IMPOSSIBLE; -} - -// Is a right "start-goal". Calculates the point located at the distance "step" -// from the point "start" and an angle "angle" with the right. - -D3DVECTOR CTaskGoto::BeamPoint(const D3DVECTOR &startPoint, - const D3DVECTOR &goalPoint, - float angle, float step) -{ - D3DVECTOR resPoint; - float goalAngle; - - goalAngle = RotateAngle(goalPoint.x-startPoint.x, goalPoint.z-startPoint.z); - - resPoint.x = startPoint.x + cosf(goalAngle+angle)*step; - resPoint.z = startPoint.z + sinf(goalAngle+angle)*step; - resPoint.y = 0.0f; - - return resPoint; -} - -// Displays a bitmap part. - -void CTaskGoto::BitmapDebug(const D3DVECTOR &min, const D3DVECTOR &max, - const D3DVECTOR &start, const D3DVECTOR &goal) -{ - int minx, miny, maxx, maxy, x, y, i ,n; - char s[2000]; - - minx = (int)((min.x+1600.0f)/BM_DIM_STEP); - miny = (int)((min.z+1600.0f)/BM_DIM_STEP); - maxx = (int)((max.x+1600.0f)/BM_DIM_STEP); - maxy = (int)((max.z+1600.0f)/BM_DIM_STEP); - - if ( minx > maxx ) Swap(minx, maxx); - if ( miny > maxy ) Swap(miny, maxy); - - OutputDebugString("Bitmap :\n"); - for ( y=miny ; y<=maxy ; y++ ) - { - s[0] = 0; - for ( x=minx ; x<=maxx ; x++ ) - { - n = -1; - for ( i=0 ; i<=m_bmTotal ; i++ ) - { - if ( x == (int)((m_bmPoints[i].x+1600.0f)/BM_DIM_STEP) && - y == (int)((m_bmPoints[i].z+1600.0f)/BM_DIM_STEP) ) - { - n = i; - break; - } - } - - if ( BitmapTestDot(0, x,y) ) - { - strcat(s, "o"); - } - else - { - if ( BitmapTestDot(1, x,y) ) - { - strcat(s, "-"); - } - else - { - strcat(s, "."); - } - } - - if ( x == (int)((start.x+1600.0f)/BM_DIM_STEP) && - y == (int)((start.z+1600.0f)/BM_DIM_STEP) ) - { - strcat(s, "s"); - } - else - if ( x == (int)((goal.x+1600.0f)/BM_DIM_STEP) && - y == (int)((goal.z+1600.0f)/BM_DIM_STEP) ) - { - strcat(s, "g"); - } - else - if ( n != -1 ) - { - char ss[2]; - ss[0] = 'A'+n; - ss[1] = 0; - strcat(s, ss); - } - else - { - strcat(s, " "); - } - } - strcat(s, "\n"); - OutputDebugString(s); - } -} - -// Tests if a path along a straight line is possible. - -BOOL CTaskGoto::BitmapTestLine(const D3DVECTOR &start, const D3DVECTOR &goal, - float stepAngle, BOOL bSecond) -{ - D3DVECTOR pos, inc; - float dist, step; - float distNoB2; - int i, max, x, y; - - if ( m_bmArray == 0 ) return TRUE; - - dist = Length2d(start, goal); - if ( dist == 0.0f ) return TRUE; - step = BM_DIM_STEP*0.5f; - - inc.x = (goal.x-start.x)*step/dist; - inc.z = (goal.z-start.z)*step/dist; - - pos = start; - - if ( bSecond ) - { - x = (int)((pos.x+1600.0f)/BM_DIM_STEP); - y = (int)((pos.z+1600.0f)/BM_DIM_STEP); - BitmapSetDot(1, x, y); // puts the flag as the starting point - } - - max = (int)(dist/step); - if ( max == 0 ) max = 1; - distNoB2 = BM_DIM_STEP*sqrtf(2.0f)/sinf(stepAngle); - for ( i=0 ; i 2 && BitmapTestDot(1, x, y) ) return FALSE; - - if ( step*(i+1) > distNoB2 && i < max-2 ) - { - BitmapSetDot(1, x, y); - } - } - - if ( BitmapTestDot(0, x, y) ) return FALSE; - } - return TRUE; -} - -// Adds the objects in the bitmap. - -void CTaskGoto::BitmapObject() -{ - CObject *pObj; - ObjectType type; - D3DVECTOR iPos, oPos; - float iRadius, oRadius, h; - int i, j; - - m_object->GetCrashSphere(0, iPos, iRadius); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - - if ( pObj == m_object ) continue; - if ( pObj == m_bmFretObject ) continue; - if ( pObj->RetTruck() != 0 ) continue; - - h = m_terrain->RetFloorLevel(pObj->RetPosition(0), FALSE); - if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f ) - { - h += m_altitude; - } - - j = 0; - while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) - { - if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f ) // flying? - { - if ( oPos.y-oRadius > h+8.0f || - oPos.y+oRadius < h-8.0f ) continue; - } - else // crawling? - { - if ( oPos.y-oRadius > h+8.0f ) continue; - } - - if ( type == OBJECT_PARA ) oRadius -= 2.0f; - BitmapSetCircle(oPos, oRadius+iRadius+4.0f); - } - } -} - -// Adds a section of land in the bitmap. - -void CTaskGoto::BitmapTerrain(const D3DVECTOR &min, const D3DVECTOR &max) -{ - int minx, miny, maxx, maxy; - - minx = (int)((min.x+1600.0f)/BM_DIM_STEP); - miny = (int)((min.z+1600.0f)/BM_DIM_STEP); - maxx = (int)((max.x+1600.0f)/BM_DIM_STEP); - maxy = (int)((max.z+1600.0f)/BM_DIM_STEP); - - BitmapTerrain(minx, miny, maxx, maxy); -} - -// Adds a section of land in the bitmap. - -void CTaskGoto::BitmapTerrain(int minx, int miny, int maxx, int maxy) -{ - ObjectType type; - D3DVECTOR p; - float aLimit, angle, h; - int x, y; - BOOL bAcceptWater, bFly; - - if ( minx > maxx ) Swap(minx, maxx); - if ( miny > maxy ) Swap(miny, maxy); - - if ( minx < 0 ) minx = 0; - if ( miny < 0 ) miny = 0; - if ( maxx > m_bmSize-1 ) maxx = m_bmSize-1; - if ( maxy > m_bmSize-1 ) maxy = m_bmSize-1; - - if ( minx > m_bmMinX ) minx = m_bmMinX; - if ( miny > m_bmMinY ) miny = m_bmMinY; - if ( maxx < m_bmMaxX ) maxx = m_bmMaxX; - if ( maxy < m_bmMaxY ) maxy = m_bmMaxY; - - if ( minx >= m_bmMinX && maxx <= m_bmMaxX && - miny >= m_bmMinY && maxy <= m_bmMaxY ) return; - - aLimit = 20.0f*PI/180.0f; - bAcceptWater = FALSE; - bFly = FALSE; - - type = m_object->RetType(); - - if ( type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEtg ) // wheels? - { - aLimit = 20.0f*PI/180.0f; - } - - if ( type == OBJECT_MOBILEta || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEts ) // caterpillars? - { - aLimit = 35.0f*PI/180.0f; - } - - if ( type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs ) // large caterpillars? - { - aLimit = 35.0f*PI/180.0f; - } - - if ( type == OBJECT_MOBILEsa ) // submarine caterpillars? - { - aLimit = 35.0f*PI/180.0f; - bAcceptWater = TRUE; - } - - if ( type == OBJECT_MOBILEdr ) // designer caterpillars? - { - aLimit = 35.0f*PI/180.0f; - } - - if ( type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEft ) // flying? - { - aLimit = 15.0f*PI/180.0f; - bFly = TRUE; - } - - if ( type == OBJECT_MOBILEia || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILEii ) // insect legs? - { - aLimit = 60.0f*PI/180.0f; - } - - for ( y=miny ; y<=maxy ; y++ ) - { - for ( x=minx ; x<=maxx ; x++ ) - { - if ( x >= m_bmMinX && x <= m_bmMaxX && - y >= m_bmMinY && y <= m_bmMaxY ) continue; - - p.x = x*BM_DIM_STEP-1600.0f; - p.z = y*BM_DIM_STEP-1600.0f; - - if ( bFly ) // flying robot? - { - h = m_terrain->RetFloorLevel(p, TRUE); - if ( h >= m_terrain->RetFlyingMaxHeight()-5.0f ) - { - BitmapSetDot(0, x, y); - } - continue; - } - - if ( !bAcceptWater ) // not going underwater? - { - h = m_terrain->RetFloorLevel(p, TRUE); - if ( h < m_water->RetLevel()-2.0f ) // under water (*)? - { -//? BitmapSetDot(0, x, y); - BitmapSetCircle(p, BM_DIM_STEP*1.0f); - continue; - } - } - - angle = m_terrain->RetFineSlope(p); - if ( angle > aLimit ) - { - BitmapSetDot(0, x, y); - } - } - } - - m_bmMinX = minx; - m_bmMinY = miny; - m_bmMaxX = maxx; - m_bmMaxY = maxy; // expanded rectangular area -} - -// (*) Accepts that a robot is 50cm under water, for example Tropica 3! - -// Opens an empty bitmap. - -BOOL CTaskGoto::BitmapOpen() -{ - BitmapClose(); - - m_bmSize = (int)(3200.0f/BM_DIM_STEP); - m_bmArray = (unsigned char*)malloc(m_bmSize*m_bmSize/8*2); - ZeroMemory(m_bmArray, m_bmSize*m_bmSize/8*2); - - m_bmOffset = m_bmSize/2; - m_bmLine = m_bmSize/8; - - m_bmMinX = m_bmSize; // non-existent rectangular area - m_bmMinY = m_bmSize; - m_bmMaxX = 0; - m_bmMaxY = 0; - - return TRUE; -} - -// Closes the bitmap. - -BOOL CTaskGoto::BitmapClose() -{ - free(m_bmArray); - m_bmArray = 0; - return TRUE; -} - -// Puts a circle in the bitmap. - -void CTaskGoto::BitmapSetCircle(const D3DVECTOR &pos, float radius) -{ - float d, r; - int cx, cy, ix, iy; - - cx = (int)((pos.x+1600.0f)/BM_DIM_STEP); - cy = (int)((pos.z+1600.0f)/BM_DIM_STEP); - r = radius/BM_DIM_STEP; - - for ( iy=cy-(int)r ; iy<=cy+(int)r ; iy++ ) - { - for ( ix=cx-(int)r ; ix<=cx+(int)r ; ix++ ) - { - d = Length((float)(ix-cx), (float)(iy-cy)); - if ( d > r ) continue; - BitmapSetDot(0, ix, iy); - } - } -} - -// Removes a circle in the bitmap. - -void CTaskGoto::BitmapClearCircle(const D3DVECTOR &pos, float radius) -{ - float d, r; - int cx, cy, ix, iy; - - cx = (int)((pos.x+1600.0f)/BM_DIM_STEP); - cy = (int)((pos.z+1600.0f)/BM_DIM_STEP); - r = radius/BM_DIM_STEP; - - for ( iy=cy-(int)r ; iy<=cy+(int)r ; iy++ ) - { - for ( ix=cx-(int)r ; ix<=cx+(int)r ; ix++ ) - { - d = Length((float)(ix-cx), (float)(iy-cy)); - if ( d > r ) continue; - BitmapClearDot(0, ix, iy); - } - } -} - -// Makes a point in the bitmap. -// x:y: 0..m_bmSize-1 - -void CTaskGoto::BitmapSetDot(int rank, int x, int y) -{ - if ( x < 0 || x >= m_bmSize || - y < 0 || y >= m_bmSize ) return; - - m_bmArray[rank*m_bmLine*m_bmSize + m_bmLine*y + x/8] |= (1<= m_bmSize || - y < 0 || y >= m_bmSize ) return; - - m_bmArray[rank*m_bmLine*m_bmSize + m_bmLine*y + x/8] &= ~(1<= m_bmSize || - y < 0 || y >= m_bmSize ) return FALSE; - - if ( x < m_bmMinX || x > m_bmMaxX || - y < m_bmMinY || y > m_bmMaxY ) - { - BitmapTerrain(x-10,y-10, x+10,y+10); // remade a layer - } - - return m_bmArray[rank*m_bmLine*m_bmSize + m_bmLine*y + x/8] & (1< -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "object.h" -#include "sound.h" -#include "task.h" -#include "taskgungoal.h" - - - - -// Object's constructor. - -CTaskGunGoal::CTaskGunGoal(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); -} - -// Object's destructor. - -CTaskGunGoal::~CTaskGunGoal() -{ -} - - -// Management of an event. - -BOOL CTaskGunGoal::EventProcess(const Event &event) -{ - float dir; - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_progress += event.rTime*m_speed; - - if ( m_progress < 1.0f ) - { - dir = m_initialDirV + (m_finalDirV-m_initialDirV)*m_progress; - } - else - { - dir = m_finalDirV; - } - m_object->SetGunGoalV(dir); - - if ( m_progress < 1.0f ) - { - dir = m_initialDirH + (m_finalDirH-m_initialDirH)*m_progress; - } - else - { - dir = m_finalDirH; - } - m_object->SetGunGoalH(dir); - - return TRUE; -} - - -// Assigns the goal was achieved. - -Error CTaskGunGoal::Start(float dirV, float dirH) -{ - float speedV, speedH; - int i; - - m_initialDirV = m_object->RetGunGoalV(); - m_object->SetGunGoalV(dirV); - m_finalDirV = m_object->RetGunGoalV(); // possible direction - m_object->SetGunGoalV(m_initialDirV); // gives initial direction - - if ( m_finalDirV == m_initialDirV ) - { - speedV = 100.0f; - } - else - { - speedV = 1.0f/(Abs(m_finalDirV-m_initialDirV)*1.0f); - } - - m_initialDirH = m_object->RetGunGoalH(); - m_object->SetGunGoalH(dirH); - m_finalDirH = m_object->RetGunGoalH(); // possible direction - m_object->SetGunGoalH(m_initialDirH); // gives initial direction - - if ( m_finalDirH == m_initialDirH ) - { - speedH = 100.0f; - } - else - { - speedH = 1.0f/(Abs(m_finalDirH-m_initialDirH)*1.0f); - } - - m_speed = Min(speedV, speedH); - - if ( m_finalDirV != m_initialDirV || - m_finalDirH != m_initialDirH ) - { - i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.3f, 1.5f, TRUE); - m_sound->AddEnvelope(i, 0.3f, 1.5f, 1.0f/m_speed, SOPER_STOP); - } - - m_progress = 0.0f; - - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskGunGoal::IsEnded() -{ - if ( m_engine->RetPause() ) return ERR_CONTINUE; - - if ( m_initialDirV == m_finalDirV && - m_initialDirH == m_finalDirH ) return ERR_STOP; - if ( m_progress < 1.0f ) return ERR_CONTINUE; - - m_object->SetGunGoalV(m_finalDirV); - m_object->SetGunGoalH(m_finalDirH); - Abort(); - return ERR_STOP; -} - -// Suddenly ends the current action. - -BOOL CTaskGunGoal::Abort() -{ - return TRUE; -} - diff --git a/src/taskgungoal.h b/src/taskgungoal.h deleted file mode 100644 index 4b6cbc7..0000000 --- a/src/taskgungoal.h +++ /dev/null @@ -1,57 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskgungoal.h - -#ifndef _TASKGUNGOAL_H_ -#define _TASKGUNGOAL_H_ - - -#include "misc.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - -class CTaskGunGoal : public CTask -{ -public: - CTaskGunGoal(CInstanceManager* iMan, CObject* object); - ~CTaskGunGoal(); - - BOOL EventProcess(const Event &event); - - Error Start(float dirV, float dirH); - Error IsEnded(); - BOOL Abort(); - -protected: - -protected: - float m_progress; - float m_speed; - float m_initialDirV; // initial direction - float m_finalDirV; // direction to reach - float m_initialDirH; // initial direction - float m_finalDirH; // direction to reach -}; - - -#endif //_TASKGUNGOAL_H_ diff --git a/src/taskinfo.cpp b/src/taskinfo.cpp deleted file mode 100644 index 51deb79..0000000 --- a/src/taskinfo.cpp +++ /dev/null @@ -1,233 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskinfo.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "sound.h" -#include "auto.h" -#include "autoinfo.h" -#include "task.h" -#include "taskinfo.h" - - - - -// Object's constructor. - -CTaskInfo::CTaskInfo(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); -} - -// Object's destructor. - -CTaskInfo::~CTaskInfo() -{ -} - - -// Management of an event. - -BOOL CTaskInfo::EventProcess(const Event &event) -{ - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_bError ) return FALSE; - - m_progress += event.rTime*m_speed; // other advance - m_time += event.rTime; - - return TRUE; -} - - -// Assigns the goal was achieved. - -Error CTaskInfo::Start(char *name, float value, float power, BOOL bSend) -{ - CObject* pInfo; - CAutoInfo* pAuto; - D3DVECTOR pos, goal; - Info info; - int i, total, op; - - m_bError = TRUE; - m_object->SetInfoReturn(NAN); - - pInfo = SearchInfo(power); // seeks terminal - if ( pInfo == 0 ) - { - return ERR_INFO_NULL; - } - - pAuto = (CAutoInfo*)pInfo->RetAuto(); - if ( pAuto == 0 ) - { - return ERR_INFO_NULL; - } - - op = 1; // transmission impossible - if ( bSend ) // send? - { - total = pInfo->RetInfoTotal(); - for ( i=0 ; iRetInfo(i); - if ( strcmp(info.name, name) == 0 ) - { - info.value = value; - pInfo->SetInfo(i, info); - break; - } - } - if ( i == total ) - { - if ( total < OBJECTMAXINFO ) - { - strcpy(info.name, name); - info.value = value; - pInfo->SetInfo(total, info); - op = 2; // start of reception (for terminal) - } - } - else - { - op = 2; // start of reception (for terminal) - } - } - else // receive? - { - total = pInfo->RetInfoTotal(); - for ( i=0 ; iRetInfo(i); - if ( strcmp(info.name, name) == 0 ) - { - m_object->SetInfoReturn(info.value); - break; - } - } - if ( i < total ) - { - op = 0; // beginning of transmission (for terminal) - } - } - - pAuto->Start(op); - - if ( op == 0 ) // transmission? - { - pos = pInfo->RetPosition(0); - pos.y += 9.5f; - goal = m_object->RetPosition(0); - goal.y += 4.0f; - m_particule->CreateRay(pos, goal, PARTIRAY3, FPOINT(2.0f, 2.0f), 1.0f); - } - if ( op == 2 ) // reception? - { - goal = pInfo->RetPosition(0); - goal.y += 9.5f; - pos = m_object->RetPosition(0); - pos.y += 4.0f; - m_particule->CreateRay(pos, goal, PARTIRAY3, FPOINT(2.0f, 2.0f), 1.0f); - } - - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - m_time = 0.0f; - - m_bError = FALSE; // ok - - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskInfo::IsEnded() -{ - if ( m_engine->RetPause() ) return ERR_CONTINUE; - if ( m_bError ) return ERR_STOP; - - if ( m_progress < 1.0f ) return ERR_CONTINUE; - m_progress = 0.0f; - - Abort(); - return ERR_STOP; -} - -// Suddenly ends the current action. - -BOOL CTaskInfo::Abort() -{ - return TRUE; -} - - -// Seeks the nearest information terminal. - -CObject* CTaskInfo::SearchInfo(float power) -{ - CObject *pObj, *pBest; - D3DVECTOR iPos, oPos; - ObjectType type; - float dist, min; - int i; - - iPos = m_object->RetPosition(0); - - min = 100000.0f; - pBest = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type != OBJECT_INFO ) continue; - - if ( !pObj->RetActif() ) continue; - - oPos = pObj->RetPosition(0); - dist = Length(oPos, iPos); - if ( dist > power ) continue; // too far? - if ( dist < min ) - { - min = dist; - pBest = pObj; - } - } - - return pBest; -} - diff --git a/src/taskinfo.h b/src/taskinfo.h deleted file mode 100644 index 26b2071..0000000 --- a/src/taskinfo.h +++ /dev/null @@ -1,57 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskinfo.h - -#ifndef _TASKINFO_H_ -#define _TASKINFO_H_ - - -#include "misc.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - - -class CTaskInfo : public CTask -{ -public: - CTaskInfo(CInstanceManager* iMan, CObject* object); - ~CTaskInfo(); - - BOOL EventProcess(const Event &event); - - Error Start(char *name, float value, float power, BOOL bSend); - Error IsEnded(); - BOOL Abort(); - -protected: - CObject* SearchInfo(float power); - -protected: - float m_progress; - float m_speed; - float m_time; - BOOL m_bError; -}; - - -#endif //_TASKINFO_H_ diff --git a/src/taskmanager.cpp b/src/taskmanager.cpp deleted file mode 100644 index ffc0d05..0000000 --- a/src/taskmanager.cpp +++ /dev/null @@ -1,291 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskmanager.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "misc.h" -#include "iman.h" -#include "event.h" -#include "object.h" -#include "task.h" -#include "taskwait.h" -#include "taskadvance.h" -#include "taskturn.h" -#include "taskgoto.h" -#include "tasktake.h" -#include "taskmanip.h" -#include "taskflag.h" -#include "taskbuild.h" -#include "tasksearch.h" -#include "taskterraform.h" -#include "taskpen.h" -#include "taskrecover.h" -#include "taskshield.h" -#include "taskinfo.h" -#include "taskfire.h" -#include "taskfireant.h" -#include "taskgungoal.h" -#include "taskspiderexplo.h" -#include "taskreset.h" -#include "taskmanager.h" - - - - -// Object's constructor. - -CTaskManager::CTaskManager(CInstanceManager* iMan, CObject* object) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_TASKMANAGER, this, 100); - - m_task = 0; - m_object = object; - m_bPilot = FALSE; -} - -// Object's destructor. - -CTaskManager::~CTaskManager() -{ - delete m_task; -} - - - -// Waits for a while. - -Error CTaskManager::StartTaskWait(float time) -{ - m_task = new CTaskWait(m_iMan, m_object); - return ((CTaskWait*)m_task)->Start(time); -} - -// Advance straight ahead a certain distance. - -Error CTaskManager::StartTaskAdvance(float length) -{ - m_task = new CTaskAdvance(m_iMan, m_object); - return ((CTaskAdvance*)m_task)->Start(length); -} - -// Turns through an certain angle. - -Error CTaskManager::StartTaskTurn(float angle) -{ - m_task = new CTaskTurn(m_iMan, m_object); - return ((CTaskTurn*)m_task)->Start(angle); -} - -// Reaches a given position. - -Error CTaskManager::StartTaskGoto(D3DVECTOR pos, float altitude, TaskGotoGoal goalMode, TaskGotoCrash crashMode) -{ - m_task = new CTaskGoto(m_iMan, m_object); - return ((CTaskGoto*)m_task)->Start(pos, altitude, goalMode, crashMode); -} - -// Move the manipulator arm. - -Error CTaskManager::StartTaskTake() -{ - m_task = new CTaskTake(m_iMan, m_object); - return ((CTaskTake*)m_task)->Start(); -} - -// Move the manipulator arm. - -Error CTaskManager::StartTaskManip(TaskManipOrder order, TaskManipArm arm) -{ - m_task = new CTaskManip(m_iMan, m_object); - return ((CTaskManip*)m_task)->Start(order, arm); -} - -// Puts or removes a flag. - -Error CTaskManager::StartTaskFlag(TaskFlagOrder order, int rank) -{ - m_task = new CTaskFlag(m_iMan, m_object); - return ((CTaskFlag*)m_task)->Start(order, rank); -} - -// Builds a building. - -Error CTaskManager::StartTaskBuild(ObjectType type) -{ - m_task = new CTaskBuild(m_iMan, m_object); - return ((CTaskBuild*)m_task)->Start(type); -} - -// Probe the ground. - -Error CTaskManager::StartTaskSearch() -{ - m_task = new CTaskSearch(m_iMan, m_object); - return ((CTaskSearch*)m_task)->Start(); -} - -// Reads an information terminal. - -Error CTaskManager::StartTaskInfo(char *name, float value, float power, BOOL bSend) -{ - m_task = new CTaskInfo(m_iMan, m_object); - return ((CTaskInfo*)m_task)->Start(name, value, power, bSend); -} - -// Terraforms the ground. - -Error CTaskManager::StartTaskTerraform() -{ - m_task = new CTaskTerraform(m_iMan, m_object); - return ((CTaskTerraform*)m_task)->Start(); -} - -// Changes the pencil. - -Error CTaskManager::StartTaskPen(BOOL bDown, int color) -{ - m_task = new CTaskPen(m_iMan, m_object); - return ((CTaskPen*)m_task)->Start(bDown, color); -} - -// Recovers a ruin. - -Error CTaskManager::StartTaskRecover() -{ - m_task = new CTaskRecover(m_iMan, m_object); - return ((CTaskRecover*)m_task)->Start(); -} - -// Deploys the shield. - -Error CTaskManager::StartTaskShield(TaskShieldMode mode, float delay) -{ - if ( mode == TSM_UP ) - { - m_task = new CTaskShield(m_iMan, m_object); - return ((CTaskShield*)m_task)->Start(mode, delay); - } - if ( mode == TSM_DOWN && m_task != 0 ) - { - return ((CTaskShield*)m_task)->Start(mode, delay); - } - if ( mode == TSM_UPDATE && m_task != 0 ) - { - return ((CTaskShield*)m_task)->Start(mode, delay); - } - return ERR_GENERIC; -} - -// Shoots. - -Error CTaskManager::StartTaskFire(float delay) -{ - m_bPilot = TRUE; - m_task = new CTaskFire(m_iMan, m_object); - return ((CTaskFire*)m_task)->Start(delay); -} - -// Shoots with the ant. - -Error CTaskManager::StartTaskFireAnt(D3DVECTOR impact) -{ - m_task = new CTaskFireAnt(m_iMan, m_object); - return ((CTaskFireAnt*)m_task)->Start(impact); -} - -// Adjusts higher. - -Error CTaskManager::StartTaskGunGoal(float dirV, float dirH) -{ - m_task = new CTaskGunGoal(m_iMan, m_object); - return ((CTaskGunGoal*)m_task)->Start(dirV, dirH); -} - -// Suicide of the spider. - -Error CTaskManager::StartTaskSpiderExplo() -{ - m_task = new CTaskSpiderExplo(m_iMan, m_object); - return ((CTaskSpiderExplo*)m_task)->Start(); -} - -// Reset. - -Error CTaskManager::StartTaskReset(D3DVECTOR goal, D3DVECTOR angle) -{ - m_task = new CTaskReset(m_iMan, m_object); - return ((CTaskReset*)m_task)->Start(goal, angle); -} - - - - - -// Management of an event. - -BOOL CTaskManager::EventProcess(const Event &event) -{ - if ( m_task == 0 ) return FALSE; - return m_task->EventProcess(event); -} - - -// Indicates whether the action is finished. - -Error CTaskManager::IsEnded() -{ - if ( m_task == 0 ) return ERR_GENERIC; - return m_task->IsEnded(); -} - - -// Indicates whether the action is pending. - -BOOL CTaskManager::IsBusy() -{ - if ( m_task == 0 ) return FALSE; - return m_task->IsBusy(); -} - - -// Indicates whether it is possible to control the robot -// during the execution of the current task. - -BOOL CTaskManager::IsPilot() -{ - return m_bPilot; -} - - -// Suddenly ends the current action. - -BOOL CTaskManager::Abort() -{ - if ( m_task == 0 ) return FALSE; - return m_task->Abort(); -} - - diff --git a/src/taskmanager.h b/src/taskmanager.h deleted file mode 100644 index 2c6c21f..0000000 --- a/src/taskmanager.h +++ /dev/null @@ -1,77 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskmanager.h - -#ifndef _TASKMANAGER_H_ -#define _TASKMANAGER_H_ - -#include "misc.h" -#include "object.h" -#include "taskmanip.h" -#include "taskgoto.h" -#include "taskshield.h" -#include "taskflag.h" - - -class CInstanceManager; -class CTask; - - - -class CTaskManager -{ -public: - CTaskManager(CInstanceManager* iMan, CObject* object); - ~CTaskManager(); - - Error StartTaskWait(float time); - Error StartTaskAdvance(float length); - Error StartTaskTurn(float angle); - Error StartTaskGoto(D3DVECTOR pos, float altitude, TaskGotoGoal goalMode, TaskGotoCrash crashMode); - Error StartTaskTake(); - Error StartTaskManip(TaskManipOrder order, TaskManipArm arm); - Error StartTaskFlag(TaskFlagOrder order, int rank); - Error StartTaskBuild(ObjectType type); - Error StartTaskSearch(); - Error StartTaskInfo(char *name, float value, float power, BOOL bSend); - Error StartTaskTerraform(); - Error StartTaskPen(BOOL bDown, int color); - Error StartTaskRecover(); - Error StartTaskShield(TaskShieldMode mode, float delay); - Error StartTaskFire(float delay); - Error StartTaskFireAnt(D3DVECTOR impact); - Error StartTaskGunGoal(float dirV, float dirH); - Error StartTaskSpiderExplo(); - Error StartTaskReset(D3DVECTOR goal, D3DVECTOR angle); - - BOOL EventProcess(const Event &event); - Error IsEnded(); - BOOL IsBusy(); - BOOL IsPilot(); - BOOL Abort(); - -protected: - -protected: - CInstanceManager* m_iMan; - CTask* m_task; - CObject* m_object; - BOOL m_bPilot; -}; - - -#endif //_TASKMANAGER_H_ diff --git a/src/taskmanip.cpp b/src/taskmanip.cpp deleted file mode 100644 index 672b96e..0000000 --- a/src/taskmanip.cpp +++ /dev/null @@ -1,1398 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskmanip.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "terrain.h" -#include "object.h" -#include "pyro.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "sound.h" -#include "robotmain.h" -#include "task.h" -#include "taskmanip.h" - - -//?#define MARGIN_FRONT 2.0f -//?#define MARGIN_BACK 2.0f -//?#define MARGIN_FRIEND 2.0f -//?#define MARGIN_BEE 5.0f -#define MARGIN_FRONT 4.0f //OK 1.9 -#define MARGIN_BACK 4.0f //OK 1.9 -#define MARGIN_FRIEND 4.0f //OK 1.9 -#define MARGIN_BEE 5.0f //OK 1.9 - - - - -// Object's constructor. - -CTaskManip::CTaskManip(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); - - m_arm = TMA_NEUTRAL; - m_hand = TMH_OPEN; -} - -// Object's destructor. - -CTaskManip::~CTaskManip() -{ -} - - -// Management of an event. - -BOOL CTaskManip::EventProcess(const Event &event) -{ - D3DVECTOR pos; - float angle, a, g, cirSpeed, progress; - int i; - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_bError ) return FALSE; - - if ( m_bBee ) // bee? - { - return TRUE; - } - - if ( m_bTurn ) // preliminary rotation? - { - a = m_object->RetAngleY(0); - g = m_angle; - cirSpeed = Direction(a, g)*1.0f; - if ( m_physics->RetType() == TYPE_FLYING ) // flying on the ground? - { - cirSpeed *= 4.0f; // more fishing - } - if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; - if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; - - m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right - return TRUE; - } - - if ( m_move != 0 ) // preliminary advance? - { - m_timeLimit -= event.rTime; - m_physics->SetMotorSpeedX(m_move); // forward/backward - return TRUE; - } - - m_progress += event.rTime*m_speed; // others advance - progress = m_progress; - if ( progress > 1.0f ) progress = 1.0f; - - if ( m_bSubm ) // submarine? - { - if ( m_order == TMO_GRAB ) - { - if ( m_step == 0 ) // fall? - { - pos = m_object->RetPosition(1); - pos.y = 3.0f-progress*2.0f; - m_object->SetPosition(1, pos); - } - if ( m_step == 1 ) // farm? - { - pos = m_object->RetPosition(2); - pos.z = -1.5f+progress*0.5f; - m_object->SetPosition(2, pos); - - pos = m_object->RetPosition(3); - pos.z = 1.5f-progress*0.5f; - m_object->SetPosition(3, pos); - } - if ( m_step == 2 ) // up? - { - pos = m_object->RetPosition(1); - pos.y = 3.0f-(1.0f-progress)*2.0f; - m_object->SetPosition(1, pos); - } - } - else - { - if ( m_step == 0 ) // fall? - { - pos = m_object->RetPosition(1); - pos.y = 3.0f-progress*2.0f; - m_object->SetPosition(1, pos); - } - if ( m_step == 1 ) // farm? - { - pos = m_object->RetPosition(2); - pos.z = -1.5f+(1.0f-progress)*0.5f; - m_object->SetPosition(2, pos); - - pos = m_object->RetPosition(3); - pos.z = 1.5f-(1.0f-progress)*0.5f; - m_object->SetPosition(3, pos); - } - if ( m_step == 2 ) // up? - { - pos = m_object->RetPosition(1); - pos.y = 3.0f-(1.0f-progress)*2.0f; - m_object->SetPosition(1, pos); - } - } - } - else - { - for ( i=0 ; i<5 ; i++ ) - { - angle = (m_finalAngle[i]-m_initialAngle[i])*progress; - angle += m_initialAngle[i]; - m_object->SetAngleZ(i+1, angle); - } - } - - return TRUE; -} - - -// Initializes the initial and final angles. - -void CTaskManip::InitAngle() -{ - CObject* power; - float max, energy; - int i; - - if ( m_bSubm || m_bBee ) return; - - if ( m_arm == TMA_NEUTRAL || - m_arm == TMA_GRAB ) - { - m_finalAngle[0] = ARM_NEUTRAL_ANGLE1; // arm - m_finalAngle[1] = ARM_NEUTRAL_ANGLE2; // forearm - m_finalAngle[2] = ARM_NEUTRAL_ANGLE3; // hand - } - if ( m_arm == TMA_STOCK ) - { - m_finalAngle[0] = ARM_STOCK_ANGLE1; // arm - m_finalAngle[1] = ARM_STOCK_ANGLE2; // forearm - m_finalAngle[2] = ARM_STOCK_ANGLE3; // hand - } - if ( m_arm == TMA_FFRONT ) - { - m_finalAngle[0] = 35.0f*PI/180.0f; // arm - m_finalAngle[1] = -95.0f*PI/180.0f; // forearm - m_finalAngle[2] = -27.0f*PI/180.0f; // hand - } - if ( m_arm == TMA_FBACK ) - { - m_finalAngle[0] = 145.0f*PI/180.0f; // arm - m_finalAngle[1] = 95.0f*PI/180.0f; // forearm - m_finalAngle[2] = 27.0f*PI/180.0f; // hand - } - if ( m_arm == TMA_POWER ) - { - m_finalAngle[0] = 95.0f*PI/180.0f; // arm - m_finalAngle[1] = 125.0f*PI/180.0f; // forearm - m_finalAngle[2] = 50.0f*PI/180.0f; // hand - } - if ( m_arm == TMA_OTHER ) - { - if ( m_height <= 3.0f ) - { - m_finalAngle[0] = 55.0f*PI/180.0f; // arm - m_finalAngle[1] = -90.0f*PI/180.0f; // forearm - m_finalAngle[2] = -35.0f*PI/180.0f; // hand - } - else - { - m_finalAngle[0] = 70.0f*PI/180.0f; // arm - m_finalAngle[1] = -90.0f*PI/180.0f; // forearm - m_finalAngle[2] = -50.0f*PI/180.0f; // hand - } - } - - if ( m_hand == TMH_OPEN ) // open clamp? - { - m_finalAngle[3] = -PI*0.10f; // clamp close - m_finalAngle[4] = PI*0.10f; // clamp remote - } - if ( m_hand == TMH_CLOSE ) // clamp closed? - { - m_finalAngle[3] = PI*0.05f; // clamp close - m_finalAngle[4] = -PI*0.05f; // clamp remote - } - - for ( i=0 ; i<5 ; i++ ) - { - m_initialAngle[i] = m_object->RetAngleZ(i+1); - } - - max = 0.0f; - for ( i=0 ; i<5 ; i++ ) - { - max = Max(max, Abs(m_initialAngle[i] - m_finalAngle[i])); - } - m_speed = (PI*1.0f)/max; - if ( m_speed > 3.0f ) m_speed = 3.0f; // piano, ma non troppo (?) - - energy = 0.0f; - power = m_object->RetPower(); - if ( power != 0 ) - { - energy = power->RetEnergy(); - } - - if ( energy == 0.0f ) - { - m_speed *= 0.7f; // slower if more energy! - } -} - - -// Tests whether an object is compatible with the operation TMA_OTHER. - -BOOL TestFriend(ObjectType oType, ObjectType fType) -{ - if ( oType == OBJECT_ENERGY ) - { - return ( fType == OBJECT_METAL ); - } - if ( oType == OBJECT_LABO ) - { - return ( fType == OBJECT_BULLET ); - } - if ( oType == OBJECT_NUCLEAR ) - { - return ( fType == OBJECT_URANIUM ); - } - - return ( fType == OBJECT_POWER || - fType == OBJECT_ATOMIC ); -} - -// Assigns the goal was achieved. - -Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) -{ - ObjectType type; - CObject *front, *other, *power; - CPyro *pyro; - float iAngle, dist, len; - float fDist, fAngle, oDist, oAngle, oHeight; - D3DVECTOR pos, fPos, oPos; - - m_arm = arm; - m_height = 0.0f; - m_step = 0; - m_progress = 0.0f; - m_speed = 1.0f/1.5f; - - iAngle = m_object->RetAngleY(0); - iAngle = NormAngle(iAngle); // 0..2*PI - oAngle = iAngle; - - m_bError = TRUE; // operation impossible - - if ( m_arm != TMA_FFRONT && - m_arm != TMA_FBACK && - m_arm != TMA_POWER && - m_arm != TMA_GRAB ) return ERR_MANIP_VEH; - - m_physics->SetMotorSpeed(D3DVECTOR(0.0f, 0.0f, 0.0f)); - - type = m_object->RetType(); - if ( type == OBJECT_BEE ) // bee? - { - if ( m_object->RetFret() == 0 ) - { - if ( !m_physics->RetLand() ) return ERR_MANIP_FLY; - - other = SearchTakeUnderObject(m_targetPos, MARGIN_BEE); - if ( other == 0 ) return ERR_MANIP_NIL; - m_object->SetFret(other); // takes the ball - other->SetTruck(m_object); - other->SetTruckPart(0); // taken with the base - other->SetPosition(0, D3DVECTOR(0.0f, -3.0f, 0.0f)); - } - else - { - other = m_object->RetFret(); // other = ball - m_object->SetFret(0); // lick the ball - other->SetTruck(0); - pos = m_object->RetPosition(0); - pos.y -= 3.0f; - other->SetPosition(0, pos); - - pos = m_object->RetPosition(0); - pos.y += 2.0f; - m_object->SetPosition(0, pos); // against the top of jump - - pyro = new CPyro(m_iMan); - pyro->Create(PT_FALL, other); // the ball falls - } - - m_bBee = TRUE; - m_bError = FALSE; // ok - return ERR_OK; - } - m_bBee = FALSE; - - m_bSubm = ( type == OBJECT_MOBILEsa ); // submarine? - - if ( m_arm == TMA_GRAB ) // takes immediately? - { - TruckTakeObject(); - Abort(); - return ERR_OK; - } - - m_energy = 0.0f; - power = m_object->RetPower(); - if ( power != 0 ) - { - m_energy = power->RetEnergy(); - } - - if ( !m_physics->RetLand() ) return ERR_MANIP_FLY; - - if ( type != OBJECT_MOBILEfa && - type != OBJECT_MOBILEta && - type != OBJECT_MOBILEwa && - type != OBJECT_MOBILEia && - type != OBJECT_MOBILEsa ) return ERR_MANIP_VEH; - - if ( m_bSubm ) // submarine? - { - m_arm = TMA_FFRONT; // only possible in front! - } - - m_move = 0.0f; // advance not necessary - m_angle = iAngle; - - if ( order == TMO_AUTO ) - { - if ( m_object->RetFret() == 0 ) - { - m_order = TMO_GRAB; - } - else - { - m_order = TMO_DROP; - } - } - else - { - m_order = order; - } - - if ( m_order == TMO_GRAB && m_object->RetFret() != 0 ) - { - return ERR_MANIP_BUSY; - } - if ( m_order == TMO_DROP && m_object->RetFret() == 0 ) - { - return ERR_MANIP_EMPTY; - } - -//? speed = m_physics->RetMotorSpeed(); -//? if ( speed.x != 0.0f || -//? speed.z != 0.0f ) return ERR_MANIP_MOTOR; - - if ( m_order == TMO_GRAB ) - { - if ( m_arm == TMA_FFRONT ) - { - front = SearchTakeFrontObject(TRUE, fPos, fDist, fAngle); - other = SearchOtherObject(TRUE, oPos, oDist, oAngle, oHeight); - - if ( front != 0 && fDist < oDist ) - { - m_targetPos = fPos; - m_angle = fAngle; - m_move = 1.0f; // advance required - } - else if ( other != 0 && oDist < fDist ) - { - if ( other->RetPower() == 0 ) return ERR_MANIP_NIL; - m_targetPos = oPos; - m_angle = oAngle; - m_height = oHeight; - m_move = 1.0f; // advance required - m_arm = TMA_OTHER; - } - else - { - return ERR_MANIP_NIL; - } - m_main->HideDropZone(front); // hides buildable area - } - if ( m_arm == TMA_FBACK ) - { - if ( SearchTakeBackObject(TRUE, m_targetPos, fDist, m_angle) == 0 ) - { - return ERR_MANIP_NIL; - } - m_angle += PI; - m_move = -1.0f; // back necessary - } - if ( m_arm == TMA_POWER ) - { - if ( m_object->RetPower() == 0 ) return ERR_MANIP_NIL; - } - } - - if ( m_order == TMO_DROP ) - { - if ( m_arm == TMA_FFRONT ) - { - other = SearchOtherObject(TRUE, oPos, oDist, oAngle, oHeight); - if ( other != 0 && other->RetPower() == 0 ) - { - m_targetPos = oPos; - m_angle = oAngle; - m_height = oHeight; - m_move = 1.0f; // advance required - m_arm = TMA_OTHER; - } - else - { - if ( !IsFreeDeposeObject(D3DVECTOR(TAKE_DIST, 0.0f, 0.0f)) ) return ERR_MANIP_OCC; - } - } - if ( m_arm == TMA_FBACK ) - { - if ( !IsFreeDeposeObject(D3DVECTOR(-TAKE_DIST, 0.0f, 0.0f)) ) return ERR_MANIP_OCC; - } - if ( m_arm == TMA_POWER ) - { - if ( m_object->RetPower() != 0 ) return ERR_MANIP_OCC; - } - } - - dist = Length(m_object->RetPosition(0), m_targetPos); - len = dist-TAKE_DIST; - if ( m_arm == TMA_OTHER ) len -= TAKE_DIST_OTHER; - if ( len < 0.0f ) len = 0.0f; - if ( m_arm == TMA_FBACK ) len = -len; - m_advanceLength = dist-m_physics->RetLinLength(len); - if ( dist <= m_advanceLength+0.2f ) m_move = 0.0f; // not necessary to advance - - if ( m_energy == 0.0f ) m_move = 0.0f; - - if ( m_move != 0.0f ) // forward or backward? - { - m_timeLimit = m_physics->RetLinTimeLength(Abs(len))*1.5f; - if ( m_timeLimit < 0.5f ) m_timeLimit = 0.5f; - } - - if ( m_object->RetFret() == 0 ) // not carrying anything? - { - m_hand = TMH_OPEN; // open clamp - } - else - { - m_hand = TMH_CLOSE; // closed clamp - } - - InitAngle(); - - if ( iAngle == m_angle || m_energy == 0.0f ) - { - m_bTurn = FALSE; // preliminary rotation unnecessary - SoundManip(1.0f/m_speed); - } - else - { - m_bTurn = TRUE; // preliminary rotation necessary - } - - if ( m_bSubm ) - { - m_camera->StartCentering(m_object, PI*0.8f, 99.9f, 0.0f, 0.5f); - } - - m_physics->SetFreeze(TRUE); // it does not move - - m_bError = FALSE; // ok - return ERR_OK; -} - -// Indicates whether the action is complete. - -Error CTaskManip::IsEnded() -{ - CObject* fret; - D3DVECTOR pos; - float angle, dist; - int i; - - if ( m_engine->RetPause() ) return ERR_CONTINUE; - if ( m_bError ) return ERR_STOP; - - if ( m_bBee ) // bee? - { - return ERR_STOP; - } - - if ( m_bTurn ) // preliminary rotation? - { - angle = m_object->RetAngleY(0); - angle = NormAngle(angle); // 0..2*PI - - if ( TestAngle(angle, m_angle-PI*0.01f, m_angle+PI*0.01f) ) - { - m_bTurn = FALSE; // rotation ended - m_physics->SetMotorSpeedZ(0.0f); - if ( m_move == 0.0f ) - { - SoundManip(1.0f/m_speed); - } - } - return ERR_CONTINUE; - } - - if ( m_move != 0.0f ) // preliminary advance? - { - if ( m_timeLimit <= 0.0f ) - { -//OK 1.9 - dist = Length(m_object->RetPosition(0), m_targetPos); - if ( dist <= m_advanceLength + 2.0f ) - { - m_move = 0.0f; // advance ended - m_physics->SetMotorSpeedX(0.0f); - SoundManip(1.0f/m_speed); - return ERR_CONTINUE; - } - else - { -//EOK 1.9 - m_move = 0.0f; // advance ended - m_physics->SetMotorSpeedX(0.0f); // stops - Abort(); - return ERR_STOP; - } - } - - dist = Length(m_object->RetPosition(0), m_targetPos); - if ( dist <= m_advanceLength ) - { - m_move = 0.0f; // advance ended - m_physics->SetMotorSpeedX(0.0f); - SoundManip(1.0f/m_speed); - } - return ERR_CONTINUE; - } - - if ( m_progress < 1.0f ) return ERR_CONTINUE; - m_progress = 0.0f; - - if ( !m_bSubm ) - { - for ( i=0 ; i<5 ; i++ ) - { - m_object->SetAngleZ(i+1, m_finalAngle[i]); - } - } - m_step ++; - - if ( m_order == TMO_GRAB ) - { - if ( m_step == 1 ) - { - if ( m_bSubm ) m_speed = 1.0f/0.7f; - m_hand = TMH_CLOSE; // closes the clamp to take - InitAngle(); - SoundManip(1.0f/m_speed, 0.8f, 1.5f); - return ERR_CONTINUE; - } - if ( m_step == 2 ) - { - if ( m_bSubm ) m_speed = 1.0f/1.5f; - if ( !TruckTakeObject() && - m_object->RetFret() == 0 ) - { - m_hand = TMH_OPEN; // reopens the clamp - m_arm = TMA_NEUTRAL; - InitAngle(); - SoundManip(1.0f/m_speed, 0.8f, 1.5f); - } - else - { - if ( (m_arm == TMA_OTHER || - m_arm == TMA_POWER ) && - (m_fretType == OBJECT_POWER || - m_fretType == OBJECT_ATOMIC ) ) - { - m_sound->Play(SOUND_POWEROFF, m_object->RetPosition(0)); - } - m_arm = TMA_STOCK; - InitAngle(); - SoundManip(1.0f/m_speed); - } - return ERR_CONTINUE; - } - } - - if ( m_order == TMO_DROP ) - { - if ( m_step == 1 ) - { - if ( m_bSubm ) m_speed = 1.0f/0.7f; - fret = m_object->RetFret(); - if ( TruckDeposeObject() ) - { - if ( (m_arm == TMA_OTHER || - m_arm == TMA_POWER ) && - (m_fretType == OBJECT_POWER || - m_fretType == OBJECT_ATOMIC ) ) - { - m_sound->Play(SOUND_POWERON, m_object->RetPosition(0)); - } - if ( fret != 0 && m_fretType == OBJECT_METAL && m_arm == TMA_FFRONT ) - { - m_main->ShowDropZone(fret, m_object); // shows buildable area - } - m_hand = TMH_OPEN; // opens the clamp to deposit - SoundManip(1.0f/m_speed, 0.8f, 1.5f); - } - InitAngle(); - return ERR_CONTINUE; - } - if ( m_step == 2 ) - { - if ( m_bSubm ) m_speed = 1.0f/1.5f; - m_arm = TMA_NEUTRAL; - InitAngle(); - SoundManip(1.0f/m_speed); - return ERR_CONTINUE; - } - } - - Abort(); - return ERR_STOP; -} - -// Suddenly ends the current action. - -BOOL CTaskManip::Abort() -{ - int i; - - if ( m_object->RetFret() == 0 ) // not carrying anything? - { - m_hand = TMH_OPEN; // open clamp - m_arm = TMA_NEUTRAL; - } - else - { - m_hand = TMH_CLOSE; // closed clamp - m_arm = TMA_STOCK; - } - InitAngle(); - - if ( !m_bSubm ) - { - for ( i=0 ; i<5 ; i++ ) - { - m_object->SetAngleZ(i+1, m_finalAngle[i]); - } - } - - m_camera->StopCentering(m_object, 2.0f); - m_physics->SetFreeze(FALSE); // is moving again - return TRUE; -} - - -// Seeks the object below to take (for bees). - -CObject* CTaskManip::SearchTakeUnderObject(D3DVECTOR &pos, float dLimit) -{ - CObject *pObj, *pBest; - D3DVECTOR iPos, oPos; - ObjectType type; - float min, distance; - int i; - - iPos = m_object->RetPosition(0); - - min = 1000000.0f; - pBest = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - - if ( type != OBJECT_FRET && - type != OBJECT_STONE && - type != OBJECT_URANIUM && - type != OBJECT_BULLET && - type != OBJECT_METAL && - type != OBJECT_POWER && - type != OBJECT_ATOMIC && - type != OBJECT_BBOX && - type != OBJECT_KEYa && - type != OBJECT_KEYb && - type != OBJECT_KEYc && - type != OBJECT_KEYd && - type != OBJECT_TNT ) continue; - - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( pObj->RetLock() ) continue; - if ( pObj->RetZoomY(0) != 1.0f ) continue; - - oPos = pObj->RetPosition(0); - distance = Length(oPos, iPos); - if ( distance <= dLimit && - distance < min ) - { - min = distance; - pBest = pObj; - } - } - if ( pBest != 0 ) - { - pos = pBest->RetPosition(0); - } - return pBest; -} - -// Seeks the object in front to take. - -CObject* CTaskManip::SearchTakeFrontObject(BOOL bAdvance, D3DVECTOR &pos, - float &distance, float &angle) -{ - CObject *pObj, *pBest; - D3DVECTOR iPos, oPos; - ObjectType type; - float min, iAngle, bAngle, aLimit, dLimit, f; - int i; - - iPos = m_object->RetPosition(0); - iAngle = m_object->RetAngleY(0); - iAngle = NormAngle(iAngle); // 0..2*PI - - if ( bAdvance && m_energy > 0.0f ) - { - aLimit = 60.0f*PI/180.0f; - dLimit = MARGIN_FRONT+10.0f; - } - else - { -//? aLimit = 7.0f*PI/180.0f; - aLimit = 15.0f*PI/180.0f; //OK 1.9 - dLimit = MARGIN_FRONT; - } - - min = 1000000.0f; - pBest = 0; - bAngle = 0.0f; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - - if ( type != OBJECT_FRET && - type != OBJECT_STONE && - type != OBJECT_URANIUM && - type != OBJECT_BULLET && - type != OBJECT_METAL && - type != OBJECT_POWER && - type != OBJECT_ATOMIC && - type != OBJECT_BBOX && - type != OBJECT_KEYa && - type != OBJECT_KEYb && - type != OBJECT_KEYc && - type != OBJECT_KEYd && - type != OBJECT_TNT && - type != OBJECT_SCRAP1 && - type != OBJECT_SCRAP2 && - type != OBJECT_SCRAP3 && - type != OBJECT_SCRAP4 && - type != OBJECT_SCRAP5 ) continue; - - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( pObj->RetLock() ) continue; - if ( pObj->RetZoomY(0) != 1.0f ) continue; - - oPos = pObj->RetPosition(0); - distance = Abs(Length(oPos, iPos)-TAKE_DIST); - f = 1.0f-distance/50.0f; - if ( f < 0.5f ) f = 0.5f; - - angle = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! - if ( !TestAngle(angle, iAngle-aLimit*f, iAngle+aLimit*f) ) continue; - - if ( distance < -dLimit || - distance > dLimit ) continue; - - if ( distance < min ) - { - min = distance; - pBest = pObj; - bAngle = angle; - } - } - if ( pBest == 0 ) - { - distance = 1000000.0f; - angle = 0.0f; - } - else - { - pos = pBest->RetPosition(0); - distance = min; - angle = bAngle; - } - return pBest; -} - -// Seeks the object back to take. - -CObject* CTaskManip::SearchTakeBackObject(BOOL bAdvance, D3DVECTOR &pos, - float &distance, float &angle) -{ - CObject *pObj, *pBest; - D3DVECTOR iPos, oPos; - ObjectType type; - float min, iAngle, bAngle, aLimit, dLimit, f; - int i; - - iPos = m_object->RetPosition(0); - iAngle = m_object->RetAngleY(0)+PI; - iAngle = NormAngle(iAngle); // 0..2*PI - - if ( bAdvance && m_energy > 0.0f ) - { - aLimit = 60.0f*PI/180.0f; - dLimit = MARGIN_BACK+5.0f; - } - else - { - aLimit = 7.0f*PI/180.0f; - dLimit = MARGIN_BACK; - } - - min = 1000000.0f; - pBest = 0; - bAngle = 0.0f; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - - if ( type != OBJECT_FRET && - type != OBJECT_STONE && - type != OBJECT_URANIUM && - type != OBJECT_BULLET && - type != OBJECT_METAL && - type != OBJECT_POWER && - type != OBJECT_ATOMIC && - type != OBJECT_BBOX && - type != OBJECT_KEYa && - type != OBJECT_KEYb && - type != OBJECT_KEYc && - type != OBJECT_KEYd && - type != OBJECT_TNT && - type != OBJECT_SCRAP1 && - type != OBJECT_SCRAP2 && - type != OBJECT_SCRAP3 && - type != OBJECT_SCRAP4 && - type != OBJECT_SCRAP5 ) continue; - - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( pObj->RetLock() ) continue; - if ( pObj->RetZoomY(0) != 1.0f ) continue; - - oPos = pObj->RetPosition(0); - distance = Abs(Length(oPos, iPos)-TAKE_DIST); - f = 1.0f-distance/50.0f; - if ( f < 0.5f ) f = 0.5f; - - angle = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! - if ( !TestAngle(angle, iAngle-aLimit*f, iAngle+aLimit*f) ) continue; - - if ( distance < -dLimit || - distance > dLimit ) continue; - - if ( distance < min ) - { - min = distance; - pBest = pObj; - bAngle = angle; - } - } - if ( pBest == 0 ) - { - distance = 1000000.0f; - angle = 0.0f; - } - else - { - pos = pBest->RetPosition(0); - distance = min; - angle = bAngle; - } - return pBest; -} - -// Seeks the robot or building on which it wants to put a battery or or other object. - -CObject* CTaskManip::SearchOtherObject(BOOL bAdvance, D3DVECTOR &pos, - float &distance, float &angle, - float &height) -{ - Character* character; - CObject* pObj; - CObject* pPower; - D3DMATRIX* mat; - D3DVECTOR iPos, oPos; - ObjectType type, powerType; - float iAngle, iRad, oAngle, oLimit, aLimit, dLimit; - int i; - - distance = 1000000.0f; - angle = 0.0f; - - if ( m_bSubm ) return 0; // impossible with the submarine - - if ( !m_object->GetCrashSphere(0, iPos, iRad) ) return 0; - iAngle = m_object->RetAngleY(0); - iAngle = NormAngle(iAngle); // 0..2*PI - - if ( bAdvance && m_energy > 0.0f ) - { - aLimit = 60.0f*PI/180.0f; - dLimit = MARGIN_FRIEND+10.0f; - } - else - { - aLimit = 7.0f*PI/180.0f; - dLimit = MARGIN_FRIEND; - } - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj == m_object ) continue; // yourself? - - type = pObj->RetType(); - if ( type != OBJECT_MOBILEfa && - type != OBJECT_MOBILEta && - type != OBJECT_MOBILEwa && - type != OBJECT_MOBILEia && - type != OBJECT_MOBILEfc && - type != OBJECT_MOBILEtc && - type != OBJECT_MOBILEwc && - type != OBJECT_MOBILEic && - type != OBJECT_MOBILEfi && - type != OBJECT_MOBILEti && - type != OBJECT_MOBILEwi && - type != OBJECT_MOBILEii && - type != OBJECT_MOBILEfs && - type != OBJECT_MOBILEts && - type != OBJECT_MOBILEws && - type != OBJECT_MOBILEis && - type != OBJECT_MOBILErt && - type != OBJECT_MOBILErc && - type != OBJECT_MOBILErr && - type != OBJECT_MOBILErs && - type != OBJECT_MOBILEsa && - type != OBJECT_MOBILEtg && - type != OBJECT_MOBILEft && - type != OBJECT_MOBILEtt && - type != OBJECT_MOBILEwt && - type != OBJECT_MOBILEit && - type != OBJECT_TOWER && - type != OBJECT_RESEARCH && - type != OBJECT_ENERGY && - type != OBJECT_LABO && - type != OBJECT_NUCLEAR ) continue; - - pPower = pObj->RetPower(); - if ( pPower != 0 ) - { - if ( pPower->RetLock() ) continue; - if ( pPower->RetZoomY(0) != 1.0f ) continue; - - powerType = pPower->RetType(); - if ( powerType == OBJECT_NULL || - powerType == OBJECT_FIX ) continue; - } - - mat = pObj->RetWorldMatrix(0); - character = pObj->RetCharacter(); - oPos = Transform(*mat, character->posPower); - - oAngle = pObj->RetAngleY(0); - if ( type == OBJECT_TOWER || - type == OBJECT_RESEARCH ) - { - oLimit = 45.0f*PI/180.0f; - } - else if ( type == OBJECT_ENERGY ) - { - oLimit = 90.0f*PI/180.0f; - } - else if ( type == OBJECT_LABO ) - { - oLimit = 120.0f*PI/180.0f; - } - else if ( type == OBJECT_NUCLEAR ) - { - oLimit = 45.0f*PI/180.0f; - } - else - { - oLimit = 45.0f*PI/180.0f; - oAngle += PI; // is behind - } - oAngle = NormAngle(oAngle); // 0..2*PI - angle = RotateAngle(iPos.x-oPos.x, oPos.z-iPos.z); // CW ! - if ( !TestAngle(angle, oAngle-oLimit, oAngle+oLimit) ) continue; - - distance = Abs(Length(oPos, iPos)-TAKE_DIST); - if ( distance <= dLimit ) - { - angle = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! - if ( TestAngle(angle, iAngle-aLimit, iAngle+aLimit) ) - { - character = pObj->RetCharacter(); - height = character->posPower.y; - pos = oPos; - return pObj; - } - } - } - - distance = 1000000.0f; - angle = 0.0f; - return 0; -} - -// Takes the object placed in front. - -BOOL CTaskManip::TruckTakeObject() -{ - CObject* fret; - CObject* other; - D3DMATRIX matRotate; - D3DVECTOR pos; - float angle, dist; - - if ( m_arm == TMA_GRAB ) // takes immediately? - { - fret = m_object->RetFret(); - if ( fret == 0 ) return FALSE; // nothing to take? - m_fretType = fret->RetType(); - - if ( m_object->RetType() == OBJECT_HUMAN || - m_object->RetType() == OBJECT_TECH ) - { - fret->SetTruck(m_object); - fret->SetTruckPart(4); // takes with the hand - - fret->SetPosition(0, D3DVECTOR(1.7f, -0.5f, 1.1f)); - fret->SetAngleY(0, 0.1f); - fret->SetAngleX(0, 0.0f); - fret->SetAngleZ(0, 0.8f); - } - else if ( m_bSubm ) - { - fret->SetTruck(m_object); - fret->SetTruckPart(2); // takes with the right claw - - pos = D3DVECTOR(1.1f, -1.0f, 1.0f); // relative - fret->SetPosition(0, pos); - fret->SetAngleX(0, 0.0f); - fret->SetAngleY(0, 0.0f); - fret->SetAngleZ(0, 0.0f); - } - else - { - fret->SetTruck(m_object); - fret->SetTruckPart(3); // takes with the hand - - pos = D3DVECTOR(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) - fret->SetPosition(0, pos); - fret->SetAngleX(0, 0.0f); - fret->SetAngleZ(0, PI/2.0f); - fret->SetAngleY(0, 0.0f); - } - - m_object->SetFret(fret); // takes - } - - if ( m_arm == TMA_FFRONT ) // takes on the ground in front? - { - fret = SearchTakeFrontObject(FALSE, pos, dist, angle); - if ( fret == 0 ) return FALSE; // nothing to take? - m_fretType = fret->RetType(); - - if ( m_bSubm ) - { - fret->SetTruck(m_object); - fret->SetTruckPart(2); // takes with the right claw - - pos = D3DVECTOR(1.1f, -1.0f, 1.0f); // relative - fret->SetPosition(0, pos); - fret->SetAngleX(0, 0.0f); - fret->SetAngleY(0, 0.0f); - fret->SetAngleZ(0, 0.0f); - } - else - { - fret->SetTruck(m_object); - fret->SetTruckPart(3); // takes with the hand - - pos = D3DVECTOR(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) - fret->SetPosition(0, pos); - fret->SetAngleX(0, 0.0f); - fret->SetAngleZ(0, PI/2.0f); - fret->SetAngleY(0, 0.0f); - } - - m_object->SetFret(fret); // takes - } - - if ( m_arm == TMA_FBACK ) // takes on the ground behind? - { - fret = SearchTakeBackObject(FALSE, pos, dist, angle); - if ( fret == 0 ) return FALSE; // nothing to take? - m_fretType = fret->RetType(); - - fret->SetTruck(m_object); - fret->SetTruckPart(3); // takes with the hand - - pos = D3DVECTOR(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) - fret->SetPosition(0, pos); - fret->SetAngleX(0, 0.0f); - fret->SetAngleZ(0, PI/2.0f); - fret->SetAngleY(0, 0.0f); - - m_object->SetFret(fret); // takes - } - - if ( m_arm == TMA_POWER ) // takes battery in the back? - { - fret = m_object->RetPower(); - if ( fret == 0 ) return FALSE; // no battery? - m_fretType = fret->RetType(); - - pos = D3DVECTOR(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) - fret->SetPosition(0, pos); - fret->SetAngleX(0, 0.0f); - fret->SetAngleZ(0, PI/2.0f); - fret->SetAngleY(0, 0.0f); - fret->SetTruckPart(3); // takes with the hand - - m_object->SetPower(0); - m_object->SetFret(fret); // takes - } - - if ( m_arm == TMA_OTHER ) // battery takes from friend? - { - other = SearchOtherObject(FALSE, pos, dist, angle, m_height); - if ( other == 0 ) return FALSE; - - fret = other->RetPower(); - if ( fret == 0 ) return FALSE; // the other does not have a battery? - m_fretType = fret->RetType(); - - other->SetPower(0); - fret->SetTruck(m_object); - fret->SetTruckPart(3); // takes with the hand - - pos = D3DVECTOR(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) - fret->SetPosition(0, pos); - fret->SetAngleX(0, 0.0f); - fret->SetAngleZ(0, PI/2.0f); - fret->SetAngleY(0, 0.0f); - - m_object->SetFret(fret); // takes - } - - return TRUE; -} - -// Deposes the object taken. - -BOOL CTaskManip::TruckDeposeObject() -{ - Character* character; - CObject* fret; - CObject* other; - D3DMATRIX* mat; - D3DVECTOR pos; - float angle, dist; - - if ( m_arm == TMA_FFRONT ) // deposits on the ground in front? - { - fret = m_object->RetFret(); - if ( fret == 0 ) return FALSE; // nothing transported? - m_fretType = fret->RetType(); - - mat = fret->RetWorldMatrix(0); - pos = Transform(*mat, D3DVECTOR(0.0f, 1.0f, 0.0f)); - m_terrain->MoveOnFloor(pos); - fret->SetPosition(0, pos); - fret->SetAngleY(0, m_object->RetAngleY(0)+PI/2.0f); - fret->SetAngleX(0, 0.0f); - fret->SetAngleZ(0, 0.0f); - fret->FloorAdjust(); // plate well on the ground - - fret->SetTruck(0); - m_object->SetFret(0); // deposit - } - - if ( m_arm == TMA_FBACK ) // deposited on the ground behind? - { - fret = m_object->RetFret(); - if ( fret == 0 ) return FALSE; // nothing transported? - m_fretType = fret->RetType(); - - mat = fret->RetWorldMatrix(0); - pos = Transform(*mat, D3DVECTOR(0.0f, 1.0f, 0.0f)); - m_terrain->MoveOnFloor(pos); - fret->SetPosition(0, pos); - fret->SetAngleY(0, m_object->RetAngleY(0)+PI/2.0f); - fret->SetAngleX(0, 0.0f); - fret->SetAngleZ(0, 0.0f); - - fret->SetTruck(0); - m_object->SetFret(0); // deposit - } - - if ( m_arm == TMA_POWER ) // deposits battery in the back? - { - fret = m_object->RetFret(); - if ( fret == 0 ) return FALSE; // nothing transported? - m_fretType = fret->RetType(); - - if ( m_object->RetPower() != 0 ) return FALSE; - - fret->SetTruck(m_object); - fret->SetTruckPart(0); // carried by the base - - character = m_object->RetCharacter(); - fret->SetPosition(0, character->posPower); - fret->SetAngleY(0, 0.0f); - fret->SetAngleX(0, 0.0f); - fret->SetAngleZ(0, 0.0f); - - m_object->SetPower(fret); // uses - m_object->SetFret(0); - } - - if ( m_arm == TMA_OTHER ) // deposits battery on friend? - { - other = SearchOtherObject(FALSE, pos, dist, angle, m_height); - if ( other == 0 ) return FALSE; - - fret = other->RetPower(); - if ( fret != 0 ) return FALSE; // the other already has a battery? - - fret = m_object->RetFret(); - if ( fret == 0 ) return FALSE; - m_fretType = fret->RetType(); - - other->SetPower(fret); - fret->SetTruck(other); - - character = other->RetCharacter(); - fret->SetPosition(0, character->posPower); - fret->SetAngleY(0, 0.0f); - fret->SetAngleX(0, 0.0f); - fret->SetAngleZ(0, 0.0f); - fret->SetTruckPart(0); // carried by the base - - m_object->SetFret(0); // deposit - } - - return TRUE; -} - -// Seeks if a location allows to deposit an object. - -BOOL CTaskManip::IsFreeDeposeObject(D3DVECTOR pos) -{ - CObject* pObj; - D3DMATRIX* mat; - D3DVECTOR iPos, oPos; - float oRadius; - int i, j; - - mat = m_object->RetWorldMatrix(0); - iPos = Transform(*mat, pos); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj == m_object ) continue; - if ( !pObj->RetActif() ) continue; // inactive? - if ( pObj->RetTruck() != 0 ) continue; // object transported? - - j = 0; - while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) - { - if ( Length(iPos, oPos)-(oRadius+1.0f) < 2.0f ) - { - return FALSE; // location occupied - } - } - } - return TRUE; // location free -} - -// Plays the sound of the manipulator arm. - -void CTaskManip::SoundManip(float time, float amplitude, float frequency) -{ - int i; - - i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f*frequency, TRUE); - m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, 0.1f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP); -} - diff --git a/src/taskmanip.h b/src/taskmanip.h deleted file mode 100644 index bc746cf..0000000 --- a/src/taskmanip.h +++ /dev/null @@ -1,109 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskmanip.h - -#ifndef _TASKMANIP_H_ -#define _TASKMANIP_H_ - - -#include "task.h" -#include "misc.h" -#include "d3dengine.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - - -enum TaskManipOrder -{ - TMO_AUTO = 0, // deposits or takes automatically - TMO_GRAB = 1, // takes an object - TMO_DROP = 2, // deposits the object -}; - -enum TaskManipArm -{ - TMA_NEUTRAL = 1, // empty arm at rest - TMA_STOCK = 2, // right arm resting - TMA_FFRONT = 3, // arm on the ground - TMA_FBACK = 4, // arm behind the robot - TMA_POWER = 5, // arm behind the robot - TMA_OTHER = 6, // arm behind a friend robot - TMA_GRAB = 7, // takes immediately -}; - -enum TaskManipHand -{ - TMH_OPEN = 1, // open clamp - TMH_CLOSE = 2, // closed clamp -}; - - - -class CTaskManip : public CTask -{ -public: - CTaskManip(CInstanceManager* iMan, CObject* object); - ~CTaskManip(); - - BOOL EventProcess(const Event &event); - - Error Start(TaskManipOrder order, TaskManipArm arm); - Error IsEnded(); - BOOL Abort(); - -protected: - void InitAngle(); - CObject* SearchTakeUnderObject(D3DVECTOR &pos, float dLimit); - CObject* SearchTakeFrontObject(BOOL bAdvance, D3DVECTOR &pos, float &distance, float &angle); - CObject* SearchTakeBackObject(BOOL bAdvance, D3DVECTOR &pos, float &distance, float &angle); - CObject* SearchOtherObject(BOOL bAdvance, D3DVECTOR &pos, float &distance, float &angle, float &height); - BOOL TruckTakeObject(); - BOOL TruckDeposeObject(); - BOOL IsFreeDeposeObject(D3DVECTOR pos); - void SoundManip(float time, float amplitude=1.0f, float frequency=1.0f); - -protected: - TaskManipOrder m_order; - TaskManipArm m_arm; - TaskManipHand m_hand; - int m_step; - float m_speed; - float m_progress; - float m_initialAngle[5]; - float m_finalAngle[5]; - float m_height; - float m_advanceLength; - float m_energy; - BOOL m_bError; - BOOL m_bTurn; - BOOL m_bSubm; - BOOL m_bBee; - float m_angle; - float m_move; - D3DVECTOR m_targetPos; - float m_timeLimit; - ObjectType m_fretType; -}; - - -#endif //_TASKMANIP_H_ diff --git a/src/taskpen.cpp b/src/taskpen.cpp deleted file mode 100644 index 7d95f21..0000000 --- a/src/taskpen.cpp +++ /dev/null @@ -1,304 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskpen.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "sound.h" -#include "motion.h" -#include "motionant.h" -#include "motionspider.h" -#include "task.h" -#include "taskpen.h" - - - -// Object's constructor. - -CTaskPen::CTaskPen(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); -} - -// Object's destructor. - -CTaskPen::~CTaskPen() -{ -} - - -// Management of an event. - -BOOL CTaskPen::EventProcess(const Event &event) -{ - D3DVECTOR pos, speed; - FPOINT dim; - int i; - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_bError ) return FALSE; - - if ( m_delay == 0.0f ) - { - m_progress = 1.0f; - } - else - { - m_progress += event.rTime*(1.0f/m_delay); // others advance - if ( m_progress > 1.0f ) m_progress = 1.0f; - } - - m_time += event.rTime; - - if ( m_phase == TPP_UP ) // back the pencil - { - i = AngleToRank(m_object->RetAngleY(1)); - pos = m_object->RetPosition(10+i); - pos.y = -3.2f*(1.0f-m_progress); - m_object->SetPosition(10+i, pos); - } - - if ( m_phase == TPP_TURN ) // turns the carousel? - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_supportPos; - pos.x += (Rand()-0.5f)*5.0f; - pos.z += (Rand()-0.5f)*5.0f; - speed.x = (Rand()-0.5f)*3.0f; - speed.z = (Rand()-0.5f)*3.0f; - speed.y = Rand()*2.0f; - dim.x = Rand()*1.5f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); - } - - m_object->SetAngleY(1, m_oldAngle+(m_newAngle-m_oldAngle)*m_progress); - } - - if ( m_phase == TPP_DOWN ) // down the pencil? - { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_supportPos; - pos.x += (Rand()-0.5f)*5.0f; - pos.z += (Rand()-0.5f)*5.0f; - speed.x = (Rand()-0.5f)*3.0f; - speed.z = (Rand()-0.5f)*3.0f; - speed.y = Rand()*5.0f; - dim.x = Rand()*1.0f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIVAPOR, 4.0f); - } - - i = AngleToRank(m_object->RetAngleY(1)); - pos = m_object->RetPosition(10+i); - if ( m_timeDown == 0.0f ) - { - pos.y = 0.0f; - } - else - { - pos.y = -3.2f*Bounce(Min(m_progress*1.8f, 1.0f)); - } - m_object->SetPosition(10+i, pos); - } - - return TRUE; -} - - -// Assigns the goal has achieved. - -Error CTaskPen::Start(BOOL bDown, int color) -{ - D3DVECTOR pos; - D3DMATRIX* mat; - ObjectType type; - int i; - - m_bError = TRUE; // operation impossible - - type = m_object->RetType(); - if ( type != OBJECT_MOBILEdr ) return ERR_FIRE_VEH; - - m_bError = FALSE; // ok - - m_oldAngle = m_object->RetAngleY(1); - m_newAngle = ColorToAngle(color); - - i = AngleToRank(m_oldAngle); - pos = m_object->RetPosition(10+i); - - if ( pos.y == 0.0f ) // pencil at the top? - { - m_timeUp = 0.0f; - } - else // pencil on the bottom? - { - m_timeUp = 1.0f; // must rise up - } - - if ( bDown ) // must go down ? - { - m_timeDown = 0.7f; - } - else - { - m_timeDown = 0.0f; - } - - mat = m_object->RetWorldMatrix(0); - pos = D3DVECTOR(-3.0f, 7.0f, 0.0f); - pos = Transform(*mat, pos); // position of carousel - m_supportPos = pos; - - m_phase = TPP_UP; - m_progress = 0.0f; - m_delay = m_timeUp; - m_time = 0.0f; - - if ( m_timeUp > 0.0f ) - { - SoundManip(m_timeUp, 1.0f, 0.5f); - } - - m_lastParticule = 0.0f; - -//? m_camera->StartCentering(m_object, PI*0.60f, 99.9f, 5.0f, 0.5f); - - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskPen::IsEnded() -{ - if ( m_engine->RetPause() ) return ERR_CONTINUE; - if ( m_bError ) return ERR_STOP; - - if ( m_progress < 1.0f ) return ERR_CONTINUE; - m_progress = 0.0f; - - if ( m_phase == TPP_UP ) - { - m_phase = TPP_TURN; - m_progress = 0.0f; - m_delay = Abs(m_oldAngle-m_newAngle)/PI; - m_time = 0.0f; - m_lastParticule = 0.0f; - if ( m_delay > 0.0f ) - { - SoundManip(m_delay, 1.0f, 1.0f); - } - return ERR_CONTINUE; - } - - if ( m_phase == TPP_TURN ) - { - m_sound->Play(SOUND_PSHHH2, m_supportPos, 1.0f, 1.4f); - m_phase = TPP_DOWN; - m_progress = 0.0f; - m_delay = m_timeDown; - m_time = 0.0f; - m_lastParticule = 0.0f; - return ERR_CONTINUE; - } - - Abort(); - return ERR_STOP; -} - -// Suddenly ends the current action. - -BOOL CTaskPen::Abort() -{ -//? m_camera->StopCentering(m_object, 0.5f); - return TRUE; -} - - -// Plays the sound of the manipulator arm. - -void CTaskPen::SoundManip(float time, float amplitude, float frequency) -{ - int i; - - i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f*frequency, TRUE); - m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, 0.1f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP); -} - - -// Converting a angle to number of pencil. - -int CTaskPen::AngleToRank(float angle) -{ -//? return (int)(angle/(-45.0f*PI/180.0f)); - angle = -angle; - angle += (45.0f*PI/180.0f)/2.0f; - return (int)(angle/(45.0f*PI/180.0f)); -} - -// Converting a color to the angle of carousel of pencils. - -float CTaskPen::ColorToAngle(int color) -{ - return -45.0f*PI/180.0f*ColorToRank(color); -} - -// Converting a color number to the pencil (0 .. 7). - -int CTaskPen::ColorToRank(int color) -{ - if ( color == 8 ) return 1; // yellow - if ( color == 7 ) return 2; // orange - if ( color == 5 ) return 2; // pink - if ( color == 4 ) return 3; // red - if ( color == 6 ) return 4; // purple - if ( color == 14 ) return 5; // blue - if ( color == 15 ) return 5; // light blue - if ( color == 12 ) return 6; // green - if ( color == 13 ) return 6; // light green - if ( color == 10 ) return 7; // brown - if ( color == 9 ) return 7; // beige - return 0; // black -} - diff --git a/src/taskpen.h b/src/taskpen.h deleted file mode 100644 index 752a52d..0000000 --- a/src/taskpen.h +++ /dev/null @@ -1,77 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskpen.h - -#ifndef _TASKSPEN_H_ -#define _TASKSPEN_H_ - - -#include "d3dengine.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - - -enum TaskPenPhase -{ - TPP_UP = 1, // rises the pencil - TPP_TURN = 2, // turns the carousel - TPP_DOWN = 3, // descends the pencil -}; - - - -class CTaskPen : public CTask -{ -public: - CTaskPen(CInstanceManager* iMan, CObject* object); - ~CTaskPen(); - - BOOL EventProcess(const Event &event); - - Error Start(BOOL bDown, int color); - Error IsEnded(); - BOOL Abort(); - -protected: - void SoundManip(float time, float amplitude, float frequency); - int AngleToRank(float angle); - float ColorToAngle(int color); - int ColorToRank(int color); - -protected: - BOOL m_bError; - TaskPenPhase m_phase; - float m_progress; - float m_delay; - float m_time; - float m_lastParticule; - D3DVECTOR m_supportPos; - - float m_timeUp; - float m_oldAngle; - float m_newAngle; - float m_timeDown; -}; - - -#endif //_TASKSPEN_H_ diff --git a/src/taskrecover.cpp b/src/taskrecover.cpp deleted file mode 100644 index 1284bb5..0000000 --- a/src/taskrecover.cpp +++ /dev/null @@ -1,431 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskrecover.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "sound.h" -#include "displaytext.h" -#include "task.h" -#include "taskrecover.h" - - -#define ENERGY_RECOVER 0.25f // energy consumed by recovery -#define RECOVER_DIST 11.8f - - - -// Object's constructor. - -CTaskRecover::CTaskRecover(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); - - m_ruin = 0; - m_soundChannel = -1; -} - -// Object's constructor. - -CTaskRecover::~CTaskRecover() -{ -} - - -// Management of an event. - -BOOL CTaskRecover::EventProcess(const Event &event) -{ - CObject* power; - D3DVECTOR pos, speed; - FPOINT dim; - float a, g, cirSpeed, angle, energy, dist, linSpeed; - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_bError ) return FALSE; - - if ( m_phase == TRP_TURN ) // preliminary rotation? - { - a = m_object->RetAngleY(0); - g = m_angle; - cirSpeed = Direction(a, g)*1.0f; - if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; - if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; - - m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right - return TRUE; - } - - m_progress += event.rTime*m_speed; // others advance - m_time += event.rTime; - - if ( m_phase == TRP_DOWN ) - { - angle = Prop(126, -10, m_progress); - m_object->SetAngleZ(2, angle); - m_object->SetAngleZ(4, angle); - - angle = Prop(-144, 0, m_progress); - m_object->SetAngleZ(3, angle); - m_object->SetAngleZ(5, angle); - } - - if ( m_phase == TRP_MOVE ) // preliminary forward/backward? - { - dist = Length(m_object->RetPosition(0), m_ruin->RetPosition(0)); - linSpeed = 0.0f; - if ( dist > RECOVER_DIST ) linSpeed = 1.0f; - if ( dist < RECOVER_DIST ) linSpeed = -1.0f; - m_physics->SetMotorSpeedX(linSpeed); // forward/backward - return TRUE; - } - - if ( m_phase == TRP_OPER ) - { - power = m_object->RetPower(); - if ( power != 0 ) - { - energy = power->RetEnergy(); - power->SetEnergy(energy-ENERGY_RECOVER*event.rTime*m_speed); - } - - speed.x = (Rand()-0.5f)*0.1f*m_progress; - speed.y = (Rand()-0.5f)*0.1f*m_progress; - speed.z = (Rand()-0.5f)*0.1f*m_progress; - m_ruin->SetCirVibration(speed); - - if ( m_progress >= 0.75f ) - { - m_ruin->SetZoom(0, 1.0f-(m_progress-0.75f)/0.25f); - } - - if ( m_progress > 0.5f && m_progress < 0.8f ) - { - m_metal->SetZoom(0, (m_progress-0.5f)/0.3f); - } - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.02f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_recoverPos; - pos.x += (Rand()-0.5f)*8.0f*(1.0f-m_progress); - pos.z += (Rand()-0.5f)*8.0f*(1.0f-m_progress); - pos.y -= 4.0f; - speed.x = (Rand()-0.5f)*0.0f; - speed.z = (Rand()-0.5f)*0.0f; - speed.y = Rand()*15.0f; - dim.x = Rand()*2.0f+1.5f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIRECOVER, 1.0f, 0.0f, 0.0f); - } - } - - if ( m_phase == TRP_UP ) - { - angle = Prop(-10, 126, m_progress); - m_object->SetAngleZ(2, angle); - m_object->SetAngleZ(4, angle); - - angle = Prop(0, -144, m_progress); - m_object->SetAngleZ(3, angle); - m_object->SetAngleZ(5, angle); - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.02f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_recoverPos; - pos.y -= 4.0f; - speed.x = (Rand()-0.5f)*0.0f; - speed.z = (Rand()-0.5f)*0.0f; - speed.y = Rand()*15.0f; - dim.x = Rand()*2.0f+1.5f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIRECOVER, 1.0f, 0.0f, 0.0f); - } - } - - return TRUE; -} - - -// Assigns the goal was achieved. - -Error CTaskRecover::Start() -{ - CObject* power; - D3DMATRIX* mat; - D3DVECTOR pos, iPos, oPos; - float energy; - - ObjectType type; - - m_bError = TRUE; // operation impossible - if ( !m_physics->RetLand() ) return ERR_RECOVER_VEH; - - type = m_object->RetType(); - if ( type != OBJECT_MOBILErr ) return ERR_RECOVER_VEH; - - power = m_object->RetPower(); - if ( power == 0 ) return ERR_RECOVER_ENERGY; - energy = power->RetEnergy(); - if ( energy < ENERGY_RECOVER/power->RetCapacity()+0.05f ) return ERR_RECOVER_ENERGY; - - mat = m_object->RetWorldMatrix(0); - pos = D3DVECTOR(RECOVER_DIST, 3.3f, 0.0f); - pos = Transform(*mat, pos); // position in front - m_recoverPos = pos; - - m_ruin = SearchRuin(); - if ( m_ruin == 0 ) return ERR_RECOVER_NULL; - m_ruin->SetLock(TRUE); // ruin no longer usable - - iPos = m_object->RetPosition(0); - oPos = m_ruin->RetPosition(0); - m_angle = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! - - m_metal = 0; - - m_phase = TRP_TURN; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - m_time = 0.0f; - m_lastParticule = 0.0f; - - m_bError = FALSE; // ok - - m_camera->StartCentering(m_object, PI*0.85f, 99.9f, 10.0f, 3.0f); - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskRecover::IsEnded() -{ - D3DMATRIX* mat; - D3DVECTOR pos, speed, goal; - FPOINT dim; - float angle, dist, time; - int i; - - if ( m_engine->RetPause() ) return ERR_CONTINUE; - if ( m_bError ) return ERR_STOP; - - if ( m_phase == TRP_TURN ) // preliminary rotation? - { - angle = m_object->RetAngleY(0); - angle = NormAngle(angle); // 0..2*PI - - if ( TestAngle(angle, m_angle-PI*0.01f, m_angle+PI*0.01f) ) - { - m_physics->SetMotorSpeedZ(0.0f); - - dist = Length(m_object->RetPosition(0), m_ruin->RetPosition(0)); - if ( dist > RECOVER_DIST ) - { - time = m_physics->RetLinTimeLength(dist-RECOVER_DIST, 1.0f); - m_speed = 1.0f/time; - } - else - { - time = m_physics->RetLinTimeLength(RECOVER_DIST-dist, -1.0f); - m_speed = 1.0f/time; - } - m_phase = TRP_MOVE; - m_progress = 0.0f; - } - return ERR_CONTINUE; - } - - if ( m_phase == TRP_MOVE ) // preliminary advance? - { - dist = Length(m_object->RetPosition(0), m_ruin->RetPosition(0)); - - if ( dist >= RECOVER_DIST-1.0f && - dist <= RECOVER_DIST+1.0f ) - { - m_physics->SetMotorSpeedX(0.0f); - - mat = m_object->RetWorldMatrix(0); - pos = D3DVECTOR(RECOVER_DIST, 3.3f, 0.0f); - pos = Transform(*mat, pos); // position in front - m_recoverPos = pos; - - i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.9f, TRUE); - m_sound->AddEnvelope(i, 1.0f, 1.5f, 0.3f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 1.0f, 1.5f, 1.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 0.0f, 0.9f, 0.3f, SOPER_STOP); - - m_phase = TRP_DOWN; - m_progress = 0.0f; - m_speed = 1.0f/1.5f; - m_time = 0.0f; - } - else - { - if ( m_progress > 1.0f ) // timeout? - { - m_ruin->SetLock(FALSE); // usable again - m_camera->StopCentering(m_object, 2.0f); - return ERR_RECOVER_NULL; - } - } - return ERR_CONTINUE; - } - - if ( m_progress < 1.0f ) return ERR_CONTINUE; - m_progress = 0.0f; - - if ( m_phase == TRP_DOWN ) - { - m_metal = new CObject(m_iMan); - if ( !m_metal->CreateResource(m_recoverPos, 0.0f, OBJECT_METAL) ) - { - delete m_metal; - m_metal = 0; - Abort(); - m_bError = TRUE; - m_displayText->DisplayError(ERR_TOOMANY, m_object); - return ERR_STOP; - } - m_metal->SetLock(TRUE); // metal not yet usable - m_metal->SetZoom(0, 0.0f); - - mat = m_object->RetWorldMatrix(0); - pos = D3DVECTOR(RECOVER_DIST, 3.1f, 3.9f); - pos = Transform(*mat, pos); - goal = D3DVECTOR(RECOVER_DIST, 3.1f, -3.9f); - goal = Transform(*mat, goal); - m_particule->CreateRay(pos, goal, PARTIRAY2, - FPOINT(2.0f, 2.0f), 8.0f); - - m_soundChannel = m_sound->Play(SOUND_RECOVER, m_ruin->RetPosition(0), 0.0f, 1.0f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 0.6f, 1.0f, 2.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.6f, 1.0f, 4.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.7f, 2.0f, SOPER_STOP); - - m_phase = TRP_OPER; - m_speed = 1.0f/8.0f; - return ERR_CONTINUE; - } - - if ( m_phase == TRP_OPER ) - { - m_metal->SetZoom(0, 1.0f); - - m_ruin->DeleteObject(); // destroys the ruin - delete m_ruin; - m_ruin = 0; - - m_soundChannel = -1; - - i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.9f, TRUE); - m_sound->AddEnvelope(i, 1.0f, 1.5f, 0.3f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 1.0f, 1.5f, 1.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 0.0f, 0.9f, 0.3f, SOPER_STOP); - - m_phase = TRP_UP; - m_speed = 1.0f/1.5f; - return ERR_CONTINUE; - } - - m_metal->SetLock(FALSE); // metal usable - - Abort(); - return ERR_STOP; -} - -// Suddenly ends the current action. - -BOOL CTaskRecover::Abort() -{ - m_object->SetAngleZ(2, 126.0f*PI/180.0f); - m_object->SetAngleZ(4, 126.0f*PI/180.0f); - m_object->SetAngleZ(3, -144.0f*PI/180.0f); - m_object->SetAngleZ(5, -144.0f*PI/180.0f); // rest - - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 1.0f, SOPER_STOP); - m_soundChannel = -1; - } - - m_camera->StopCentering(m_object, 2.0f); - return TRUE; -} - - -// Seeks if a ruin is in front of the vehicle. - -CObject* CTaskRecover::SearchRuin() -{ - CObject *pObj, *pBest; - D3DVECTOR oPos; - ObjectType type; - float dist, min; - int i; - - pBest = 0; - min = 100000.0f; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type == OBJECT_RUINmobilew1 || - type == OBJECT_RUINmobilew2 || - type == OBJECT_RUINmobilet1 || - type == OBJECT_RUINmobilet2 || - type == OBJECT_RUINmobiler1 || - type == OBJECT_RUINmobiler2 ) // vehicle in ruin? - { - oPos = pObj->RetPosition(0); - dist = Length(oPos, m_recoverPos); - if ( dist > 40.0f ) continue; - - if ( dist < min ) - { - min = dist; - pBest = pObj; - } - } - - } - return pBest; -} - diff --git a/src/taskrecover.h b/src/taskrecover.h deleted file mode 100644 index cc2adce..0000000 --- a/src/taskrecover.h +++ /dev/null @@ -1,75 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskrecover.h - -#ifndef _TASKSRECOVER_H_ -#define _TASKSRECOVER_H_ - - -#include "d3dengine.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - - -enum TaskRecoverPhase -{ - TRP_TURN = 1, // turns - TRP_MOVE = 2, // advance - TRP_DOWN = 3, // descends - TRP_OPER = 4, // operates - TRP_UP = 5, // back -}; - - - -class CTaskRecover : public CTask -{ -public: - CTaskRecover(CInstanceManager* iMan, CObject* object); - ~CTaskRecover(); - - BOOL EventProcess(const Event &event); - - Error Start(); - Error IsEnded(); - BOOL Abort(); - -protected: - CObject* SearchRuin(); - -protected: - TaskRecoverPhase m_phase; - float m_progress; - float m_speed; - float m_time; - float m_angle; - float m_lastParticule; - BOOL m_bError; - CObject* m_ruin; - CObject* m_metal; - D3DVECTOR m_recoverPos; - int m_soundChannel; -}; - - -#endif //_TASKSRECOVER_H_ diff --git a/src/taskreset.cpp b/src/taskreset.cpp deleted file mode 100644 index a626c02..0000000 --- a/src/taskreset.cpp +++ /dev/null @@ -1,345 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskreset.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "sound.h" -#include "robotmain.h" -#include "task.h" -#include "taskreset.h" - - - -#define RESET_DELAY_ZOOM 0.7f -#define RESET_DELAY_MOVE 0.7f - - - - -// Object's constructor. - -CTaskReset::CTaskReset(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); -} - -// Object's destructor. - -CTaskReset::~CTaskReset() -{ -} - - -// Management of an event. - -BOOL CTaskReset::EventProcess(const Event &event) -{ - D3DVECTOR pos, speed; - FPOINT dim; - float angle, duration; - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_bError ) return FALSE; - - m_time += event.rTime; - m_progress += event.rTime*m_speed; - - if ( m_phase == TRSP_ZOUT ) - { - angle = m_iAngle; - angle += powf(m_progress*5.0f, 2.0f); // accelerates - m_object->SetAngleY(0, angle); - m_object->SetZoom(0, 1.0f-m_progress); - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_begin; - pos.x += (Rand()-0.5f)*5.0f; - pos.z += (Rand()-0.5f)*5.0f; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 5.0f+Rand()*5.0f; - dim.x = Rand()*2.0f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINTb, 2.0f); - - pos = m_begin; - speed.x = (Rand()-0.5f)*20.0f; - speed.z = (Rand()-0.5f)*20.0f; - speed.y = Rand()*10.0f; - speed *= 1.0f-m_progress*0.5f; - pos += speed*1.5f; - speed = -speed; - dim.x = 0.6f; - dim.y = dim.x; - pos.y += dim.y; - duration = Rand()*1.5f+1.5f; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK6, - duration, 0.0f, - duration*0.9f, 0.7f); - } - } - - if ( m_phase == TRSP_MOVE ) - { - pos = m_begin+(m_goal-m_begin)*m_progress; - m_object->SetPosition(0, pos); - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos.x += (Rand()-0.5f)*5.0f; - pos.z += (Rand()-0.5f)*5.0f; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 2.0f+Rand()*2.0f; - dim.x = Rand()*2.0f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINTb, 2.0f); - } - } - - if ( m_phase == TRSP_ZIN ) - { - angle = m_angle.y; - angle += -powf((1.0f-m_progress)*5.0f, 2.0f); // slows - m_object->SetAngleY(0, angle); - m_object->SetZoom(0, m_progress); - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_goal; - pos.x += (Rand()-0.5f)*5.0f; - pos.z += (Rand()-0.5f)*5.0f; - speed.x = 0.0f; - speed.z = 0.0f; - speed.y = 5.0f+Rand()*5.0f; - dim.x = Rand()*2.0f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINTb, 2.0f); - - pos = m_goal; - speed.x = (Rand()-0.5f)*20.0f; - speed.z = (Rand()-0.5f)*20.0f; - speed.y = Rand()*10.0f; - speed *= 0.5f+m_progress*0.5f; - dim.x = 0.6f; - dim.y = dim.x; - pos.y += dim.y; - duration = Rand()*1.5f+1.5f; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK6, - duration, 0.0f, - duration*0.9f, 0.7f); - } - } - - return TRUE; -} - - -// Assigns the goal was achieved. -// A positive angle makes a turn right. - -Error CTaskReset::Start(D3DVECTOR goal, D3DVECTOR angle) -{ - CObject* fret; - int i; - - fret = m_object->RetFret(); - if ( fret != 0 && fret->RetResetCap() == RESET_MOVE ) - { - fret->SetTruck(0); - m_object->SetFret(0); // does nothing - } - - if ( !m_main->RetNiceReset() ) // quick return? - { - m_object->SetPosition(0, goal); - m_object->SetAngle(0, angle); - m_brain->RunProgram(m_object->RetResetRun()); - - m_bError = FALSE; - return ERR_OK; - } - - m_begin = m_object->RetPosition(0); - m_goal = goal; - m_angle = angle; - - if ( SearchVehicle() ) // starting location occupied? - { - m_bError = TRUE; - return ERR_RESET_NEAR; - } - - m_iAngle = m_object->RetAngleY(0); - m_time = 0.0f; - m_phase = TRSP_ZOUT; - m_speed = 1.0f/RESET_DELAY_ZOOM; - m_progress = 0.0f; - m_lastParticule = 0.0f; - - m_object->SetResetBusy(TRUE); - - i = m_sound->Play(SOUND_GGG, m_begin, 1.0f, 2.0f, TRUE); - m_sound->AddEnvelope(i, 0.0f, 0.5f, RESET_DELAY_ZOOM, SOPER_STOP); - - m_bError = FALSE; - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskReset::IsEnded() -{ - CObject* power; - float dist; - int i; - - if ( !m_main->RetNiceReset() ) // quick return? - { - return ERR_STOP; - } - - if ( m_engine->RetPause() ) return ERR_CONTINUE; - if ( m_bError ) return ERR_STOP; - if ( m_progress < 1.0f ) return ERR_CONTINUE; - - if ( m_phase == TRSP_ZOUT ) - { - dist = Length(m_begin, m_goal); - m_phase = TRSP_MOVE; - m_speed = 1.0f/(dist*RESET_DELAY_MOVE/100.0f); - m_progress = 0.0f; - return ERR_CONTINUE; - } - - if ( m_phase == TRSP_MOVE ) - { - m_object->SetPosition(0, m_goal); - m_object->SetAngle(0, m_angle); - - i = m_sound->Play(SOUND_GGG, m_goal, 1.0f, 0.5f, TRUE); - m_sound->AddEnvelope(i, 0.0f, 2.0f, RESET_DELAY_ZOOM, SOPER_STOP); - - m_phase = TRSP_ZIN; - m_speed = 1.0f/RESET_DELAY_ZOOM; - m_progress = 0.0f; - return ERR_CONTINUE; - } - - m_object->SetAngle(0, m_angle); - m_object->SetZoom(0, 1.0f); - - power = m_object->RetPower(); - if ( power != 0 ) - { - power->SetEnergy(power->RetCapacity()); // refueling - } - - m_brain->RunProgram(m_object->RetResetRun()); - m_object->SetResetBusy(FALSE); - return ERR_STOP; -} - - -// Seeks if a vehicle is too close. - -BOOL CTaskReset::SearchVehicle() -{ - CObject* pObj; - D3DVECTOR oPos; - ObjectType type; - float oRadius, dist; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj == m_object ) continue; - - type = pObj->RetType(); - if ( type != OBJECT_HUMAN && - type != OBJECT_TECH && - type != OBJECT_MOBILEfa && - type != OBJECT_MOBILEta && - type != OBJECT_MOBILEwa && - type != OBJECT_MOBILEia && - type != OBJECT_MOBILEfc && - type != OBJECT_MOBILEtc && - type != OBJECT_MOBILEwc && - type != OBJECT_MOBILEic && - type != OBJECT_MOBILEfi && - type != OBJECT_MOBILEti && - type != OBJECT_MOBILEwi && - type != OBJECT_MOBILEii && - type != OBJECT_MOBILEfs && - type != OBJECT_MOBILEts && - type != OBJECT_MOBILEws && - type != OBJECT_MOBILEis && - type != OBJECT_MOBILErt && - type != OBJECT_MOBILErc && - type != OBJECT_MOBILErr && - type != OBJECT_MOBILErs && - type != OBJECT_MOBILEsa && - type != OBJECT_MOBILEtg && - type != OBJECT_MOBILEft && - type != OBJECT_MOBILEtt && - type != OBJECT_MOBILEwt && - type != OBJECT_MOBILEit && - type != OBJECT_MOBILEdr && - type != OBJECT_MOTHER && - type != OBJECT_ANT && - type != OBJECT_SPIDER && - type != OBJECT_BEE && - type != OBJECT_WORM ) continue; - - if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; - dist = Length(oPos, m_goal)-oRadius; - - if ( dist < 5.0f ) return TRUE; - } - - return FALSE; -} - diff --git a/src/taskreset.h b/src/taskreset.h deleted file mode 100644 index a866d1f..0000000 --- a/src/taskreset.h +++ /dev/null @@ -1,73 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskreset.h - -#ifndef _TASKRESET_H_ -#define _TASKRESET_H_ - - -#include "misc.h" -#include "d3dengine.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - - -enum TaskResetPhase -{ - TRSP_ZOUT = 1, // disappears - TRSP_MOVE = 2, // moves - TRSP_ZIN = 3, // reappears -}; - - - -class CTaskReset : public CTask -{ -public: - CTaskReset(CInstanceManager* iMan, CObject* object); - ~CTaskReset(); - - BOOL EventProcess(const Event &event); - - Error Start(D3DVECTOR goal, D3DVECTOR angle); - Error IsEnded(); - -protected: - BOOL SearchVehicle(); - -protected: - D3DVECTOR m_begin; - D3DVECTOR m_goal; - D3DVECTOR m_angle; - - TaskResetPhase m_phase; - BOOL m_bError; - float m_time; - float m_speed; - float m_progress; - float m_lastParticule; // time of generation last particle - float m_iAngle; -}; - - -#endif //_TASKRESET_H_ diff --git a/src/tasksearch.cpp b/src/tasksearch.cpp deleted file mode 100644 index 8857e35..0000000 --- a/src/tasksearch.cpp +++ /dev/null @@ -1,334 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// tasksearch.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "sound.h" -#include "displaytext.h" -#include "task.h" -#include "tasksearch.h" - - - - -// Object's constructor. - -CTaskSearch::CTaskSearch(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); - - m_hand = TSH_UP; -} - -// Object's destructor. - -CTaskSearch::~CTaskSearch() -{ -} - - -// Management of an event. - -BOOL CTaskSearch::EventProcess(const Event &event) -{ - D3DMATRIX* mat; - D3DVECTOR pos, speed; - FPOINT dim; - float angle; - int i; - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_bError ) return FALSE; - - m_progress += event.rTime*m_speed; // others advance - m_time += event.rTime; - - if ( m_phase == TSP_DOWN || - m_phase == TSP_UP ) - { - for ( i=0 ; i<3 ; i++ ) - { - angle = (m_finalAngle[i]-m_initialAngle[i])*m_progress; - angle += m_initialAngle[i]; - m_object->SetAngleZ(i+1, angle); - } - } - - if ( m_phase == TSP_SEARCH && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - mat = m_object->RetWorldMatrix(0); - pos = D3DVECTOR(6.5f, 0.2f, 0.0f); - pos = Transform(*mat, pos); // sensor position - - speed.x = (Rand()-0.5f)*20.0f; - speed.z = (Rand()-0.5f)*20.0f; - speed.y = 0.0f; - dim.x = Rand()*1.0f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGAS); - } - - return TRUE; -} - - -// Initializes the initial and final angles. - -void CTaskSearch::InitAngle() -{ - int i; - - if ( m_hand == TSH_UP ) - { - m_finalAngle[0] = 110.0f*PI/180.0f; // arm - m_finalAngle[1] = -110.0f*PI/180.0f; // forearm - m_finalAngle[2] = -65.0f*PI/180.0f; // sensor - } - if ( m_hand == TSH_DOWN ) - { - m_finalAngle[0] = 25.0f*PI/180.0f; // arm - m_finalAngle[1] = -70.0f*PI/180.0f; // forearm - m_finalAngle[2] = -45.0f*PI/180.0f; // sensor - } - - for ( i=0 ; i<3 ; i++ ) - { - m_initialAngle[i] = m_object->RetAngleZ(i+1); - } -} - - -// Assigns the goal was achieved. - -Error CTaskSearch::Start() -{ - ObjectType type; - D3DVECTOR speed; - int i; - - m_bError = TRUE; - if ( !m_physics->RetLand() ) return ERR_SEARCH_FLY; - - speed = m_physics->RetMotorSpeed(); - if ( speed.x != 0.0f || - speed.z != 0.0f ) return ERR_SEARCH_MOTOR; - - type = m_object->RetType(); - if ( type != OBJECT_MOBILEfs && - type != OBJECT_MOBILEts && - type != OBJECT_MOBILEws && - type != OBJECT_MOBILEis ) return ERR_SEARCH_VEH; - - m_hand = TSH_DOWN; - m_phase = TSP_DOWN; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - m_time = 0.0f; - m_lastParticule = 0.0f; - - InitAngle(); - m_bError = FALSE; // ok - - m_camera->StartCentering(m_object, PI*0.50f, 99.9f, 0.0f, 1.0f); - - i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f, TRUE); - m_sound->AddEnvelope(i, 0.5f, 1.0f, 0.1f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 0.5f, 1.0f, 0.9f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 0.0f, 0.3f, 0.1f, SOPER_STOP); - - m_physics->SetFreeze(TRUE); // it does not move - - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskSearch::IsEnded() -{ - int i; - - if ( m_engine->RetPause() ) return ERR_CONTINUE; - if ( m_bError ) return ERR_STOP; - - if ( m_progress < 1.0f ) return ERR_CONTINUE; - m_progress = 0.0f; - - if ( m_phase == TSP_DOWN || - m_phase == TSP_UP ) - { - for ( i=0 ; i<3 ; i++ ) - { - m_object->SetAngleZ(i+1, m_finalAngle[i]); - } - } - - if ( m_phase == TSP_DOWN ) - { - m_sound->Play(SOUND_REPAIR, m_object->RetPosition(0)); - - m_phase = TSP_SEARCH; - m_speed = 1.0f/4.0f; - return ERR_CONTINUE; - } - - if ( m_phase == TSP_SEARCH ) - { - CreateMark(); - - m_hand = TSH_UP; - InitAngle(); - - i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f, TRUE); - m_sound->AddEnvelope(i, 0.5f, 1.0f, 0.1f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 0.5f, 1.0f, 0.9f, SOPER_CONTINUE); - m_sound->AddEnvelope(i, 0.0f, 0.3f, 0.1f, SOPER_STOP); - - m_phase = TSP_UP; - m_speed = 1.0f/1.0f; - return ERR_CONTINUE; - } - - Abort(); - return ERR_STOP; -} - -// Suddenly ends the current action. - -BOOL CTaskSearch::Abort() -{ - m_camera->StopCentering(m_object, 2.0f); - m_physics->SetFreeze(FALSE); // is moving again - return TRUE; -} - - -// Creates a mark if possible. - -BOOL CTaskSearch::CreateMark() -{ - CObject* fret; - ObjectType type; - D3DMATRIX* mat; - D3DVECTOR pos; - TerrainRes res; - Error info; - - mat = m_object->RetWorldMatrix(0); - pos = D3DVECTOR(7.5f, 0.0f, 0.0f); - pos = Transform(*mat, pos); // sensor position - - res = m_terrain->RetResource(pos); - if ( res == TR_NULL ) return FALSE; - - type = OBJECT_NULL; - if ( res == TR_STONE ) - { - type = OBJECT_MARKSTONE; - info = INFO_MARKSTONE; - } - if ( res == TR_URANIUM ) - { - type = OBJECT_MARKURANIUM; - info = INFO_MARKURANIUM; - } - if ( res == TR_POWER ) - { - type = OBJECT_MARKPOWER; - info = INFO_MARKPOWER; - } - if ( res == TR_KEYa ) - { - type = OBJECT_MARKKEYa; - info = INFO_MARKKEYa; - } - if ( res == TR_KEYb ) - { - type = OBJECT_MARKKEYb; - info = INFO_MARKKEYb; - } - if ( res == TR_KEYc ) - { - type = OBJECT_MARKKEYc; - info = INFO_MARKKEYc; - } - if ( res == TR_KEYd ) - { - type = OBJECT_MARKKEYd; - info = INFO_MARKKEYd; - } - if ( type == OBJECT_NULL ) return FALSE; - -//? DeleteMark(type); - - fret = new CObject(m_iMan); - if ( !fret->CreateResource(pos, 0.0f, type) ) - { - delete fret; - m_displayText->DisplayError(ERR_TOOMANY, m_object); - return FALSE; - } - - m_displayText->DisplayError(info, pos, 5.0f, 50.0f); // displays the message - - return TRUE; -} - -// Destroys the marks of a given type. - -void CTaskSearch::DeleteMark(ObjectType type) -{ - CObject* pObj; - D3DVECTOR oPos; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( type == pObj->RetType() ) - { - pObj->DeleteObject(); // removes the mark - delete pObj; - break; - } - } -} - - diff --git a/src/tasksearch.h b/src/tasksearch.h deleted file mode 100644 index 80970e1..0000000 --- a/src/tasksearch.h +++ /dev/null @@ -1,79 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// tasksearch.h - -#ifndef _TASKSEARCH_H_ -#define _TASKSEARCH_H_ - - -#include "misc.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - - -enum TaskSearchHand -{ - TSH_UP = 1, // sensor at the top - TSH_DOWN = 2, // sensor at the bottom -}; - -enum TaskSearchPhase -{ - TSP_DOWN = 1, // descends - TSP_SEARCH = 2, // seeks - TSP_UP = 3, // rises -}; - - - -class CTaskSearch : public CTask -{ -public: - CTaskSearch(CInstanceManager* iMan, CObject* object); - ~CTaskSearch(); - - BOOL EventProcess(const Event &event); - - Error Start(); - Error IsEnded(); - BOOL Abort(); - -protected: - void InitAngle(); - BOOL CreateMark(); - void DeleteMark(ObjectType type); - -protected: - TaskSearchHand m_hand; - TaskSearchPhase m_phase; - float m_progress; - float m_speed; - float m_time; - float m_lastParticule; - float m_initialAngle[3]; - float m_finalAngle[3]; - BOOL m_bError; -}; - - -#endif //_TASKSEARCH_H_ diff --git a/src/taskshield.cpp b/src/taskshield.cpp deleted file mode 100644 index 9269c4b..0000000 --- a/src/taskshield.cpp +++ /dev/null @@ -1,573 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskshield.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "camera.h" -#include "light.h" -#include "sound.h" -#include "task.h" -#include "taskshield.h" - - -#define ENERGY_TIME 20.0f // maximum duration if full battery - - - -// Object's constructor. - -CTaskShield::CTaskShield(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); - - m_rankSphere = -1; - m_soundChannel = -1; - m_effectLight = -1; -} - -// Object's destructor. - -CTaskShield::~CTaskShield() -{ - Abort(); -} - - -// Management of an event. - -BOOL CTaskShield::EventProcess(const Event &event) -{ - CObject* power; - D3DMATRIX* mat; - D3DMATRIX matrix; - D3DVECTOR pos, speed, goal, angle; - D3DCOLORVALUE color; - FPOINT dim; - float energy; - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_bError ) return FALSE; - - m_progress += event.rTime*m_speed; // others advance - m_time += event.rTime; - m_delay -= event.rTime; - - mat = m_object->RetWorldMatrix(0); - pos = D3DVECTOR(7.0f, 15.0f, 0.0f); - pos = Transform(*mat, pos); // sphere position - m_shieldPos = pos; - - if ( m_rankSphere != -1 ) - { - m_particule->SetPosition(m_rankSphere, m_shieldPos); - dim.x = RetRadius(); - dim.y = dim.x; - m_particule->SetDimension(m_rankSphere, dim); - } - - if ( m_phase == TS_UP1 ) - { - pos.x = 7.0f; - pos.y = 4.5f+Bounce(m_progress)*3.0f; - pos.z = 0.0f; - m_object->SetPosition(2, pos); - } - - if ( m_phase == TS_UP2 ) - { - pos.x = 0.0f; - pos.y = 1.0f+Bounce(m_progress)*3.0f; - pos.z = 0.0f; - m_object->SetPosition(3, pos); - } - - if ( m_phase == TS_SHIELD ) - { - energy = (1.0f/ENERGY_TIME)*event.rTime; - energy *= RetRadius()/RADIUS_SHIELD_MAX; - power = m_object->RetPower(); - if ( power != 0 ) - { - power->SetEnergy(power->RetEnergy()-energy/power->RetCapacity()); - } - m_energyUsed += energy; - - if ( m_soundChannel == -1 ) - { - m_soundChannel = m_sound->Play(SOUND_SHIELD, m_shieldPos, 0.5f, 0.5f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 2.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 1.0f, SOPER_LOOP); - } - else - { - m_sound->Position(m_soundChannel, m_shieldPos); - } - - pos = m_shieldPos; - pos.y += RetRadius()*(2.0f+sinf(m_time*9.0f)*0.2f); - if ( m_effectLight == -1 ) - { - CreateLight(pos); - } - else - { - m_light->SetLightPos(m_effectLight, pos); - - color.r = 0.0f+sinf(m_time*33.2f)*0.2f; - color.g = 0.5f+sinf(m_time*20.0f)*0.5f; - color.b = 0.5f+sinf(m_time*21.3f)*1.0f; - color.a = 0.0f; - m_light->SetLightColor(m_effectLight, color); - } - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_shieldPos; - pos.x += (Rand()-0.5f)*5.0f; - pos.z += (Rand()-0.5f)*5.0f; - speed.x = (Rand()-0.5f)*0.0f; - speed.z = (Rand()-0.5f)*0.0f; - speed.y = Rand()*15.0f; - dim.x = Rand()*6.0f+4.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); - } - - if ( m_lastRay+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastRay = m_time; - - pos = m_shieldPos; - dim.x = RetRadius()/20.0f; - dim.y = dim.x; - angle.x = (Rand()-0.5f)*PI*1.2f; - angle.y = 0.0f; - angle.z = (Rand()-0.5f)*PI*1.2f; - MatRotateXZY(matrix, angle); - goal = Transform(matrix, D3DVECTOR(0.0f, RetRadius()-dim.x, 0.0f)); - goal += pos; - m_particule->CreateRay(pos, goal, PARTIRAY2, dim, 0.3f); - } - - if ( m_lastIncrease+0.2f <= m_time ) - { - m_lastIncrease = m_time; - IncreaseShield(); - } - } - - if ( m_phase == TS_SMOKE ) - { - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.5f, 2.0f, SOPER_STOP); - m_soundChannel = -1; - } - - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) - { - m_lastParticule = m_time; - - pos = m_shieldPos; - pos.x += (Rand()-0.5f)*5.0f; - pos.z += (Rand()-0.5f)*5.0f; - speed.x = (Rand()-0.5f)*3.0f; - speed.z = (Rand()-0.5f)*3.0f; - speed.y = (Rand()-0.5f)*3.0f; - dim.x = Rand()*1.5f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); - } - } - - if ( m_phase == TS_DOWN1 ) - { - pos.x = 0.0f; - pos.y = 1.0f+(1.0f-Bounce(m_progress))*3.0f; - pos.z = 0.0f; - m_object->SetPosition(3, pos); - } - - if ( m_phase == TS_DOWN2 ) - { - pos.x = 7.0f; - pos.y = 4.5f+(1.0f-Bounce(m_progress))*3.0f; - pos.z = 0.0f; - m_object->SetPosition(2, pos); - } - - return TRUE; -} - - -// Deploys the shield. -// The period is only useful with TSM_UP! - -Error CTaskShield::Start(TaskShieldMode mode, float delay) -{ - CObject* power; - D3DMATRIX* mat; - D3DVECTOR pos, iPos, oPos, speed; - ObjectType type; - float energy; - - if ( mode == TSM_DOWN ) - { - return Stop(); - } - - if ( mode == TSM_UPDATE ) - { - if ( m_object->RetSelect() ) - { - m_brain->UpdateInterface(); - } - return ERR_OK; - } - - type = m_object->RetType(); - if ( type != OBJECT_MOBILErs ) return ERR_SHIELD_VEH; - - m_bError = TRUE; // operation impossible - if ( !m_physics->RetLand() ) return ERR_SHIELD_VEH; - - power = m_object->RetPower(); - if ( power == 0 ) return ERR_SHIELD_ENERGY; - energy = power->RetEnergy(); - if ( energy == 0.0f ) return ERR_SHIELD_ENERGY; - - mat = m_object->RetWorldMatrix(0); - pos = D3DVECTOR(7.0f, 15.0f, 0.0f); - pos = Transform(*mat, pos); // sphere position - m_shieldPos = pos; - - m_sound->Play(SOUND_PSHHH2, m_shieldPos, 1.0f, 0.7f); - - m_phase = TS_UP1; - m_progress = 0.0f; - m_speed = 1.0f/1.0f; - m_time = 0.0f; - m_delay = delay; - m_lastParticule = 0.0f; - m_lastRay = 0.0f; - m_lastIncrease = 0.0f; - m_energyUsed = 0.0f; - - m_bError = FALSE; // ok - - if ( m_object->RetSelect() ) - { - m_brain->UpdateInterface(); - } -//? m_camera->StartCentering(m_object, PI*0.85f, -PI*0.15f, RetRadius()+40.0f, 3.0f); - return ERR_OK; -} - -// Returns the shield. - -Error CTaskShield::Stop() -{ - float time; - - if ( m_phase == TS_SHIELD ) - { - m_object->SetShieldRadius(0.0f); - - if ( m_rankSphere != -1 ) - { - m_particule->SetPhase(m_rankSphere, PARPHEND, 3.0f); - m_rankSphere = -1; - } - - if ( m_effectLight != -1 ) - { - m_light->DeleteLight(m_effectLight); - m_effectLight = -1; - } - - time = m_energyUsed*4.0f; - if ( time < 1.0f ) time = 1.0f; - if ( time > 4.0f ) time = 4.0f; - - m_phase = TS_SMOKE; - m_speed = 1.0f/time; - - m_camera->StopCentering(m_object, 4.0f); - - if ( m_object->RetSelect() ) - { - m_brain->UpdateInterface(); - } - return ERR_CONTINUE; - } - - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskShield::IsEnded() -{ - CObject* power; - D3DVECTOR pos, speed; - FPOINT dim; - float energy; - - if ( m_engine->RetPause() ) return ERR_CONTINUE; - if ( m_bError ) return ERR_STOP; - - if ( m_phase == TS_SHIELD ) - { - m_object->SetShieldRadius(RetRadius()); - - power = m_object->RetPower(); - if ( power == 0 ) - { - energy = 0.0f; - } - else - { - energy = power->RetEnergy(); - } - - if ( energy == 0.0f || m_delay <= 0.0f ) - { - Stop(); - } - return ERR_CONTINUE; - } - - if ( m_progress < 1.0f ) return ERR_CONTINUE; - m_progress = 0.0f; - - if ( m_phase == TS_UP1 ) - { - pos.x = 7.0f; - pos.y = 4.5f+3.0f; - pos.z = 0.0f; - m_object->SetPosition(2, pos); - - m_sound->Play(SOUND_PSHHH2, m_shieldPos, 1.0f, 1.0f); - - m_phase = TS_UP2; - m_speed = 1.0f/0.8f; - return ERR_CONTINUE; - } - - if ( m_phase == TS_UP2 ) - { - pos.x = 0.0f; - pos.y = 1.0f+3.0f; - pos.z = 0.0f; - m_object->SetPosition(3, pos); - - m_object->SetShieldRadius(RetRadius()); - - pos = m_shieldPos; - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = RetRadius(); - dim.y = dim.x; - m_rankSphere = m_particule->CreateParticule(pos, speed, dim, PARTISPHERE3, 2.0f, 0.0f, 0.0f); - - m_phase = TS_SHIELD; - m_speed = 1.0f/999.9f; - - if ( m_object->RetSelect() ) - { - m_brain->UpdateInterface(); - } - return ERR_CONTINUE; - } - - if ( m_phase == TS_SMOKE ) - { - m_sound->Play(SOUND_PSHHH2, m_shieldPos, 1.0f, 1.0f); - - m_phase = TS_DOWN1; - m_speed = 1.0f/0.8f; - return ERR_CONTINUE; - } - - if ( m_phase == TS_DOWN1 ) - { - m_sound->Play(SOUND_PSHHH2, m_shieldPos, 1.0f, 0.7f); - - m_phase = TS_DOWN2; - m_speed = 1.0f/1.0f; - return ERR_CONTINUE; - } - - Abort(); - return ERR_STOP; -} - -// Indicates whether the action is pending. - -BOOL CTaskShield::IsBusy() -{ - if ( m_phase == TS_SHIELD ) - { - return FALSE; - } - - return TRUE; -} - -// Suddenly ends the current action. - -BOOL CTaskShield::Abort() -{ - D3DVECTOR pos; - - m_object->SetShieldRadius(0.0f); - - pos.x = 7.0f; - pos.y = 4.5f; - pos.z = 0.0f; - m_object->SetPosition(2, pos); - - pos.x = 0.0f; - pos.y = 1.0f; - pos.z = 0.0f; - m_object->SetPosition(3, pos); - - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.5f, 2.0f, SOPER_STOP); - m_soundChannel = -1; - } - - if ( m_rankSphere != -1 ) - { - m_particule->SetPhase(m_rankSphere, PARPHEND, 3.0f); - m_rankSphere = -1; - } - - if ( m_effectLight != -1 ) - { - m_light->DeleteLight(m_effectLight); - m_effectLight = -1; - } - - m_camera->StopCentering(m_object, 2.0f); - return TRUE; -} - - -// Creates the light to accompany a pyrotechnic effect. - -BOOL CTaskShield::CreateLight(D3DVECTOR pos) -{ - D3DLIGHT7 light; - - if ( !m_engine->RetLightMode() ) return TRUE; - - ZeroMemory( &light, sizeof(light) ); - light.dltType = D3DLIGHT_SPOT; - light.dcvDiffuse.r = 0.0f; - light.dcvDiffuse.g = 1.0f; - light.dcvDiffuse.b = 2.0f; - light.dvPosition.x = pos.x; - light.dvPosition.y = pos.y; - light.dvPosition.z = pos.z; - light.dvDirection.x = 0.0f; - light.dvDirection.y = -1.0f; // against the bottom - light.dvDirection.z = 0.0f; - light.dvRange = D3DLIGHT_RANGE_MAX; - light.dvFalloff = 1.0f; - light.dvAttenuation0 = 1.0f; - light.dvAttenuation1 = 0.0f; - light.dvAttenuation2 = 0.0f; - light.dvTheta = 0.0f; - light.dvPhi = PI/4.0f; - - m_effectLight = m_light->CreateLight(); - if ( m_effectLight == -1 ) return FALSE; - - m_light->SetLight(m_effectLight, light); - m_light->SetLightIntensity(m_effectLight, 1.0f); - - return TRUE; -} - - -// Repaired the shielded objects within the sphere of the shield. - -void CTaskShield::IncreaseShield() -{ - ObjectType type; - CObject* pObj; - D3DVECTOR oPos; - float dist, shield; - int i; - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type == OBJECT_MOTHER || - type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_BEE || - type == OBJECT_WORM ) continue; - - oPos = pObj->RetPosition(0); - dist = Length(oPos, m_shieldPos); - if ( dist <= RetRadius()+10.0f ) - { - shield = pObj->RetShield(); - shield += 0.1f; - if ( shield > 1.0f ) shield = 1.0f; - pObj->SetShield(shield); - } - } -} - - -// Returns the radius of the shield. - -float CTaskShield::RetRadius() -{ - return RADIUS_SHIELD_MIN + (RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)*m_object->RetParam(); -} - - - diff --git a/src/taskshield.h b/src/taskshield.h deleted file mode 100644 index 8ec2d05..0000000 --- a/src/taskshield.h +++ /dev/null @@ -1,94 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskshield.h - -#ifndef _TASKSHIELD_H_ -#define _TASKSHIELD_H_ - - -#include "misc.h" -#include "d3dengine.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - -#define RADIUS_SHIELD_MIN 40.0f // minimal radius of the protected zone -#define RADIUS_SHIELD_MAX 100.0f // maximal radius of the protected zone - - -enum TaskShieldPhase -{ - TS_UP1 = 1, // up - TS_UP2 = 2, // up - TS_SHIELD = 3, // shield deployed - TS_SMOKE = 4, // smoke - TS_DOWN1 = 5, // down - TS_DOWN2 = 6, // down -}; - -enum TaskShieldMode -{ - TSM_UP = 1, // deploys shield - TSM_DOWN = 2, // returns the shield - TSM_UPDATE = 3, // radius change -}; - - - -class CTaskShield : public CTask -{ -public: - CTaskShield(CInstanceManager* iMan, CObject* object); - ~CTaskShield(); - - BOOL EventProcess(const Event &event); - - Error Start(TaskShieldMode mode, float delay); - Error IsEnded(); - BOOL IsBusy(); - BOOL Abort(); - -protected: - Error Stop(); - BOOL CreateLight(D3DVECTOR pos); - void IncreaseShield(); - float RetRadius(); - -protected: - TaskShieldPhase m_phase; - float m_progress; - float m_speed; - float m_time; - float m_delay; - float m_lastParticule; - float m_lastRay; - float m_lastIncrease; - float m_energyUsed; - BOOL m_bError; - D3DVECTOR m_shieldPos; - int m_rankSphere; - int m_soundChannel; - int m_effectLight; -}; - - -#endif //_TASKSHIELD_H_ diff --git a/src/taskspiderexplo.cpp b/src/taskspiderexplo.cpp deleted file mode 100644 index b655fe6..0000000 --- a/src/taskspiderexplo.cpp +++ /dev/null @@ -1,124 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskspiderexplo.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "object.h" -#include "physics.h" -#include "pyro.h" -#include "motion.h" -#include "motionspider.h" -#include "task.h" -#include "taskspiderexplo.h" - - - - -// Object's constructor. - -CTaskSpiderExplo::CTaskSpiderExplo(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); - - m_time = 0.0f; - m_bError = FALSE; -} - -// Object's destructor. - -CTaskSpiderExplo::~CTaskSpiderExplo() -{ -} - - -// Management of an event. - -BOOL CTaskSpiderExplo::EventProcess(const Event &event) -{ - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - // Momentarily stationary object (ant on the back)? - if ( m_object->RetFixed() ) - { - m_bError = TRUE; - return TRUE; - } - - m_time += event.rTime; - - return TRUE; -} - - -// Assigns the goal was achieved. - -Error CTaskSpiderExplo::Start() -{ - m_motion->SetAction(MSS_EXPLO, 1.0f); // swells abdominal - m_time = 0.0f; - - m_physics->SetMotorSpeedX(0.0f); // stops the advance - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - - m_bError = FALSE; - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskSpiderExplo::IsEnded() -{ - CPyro* pyro; - - if ( m_engine->RetPause() ) return ERR_CONTINUE; - - if ( m_bError ) - { - Abort(); - return ERR_STOP; - } - - if ( m_time < 1.0f ) return ERR_CONTINUE; - - pyro = new CPyro(m_iMan); - pyro->Create(PT_SPIDER, m_object); // the spider explodes (suicide) - - Abort(); - return ERR_STOP; -} - -// Suddenly ends the current action. - -BOOL CTaskSpiderExplo::Abort() -{ - return TRUE; -} - diff --git a/src/taskspiderexplo.h b/src/taskspiderexplo.h deleted file mode 100644 index fb7f5f6..0000000 --- a/src/taskspiderexplo.h +++ /dev/null @@ -1,53 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskspiderexplo.h - -#ifndef _TASKSPIDEREXPLO_H_ -#define _TASKSPIDEREXPLO_H_ - - -#include "misc.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - -class CTaskSpiderExplo : public CTask -{ -public: - CTaskSpiderExplo(CInstanceManager* iMan, CObject* object); - ~CTaskSpiderExplo(); - - BOOL EventProcess(const Event &event); - - Error Start(); - Error IsEnded(); - BOOL Abort(); - -protected: - -protected: - float m_time; - BOOL m_bError; -}; - - -#endif //_TASKSPIDEREXPLO_H_ diff --git a/src/tasktake.cpp b/src/tasktake.cpp deleted file mode 100644 index 35de2b7..0000000 --- a/src/tasktake.cpp +++ /dev/null @@ -1,612 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// tasktake.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "water.h" -#include "camera.h" -#include "motion.h" -#include "motionhuman.h" -#include "sound.h" -#include "robotmain.h" -#include "task.h" -#include "tasktake.h" - - - - -// Object's constructor. - -CTaskTake::CTaskTake(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); - - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - - m_arm = TTA_NEUTRAL; -} - -// Object's destructor. - -CTaskTake::~CTaskTake() -{ -} - - -// Management of an event. - -BOOL CTaskTake::EventProcess(const Event &event) -{ - float a, g, cirSpeed; - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_bError ) return FALSE; - - if ( m_bTurn ) // preliminary rotation? - { - a = m_object->RetAngleY(0); - g = m_angle; - cirSpeed = Direction(a, g)*2.0f; - if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; - if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; - - m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right - return TRUE; - } - - m_progress += event.rTime*m_speed; // others advance - - m_physics->SetMotorSpeed(D3DVECTOR(0.0f, 0.0f, 0.0f)); // immobile! - - return TRUE; -} - - -// Assigns the goal was achieved. - -Error CTaskTake::Start() -{ - ObjectType type; - CObject* other; - float iAngle, oAngle, h; - D3DVECTOR pos; - - m_height = 0.0f; - m_step = 0; - m_progress = 0.0f; - - iAngle = m_object->RetAngleY(0); - iAngle = NormAngle(iAngle); // 0..2*PI - oAngle = iAngle; - - m_bError = TRUE; // operation impossible - if ( !m_physics->RetLand() ) - { - pos = m_object->RetPosition(0); - h = m_water->RetLevel(m_object); - if ( pos.y < h ) return ERR_MANIP_WATER; // impossible under water - return ERR_MANIP_FLY; - } - - type = m_object->RetType(); - if ( type != OBJECT_HUMAN && - type != OBJECT_TECH ) return ERR_MANIP_VEH; - - m_physics->SetMotorSpeed(D3DVECTOR(0.0f, 0.0f, 0.0f)); - - if ( m_object->RetFret() == 0 ) - { - m_order = TTO_TAKE; - } - else - { - m_order = TTO_DEPOSE; - } - - if ( m_order == TTO_TAKE ) - { - pos = m_object->RetPosition(0); - h = m_water->RetLevel(m_object); - if ( pos.y < h ) return ERR_MANIP_WATER; // impossible under water - - other = SearchFriendObject(oAngle, 1.5f, PI*0.50f); - if ( other != 0 && other->RetPower() != 0 ) - { - type = other->RetPower()->RetType(); - if ( type == OBJECT_URANIUM ) return ERR_MANIP_RADIO; - if ( type != OBJECT_FRET && - type != OBJECT_STONE && - type != OBJECT_BULLET && - type != OBJECT_METAL && - type != OBJECT_POWER && - type != OBJECT_ATOMIC && - type != OBJECT_BBOX && - type != OBJECT_KEYa && - type != OBJECT_KEYb && - type != OBJECT_KEYc && - type != OBJECT_KEYd && - type != OBJECT_TNT ) return ERR_MANIP_FRIEND; -//? m_camera->StartCentering(m_object, PI*0.3f, -PI*0.1f, 0.0f, 0.8f); - m_arm = TTA_FRIEND; - } - else - { - other = SearchTakeObject(oAngle, 1.5f, PI*0.45f); - if ( other == 0 ) return ERR_MANIP_NIL; - type = other->RetType(); - if ( type == OBJECT_URANIUM ) return ERR_MANIP_RADIO; -//? m_camera->StartCentering(m_object, PI*0.3f, 99.9f, 0.0f, 0.8f); - m_arm = TTA_FFRONT; - m_main->HideDropZone(other); // hides buildable area - } - } - - if ( m_order == TTO_DEPOSE ) - { -//? speed = m_physics->RetMotorSpeed(); -//? if ( speed.x != 0.0f || -//? speed.z != 0.0f ) return ERR_MANIP_MOTOR; - - other = SearchFriendObject(oAngle, 1.5f, PI*0.50f); - if ( other != 0 && other->RetPower() == 0 ) - { -//? m_camera->StartCentering(m_object, PI*0.3f, -PI*0.1f, 0.0f, 0.8f); - m_arm = TTA_FRIEND; - } - else - { - if ( !IsFreeDeposeObject(D3DVECTOR(2.5f, 0.0f, 0.0f)) ) return ERR_MANIP_OCC; -//? m_camera->StartCentering(m_object, PI*0.3f, 99.9f, 0.0f, 0.8f); - m_arm = TTA_FFRONT; - } - } - - m_bTurn = TRUE; // preliminary rotation necessary - m_angle = oAngle; // angle was reached - - m_physics->SetFreeze(TRUE); // it does not move - - m_bError = FALSE; // ok - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskTake::IsEnded() -{ - CObject* fret; - float angle; - - if ( m_engine->RetPause() ) return ERR_CONTINUE; - if ( m_bError ) return ERR_STOP; - - if ( m_bTurn ) // preliminary rotation? - { - angle = m_object->RetAngleY(0); - angle = NormAngle(angle); // 0..2*PI - - if ( TestAngle(angle, m_angle-PI*0.01f, m_angle+PI*0.01f) ) - { - m_bTurn = FALSE; // rotation ended - m_physics->SetMotorSpeedZ(0.0f); - - if ( m_arm == TTA_FFRONT ) - { - m_motion->SetAction(MHS_TAKE, 0.2f); // will decrease - } - if ( m_arm == TTA_FRIEND ) - { - if ( m_height <= 3.0f ) - { - m_motion->SetAction(MHS_TAKEOTHER, 0.2f); // will decrease - } - else - { - m_motion->SetAction(MHS_TAKEHIGH, 0.2f); // will decrease - } - } - m_progress = 0.0f; - m_speed = 1.0f/0.6f; - } - return ERR_CONTINUE; - } - - if ( m_progress < 1.0f ) return ERR_CONTINUE; - m_progress = 0.0f; - - m_step ++; - - if ( m_order == TTO_TAKE ) - { - if ( m_step == 1 ) - { - if ( TruckTakeObject() ) - { - if ( m_arm == TTA_FRIEND && - (m_fretType == OBJECT_POWER || - m_fretType == OBJECT_ATOMIC ) ) - { - m_sound->Play(SOUND_POWEROFF, m_object->RetPosition(0)); - } - } - m_motion->SetAction(MHS_UPRIGHT, 0.4f); // gets up - m_progress = 0.0f; - m_speed = 1.0f/0.8f; - m_camera->StopCentering(m_object, 0.8f); - return ERR_CONTINUE; - } - } - - if ( m_order == TTO_DEPOSE ) - { - if ( m_step == 1 ) - { - fret = m_object->RetFret(); - TruckDeposeObject(); - if ( m_arm == TTA_FRIEND && - (m_fretType == OBJECT_POWER || - m_fretType == OBJECT_ATOMIC ) ) - { - m_sound->Play(SOUND_POWERON, m_object->RetPosition(0)); - } - if ( fret != 0 && m_fretType == OBJECT_METAL && m_arm == TTA_FFRONT ) - { - m_main->ShowDropZone(fret, m_object); // shows buildable area - } - m_motion->SetAction(-1); // gets up - m_progress = 0.0f; - m_speed = 1.0f/0.4f; - m_camera->StopCentering(m_object, 0.8f); - return ERR_CONTINUE; - } - } - - Abort(); - return ERR_STOP; -} - -// Suddenly ends the current action. - -BOOL CTaskTake::Abort() -{ - m_motion->SetAction(-1); - m_camera->StopCentering(m_object, 0.8f); - m_physics->SetFreeze(FALSE); // is moving again - return TRUE; -} - - -// Seeks the object to take in front. - -CObject* CTaskTake::SearchTakeObject(float &angle, - float dLimit, float aLimit) -{ - CObject *pObj, *pBest; - D3DVECTOR iPos, oPos; - ObjectType type; - float min, iAngle, bAngle, a, distance; - int i; - - iPos = m_object->RetPosition(0); - iAngle = m_object->RetAngleY(0); - iAngle = NormAngle(iAngle); // 0..2*PI - - min = 1000000.0f; - pBest = 0; - bAngle = 0.0f; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - - if ( type != OBJECT_FRET && - type != OBJECT_STONE && - type != OBJECT_URANIUM && - type != OBJECT_BULLET && - type != OBJECT_METAL && - type != OBJECT_POWER && - type != OBJECT_ATOMIC && - type != OBJECT_BBOX && - type != OBJECT_KEYa && - type != OBJECT_KEYb && - type != OBJECT_KEYc && - type != OBJECT_KEYd && - type != OBJECT_TNT ) continue; - - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( pObj->RetLock() ) continue; - if ( pObj->RetZoomY(0) != 1.0f ) continue; - - oPos = pObj->RetPosition(0); - distance = Length(oPos, iPos); - if ( distance >= 4.0f-dLimit && - distance <= 4.0f+dLimit ) - { - angle = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! - if ( TestAngle(angle, iAngle-aLimit, iAngle+aLimit) ) - { - a = Abs(angle-iAngle); - if ( a > PI ) a = PI*2.0f-a; - if ( a < min ) - { - min = a; - pBest = pObj; - bAngle = angle; - } - } - } - } - angle = bAngle; - return pBest; -} - -// Seeks the robot on which you want take or put a battery. - -CObject* CTaskTake::SearchFriendObject(float &angle, - float dLimit, float aLimit) -{ - Character* character; - CObject* pObj; - CObject* pPower; - D3DMATRIX* mat; - D3DVECTOR iPos, oPos; - ObjectType type, powerType; - float iAngle, iRad, distance; - int i; - - if ( !m_object->GetCrashSphere(0, iPos, iRad) ) return 0; - iAngle = m_object->RetAngleY(0); - iAngle = NormAngle(iAngle); // 0..2*PI - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj == m_object ) continue; // yourself? - - type = pObj->RetType(); - if ( type != OBJECT_MOBILEfa && - type != OBJECT_MOBILEta && - type != OBJECT_MOBILEwa && - type != OBJECT_MOBILEia && - type != OBJECT_MOBILEfc && - type != OBJECT_MOBILEtc && - type != OBJECT_MOBILEwc && - type != OBJECT_MOBILEic && - type != OBJECT_MOBILEfi && - type != OBJECT_MOBILEti && - type != OBJECT_MOBILEwi && - type != OBJECT_MOBILEii && - type != OBJECT_MOBILEfs && - type != OBJECT_MOBILEts && - type != OBJECT_MOBILEws && - type != OBJECT_MOBILEis && - type != OBJECT_MOBILErt && - type != OBJECT_MOBILErc && - type != OBJECT_MOBILErr && - type != OBJECT_MOBILErs && - type != OBJECT_MOBILEsa && - type != OBJECT_MOBILEtg && - type != OBJECT_MOBILEft && - type != OBJECT_MOBILEtt && - type != OBJECT_MOBILEwt && - type != OBJECT_MOBILEit && - type != OBJECT_TOWER && - type != OBJECT_RESEARCH && - type != OBJECT_ENERGY && - type != OBJECT_LABO && - type != OBJECT_NUCLEAR ) continue; - - pPower = pObj->RetPower(); - if ( pPower != 0 ) - { - if ( pPower->RetLock() ) continue; - if ( pPower->RetZoomY(0) != 1.0f ) continue; - - powerType = pPower->RetType(); - if ( powerType == OBJECT_NULL || - powerType == OBJECT_FIX ) continue; - } - - mat = pObj->RetWorldMatrix(0); - character = pObj->RetCharacter(); - oPos = Transform(*mat, character->posPower); - - distance = Abs(Length(oPos, iPos) - (iRad+1.0f)); - if ( distance <= dLimit ) - { - angle = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! - if ( TestAngle(angle, iAngle-aLimit, iAngle+aLimit) ) - { - character = pObj->RetCharacter(); - m_height = character->posPower.y; - return pObj; - } - } - } - - return 0; -} - -// Takes the object in front. - -BOOL CTaskTake::TruckTakeObject() -{ - CObject* fret; - CObject* other; - D3DMATRIX matRotate; - float angle; - - if ( m_arm == TTA_FFRONT ) // takes on the ground in front? - { -//? fret = SearchTakeObject(angle, 1.5f, PI*0.04f); - fret = SearchTakeObject(angle, 1.5f, PI*0.15f); //OK 1.9 - if ( fret == 0 ) return FALSE; // rien � prendre ? - m_fretType = fret->RetType(); - - fret->SetTruck(m_object); - fret->SetTruckPart(4); // takes with the hand - -//? fret->SetPosition(0, D3DVECTOR(2.2f, -1.0f, 1.1f)); - fret->SetPosition(0, D3DVECTOR(1.7f, -0.5f, 1.1f)); - fret->SetAngleY(0, 0.1f); - fret->SetAngleX(0, 0.0f); - fret->SetAngleZ(0, 0.8f); - - m_object->SetFret(fret); // takes - } - - if ( m_arm == TTA_FRIEND ) // takes friend's battery? - { - other = SearchFriendObject(angle, 1.5f, PI*0.04f); - if ( other == 0 ) return FALSE; - - fret = other->RetPower(); - if ( fret == 0 ) return FALSE; // the other does not have a battery? - m_fretType = fret->RetType(); - - other->SetPower(0); - fret->SetTruck(m_object); - fret->SetTruckPart(4); // takes with the hand - -//? fret->SetPosition(0, D3DVECTOR(2.2f, -1.0f, 1.1f)); - fret->SetPosition(0, D3DVECTOR(1.7f, -0.5f, 1.1f)); - fret->SetAngleY(0, 0.1f); - fret->SetAngleX(0, 0.0f); - fret->SetAngleZ(0, 0.8f); - - m_object->SetFret(fret); // takes - } - - return TRUE; -} - -// Deposes the object taken. - -BOOL CTaskTake::TruckDeposeObject() -{ - Character* character; - CObject* fret; - CObject* other; - D3DMATRIX* mat; - D3DVECTOR pos; - float angle; - - if ( m_arm == TTA_FFRONT ) // deposes on the ground in front? - { - fret = m_object->RetFret(); - if ( fret == 0 ) return FALSE; // does nothing? - m_fretType = fret->RetType(); - - mat = fret->RetWorldMatrix(0); - pos = Transform(*mat, D3DVECTOR(-0.5f, 1.0f, 0.0f)); - m_terrain->MoveOnFloor(pos); - fret->SetPosition(0, pos); - fret->SetAngleY(0, m_object->RetAngleY(0)+PI/2.0f); - fret->SetAngleX(0, 0.0f); - fret->SetAngleZ(0, 0.0f); - fret->FloorAdjust(); // plate well on the ground - - fret->SetTruck(0); - m_object->SetFret(0); // deposit - } - - if ( m_arm == TTA_FRIEND ) // deposes battery on friends? - { - other = SearchFriendObject(angle, 1.5f, PI*0.04f); - if ( other == 0 ) return FALSE; - - fret = other->RetPower(); - if ( fret != 0 ) return FALSE; // the other already has a battery? - - fret = m_object->RetFret(); - if ( fret == 0 ) return FALSE; - m_fretType = fret->RetType(); - - other->SetPower(fret); - fret->SetTruck(other); - - character = other->RetCharacter(); - fret->SetPosition(0, character->posPower); - fret->SetAngleY(0, 0.0f); - fret->SetAngleX(0, 0.0f); - fret->SetAngleZ(0, 0.0f); - fret->SetTruckPart(0); // carried by the base - - m_object->SetFret(0); // deposit - } - - return TRUE; -} - -// Seeks if a location allows to deposit an object. - -BOOL CTaskTake::IsFreeDeposeObject(D3DVECTOR pos) -{ - CObject* pObj; - D3DMATRIX* mat; - D3DVECTOR iPos, oPos; - float oRadius; - int i, j; - - mat = m_object->RetWorldMatrix(0); - iPos = Transform(*mat, pos); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - if ( pObj == m_object ) continue; - if ( !pObj->RetActif() ) continue; // inactive? - if ( pObj->RetTruck() != 0 ) continue; // object transported? - - j = 0; - while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) - { - if ( Length(iPos, oPos)-(oRadius+1.0f) < 1.0f ) - { - return FALSE; // location occupied - } - } - } - return TRUE; // location free -} - - diff --git a/src/tasktake.h b/src/tasktake.h deleted file mode 100644 index 80b8736..0000000 --- a/src/tasktake.h +++ /dev/null @@ -1,85 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// tasktake.h - -#ifndef _TASKTAKE_H_ -#define _TASKTAKE_H_ - - -#include "misc.h" -#include "object.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - - -enum TaskTakeOrder -{ - TTO_TAKE = 1, // takes an object - TTO_DEPOSE = 2, // deposes the object -}; - -enum TaskTakeArm -{ - TTA_NEUTRAL = 1, // empty arm at rest - TTA_FFRONT = 2, // arm on the ground - TTA_FRIEND = 3, // arm behind a friend robot -}; - - - -class CTaskTake : public CTask -{ -public: - CTaskTake(CInstanceManager* iMan, CObject* object); - ~CTaskTake(); - - BOOL EventProcess(const Event &event); - - Error Start(); - Error IsEnded(); - BOOL Abort(); - -protected: - CObject* SearchTakeObject(float &angle, float dLimit, float aLimit); - CObject* SearchFriendObject(float &angle, float dLimit, float aLimit); - BOOL TruckTakeObject(); - BOOL TruckDeposeObject(); - BOOL IsFreeDeposeObject(D3DVECTOR pos); - -protected: - CTerrain* m_terrain; - - TaskTakeOrder m_order; - TaskTakeArm m_arm; - int m_step; - float m_speed; - float m_progress; - float m_height; - BOOL m_bError; - BOOL m_bTurn; - float m_angle; - ObjectType m_fretType; -}; - - -#endif //_TASKTAKE_H_ diff --git a/src/taskterraform.cpp b/src/taskterraform.cpp deleted file mode 100644 index e2f75fc..0000000 --- a/src/taskterraform.cpp +++ /dev/null @@ -1,429 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskterraform.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "language.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "pyro.h" -#include "brain.h" -#include "camera.h" -#include "sound.h" -#include "motion.h" -#include "motionant.h" -#include "motionspider.h" -#include "task.h" -#include "taskterraform.h" - - -#define ENERGY_TERRA 0.40f // energy consumed by blow -#define ACTION_RADIUS 400.0f - - - -// Object's constructor. - -CTaskTerraform::CTaskTerraform(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); - m_lastParticule = 0.0f; - m_soundChannel = -1; -} - -// Object's destructor. - -CTaskTerraform::~CTaskTerraform() -{ -} - - -// Management of an event. - -BOOL CTaskTerraform::EventProcess(const Event &event) -{ - CObject* power; - D3DMATRIX* mat; - D3DVECTOR pos, dir, speed; - FPOINT dim; - float energy; - - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - if ( m_bError ) return FALSE; - - m_progress += event.rTime*m_speed; // others advance - m_time += event.rTime; - - if ( m_phase == TTP_CHARGE ) - { - if ( m_soundChannel == -1 ) - { -#if _TEEN - m_soundChannel = m_sound->Play(SOUND_GGG, m_object->RetPosition(0), 1.0f, 0.5f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 2.0f, 1.5f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.5f, SOPER_STOP); -#else - m_soundChannel = m_sound->Play(SOUND_GGG, m_object->RetPosition(0), 1.0f, 0.5f, TRUE); - m_sound->AddEnvelope(m_soundChannel, 1.0f, 2.0f, 4.0f, SOPER_CONTINUE); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.5f, SOPER_STOP); -#endif - } - - dir.x = 0.0f; - dir.y = (Rand()-0.5f)*0.2f*m_progress; - dir.z = 0.0f; - m_object->SetCirVibration(dir); - - m_object->SetZoom(0, 1.0f+m_progress*0.2f); - - power = m_object->RetPower(); - if ( power != 0 ) - { - power->SetZoom(0, 1.0f+m_progress*1.0f); - - energy = power->RetEnergy(); - energy -= event.rTime*ENERGY_TERRA/power->RetCapacity()/4.0f; - if ( energy < 0.0f ) energy = 0.0f; - power->SetEnergy(energy); - } - } - - if ( m_phase == TTP_DOWN ) - { - pos.x = 9.0f; -#if _TEEN - pos.y = 4.0f-m_progress*4.0f; -#else - pos.y = 4.0f-m_progress*5.8f; -#endif - pos.z = 0.0f; - m_object->SetPosition(2, pos); - } - - if ( m_phase == TTP_UP ) - { - pos.x = 9.0f; -#if _TEEN - pos.y = 4.0f-(1.0f-m_progress)*4.0f; -#else - pos.y = 4.0f-(1.0f-m_progress)*5.8f; -#endif - pos.z = 0.0f; - m_object->SetPosition(2, pos); - } - - dir.x = 0.0f; - dir.y = 0.0f; - dir.z = 0.0f; - pos = m_object->RetPosition(2); - if ( pos.y < 0.0f ) - { - dir.z = -atanf((pos.y/2.0f)/9.0f); - } - m_object->SetInclinaison(dir); - - if ( m_time-m_lastParticule >= m_engine->ParticuleAdapt(0.05f) ) - { - m_lastParticule = m_time; - - mat = m_object->RetWorldMatrix(0); - - if ( m_phase == TTP_CHARGE ) - { - // Battery. - pos = D3DVECTOR(-6.0f, 5.5f+2.0f*m_progress, 0.0f); - pos.x += (Rand()-0.5f)*1.0f; - pos.z += (Rand()-0.5f)*1.0f; - pos = Transform(*mat, pos); - speed.x = (Rand()-0.5f)*6.0f*(1.0f+m_progress*4.0f); - speed.z = (Rand()-0.5f)*6.0f*(1.0f+m_progress*4.0f); - speed.y = 6.0f+Rand()*4.0f*(1.0f+m_progress*2.0f); - dim.x = 0.5f+1.5f*m_progress; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 2.0f, 20.0f); - } - - if ( m_phase != TTP_CHARGE ) - { - // Left grid. - pos = D3DVECTOR(-1.0f, 5.8f, 3.5f); - pos.x += (Rand()-0.5f)*1.0f; - pos.z += (Rand()-0.5f)*1.0f; - pos = Transform(*mat, pos); - speed.x = Rand()*4.0f; - speed.z = Rand()*2.0f; - speed.y = 2.5f+Rand()*1.0f; - speed = Transform(*mat, speed); - speed -= m_object->RetPosition(0); - dim.x = Rand()*1.0f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 3.0f); - - // Right grid. - pos = D3DVECTOR(-1.0f, 5.8f, -3.5f); - pos.x += (Rand()-0.5f)*1.0f; - pos.z += (Rand()-0.5f)*1.0f; - pos = Transform(*mat, pos); - speed.x = Rand()*4.0f; - speed.z = -Rand()*2.0f; - speed.y = 2.5f+Rand()*1.0f; - speed = Transform(*mat, speed); - speed -= m_object->RetPosition(0); - dim.x = Rand()*1.0f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 3.0f); - } - } - - return TRUE; -} - - -// Assigns the goal was achieved. - -Error CTaskTerraform::Start() -{ - CObject* power; - D3DMATRIX* mat; - D3DVECTOR pos, speed; - float energy; - - ObjectType type; - - m_bError = TRUE; // operation impossible - if ( !m_physics->RetLand() ) return ERR_TERRA_VEH; - - type = m_object->RetType(); - if ( type != OBJECT_MOBILErt ) return ERR_TERRA_VEH; - - power = m_object->RetPower(); - if ( power == 0 ) return ERR_TERRA_ENERGY; - energy = power->RetEnergy(); - if ( energy < ENERGY_TERRA/power->RetCapacity()+0.05f ) return ERR_TERRA_ENERGY; - - speed = m_physics->RetMotorSpeed(); - if ( speed.x != 0.0f || - speed.z != 0.0f ) return ERR_MANIP_MOTOR; - - mat = m_object->RetWorldMatrix(0); - pos = D3DVECTOR(9.0f, 0.0f, 0.0f); - pos = Transform(*mat, pos); // battery position - m_terraPos = pos; - - m_phase = TTP_CHARGE; - m_progress = 0.0f; -#if _TEEN - m_speed = 1.0f/1.5f; -#else - m_speed = 1.0f/4.0f; -#endif - m_time = 0.0f; - - m_bError = FALSE; // ok - - m_camera->StartCentering(m_object, PI*0.35f, 99.9f, 20.0f, 2.0f); - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskTerraform::IsEnded() -{ - CObject* power; - D3DVECTOR pos, speed; - FPOINT dim; - float dist, duration; - int i, max; - - if ( m_engine->RetPause() ) return ERR_CONTINUE; - if ( m_bError ) return ERR_STOP; - - if ( m_progress < 1.0f ) return ERR_CONTINUE; - m_progress = 0.0f; - - if ( m_phase == TTP_CHARGE ) - { -#if _TEEN - Terraform(); // changes the terrain. -#endif - - m_phase = TTP_DOWN; - m_speed = 1.0f/0.2f; - return ERR_CONTINUE; - } - - if ( m_phase == TTP_DOWN ) - { -#if !_TEEN - Terraform(); // changes the terrain. -#endif - - m_object->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); - m_object->SetZoom(0, 1.0f); - - power = m_object->RetPower(); - if ( power != 0 ) - { - power->SetZoom(0, 1.0f); - } - - max= (int)(50.0f*m_engine->RetParticuleDensity()); - for ( i=0 ; iMoveOnFloor(pos); - dist = Length(pos, m_terraPos); - speed = D3DVECTOR(0.0f, 0.0f, 0.0f); - dim.x = 2.0f+(40.0f-dist)/(1.0f+Rand()*4.0f); - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); - - pos = m_terraPos; - speed.x = (Rand()-0.5f)*40.0f; - speed.z = (Rand()-0.5f)*40.0f; - speed.y = Rand()*15.0f+15.0f; - dim.x = 0.6f; - dim.y = dim.x; - pos.y += dim.y; - duration = Rand()*3.0f+3.0f; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK5, - duration, Rand()*10.0f+15.0f, - duration*0.2f, 1.0f); - } - - m_phase = TTP_TERRA; - m_speed = 1.0f/2.0f; - return ERR_CONTINUE; - } - - if ( m_phase == TTP_TERRA ) - { - m_phase = TTP_UP; - m_speed = 1.0f/1.0f; - return ERR_CONTINUE; - } - - Abort(); - return ERR_STOP; -} - -// Suddenly ends the current action. - -BOOL CTaskTerraform::Abort() -{ - CObject* power; - - if ( m_soundChannel != -1 ) - { - m_sound->FlushEnvelope(m_soundChannel); - m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.3f, SOPER_STOP); - m_soundChannel = -1; - } - - m_object->SetPosition(2, D3DVECTOR(9.0f, 4.0f, 0.0f)); - m_object->SetInclinaison(D3DVECTOR(0.0f, 0.0f, 0.0f)); - m_object->SetCirVibration(D3DVECTOR(0.0f, 0.0f, 0.0f)); - m_object->SetZoom(0, 1.0f); - - power = m_object->RetPower(); - if ( power != 0 ) - { - power->SetZoom(0, 1.0f); - } - - m_camera->StopCentering(m_object, 2.0f); - return TRUE; -} - - -// Returns all the close ants and spiders. - -BOOL CTaskTerraform::Terraform() -{ - CObject* pObj; - CBrain* brain; - CMotion* motion; - CPyro* pyro; - ObjectType type; - float dist; - int i; - - m_camera->StartEffect(CE_TERRAFORM, m_terraPos, 1.0f); - - m_sound->Play(SOUND_THUMP, m_terraPos); - - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; - - type = pObj->RetType(); - if ( type == OBJECT_NULL ) continue; - - if ( type == OBJECT_TEEN34 ) // stone? - { - dist = Length(m_terraPos, pObj->RetPosition(0)); - if ( dist > 20.0f ) continue; - - pyro = new CPyro(m_iMan); - pyro->Create(PT_FRAGT, pObj); - } - else - { - motion = pObj->RetMotion(); - if ( motion == 0 ) continue; - - dist = Length(m_terraPos, pObj->RetPosition(0)); - if ( dist > ACTION_RADIUS ) continue; - - if ( type == OBJECT_ANT ) - { - brain = pObj->RetBrain(); - if ( brain != 0 ) brain->StopTask(); - motion->SetAction(MAS_BACK1, 0.8f+Rand()*0.3f); - pObj->SetFixed(TRUE); // not moving - } - if ( type == OBJECT_SPIDER ) - { - brain = pObj->RetBrain(); - if ( brain != 0 ) brain->StopTask(); - motion->SetAction(MSS_BACK1, 0.8f+Rand()*0.3f); - pObj->SetFixed(TRUE); // not moving - } - } - } - - return TRUE; -} - diff --git a/src/taskterraform.h b/src/taskterraform.h deleted file mode 100644 index 254e363..0000000 --- a/src/taskterraform.h +++ /dev/null @@ -1,72 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskterraform.h - -#ifndef _TASKSTERRAFORM_H_ -#define _TASKSTERRAFORM_H_ - - -#include "misc.h" -#include "d3dengine.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - - -enum TaskTerraPhase -{ - TTP_CHARGE = 1, // charge of energy - TTP_DOWN = 2, // down - TTP_TERRA = 3, // strike - TTP_UP = 4, // up -}; - - - -class CTaskTerraform : public CTask -{ -public: - CTaskTerraform(CInstanceManager* iMan, CObject* object); - ~CTaskTerraform(); - - BOOL EventProcess(const Event &event); - - Error Start(); - Error IsEnded(); - BOOL Abort(); - -protected: - BOOL Terraform(); - -protected: - TaskTerraPhase m_phase; - float m_progress; - float m_speed; - float m_time; - float m_lastParticule; - int m_soundChannel; - BOOL m_bError; - D3DVECTOR m_terraPos; -}; - - -#endif //_TASKSTERRAFORM_H_ diff --git a/src/taskturn.cpp b/src/taskturn.cpp deleted file mode 100644 index 832f523..0000000 --- a/src/taskturn.cpp +++ /dev/null @@ -1,147 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskturn.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "task.h" -#include "taskturn.h" - - - - -// Object's constructor. - -CTaskTurn::CTaskTurn(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); -} - -// Object's destructor. - -CTaskTurn::~CTaskTurn() -{ -} - - -// Management of an event. - -BOOL CTaskTurn::EventProcess(const Event &event) -{ - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - // Momentarily stationary object (ant on the back)? - if ( m_object->RetFixed() ) - { - m_physics->SetMotorSpeedX(0.0f); // stops the advance - m_physics->SetMotorSpeedZ(0.0f); // stops the rotation - m_bError = TRUE; - return TRUE; - } - - return TRUE; -} - - -// Assigns the goal was achieved. -// A positive angle is turning right. - -Error CTaskTurn::Start(float angle) -{ - m_startAngle = m_object->RetAngleY(0); - m_finalAngle = m_startAngle+angle; - - if ( angle < 0.0f ) - { - m_angle = angle+m_physics->RetCirStopLength(); - m_physics->SetMotorSpeedZ(-1.0f); // turns left - m_bLeft = TRUE; - } - else - { - m_angle = angle-m_physics->RetCirStopLength(); - m_physics->SetMotorSpeedZ(1.0f); // turns right - m_bLeft = FALSE; - } - m_physics->SetMotorSpeedX(0.0f); - m_physics->SetMotorSpeedY(0.0f); - - m_bError = FALSE; - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskTurn::IsEnded() -{ - float angle; - - if ( m_engine->RetPause() ) return ERR_CONTINUE; - - if ( m_bError ) - { - return ERR_STOP; - } - - angle = m_object->RetAngleY(0); - - if ( m_bLeft ) - { - if ( angle <= m_startAngle+m_angle ) - { - m_physics->SetMotorSpeedZ(0.0f); -//? m_physics->SetCirMotionY(MO_MOTSPEED, 0.0f); - m_physics->SetCirMotionY(MO_CURSPEED, 0.0f); -//? m_physics->SetCirMotionY(MO_REASPEED, 0.0f); - m_object->SetAngleY(0, m_finalAngle); - return ERR_STOP; - } - } - else - { - if ( angle >= m_startAngle+m_angle ) - { - m_physics->SetMotorSpeedZ(0.0f); -//? m_physics->SetCirMotionY(MO_MOTSPEED, 0.0f); - m_physics->SetCirMotionY(MO_CURSPEED, 0.0f); -//? m_physics->SetCirMotionY(MO_REASPEED, 0.0f); - m_object->SetAngleY(0, m_finalAngle); - return ERR_STOP; - } - } - - return ERR_CONTINUE; -} - - diff --git a/src/taskturn.h b/src/taskturn.h deleted file mode 100644 index abaef57..0000000 --- a/src/taskturn.h +++ /dev/null @@ -1,55 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskturn.h - -#ifndef _TASKTURN_H_ -#define _TASKTURN_H_ - - -#include "misc.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - -class CTaskTurn : public CTask -{ -public: - CTaskTurn(CInstanceManager* iMan, CObject* object); - ~CTaskTurn(); - - BOOL EventProcess(const Event &event); - - Error Start(float angle); - Error IsEnded(); - -protected: - -protected: - float m_angle; - float m_startAngle; - float m_finalAngle; - BOOL m_bLeft; - BOOL m_bError; -}; - - -#endif //_TASKTURN_H_ diff --git a/src/taskwait.cpp b/src/taskwait.cpp deleted file mode 100644 index af06383..0000000 --- a/src/taskwait.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskwait.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "terrain.h" -#include "object.h" -#include "physics.h" -#include "brain.h" -#include "task.h" -#include "taskwait.h" - - - - -// Object's constructor. - -CTaskWait::CTaskWait(CInstanceManager* iMan, CObject* object) - : CTask(iMan, object) -{ - CTask::CTask(iMan, object); -} - -// Object's destructor. - -CTaskWait::~CTaskWait() -{ -} - - -// Management of an event. - -BOOL CTaskWait::EventProcess(const Event &event) -{ - if ( m_engine->RetPause() ) return TRUE; - if ( event.event != EVENT_FRAME ) return TRUE; - - m_passTime += event.rTime; - m_bEnded = (m_passTime >= m_waitTime); - return TRUE; -} - - -// Assigns the goal was achieved. - -Error CTaskWait::Start(float time) -{ - m_waitTime = time; // duration to wait - m_passTime = 0.0f; // time elapsed - m_bEnded = FALSE; - return ERR_OK; -} - -// Indicates whether the action is finished. - -Error CTaskWait::IsEnded() -{ - if ( m_engine->RetPause() ) return ERR_CONTINUE; - if ( m_bEnded ) return ERR_STOP; - return ERR_CONTINUE; -} - - diff --git a/src/taskwait.h b/src/taskwait.h deleted file mode 100644 index e8ba2b6..0000000 --- a/src/taskwait.h +++ /dev/null @@ -1,53 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// taskwait.h - -#ifndef _TASKWAIT_H_ -#define _TASKWAIT_H_ - - -#include "misc.h" - - -class CInstanceManager; -class CTerrain; -class CBrain; -class CPhysics; -class CObject; - - -class CTaskWait : public CTask -{ -public: - CTaskWait(CInstanceManager* iMan, CObject* object); - ~CTaskWait(); - - BOOL EventProcess(const Event &event); - - Error Start(float time); - Error IsEnded(); - -protected: - -protected: - float m_waitTime; - float m_passTime; - BOOL m_bEnded; -}; - - -#endif //_TASKWAIT_H_ diff --git a/src/terrain.cpp b/src/terrain.cpp deleted file mode 100644 index 31b1cc9..0000000 --- a/src/terrain.cpp +++ /dev/null @@ -1,2270 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// terrain.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "d3dutil.h" -#include "language.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "modfile.h" -#include "water.h" -#include "terrain.h" - - -#define BMPHEAD 1078 - - - -// Constructor of the terrain. - -CTerrain::CTerrain(CInstanceManager* iMan) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_TERRAIN, this); - - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - - m_mosaic = 20; - m_brick = 1<<4; - m_size = 10.0f; - m_vision = 200.0f; - m_relief = 0; - m_texture = 0; - m_objRank = 0; - m_scaleMapping = 0.01f; - m_scaleRelief = 1.0f; - m_subdivMapping = 1; - m_depth = 2; - m_texBaseName[0]= 0; - m_texBaseExt[0] = 0; - m_bMultiText = TRUE; - m_bLevelText = FALSE; - m_resources = 0; - m_levelMatTotal = 0; - m_levelMatMax = 0; - m_levelDot = 0; - m_wind = D3DVECTOR(0.0f, 0.0f, 0.0f); - m_defHardness = 0.5f; - - FlushBuildingLevel(); - FlushFlyingLimit(); -} - -// Destructor of the terrain. - -CTerrain::~CTerrain() -{ - free(m_relief); - free(m_texture); - free(m_objRank); - free(m_resources); -} - - -// Generates a new flat terrain. -// The terrain is composed of mosaics, themselves composed of bricks. -// Each brick is composed of two triangles. -// mosaic: number of mosaics along the axes X and Z -// brick: number of bricks (power of 2) -// size: size of a brick along the axes X and Z -// vision: vision before a change of resolution -// scaleMapping: scale textures for mapping -// -// ^ z -// | <---> brick*size -// +---+---+---+---+ -// | | | |_|_| mosaic = 4 -// | | | | | | brick = 2 (brickP2=1) -// +---+---+---+---+ -// |\ \| | | | -// |\ \| | | | -// +---+---o---+---+---> x -// | | | | | -// | | | | | -// +---+---+---+---+ -// | | | | | The land is viewed from above here. -// | | | | | -// +---+---+---+---+ -// <---------------> mosaic*brick*size - -BOOL CTerrain::Generate(int mosaic, int brickP2, float size, float vision, - int depth, float hardness) -{ - int dim; - - m_mosaic = mosaic; - m_brick = 1<SetTerrainVision(vision); - - m_bMultiText = TRUE; - m_bLevelText = FALSE; - m_scaleMapping = 1.0f/(m_brick*m_size); - m_subdivMapping = 1; - - dim = (m_mosaic*m_brick+1)*(m_mosaic*m_brick+1); - m_relief = (float*)malloc(sizeof(float)*dim); - ZeroMemory(m_relief, sizeof(float)*dim); - - dim = m_mosaic*m_subdivMapping*m_mosaic*m_subdivMapping; - m_texture = (int*)malloc(sizeof(int)*dim); - ZeroMemory(m_texture, sizeof(int)*dim); - - dim = m_mosaic*m_mosaic; - m_objRank = (int*)malloc(sizeof(int)*dim); - ZeroMemory(m_objRank, sizeof(int)*dim); - - return TRUE; -} - - -int CTerrain::RetMosaic() -{ - return m_mosaic; -} - -int CTerrain::RetBrick() -{ - return m_brick; -} - -float CTerrain::RetSize() -{ - return m_size; -} - -float CTerrain::RetScaleRelief() -{ - return m_scaleRelief; -} - - -// Initializes the names of textures to use for the land. - -BOOL CTerrain::InitTextures(char* baseName, int* table, int dx, int dy) -{ - int x, y; - char* p; - - m_bLevelText = FALSE; - - strcpy(m_texBaseName, baseName); - p = strchr(m_texBaseName, '.'); // p <- ^beginning of the extension - if ( p == 0 ) - { - strcpy(m_texBaseExt, ".tga"); - } - else - { - strcpy(m_texBaseExt, p); // m_texBaseExt <- ".tga" or ".bmp" - *p = 0; // m_texBaseName <- name without extension - } - - for ( y=0 ; y= MAXMATTERRAIN-1 ) return FALSE; - - LevelOpenTable(); - - if ( id == 0 ) - { - id = m_levelID++; // puts an ID internal standard - } - - strcpy(m_levelMat[i].texName, baseName); - m_levelMat[i].id = id; - m_levelMat[i].u = u; - m_levelMat[i].v = v; - m_levelMat[i].mat[0] = up; - m_levelMat[i].mat[1] = right; - m_levelMat[i].mat[2] = down; - m_levelMat[i].mat[3] = left; - m_levelMat[i].hardness = hardness; - - if ( m_levelMatMax < up+1 ) m_levelMatMax = up+1; - if ( m_levelMatMax < right+1 ) m_levelMatMax = right+1; - if ( m_levelMatMax < down+1 ) m_levelMatMax = down+1; - if ( m_levelMatMax < left+1 ) m_levelMatMax = left+1; - - m_bLevelText = TRUE; - m_subdivMapping = 4; - - m_levelMatTotal ++; - return TRUE; -} - - -// Load relief from a BMP file. -// The size of the image must be dimension dx and dy with dx=dy=(mosaic*brick)+1. -// The image must be 8 bits/pixel, 256 colors with a standard pallet. - -// Converts coordinated image (x;y) -> world (x;-;z) : -// Wx = 5*Ix-400 -// Wz = -(5*Iy-400) - -// Converts coordinated world (x;-;z) -> image (x;y) : -// Ix = (400+Wx)/5 -// Iy = (400-Wz)/5 - -BOOL CTerrain::ResFromBMP(const char* filename) -{ - FILE* file; - int size, sizem; - - file = fopen(filename, "rb"); - if ( file == NULL ) return FALSE; - - size = (m_mosaic*m_brick)+1; - sizem = ((size+4-1)/4)*4; // upper size multiple of 4 - - if ( m_resources != 0 ) - { - free(m_resources); - } - - m_resources = (unsigned char*)malloc(BMPHEAD+sizem*size); - fread(m_resources, BMPHEAD+sizem*size, 1, file); - - if ( m_resources[18] != (size&0xff) || m_resources[19] != (size>>8) || - m_resources[22] != (size&0xff) || m_resources[23] != (size>>8) ) - { - free(m_resources); - m_resources = 0; - fclose(file); - return FALSE; - } - - fclose(file); - return TRUE; -} - -// Returns the resource type available underground. - -TerrainRes CTerrain::RetResource(const D3DVECTOR &p) -{ - int x, y, size, sizem, ress; - - if ( m_resources == 0 ) return TR_NULL; - - x = (int)((p.x + (m_mosaic*m_brick*m_size)/2.0f)/m_size); - y = (int)((p.z + (m_mosaic*m_brick*m_size)/2.0f)/m_size); - - if ( x < 0 || x > m_mosaic*m_brick || - y < 0 || y > m_mosaic*m_brick ) return TR_NULL; - - size = (m_mosaic*m_brick)+1; - sizem = ((size+4-1)/4)*4; // upper size multiple of 4 - - ress = m_resources[BMPHEAD+x+sizem*y]; - if ( ress == 5 ) return TR_STONE; // red? - if ( ress == 35 ) return TR_URANIUM; // yellow? - if ( ress == 30 ) return TR_POWER; // green? - if ( ress == 24 ) return TR_KEYa; // ~green? - if ( ress == 25 ) return TR_KEYb; // ~green? - if ( ress == 26 ) return TR_KEYc; // ~green? - if ( ress == 27 ) return TR_KEYd; // ~green? - - return TR_NULL; -} - - -// Initializes a completely flat terrain. - -void CTerrain::FlushRelief() -{ - free(m_relief); - m_relief = 0; -} - -// Load relief from a BMP file. -// The size of the image must be dimension dx and dy with dx=dy=(mosaic*brick)+1. -// The image must be 8 bits/pixel, 256 gray scale: -// white = ground (y=0) -// black = mountain (y=255*scaleRelief) - -// Converts coordinated image(x;y) -> world (x;-;z) : -// Wx = 5*Ix-400 -// Wz = -(5*Iy-400) - -// Converts coordinated world (x;-;z) -> image (x;y) : -// Ix = (400+Wx)/5 -// Iy = (400-Wz)/5 - -BOOL CTerrain::ReliefFromBMP(const char* filename, float scaleRelief, - BOOL adjustBorder) -{ - FILE* file; - unsigned char* buffer; - int size, sizem, x, y; - float level, limit, dist, border; - - m_scaleRelief = scaleRelief; - - file = fopen(filename, "rb"); - if ( file == NULL ) return FALSE; - - size = (m_mosaic*m_brick)+1; - sizem = ((size+4-1)/4)*4; // upper size multiple of 4 - - buffer = (unsigned char*)malloc(BMPHEAD+sizem*size); - fread(buffer, BMPHEAD+sizem*size, 1, file); - - if ( buffer[18] != (size&0xff) || buffer[19] != (size>>8) || - buffer[22] != (size&0xff) || buffer[23] != (size>>8) ) - { - free(buffer); - fclose(file); - return FALSE; - } - - limit = 0.9f; - for ( y=0 ; y limit && adjustBorder ) - { - dist = (dist-limit)/(1.0f-limit); // 0..1 - if ( dist > 1.0f ) dist = 1.0f; - border = 300.0f+Rand()*20.0f; - level = level+dist*(border-level); - } - - m_relief[x+y*size] = level; - } - } - - free(buffer); - fclose(file); - return TRUE; -} - -// Adds a point of elevation in the buffer of relief. - -BOOL CTerrain::ReliefAddDot(D3DVECTOR pos, float scaleRelief) -{ - float dim; - int size, x, y; - - dim = (m_mosaic*m_brick*m_size)/2.0f; - size = (m_mosaic*m_brick)+1; - - pos.x = (pos.x+dim)/m_size; - pos.z = (pos.z+dim)/m_size; - - x = (int)pos.x; - y = (int)pos.z; - - if ( x < 0 || x >= size || - y < 0 || y >= size ) return FALSE; - - if ( m_relief[x+y*size] < pos.y*scaleRelief ) - { - m_relief[x+y*size] = pos.y*scaleRelief; - } - return TRUE; -} - -// Load relief from a DXF file. - -BOOL CTerrain::ReliefFromDXF(const char* filename, float scaleRelief) -{ - FILE* file = NULL; - char line[100]; - int command, rankSommet, nbSommet, nbFace, size; - D3DVECTOR* table; - BOOL bWaitNbSommet; - BOOL bWaitNbFace; - BOOL bWaitSommetX; - BOOL bWaitSommetY; - BOOL bWaitSommetZ; - BOOL bWaitFaceX; - BOOL bWaitFaceY; - BOOL bWaitFaceZ; - float x,y,z; - int p1,p2,p3; - - ZeroMemory(m_relief, sizeof(float)*(m_mosaic*m_brick+1)*(m_mosaic*m_brick+1)); - - file = fopen(filename, "r"); - if ( file == NULL ) return FALSE; - - size = (m_mosaic*m_brick)+1; - table = (D3DVECTOR*)malloc(sizeof(D3DVECTOR)*size*size); - - rankSommet = 0; - bWaitNbSommet = FALSE; - bWaitNbFace = FALSE; - bWaitSommetX = FALSE; - bWaitSommetY = FALSE; - bWaitSommetZ = FALSE; - bWaitFaceX = FALSE; - bWaitFaceY = FALSE; - bWaitFaceZ = FALSE; - - while ( fgets(line, 100, file) != NULL ) - { - sscanf(line, "%d", &command); - if ( fgets(line, 100, file) == NULL ) break; - - if ( command == 66 ) - { - bWaitNbSommet = TRUE; - } - - if ( command == 71 && bWaitNbSommet ) - { - bWaitNbSommet = FALSE; - sscanf(line, "%d", &nbSommet); - if ( nbSommet > size*size ) nbSommet = size*size; - rankSommet = 0; - bWaitNbFace = TRUE; - } - - if ( command == 72 && bWaitNbFace ) - { - bWaitNbFace = FALSE; - sscanf(line, "%d", &nbFace); - bWaitSommetX = TRUE; - } - - if ( command == 10 && bWaitSommetX ) - { - bWaitSommetX = FALSE; - sscanf(line, "%f", &x); - bWaitSommetY = TRUE; - } - - if ( command == 20 && bWaitSommetY ) - { - bWaitSommetY = FALSE; - sscanf(line, "%f", &y); - bWaitSommetZ = TRUE; - } - - if ( command == 30 && bWaitSommetZ ) - { - bWaitSommetZ = FALSE; - sscanf(line, "%f", &z); - - nbSommet --; - if ( nbSommet >= 0 ) - { - D3DVECTOR p(x,z,y); // permutation of Y and Z! - table[rankSommet++] = p; - bWaitSommetX = TRUE; - } - else - { - bWaitFaceX = TRUE; - } - } - - if ( command == 71 && bWaitFaceX ) - { - bWaitFaceX = FALSE; - sscanf(line, "%d", &p1); - if ( p1 < 0 ) p1 = -p1; - bWaitFaceY = TRUE; - } - - if ( command == 72 && bWaitFaceY ) - { - bWaitFaceY = FALSE; - sscanf(line, "%d", &p2); - if ( p2 < 0 ) p2 = -p2; - bWaitFaceZ = TRUE; - } - - if ( command == 73 && bWaitFaceZ ) - { - bWaitFaceZ = FALSE; - sscanf(line, "%d", &p3); - if ( p3 < 0 ) p3 = -p3; - - nbFace --; - if ( nbFace >= 0 ) - { - ReliefAddDot(table[p3-1], scaleRelief); - ReliefAddDot(table[p2-1], scaleRelief); - ReliefAddDot(table[p1-1], scaleRelief); - bWaitFaceX = TRUE; - } - } - - } - - free(table); - fclose(file); - return TRUE; -} - - -// Adjusts a position so that it does not exceed the boundaries. - -void CTerrain::LimitPos(D3DVECTOR &pos) -{ - float dim; - -#if _TEEN - dim = (m_mosaic*m_brick*m_size)/2.0f*0.98f; -#else - dim = (m_mosaic*m_brick*m_size)/2.0f*0.92f; -#endif - - if ( pos.x < -dim ) pos.x = -dim; - if ( pos.x > dim ) pos.x = dim; - if ( pos.z < -dim ) pos.z = -dim; - if ( pos.z > dim ) pos.z = dim; -} - - -// Adjust the edges of each mosaic to be compatible with all lower resolutions. - -void CTerrain::AdjustRelief() -{ - int x, y, xx, yy, ii, b; - float level1, level2; - - if ( m_depth == 1 ) return; - - ii = m_mosaic*m_brick+1; - b = 1<<(m_depth-1); - - for ( y=0 ; y= 0 && x <= m_mosaic*m_brick && - y >= 0 && y <= m_mosaic*m_brick ) - { - p.y = m_relief[x+y*(m_mosaic*m_brick+1)]; - } - else - { - p.y = 0.0f; - } - - return p; -} - -// Calculates a vertex of the terrain. -// Calculates a normal soft, taking into account the six adjacent triangles: -// -// ^ y -// | -// b---c---+ -// |\ |\ | -// | \| \| -// a---o---d -// |\ |\ | -// | \| \| -// +---f---e--> x - -D3DVERTEX2 CTerrain::RetVertex(int x, int y, int step) -{ - D3DVERTEX2 v; - D3DVECTOR o, oo, a,b,c,d,e,f, n, s; - int brick; - - o = RetVector(x, y); - v.x = o.x; - v.y = o.y; - v.z = o.z; - - a = RetVector(x-step, y ); - b = RetVector(x-step, y+step); - c = RetVector(x, y+step); - d = RetVector(x+step, y ); - e = RetVector(x+step, y-step); - f = RetVector(x, y-step); - - s = D3DVECTOR(0.0f, 0.0f, 0.0f); - - if ( x-step >= 0 && y+step <= m_mosaic*m_brick+1 ) - { - s += ComputeNormal(b,a,o); - s += ComputeNormal(c,b,o); - } - - if ( x+step <= m_mosaic*m_brick+1 && y+step <= m_mosaic*m_brick+1 ) - { - s += ComputeNormal(d,c,o); - } - - if ( x+step <= m_mosaic*m_brick+1 && y-step >= 0 ) - { - s += ComputeNormal(e,d,o); - s += ComputeNormal(f,e,o); - } - - if ( x-step >= 0 && y-step >= 0 ) - { - s += ComputeNormal(a,f,o); - } - - s = Normalize(s); - v.nx = s.x; - v.ny = s.y; - v.nz = s.z; - - if ( m_bMultiText ) - { - brick = m_brick/m_subdivMapping; - oo = RetVector((x/brick)*brick, (y/brick)*brick); - o = RetVector(x, y); - v.tu = (o.x-oo.x)*m_scaleMapping*m_subdivMapping; - v.tv = 1.0f - (o.z-oo.z)*m_scaleMapping*m_subdivMapping; - } - else - { - v.tu = o.x*m_scaleMapping; - v.tv = o.z*m_scaleMapping; - } - - return v; -} - -// Creates all objects of a mosaic. -// The origin of mosaic is his center. -// -// ^ z -// | -// | 2---4---6-- -// | |\ |\ |\ -// | | \| \| -// | 1---3---5--- ... -// | -// +-------------------> x - -BOOL CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, - const D3DMATERIAL7 &mat, - float min, float max) -{ - D3DMATRIX transform; - D3DVERTEX2 o, p1, p2; - D3DObjLevel6* buffer; - FPOINT uv; - int brick, total, size, mx, my, x, y, xx, yy, i; - char texName1[20]; - char texName2[20]; - float pixel, dp; - - if ( step == 1 && m_engine->RetGroundSpot() ) - { - i = (ox/5) + (oy/5)*(m_mosaic/5); - sprintf(texName2, "shadow%.2d.tga", i); - } - else - { - texName2[0] = 0; - } - - brick = m_brick/m_subdivMapping; - - o = RetVertex(ox*m_brick+m_brick/2, oy*m_brick+m_brick/2, step); - total = ((brick/step)+1)*2; - size = sizeof(D3DObjLevel6)+sizeof(D3DVERTEX2)*(total-1); - - pixel = 1.0f/256.0f; // 1 pixel cover (*) -//? dp = 0.5f/512.0f; - dp = 1.0f/512.0f; - - for ( my=0 ; mytotalPossible = total; - buffer->totalUsed = total; - buffer->type = D3DTYPE6S; - buffer->material = mat; - if ( m_bMultiText ) - { -//? buffer->state = D3DSTATENORMAL; - buffer->state = D3DSTATEWRAP; - } - else - { - buffer->state = D3DSTATEWRAP; - } - buffer->state |= D3DSTATESECOND; - if ( step == 1 ) - { - buffer->state |= D3DSTATEDUALb; - } - i = 0; - for ( x=0 ; x<=brick ; x+=step ) - { - p1 = RetVertex(ox*m_brick+mx*brick+x, oy*m_brick+my*brick+y+0 , step); - p2 = RetVertex(ox*m_brick+mx*brick+x, oy*m_brick+my*brick+y+step, step); - p1.x -= o.x; p1.z -= o.z; - p2.x -= o.x; p2.z -= o.z; - - if ( m_bMultiText ) - { - if ( x == 0 ) - { - p1.tu = 0.0f+(0.5f/256.0f); - p2.tu = 0.0f+(0.5f/256.0f); - } - if ( x == brick ) - { - p1.tu = 1.0f-(0.5f/256.0f); - p2.tu = 1.0f-(0.5f/256.0f); - } - if ( y == 0 ) - { - p1.tv = 1.0f-(0.5f/256.0f); - } - if ( y == brick-step ) - { - p2.tv = 0.0f+(0.5f/256.0f); - } - } - - if ( m_bLevelText ) - { - p1.tu /= m_subdivMapping; // 0..1 -> 0..0.25 - p1.tv /= m_subdivMapping; - p2.tu /= m_subdivMapping; - p2.tv /= m_subdivMapping; - - if ( x == 0 ) - { - p1.tu = 0.0f+dp; - p2.tu = 0.0f+dp; - } - if ( x == brick ) - { - p1.tu = (1.0f/m_subdivMapping)-dp; - p2.tu = (1.0f/m_subdivMapping)-dp; - } - if ( y == 0 ) - { - p1.tv = (1.0f/m_subdivMapping)-dp; - } - if ( y == brick-step ) - { - p2.tv = 0.0f+dp; - } - - p1.tu += uv.x; - p1.tv += uv.y; - p2.tu += uv.x; - p2.tv += uv.y; - } - -#if 1 - xx = mx*(m_brick/m_subdivMapping) + x; - yy = my*(m_brick/m_subdivMapping) + y; - p1.tu2 = ((float)(ox%5)*m_brick+xx+0.0f)/(m_brick*5); - p1.tv2 = ((float)(oy%5)*m_brick+yy+0.0f)/(m_brick*5); - p2.tu2 = ((float)(ox%5)*m_brick+xx+0.0f)/(m_brick*5); - p2.tv2 = ((float)(oy%5)*m_brick+yy+1.0f)/(m_brick*5); - - // Correction for 1 pixel cover (*). - p1.tu2 = (p1.tu2+pixel)*(1.0f-pixel)/(1.0f+pixel); - p1.tv2 = (p1.tv2+pixel)*(1.0f-pixel)/(1.0f+pixel); - p2.tu2 = (p2.tu2+pixel)*(1.0f-pixel)/(1.0f+pixel); - p2.tv2 = (p2.tv2+pixel)*(1.0f-pixel)/(1.0f+pixel); -#endif - - buffer->vertex[i++] = p1; - buffer->vertex[i++] = p2; - } - m_engine->AddQuick(objRank, buffer, texName1, texName2, min, max, TRUE); - } - } - } - - D3DUtil_SetIdentityMatrix(transform); - transform._41 = o.x; - transform._43 = o.z; - m_engine->SetObjectTransform(objRank, transform); - - return TRUE; -} - -// (*) There is 1 pixel cover around each of the 16 surfaces: -// -// |<--------------256-------------->| -// | |<----------254---------->| | -// |---|---|---|-- ... --|---|---|---| -// | 0.0 1.0 | -// | | | | -// 0.0 min max 1.0 -// -// The uv coordinates used for texturing are between min and max (instead of 0 and 1). -// This allows to exclude the pixels situated in a margin of a pixel around the surface. - - -// Seeks a materials based on theirs identifier. - -TerrainMaterial* CTerrain::LevelSearchMat(int id) -{ - int i; - - for ( i=0 ; itexName); - strcpy(name, tm->texName); - uv.x = tm->u; - uv.y = tm->v; - } -} - -// Returns the height of the terrain. - -float CTerrain::LevelRetHeight(int x, int y) -{ - int size; - - size = (m_mosaic*m_brick+1); - - if ( x < 0 ) x = 0; - if ( x >= size ) x = size-1; - if ( y < 0 ) y = 0; - if ( y >= size ) y = size-1; - - return m_relief[x+y*size]; -} - -// Decide whether a point is using the materials. - -BOOL CTerrain::LevelGetDot(int x, int y, float min, float max, float slope) -{ - float hc, h[4]; - int i; - - hc = LevelRetHeight(x, y); - h[0] = LevelRetHeight(x+0, y+1); - h[1] = LevelRetHeight(x+1, y+0); - h[2] = LevelRetHeight(x+0, y-1); - h[3] = LevelRetHeight(x-1, y+0); - - if ( hc < min || - hc > max ) return FALSE; - - if ( slope == 0.0f ) - { - return TRUE; - } - - if ( slope > 0.0f ) - { - for ( i=0 ; i<4 ; i++ ) - { - if ( Abs(hc-h[i]) >= slope ) - { - return FALSE; - } - } - return TRUE; - } - - if ( slope < 0.0f ) - { - for ( i=0 ; i<4 ; i++ ) - { - if ( Abs(hc-h[i]) < -slope ) - { - return FALSE; - } - } - return TRUE; - } - - return FALSE; -} - -// Seeks if material exists. -// Returns the index within m_levelMat or -1 if there is not. -// m_levelMat[i].id gives the identifier. - -int CTerrain::LevelTestMat(char *mat) -{ - int i; - - for ( i=0 ; imat[0] != mat[0] || - tm->mat[1] != mat[1] || - tm->mat[2] != mat[2] || - tm->mat[3] != mat[3] ) // id incompatible with mat? - { - ii = LevelTestMat(mat); - if ( ii == -1 ) return; - id = m_levelMat[ii].id; // looking for a id compatible with mat - } - - // Changes the point. - m_levelDot[x+y*m_levelDotSize].id = id; - m_levelDot[x+y*m_levelDotSize].mat[0] = mat[0]; - m_levelDot[x+y*m_levelDotSize].mat[1] = mat[1]; - m_levelDot[x+y*m_levelDotSize].mat[2] = mat[2]; - m_levelDot[x+y*m_levelDotSize].mat[3] = mat[3]; - - // Changes the lower neighbor. - if ( (x+0) >= 0 && (x+0) < m_levelDotSize && - (y-1) >= 0 && (y-1) < m_levelDotSize ) - { - i = (x+0)+(y-1)*m_levelDotSize; - if ( m_levelDot[i].mat[0] != mat[2] ) - { - m_levelDot[i].mat[0] = mat[2]; - ii = LevelTestMat(m_levelDot[i].mat); - if ( ii != -1 ) - { - m_levelDot[i].id = m_levelMat[ii].id; - } - } - } - - // Modifies the left neighbor. - if ( (x-1) >= 0 && (x-1) < m_levelDotSize && - (y+0) >= 0 && (y+0) < m_levelDotSize ) - { - i = (x-1)+(y+0)*m_levelDotSize; - if ( m_levelDot[i].mat[1] != mat[3] ) - { - m_levelDot[i].mat[1] = mat[3]; - ii = LevelTestMat(m_levelDot[i].mat); - if ( ii != -1 ) - { - m_levelDot[i].id = m_levelMat[ii].id; - } - } - } - - // Changes the upper neighbor. - if ( (x+0) >= 0 && (x+0) < m_levelDotSize && - (y+1) >= 0 && (y+1) < m_levelDotSize ) - { - i = (x+0)+(y+1)*m_levelDotSize; - if ( m_levelDot[i].mat[2] != mat[0] ) - { - m_levelDot[i].mat[2] = mat[0]; - ii = LevelTestMat(m_levelDot[i].mat); - if ( ii != -1 ) - { - m_levelDot[i].id = m_levelMat[ii].id; - } - } - } - - // Changes the right neighbor. - if ( (x+1) >= 0 && (x+1) < m_levelDotSize && - (y+0) >= 0 && (y+0) < m_levelDotSize ) - { - i = (x+1)+(y+0)*m_levelDotSize; - if ( m_levelDot[i].mat[3] != mat[1] ) - { - m_levelDot[i].mat[3] = mat[1]; - ii = LevelTestMat(m_levelDot[i].mat); - if ( ii != -1 ) - { - m_levelDot[i].id = m_levelMat[ii].id; - } - } - } -} - -// Tests if a material can give a place, according to its four neighbors. -// If yes, puts the point. - -BOOL CTerrain::LevelIfDot(int x, int y, int id, char *mat) -{ - char test[4]; - - // Compatible with lower neighbor? - if ( x+0 >= 0 && x+0 < m_levelDotSize && - y-1 >= 0 && y-1 < m_levelDotSize ) - { - test[0] = mat[2]; - test[1] = m_levelDot[(x+0)+(y-1)*m_levelDotSize].mat[1]; - test[2] = m_levelDot[(x+0)+(y-1)*m_levelDotSize].mat[2]; - test[3] = m_levelDot[(x+0)+(y-1)*m_levelDotSize].mat[3]; - - if ( LevelTestMat(test) == -1 ) return FALSE; - } - - // Compatible with left neighbor? - if ( x-1 >= 0 && x-1 < m_levelDotSize && - y+0 >= 0 && y+0 < m_levelDotSize ) - { - test[0] = m_levelDot[(x-1)+(y+0)*m_levelDotSize].mat[0]; - test[1] = mat[3]; - test[2] = m_levelDot[(x-1)+(y+0)*m_levelDotSize].mat[2]; - test[3] = m_levelDot[(x-1)+(y+0)*m_levelDotSize].mat[3]; - - if ( LevelTestMat(test) == -1 ) return FALSE; - } - - // Compatible with upper neighbor? - if ( x+0 >= 0 && x+0 < m_levelDotSize && - y+1 >= 0 && y+1 < m_levelDotSize ) - { - test[0] = m_levelDot[(x+0)+(y+1)*m_levelDotSize].mat[0]; - test[1] = m_levelDot[(x+0)+(y+1)*m_levelDotSize].mat[1]; - test[2] = mat[0]; - test[3] = m_levelDot[(x+0)+(y+1)*m_levelDotSize].mat[3]; - - if ( LevelTestMat(test) == -1 ) return FALSE; - } - - // Compatible with right neighbor? - if ( x+1 >= 0 && x+1 < m_levelDotSize && - y+0 >= 0 && y+0 < m_levelDotSize ) - { - test[0] = m_levelDot[(x+1)+(y+0)*m_levelDotSize].mat[0]; - test[1] = m_levelDot[(x+1)+(y+0)*m_levelDotSize].mat[1]; - test[2] = m_levelDot[(x+1)+(y+0)*m_levelDotSize].mat[2]; - test[3] = mat[1]; - - if ( LevelTestMat(test) == -1 ) return FALSE; - } - - LevelSetDot(x, y, id, mat); // puts the point - return TRUE; -} - -// Modifies the state of a point. - -BOOL CTerrain::LevelPutDot(int x, int y, int id) -{ - TerrainMaterial *tm; - char mat[4]; - int up, right, down, left; - - x /= m_brick/m_subdivMapping; - y /= m_brick/m_subdivMapping; - - if ( x < 0 || x >= m_levelDotSize || - y < 0 || y >= m_levelDotSize ) return FALSE; - - tm = LevelSearchMat(id); - if ( tm == 0 ) return FALSE; - - // Tries without changing neighbors. - if ( LevelIfDot(x, y, id, tm->mat) ) return TRUE; - - // Tries changing a single neighbor (4x). - for ( up=0 ; upmat[1]; - mat[2] = tm->mat[2]; - mat[3] = tm->mat[3]; - - if ( LevelIfDot(x, y, id, mat) ) return TRUE; - } - - for ( right=0 ; rightmat[0]; - mat[1] = right; - mat[2] = tm->mat[2]; - mat[3] = tm->mat[3]; - - if ( LevelIfDot(x, y, id, mat) ) return TRUE; - } - - for ( down=0 ; downmat[0]; - mat[1] = tm->mat[1]; - mat[2] = down; - mat[3] = tm->mat[3]; - - if ( LevelIfDot(x, y, id, mat) ) return TRUE; - } - - for ( left=0 ; leftmat[0]; - mat[1] = tm->mat[1]; - mat[2] = tm->mat[2]; - mat[3] = left; - - if ( LevelIfDot(x, y, id, mat) ) return TRUE; - } - - // Tries changing two neighbors (6x). - for ( up=0 ; upmat[1]; - mat[2] = down; - mat[3] = tm->mat[3]; - - if ( LevelIfDot(x, y, id, mat) ) return TRUE; - } - } - - for ( right=0 ; rightmat[0]; - mat[1] = right; - mat[2] = tm->mat[2]; - mat[3] = left; - - if ( LevelIfDot(x, y, id, mat) ) return TRUE; - } - } - - for ( up=0 ; upmat[2]; - mat[3] = tm->mat[3]; - - if ( LevelIfDot(x, y, id, mat) ) return TRUE; - } - } - - for ( right=0 ; rightmat[0]; - mat[1] = right; - mat[2] = down; - mat[3] = tm->mat[3]; - - if ( LevelIfDot(x, y, id, mat) ) return TRUE; - } - } - - for ( down=0 ; downmat[0]; - mat[1] = tm->mat[1]; - mat[2] = down; - mat[3] = left; - - if ( LevelIfDot(x, y, id, mat) ) return TRUE; - } - } - - for ( up=0 ; upmat[1]; - mat[2] = tm->mat[2]; - mat[3] = left; - - if ( LevelIfDot(x, y, id, mat) ) return TRUE; - } - } - - // Tries changing all the neighbors. - for ( up=0 ; upmat[j]; - } - } - - return TRUE; -} - -// Generates a level in the terrain. - -BOOL CTerrain::LevelGenerate(int *id, float min, float max, - float slope, float freq, - D3DVECTOR center, float radius) -{ - TerrainMaterial *tm; - D3DVECTOR pos; - int i, numID, x, y, xx, yy, group, rnd; - float dim; - - static char random[100] = - { - 84,25,12, 6,34,52,85,38,97,16, - 21,31,65,19,62,40,72,22,48,61, - 56,47, 8,53,73,77, 4,91,26,88, - 76, 1,44,93,39,11,71,17,98,95, - 88,83,18,30, 3,57,28,49,74, 9, - 32,13,96,66,15,70,36,10,59,94, - 45,86, 2,29,63,42,51, 0,79,27, - 54, 7,20,69,89,23,64,43,81,92, - 90,33,46,14,67,35,50, 5,87,60, - 68,55,24,78,41,75,58,80,37,82, - }; - - i = 0; - while ( id[i] != 0 ) - { - tm = LevelSearchMat(id[i++]); - if ( tm == 0 ) return FALSE; - } - numID = i; - - group = m_brick/m_subdivMapping; - - if ( radius > 0.0f && radius < 5.0f ) // just a square? - { - dim = (m_mosaic*m_brick*m_size)/2.0f; - - xx = (int)((center.x+dim)/m_size); - yy = (int)((center.z+dim)/m_size); - - x = xx/group; - y = yy/group; - - tm = LevelSearchMat(id[0]); - if ( tm != 0 ) - { - LevelSetDot(x, y, id[0], tm->mat); // puts the point - } -//? LevelPutDot(xx,yy, id[0]); - } - else - { - for ( y=0 ; y radius ) continue; - } - - if ( freq < 100.0f ) - { - rnd = random[(x%10)+(y%10)*10]; - if ( (float)rnd > freq ) continue; - } - - xx = x*group + group/2; - yy = y*group + group/2; - - if ( LevelGetDot(xx,yy, min, max, slope) ) - { - rnd = random[(x%10)+(y%10)*10]; - i = rnd%numID; - LevelPutDot(xx,yy, id[i]); - } - } - } - } - - return TRUE; -} - -// Initializes an table with empty levels. - -void CTerrain::LevelOpenTable() -{ - int i, j; - - if ( !m_bLevelText ) return; - if ( m_levelDot != 0 ) return; // already allocated - - m_levelDotSize = (m_mosaic*m_brick)/(m_brick/m_subdivMapping)+1; - m_levelDot = (DotLevel*)malloc(m_levelDotSize*m_levelDotSize*sizeof(DotLevel)); - - for ( i=0 ; iCreateObject(); - m_engine->SetObjectType(objRank, TYPETERRAIN); // it is a terrain - - m_objRank[x+y*m_mosaic] = objRank; - - if ( bMultiRes ) - { - min = 0.0f; - max = m_vision; - max *= m_engine->RetClippingDistance(); - for ( step=0 ; step tp2.x ) - { - x = tp1.x; - tp1.x = tp2.x; - tp2.x = x; - } - - if ( tp1.y > tp2.y ) - { - y = tp1.y; - tp1.y = tp2.y; - tp2.y = y; - } - - size = (m_mosaic*m_brick)+1; - - // Calculates the current average height. - avg = 0.0f; - nb = 0; - for ( y=tp1.y ; y<=tp2.y ; y++ ) - { - for ( x=tp1.x ; x<=tp2.x ; x++ ) - { - avg += m_relief[x+y*size]; - nb ++; - } - } - avg /= (float)nb; - - // Changes the description of the relief. - for ( y=tp1.y ; y<=tp2.y ; y++ ) - { - for ( x=tp1.x ; x<=tp2.x ; x++ ) - { - m_relief[x+y*size] = avg+height; - - if ( x%m_brick == 0 && y%m_depth != 0 ) - { - m_relief[(x+0)+(y-1)*size] = avg+height; - m_relief[(x+0)+(y+1)*size] = avg+height; - } - - if ( y%m_brick == 0 && x%m_depth != 0 ) - { - m_relief[(x-1)+(y+0)*size] = avg+height; - m_relief[(x+1)+(y+0)*size] = avg+height; - } - } - } - AdjustRelief(); - - pp1.x = (tp1.x-2)/m_brick; - pp1.y = (tp1.y-2)/m_brick; - pp2.x = (tp2.x+1)/m_brick; - pp2.y = (tp2.y+1)/m_brick; - - if ( pp1.x < 0 ) pp1.x = 0; - if ( pp1.x >= m_mosaic ) pp1.x = m_mosaic-1; - if ( pp1.y < 0 ) pp1.y = 0; - if ( pp1.y >= m_mosaic ) pp1.y = m_mosaic-1; - - for ( y=pp1.y ; y<=pp2.y ; y++ ) - { - for ( x=pp1.x ; x<=pp2.x ; x++ ) - { - m_engine->DeleteObject(m_objRank[x+y*m_mosaic]); - CreateSquare(m_bMultiText, x, y); // recreates the square - } - } - m_engine->Update(); - - return TRUE; -} - - -// Management of the wind. - -void CTerrain::SetWind(D3DVECTOR speed) -{ - m_wind = speed; -} - -D3DVECTOR CTerrain::RetWind() -{ - return m_wind; -} - - -// Gives the exact slope of the terrain of a place given. - -float CTerrain::RetFineSlope(const D3DVECTOR &pos) -{ - D3DVECTOR n; - - if ( !GetNormal(n, pos) ) return 0.0f; - return Abs(RotateAngle(Length(n.x, n.z), n.y)-PI/2.0f); -} - -// Gives the approximate slope of the terrain of a specific location. - -float CTerrain::RetCoarseSlope(const D3DVECTOR &pos) -{ - float dim, level[4], min, max; - int x, y; - - if ( m_relief == 0 ) return 0.0f; - - dim = (m_mosaic*m_brick*m_size)/2.0f; - - x = (int)((pos.x+dim)/m_size); - y = (int)((pos.z+dim)/m_size); - - if ( x < 0 || x >= m_mosaic*m_brick || - y < 0 || y >= m_mosaic*m_brick ) return 0.0f; - - level[0] = m_relief[(x+0)+(y+0)*(m_mosaic*m_brick+1)]; - level[1] = m_relief[(x+1)+(y+0)*(m_mosaic*m_brick+1)]; - level[2] = m_relief[(x+0)+(y+1)*(m_mosaic*m_brick+1)]; - level[3] = m_relief[(x+1)+(y+1)*(m_mosaic*m_brick+1)]; - - min = Min(level[0], level[1], level[2], level[3]); - max = Max(level[0], level[1], level[2], level[3]); - - return atanf((max-min)/m_size); -} - -// Gives the normal vector at the position p (x,-,z) of the ground. - -BOOL CTerrain::GetNormal(D3DVECTOR &n, const D3DVECTOR &p) -{ - D3DVECTOR p1, p2, p3, p4; - float dim; - int x, y; - - dim = (m_mosaic*m_brick*m_size)/2.0f; - - x = (int)((p.x+dim)/m_size); - y = (int)((p.z+dim)/m_size); - - if ( x < 0 || x > m_mosaic*m_brick || - y < 0 || y > m_mosaic*m_brick ) return FALSE; - - p1 = RetVector(x+0, y+0); - p2 = RetVector(x+1, y+0); - p3 = RetVector(x+0, y+1); - p4 = RetVector(x+1, y+1); - - if ( Abs(p.z-p2.z) < Abs(p.x-p2.x) ) - { - n = ComputeNormal(p1,p2,p3); - } - else - { - n = ComputeNormal(p2,p4,p3); - } - return TRUE; -} - -// Returns the height of the ground. - -float CTerrain::RetFloorLevel(const D3DVECTOR &p, BOOL bBrut, BOOL bWater) -{ - D3DVECTOR p1, p2, p3, p4, ps; - float dim, level; - int x, y; - - dim = (m_mosaic*m_brick*m_size)/2.0f; - - x = (int)((p.x+dim)/m_size); - y = (int)((p.z+dim)/m_size); - - if ( x < 0 || x > m_mosaic*m_brick || - y < 0 || y > m_mosaic*m_brick ) return FALSE; - - p1 = RetVector(x+0, y+0); - p2 = RetVector(x+1, y+0); - p3 = RetVector(x+0, y+1); - p4 = RetVector(x+1, y+1); - - ps = p; - if ( Abs(p.z-p2.z) < Abs(p.x-p2.x) ) - { - if ( !IntersectY(p1, p2, p3, ps) ) return 0.0f; - } - else - { - if ( !IntersectY(p2, p4, p3, ps) ) return 0.0f; - } - - if ( !bBrut ) AdjustBuildingLevel(ps); - - if ( bWater ) // not going underwater? - { - level = m_water->RetLevel(); - if ( ps.y < level ) ps.y = level; // not under water - } - - return ps.y; -} - -// Returns the height to the ground. -// This height is positive when you are above the ground. - -float CTerrain::RetFloorHeight(const D3DVECTOR &p, BOOL bBrut, BOOL bWater) -{ - D3DVECTOR p1, p2, p3, p4, ps; - float dim, level; - int x, y; - - dim = (m_mosaic*m_brick*m_size)/2.0f; - - x = (int)((p.x+dim)/m_size); - y = (int)((p.z+dim)/m_size); - - if ( x < 0 || x > m_mosaic*m_brick || - y < 0 || y > m_mosaic*m_brick ) return FALSE; - - p1 = RetVector(x+0, y+0); - p2 = RetVector(x+1, y+0); - p3 = RetVector(x+0, y+1); - p4 = RetVector(x+1, y+1); - - ps = p; - if ( Abs(p.z-p2.z) < Abs(p.x-p2.x) ) - { - if ( !IntersectY(p1, p2, p3, ps) ) return 0.0f; - } - else - { - if ( !IntersectY(p2, p4, p3, ps) ) return 0.0f; - } - - if ( !bBrut ) AdjustBuildingLevel(ps); - - if ( bWater ) // not going underwater? - { - level = m_water->RetLevel(); - if ( ps.y < level ) ps.y = level; // not under water - } - - return p.y-ps.y; -} - -// Modifies the coordinate "y" of point "p" to rest on the ground floor. - -BOOL CTerrain::MoveOnFloor(D3DVECTOR &p, BOOL bBrut, BOOL bWater) -{ - D3DVECTOR p1, p2, p3, p4; - float dim, level; - int x, y; - - dim = (m_mosaic*m_brick*m_size)/2.0f; - - x = (int)((p.x+dim)/m_size); - y = (int)((p.z+dim)/m_size); - - if ( x < 0 || x > m_mosaic*m_brick || - y < 0 || y > m_mosaic*m_brick ) return FALSE; - - p1 = RetVector(x+0, y+0); - p2 = RetVector(x+1, y+0); - p3 = RetVector(x+0, y+1); - p4 = RetVector(x+1, y+1); - - if ( Abs(p.z-p2.z) < Abs(p.x-p2.x) ) - { - if ( !IntersectY(p1, p2, p3, p) ) return FALSE; - } - else - { - if ( !IntersectY(p2, p4, p3, p) ) return FALSE; - } - - if ( !bBrut ) AdjustBuildingLevel(p); - - if ( bWater ) // not going underwater? - { - level = m_water->RetLevel(); - if ( p.y < level ) p.y = level; // not under water - } - - return TRUE; -} - -// Modifies a coordinate so that it is on the ground. -// Returns FALSE if the initial coordinate was too far. - -BOOL CTerrain::ValidPosition(D3DVECTOR &p, float marging) -{ - BOOL bOK = TRUE; - float limit; - - limit = m_mosaic*m_brick*m_size/2.0f - marging; - - if ( p.x < -limit ) - { - p.x = -limit; - bOK = FALSE; - } - - if ( p.z < -limit ) - { - p.z = -limit; - bOK = FALSE; - } - - if ( p.x > limit ) - { - p.x = limit; - bOK = FALSE; - } - - if ( p.z > limit ) - { - p.z = limit; - bOK = FALSE; - } - - return bOK; -} - - - -// Empty the table of elevations. - -void CTerrain::FlushBuildingLevel() -{ - m_buildingUsed = 0; -} - -// Adds a new elevation for a building. - -BOOL CTerrain::AddBuildingLevel(D3DVECTOR center, float min, float max, - float height, float factor) -{ - int i; - - for ( i=0 ; i= MAXBUILDINGLEVEL ) return FALSE; - i = m_buildingUsed++; - - update: - m_buildingTable[i].center = center; - m_buildingTable[i].min = min; - m_buildingTable[i].max = max; - m_buildingTable[i].level = RetFloorLevel(center, TRUE); - m_buildingTable[i].height = height; - m_buildingTable[i].factor = factor; - m_buildingTable[i].bboxMinX = center.x-max; - m_buildingTable[i].bboxMaxX = center.x+max; - m_buildingTable[i].bboxMinZ = center.z-max; - m_buildingTable[i].bboxMaxZ = center.z+max; - - return TRUE; -} - -// Updates the elevation for a building when it was moved up (after a terraforming). - -BOOL CTerrain::UpdateBuildingLevel(D3DVECTOR center) -{ - int i; - - for ( i=0 ; i m_buildingTable[i].bboxMaxX || - p.z < m_buildingTable[i].bboxMinZ || - p.z > m_buildingTable[i].bboxMaxZ ) continue; - - dist = Length2d(p, m_buildingTable[i].center); - - if ( dist <= m_buildingTable[i].max ) - { - return m_buildingTable[i].factor; - } - } - return 1.0f; // it is normal on the ground -} - -// Adjusts a position according to a possible rise. - -void CTerrain::AdjustBuildingLevel(D3DVECTOR &p) -{ - D3DVECTOR border; - float dist, base; - int i; - - for ( i=0 ; i m_buildingTable[i].bboxMaxX || - p.z < m_buildingTable[i].bboxMinZ || - p.z > m_buildingTable[i].bboxMaxZ ) continue; - - dist = Length2d(p, m_buildingTable[i].center); - - if ( dist > m_buildingTable[i].max ) continue; - - if ( dist < m_buildingTable[i].min ) - { - p.y = m_buildingTable[i].level+m_buildingTable[i].height; - return; - } - -#if 0 - p.y = m_buildingTable[i].level; - p.y += (m_buildingTable[i].max-dist)/ - (m_buildingTable[i].max-m_buildingTable[i].min)* - m_buildingTable[i].height; - - base = RetFloorLevel(p, TRUE); - if ( p.y < base ) p.y = base; -#else - border.x = ((p.x-m_buildingTable[i].center.x)*m_buildingTable[i].max)/ - dist+m_buildingTable[i].center.x; - border.z = ((p.z-m_buildingTable[i].center.z)*m_buildingTable[i].max)/ - dist+m_buildingTable[i].center.z; - - base = RetFloorLevel(border, TRUE); - - p.y = (m_buildingTable[i].max-dist)/ - (m_buildingTable[i].max-m_buildingTable[i].min)* - (m_buildingTable[i].level+m_buildingTable[i].height-base)+ - base; -#endif - return; - } -} - - -// Returns the hardness of the ground in a given place. -// The hardness determines the noise (SOUND_STEP and SOUND_BOUM). - -float CTerrain::RetHardness(const D3DVECTOR &p) -{ - TerrainMaterial* tm; - float factor, dim; - int x, y, id; - - factor = RetBuildingFactor(p); - if ( factor != 1.0f ) return 1.0f; // on building - - if ( m_levelDot == 0 ) return m_defHardness; - - dim = (m_mosaic*m_brick*m_size)/2.0f; - - x = (int)((p.x+dim)/m_size); - y = (int)((p.z+dim)/m_size); - - if ( x < 0 || x > m_mosaic*m_brick || - y < 0 || y > m_mosaic*m_brick ) return m_defHardness; - - x /= m_brick/m_subdivMapping; - y /= m_brick/m_subdivMapping; - - if ( x < 0 || x >= m_levelDotSize || - y < 0 || y >= m_levelDotSize ) return m_defHardness; - - id = m_levelDot[x+y*m_levelDotSize].id; - tm = LevelSearchMat(id); - if ( tm == 0 ) return m_defHardness; - - return tm->hardness; -} - - -// Shows the flat areas on the ground. - -void CTerrain::GroundFlat(D3DVECTOR pos) -{ - D3DVECTOR p; - float rapport, angle; - int x, y, i; - static char table[41*41]; - - - rapport = 3200.0f/1024.0f; - - for ( y=0 ; y<=40 ; y++ ) - { - for ( x=0 ; x<=40 ; x++ ) - { - i = x + y*41; - table[i] = 0; - - p.x = (x-20)*rapport; - p.z = (y-20)*rapport; - p.y = 0.0f; - if ( Length(p.x, p.y) > 20.0f*rapport ) continue; - - angle = RetFineSlope(pos+p); - - if ( angle < FLATLIMIT ) - { - table[i] = 1; - } - else - { - table[i] = 2; - } - } - } - - m_engine->GroundMarkCreate(pos, 40.0f, 0.001f, 15.0f, 0.001f, 41, 41, table); -} - - -// Calculates the radius of the largest flat area available. -// This calculation is not optimized! - -float CTerrain::RetFlatZoneRadius(D3DVECTOR center, float max) -{ - D3DVECTOR pos; - FPOINT c, p; - float ref, radius, angle, h; - int i, nb; - - angle = RetFineSlope(center); - if ( angle >= FLATLIMIT ) return 0.0f; - - ref = RetFloorLevel(center, TRUE); - - radius = 1.0f; - while ( radius <= max ) - { - angle = 0.0f; - nb = (int)(2.0f*PI*radius); - if ( nb < 8 ) nb = 8; - for ( i=0 ; i 1.0f ) return radius; - - angle += PI*2.0f/8.0f; - } - radius += 1.0f; - } - return max; -} - - - -// Specifies the maximum height of flight. - -void CTerrain::SetFlyingMaxHeight(float height) -{ - m_flyingMaxHeight = height; -} - -// Returns the maximum height of flight. - -float CTerrain::RetFlyingMaxHeight() -{ - return m_flyingMaxHeight; -} - - -// Empty the limits table of flight. - -void CTerrain::FlushFlyingLimit() -{ - m_flyingMaxHeight = 280.0f; - m_flyingLimitTotal = 0; -} - -// Empty the limits table of flight. - -BOOL CTerrain::AddFlyingLimit(D3DVECTOR center, - float extRadius, float intRadius, - float maxHeight) -{ - int i; - - if ( m_flyingLimitTotal >= MAXFLYINGLIMIT ) return FALSE; - - i = m_flyingLimitTotal; - m_flyingLimit[i].center = center; - m_flyingLimit[i].extRadius = extRadius; - m_flyingLimit[i].intRadius = intRadius; - m_flyingLimit[i].maxHeight = maxHeight; - m_flyingLimitTotal = i+1; - - return TRUE; -} - -// Returns the maximum height of flight. - -float CTerrain::RetFlyingLimit(D3DVECTOR pos, BOOL bNoLimit) -{ - float dist, h; - int i; - - if ( bNoLimit ) return 280.0f; - if ( m_flyingLimitTotal == 0 ) return m_flyingMaxHeight; - - for ( i=0 ; i= m_flyingLimit[i].extRadius ) continue; - - if ( dist <= m_flyingLimit[i].intRadius ) - { - return m_flyingLimit[i].maxHeight; - } - - dist -= m_flyingLimit[i].intRadius; - - h = dist*(m_flyingMaxHeight-m_flyingLimit[i].maxHeight)/ - (m_flyingLimit[i].extRadius-m_flyingLimit[i].intRadius); - - return h + m_flyingLimit[i].maxHeight; - } - - return m_flyingMaxHeight; -} - diff --git a/src/terrain.h b/src/terrain.h deleted file mode 100644 index 4fc4ace..0000000 --- a/src/terrain.h +++ /dev/null @@ -1,214 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// terrain.h - -#ifndef _TERRAIN_H_ -#define _TERRAIN_H_ - - -#include "d3dengine.h" - - -class CInstanceManager; -class CD3DEngine; -class CWater; - - - -#define FLATLIMIT (5.0f*PI/180.0f) - - -enum TerrainRes -{ - TR_NULL = 0, - TR_STONE = 1, - TR_URANIUM = 2, - TR_POWER = 3, - TR_KEYa = 4, - TR_KEYb = 5, - TR_KEYc = 6, - TR_KEYd = 7, -}; - - -#define MAXBUILDINGLEVEL 100 - -typedef struct -{ - D3DVECTOR center; - float factor; - float min; - float max; - float level; - float height; - float bboxMinX; - float bboxMaxX; - float bboxMinZ; - float bboxMaxZ; -} -BuildingLevel; - - -#define MAXMATTERRAIN 100 - -typedef struct -{ - short id; - char texName[20]; - float u,v; - float hardness; - char mat[4]; // up, right, down, left -} -TerrainMaterial; - -typedef struct -{ - short id; - char mat[4]; // up, right, down, left -} -DotLevel; - - -#define MAXFLYINGLIMIT 10 - -typedef struct -{ - D3DVECTOR center; - float extRadius; - float intRadius; - float maxHeight; -} -FlyingLimit; - - - -class CTerrain -{ -public: - CTerrain(CInstanceManager* iMan); - ~CTerrain(); - - BOOL Generate(int mosaic, int brickP2, float size, float vision, int depth, float hardness); - BOOL InitTextures(char* baseName, int* table, int dx, int dy); - void LevelFlush(); - BOOL LevelMaterial(int id, char* baseName, float u, float v, int up, int right, int down, int left, float hardness); - BOOL LevelInit(int id); - BOOL LevelGenerate(int *id, float min, float max, float slope, float freq, D3DVECTOR center, float radius); - void FlushRelief(); - BOOL ReliefFromBMP(const char* filename, float scaleRelief, BOOL adjustBorder); - BOOL ReliefFromDXF(const char* filename, float scaleRelief); - BOOL ResFromBMP(const char* filename); - BOOL CreateObjects(BOOL bMultiRes); - BOOL Terraform(const D3DVECTOR &p1, const D3DVECTOR &p2, float height); - - void SetWind(D3DVECTOR speed); - D3DVECTOR RetWind(); - - float RetFineSlope(const D3DVECTOR &pos); - float RetCoarseSlope(const D3DVECTOR &pos); - BOOL GetNormal(D3DVECTOR &n, const D3DVECTOR &p); - float RetFloorLevel(const D3DVECTOR &p, BOOL bBrut=FALSE, BOOL bWater=FALSE); - float RetFloorHeight(const D3DVECTOR &p, BOOL bBrut=FALSE, BOOL bWater=FALSE); - BOOL MoveOnFloor(D3DVECTOR &p, BOOL bBrut=FALSE, BOOL bWater=FALSE); - BOOL ValidPosition(D3DVECTOR &p, float marging); - TerrainRes RetResource(const D3DVECTOR &p); - void LimitPos(D3DVECTOR &pos); - - void FlushBuildingLevel(); - BOOL AddBuildingLevel(D3DVECTOR center, float min, float max, float height, float factor); - BOOL UpdateBuildingLevel(D3DVECTOR center); - BOOL DeleteBuildingLevel(D3DVECTOR center); - float RetBuildingFactor(const D3DVECTOR &p); - float RetHardness(const D3DVECTOR &p); - - int RetMosaic(); - int RetBrick(); - float RetSize(); - float RetScaleRelief(); - - void GroundFlat(D3DVECTOR pos); - float RetFlatZoneRadius(D3DVECTOR center, float max); - - void SetFlyingMaxHeight(float height); - float RetFlyingMaxHeight(); - void FlushFlyingLimit(); - BOOL AddFlyingLimit(D3DVECTOR center, float extRadius, float intRadius, float maxHeight); - float RetFlyingLimit(D3DVECTOR pos, BOOL bNoLimit); - -protected: - BOOL ReliefAddDot(D3DVECTOR pos, float scaleRelief); - void AdjustRelief(); - D3DVECTOR RetVector(int x, int y); - D3DVERTEX2 RetVertex(int x, int y, int step); - BOOL CreateMosaic(int ox, int oy, int step, int objRank, const D3DMATERIAL7 &mat, float min, float max); - BOOL CreateSquare(BOOL bMultiRes, int x, int y); - - TerrainMaterial* LevelSearchMat(int id); - void LevelTextureName(int x, int y, char *name, FPOINT &uv); - float LevelRetHeight(int x, int y); - BOOL LevelGetDot(int x, int y, float min, float max, float slope); - int LevelTestMat(char *mat); - void LevelSetDot(int x, int y, int id, char *mat); - BOOL LevelIfDot(int x, int y, int id, char *mat); - BOOL LevelPutDot(int x, int y, int id); - void LevelOpenTable(); - void LevelCloseTable(); - - void AdjustBuildingLevel(D3DVECTOR &p); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CWater* m_water; - - int m_mosaic; // number of mosaics - int m_brick; // number of bricks per mosaics - float m_size; // size of an item in an brick - float m_vision; // vision before a change of resolution - float* m_relief; // table of the relief - int* m_texture; // table of textures - int* m_objRank; // table of rows of objects - BOOL m_bMultiText; - BOOL m_bLevelText; - float m_scaleMapping; // scale of the mapping - float m_scaleRelief; - int m_subdivMapping; - int m_depth; // number of different resolutions (1,2,3,4) - char m_texBaseName[20]; - char m_texBaseExt[10]; - float m_defHardness; - - TerrainMaterial m_levelMat[MAXMATTERRAIN+1]; - int m_levelMatTotal; - int m_levelMatMax; - int m_levelDotSize; - DotLevel* m_levelDot; - int m_levelID; - - int m_buildingUsed; - BuildingLevel m_buildingTable[MAXBUILDINGLEVEL]; - - unsigned char* m_resources; - D3DVECTOR m_wind; // wind speed - - float m_flyingMaxHeight; - int m_flyingLimitTotal; - FlyingLimit m_flyingLimit[MAXFLYINGLIMIT]; -}; - - -#endif //_TERRAIN_H_ diff --git a/src/text.cpp b/src/text.cpp deleted file mode 100644 index 88cfe0a..0000000 --- a/src/text.cpp +++ /dev/null @@ -1,1881 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// text.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "language.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "text.h" - - - -static short table_text_colobot[] = -{ -// x1, y1, x2, y2 - 219,34, 225,50, // 0 - 1,188, 9,203, // . - 51,188,59,203, // square - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 11,188,19,203, // \t - 21,188,29,203, // \n - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, // \r - 219,34, 225,50, - 219,34, 225,50, - 41,188,49,203, // > - 31,188,39,203, // < - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - -#if _NEWLOOK - 0, 0, 4, 16, // 32 - 7, 0, 9, 16, // ! - 9, 0, 13, 16, // " - 13, 0, 24, 16, // # - 24, 0, 31, 16, // $ - 31, 0, 43, 16, // % - 43, 0, 54, 16, // & - 54, 0, 56, 16, // ' - 56, 0, 61, 16, // ( - 61, 0, 67, 16, // ) - 67, 0, 73, 16, // * - 73, 0, 83, 16, // + - 83, 0, 87, 16, // , - 87, 0, 92, 16, // - - 92, 0, 94, 16, // . - 94, 0, 101,16, // / - 101,0, 109,16, // 0 - 109,0, 114,16, // 1 - 114,0, 122,16, // 2 - 122,0, 129,16, // 3 - 129,0, 138,16, // 4 - 138,0, 146,16, // 5 - 146,0, 154,16, // 6 - 154,0, 161,16, // 7 - 161,0, 169,16, // 8 - 169,0, 177,16, // 9 - 177,0, 179,16, // : - 179,0, 183,16, // ; - 183,0, 193,16, // < - 193,0, 203,16, // = - 203,0, 213,16, // > - 213,0, 219,16, // ? - - 0, 17, 14, 33, // @ 64 - 14, 17, 26, 33, // A - 26, 17, 33, 33, // B - 33, 17, 42, 33, // C - 42, 17, 51, 33, // D - 51, 17, 58, 33, // E - 58, 17, 63, 33, // F - 63, 17, 73, 33, // G - 73, 17, 82, 33, // H - 82, 17, 84, 33, // I - 84, 17, 90, 33, // J - 90, 17, 98, 33, // K - 98, 17, 103,33, // L - 103,17, 115,33, // M - 115,17, 124,33, // N - 124,17, 136,33, // O - 136,17, 142,33, // P - 142,17, 154,33, // Q - 154,17, 160,33, // R - 160,17, 167,33, // S - 167,17, 175,33, // T - 175,17, 183,33, // U - 183,17, 194,33, // V - 194,17, 208,33, // W - 208,17, 218,33, // X - 218,17, 227,33, // Y - 227,17, 236,33, // Z - 236,17, 241,33, // [ - 241,17, 248,33, // \ - 248,17, 252,33, // ] - 219,0, 229,16, // ^ - 0, 34, 9, 50, // _ - - 54, 0, 56, 16, // ` 96 - 9, 34, 16, 50, // a - 16, 34, 25, 50, // b - 25, 34, 33, 50, // c - 33, 34, 42, 50, // d - 42, 34, 50, 50, // e - 50, 34, 55, 50, // f - 55, 34, 62, 50, // g - 62, 34, 69, 50, // h - 69, 34, 71, 50, // i - 71, 34, 75, 50, // j - 75, 34, 81, 50, // k - 81, 34, 83, 50, // l - 83, 34, 93, 50, // m - 93, 34, 100,50, // n - 100,34, 109,50, // o - 109,34, 118,50, // p - 118,34, 127,50, // q - 127,34, 132,50, // r - 132,34, 138,50, // s - 138,34, 143,50, // t - 143,34, 150,50, // u - 150,34, 158,50, // v - 158,34, 171,50, // w - 171,34, 179,50, // x - 179,34, 187,50, // y - 187,34, 195,50, // z - 195,34, 201,50, // { - 201,34, 203,50, // | - 203,34, 209,50, // } - 209,34, 219,50, // ~ - 219,34, 228,50, // - - 219,34, 225,50, // 128 - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - - 219,34, 225,50, // 144 - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - - 219,34, 225,50, // 160 - 219,34, 225,50, // 161 A1 ! reverse - 219,34, 225,50, - 219,34, 225,50, // 163 A3 Å - 219,34, 225,50, - 219,34, 225,50, - 0, 0, 4, 16, // 166 A6 ¦ (space) - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - - 219,34, 225,50, // 176 - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, // 191 BF ? reverse - - 12, 51, 24, 67, // 192 C0 Å• big - 0, 51, 12, 67, // 193 C1 á big - 24, 51, 36, 67, // 194 C2 â big - 48, 51, 60, 67, // 195 C3 ă big - 36, 51, 48, 67, // 196 C4 ä big - 219,34, 225,50, - 219,34, 225,50, - 60, 51, 69, 67, // 199 C7 ç big - 77, 51, 84, 67, // 200 C8 Ä big - 70, 51, 77, 67, // 201 C9 é big - 85, 51, 92, 67, // 202 CA Ä™ big - 93, 51, 100,67, // 203 CB ë big - 219,34, 225,50, - 100,51, 104,67, // 205 CD í big - 108,51, 113,67, // 206 CE î big - 113,51, 117,67, // 207 CF Ä big - - 219,34, 225,50, // 208 - 117,51, 126,67, // 209 D1 Å„ big - 219,34, 225,50, - 126,51, 138,67, // 211 D3 ó big - 150,51, 162,67, // 212 D4 ô big - 219,34, 225,50, - 162,51, 174,67, // 214 D6 ö big - 219,34, 225,50, - 219,34, 225,50, - 194,51, 202,67, // 217 D9 ů big - 186,51, 194,67, // 218 DA ú big - 202,51, 210,67, // 219 DB ű big - 210,51, 218,67, // 220 DC ü big - 219,34, 225,50, - 219,34, 225,50, - 218,51, 227,67, // 223 DF German SS - - 7, 68, 14, 84, // 224 E0 Å• small - 0, 68, 7, 84, // 225 E1 á small - 14, 68, 21, 84, // 226 E2 â small - 28, 68, 35, 84, // 227 E3 ă small - 21, 68, 28, 84, // 228 E4 ä small - 219,34, 225,50, - 219,34, 225,50, - 35, 68, 43, 84, // 231 E7 ç small - 51, 68, 59, 84, // 232 E8 Ä small - 43, 68, 51, 84, // 233 E9 é small - 59, 68, 67, 84, // 234 EA Ä™ small - 67, 68, 75, 84, // 235 EB ë small - 219,34, 225,50, - 75, 68, 79, 84, // 237 ED í small - 83, 68, 88, 84, // 238 EE î small - 88, 68, 92, 84, // 239 EF Ä small - - 219,34, 225,50, // 240 - 92, 68, 99, 84, // 241 F1 Å„ small - 219,34, 225,50, - 99, 68, 108,84, // 243 F3 ó small - 117,68, 126,84, // 244 F4 ô small - 219,34, 225,50, - 126,68, 135,84, // 246 F6 ö small - 219,34, 225,50, - 219,34, 225,50, - 151,68, 158,84, // 249 F9 ů small - 144,68, 151,84, // 250 FA ú small - 158,68, 165,84, // 251 FB ű small - 165,68, 172,84, // 252 FC ü small - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, -#else - 0, 0, 4, 16, // 32 - 4, 0, 7, 16, // ! - 7, 0, 13, 16, - 14, 0, 21, 16, - 22, 0, 28, 16, - 29, 0, 38, 16, - 39, 0, 48, 16, - 48, 0, 51, 16, - 51, 0, 55, 16, - 55, 0, 59, 16, - 59, 0, 65, 16, - 66, 0, 72, 16, - 73, 0, 76, 16, - 76, 0, 82, 16, - 82, 0, 85, 16, - 85, 0, 90, 16, - 90, 0, 97, 16, - 98, 0, 103,16, - 104,0, 111,16, - 111,0, 118,16, - 118,0, 125,16, - 125,0, 132,16, - 132,0, 139,16, - 139,0, 146,16, - 146,0, 153,16, - 153,0, 160,16, - 160,0, 165,16, // : - 164,0, 169,16, // ; - 169,0, 177,16, // < - 177,0, 185,16, // = - 185,0, 193,16, // > - 193,0, 201,16, // ? - - 201,0, 215,16, // 64 - 0, 17, 10, 33, // A - 10, 17, 18, 33, - 19, 17, 28, 33, - 28, 17, 36, 33, - 37, 17, 44, 33, - 45, 17, 52, 33, - 53, 17, 62, 33, - 63, 17, 71, 33, - 72, 17, 75, 33, - 75, 17, 82, 33, - 83, 17, 91, 33, - 92, 17, 99, 33, - 100,17, 110,33, - 111,17, 119,33, -//? 120,17, 129,33, // O - 216,0, 227,16, // O - 130,17, 138,33, - 139,17, 148,33, - 149,17, 158,33, - 158,17, 166,33, - 166,17, 175,33, - 175,17, 183,33, - 183,17, 193,33, - 193,17, 207,33, - 207,17, 215,33, - 215,17, 224,33, - 224,17, 232,33, // Z - 232,17, 236,33, - 236,17, 241,33, - 241,17, 245,33, - 245,17, 252,33, // ^ - 0, 34, 8, 50, // _ - - 45, 17, 52, 33, // 96 - 8, 34, 15, 50, // a - 16, 34, 23, 50, - 24, 34, 31, 50, - 31, 34, 38, 50, - 39, 34, 46, 50, - 46, 34, 52, 50, - 52, 34, 59, 50, - 60, 34, 67, 50, - 68, 34, 71, 50, - 71, 34, 76, 50, - 77, 34, 84, 50, - 84, 34, 87, 50, - 88, 34, 99, 50, - 100,34, 107,50, -//? 108,34, 115,50, // o - 238,0, 246,16, // o - 116,34, 123,50, - 124,34, 131,50, - 132,34, 137,50, - 137,34, 144,50, - 144,34, 149,50, - 149,34, 156,50, - 156,34, 164,50, - 164,34, 176,50, - 176,34, 183,50, - 183,34, 191,50, - 191,34, 197,50, // z - 197,34, 203,50, - 203,34, 205,50, - 205,34, 211,50, - 211,34, 219,50, - 219,34, 225,50, - -#if _POLISH - 219,34, 225,50, // 128 - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 0, 51, 8, 67, // 140 S´ - 219,34, 225,50, - 219,34, 225,50, - 9, 51, 17, 67, // 143 Z´ - - 219,34, 225,50, // 144 - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 0, 68, 7, 84, // 156 s´ - 219,34, 225,50, - 219,34, 225,50, - 8, 68, 14, 84, // 159 z´ - - 219,34, 225,50, // 160 - 219,34, 225,50, - 219,34, 225,50, - 18, 51, 27, 67, // 163 L/ - 219,34, 225,50, - 28, 51, 39, 67, // 165 A, - 0, 0, 4, 16, // 166 A6 ¦ (space) - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 40, 51, 48, 67, // 175 Zo - - 219,34, 225,50, // 176 - 219,34, 225,50, - 219,34, 225,50, - 16, 68, 21, 84, // 179 l/ - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 23, 68, 31, 84, // 185 a, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 32, 68, 38, 84, // 191 zo - - 219,34, 225,50, // 192 - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 49, 51, 58, 67, // 198 C´ - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 59, 51, 66, 67, // 202 E, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - - 219,34, 225,50, // 208 - 67, 51, 75, 67, // 209 N´ - 219,34, 225,50, -//? 76, 51, 85, 67, // 211 O´ - 86, 51, 97, 67, // 211 O´ - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - - 219,34, 225,50, // 224 - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 39, 68, 46, 84, // 230 c´ - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 47, 68, 54, 84, // 234 e, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - - 219,34, 225,50, // 240 - 55, 68, 62, 84, // 241 n´ - 219,34, 225,50, -//? 63, 68, 70, 84, // 243 o´ - 71, 68, 79, 84, // 243 o´ - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, -#else - 219,34, 225,50, // 128 - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - - 219,34, 225,50, // 144 - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - - 219,34, 225,50, // 160 - 219,34, 225,50, // 161 A1 ! reverse - 219,34, 225,50, - 219,34, 225,50, // 163 A3 Å - 219,34, 225,50, - 219,34, 225,50, - 0, 0, 4, 16, // 166 A6 ¦ (space) - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - - 219,34, 225,50, // 176 - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, // 191 BF ? reverse - - 10, 51, 20, 67, // 192 C0 Å• big - 0, 51, 10, 67, // 193 C1 á big - 20, 51, 30, 67, // 194 C2 â big - 40, 51, 50, 67, // 195 C3 ă big - 30, 51, 40, 67, // 196 C4 ä big - 219,34, 225,50, - 219,34, 225,50, - 50, 51, 59, 67, // 199 C7 ç big - 67, 51, 74, 67, // 200 C8 Ä big - 59, 51, 66, 67, // 201 C9 é big - 75, 51, 82, 67, // 202 CA Ä™ big - 83, 51, 90, 67, // 203 CB ë big - 219,34, 225,50, - 91, 51, 95, 67, // 205 CD í big - 100,51, 103,67, // 206 CE î big - 104,51, 109,67, // 207 CF Ä big - - 219,34, 225,50, // 208 - 109,51, 117,67, // 209 D1 Å„ big - 219,34, 225,50, - 118,51, 127,67, // 211 D3 ó big - 138,51, 147,67, // 212 D4 ô big - 219,34, 225,50, - 148,51, 157,67, // 214 D6 ö big - 219,34, 225,50, - 219,34, 225,50, - 177,51, 185,67, // 217 D9 ů big - 168,51, 176,67, // 218 DA ú big - 186,51, 194,67, // 219 DB ű big - 195,51, 203,67, // 220 DC ü big - 219,34, 225,50, - 219,34, 225,50, - 211,51, 220,67, // 223 DF German SS - - 8, 68, 15, 84, // 224 E0 Å• small - 0, 68, 7, 84, // 225 E1 á small - 16, 68, 23, 84, // 226 E2 â small - 32, 68, 39, 84, // 227 E3 ă small - 24, 68, 31, 84, // 228 E4 ä small - 219,34, 225,50, - 219,34, 225,50, - 40, 68, 47, 84, // 231 E7 ç small - 55, 68, 62, 84, // 232 E8 Ä small - 47, 68, 54, 84, // 233 E9 é small - 63, 68, 70, 84, // 234 EA Ä™ small - 71, 68, 78, 84, // 235 EB ë small - 219,34, 225,50, - 79, 68, 83, 84, // 237 ED í small - 88, 68, 92, 84, // 238 EE î small - 92, 68, 97, 84, // 239 EF Ä small - - 219,34, 225,50, // 240 - 97, 68, 104,84, // 241 F1 Å„ small - 219,34, 225,50, - 105,68, 112,84, // 243 F3 ó small - 121,68, 128,84, // 244 F4 ô small - 219,34, 225,50, - 129,68, 136,84, // 246 F6 ö small - 219,34, 225,50, - 219,34, 225,50, - 153,68, 160,84, // 249 F9 ů small - 145,68, 152,84, // 250 FA ú small - 161,68, 168,84, // 251 FB ű small - 169,68, 176,84, // 252 FC ü small - 219,34, 225,50, - 219,34, 225,50, - 219,34, 225,50, -#endif -#endif -}; - - -static short table_text_courier[] = -{ -// x1, y1, x2, y2 - 231,137,239,153, // 0 - 1,188, 9,204, // . - 51,188,59,204, // square - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 11,188,19,204, // \t - 21,188,29,204, // \n - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, // \r - 231,137,239,153, - 231,137,239,153, - 41,188,49,204, // > - 31,188,39,204, // < - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - - 1, 86, 9,102, // 32 - 11, 86, 19,102, - 21, 86, 29,102, - 31, 86, 39,102, - 41, 86, 49,102, - 51, 86, 59,102, - 61, 86, 69,102, - 71, 86, 79,102, - 81, 86, 89,102, - 91, 86, 99,102, - 101, 86,109,102, - 111, 86,119,102, - 121, 86,129,102, - 131, 86,139,102, - 141, 86,149,102, - 151, 86,159,102, - 161, 86,169,102, - 171, 86,179,102, - 181, 86,189,102, - 191, 86,199,102, - 201, 86,209,102, - 211, 86,219,102, - 221, 86,229,102, - 231, 86,239,102, - 1,103, 9,119, // 56 - 11,103, 19,119, - 21,103, 29,119, - 31,103, 39,119, - 41,103, 49,119, - 51,103, 59,119, - 61,103, 69,119, - 71,103, 79,119, - - 81,103, 89,119, // @ - 91,103, 99,119, - 101,103,109,119, - 111,103,119,119, - 121,103,129,119, - 131,103,139,119, - 141,103,149,119, - 151,103,159,119, - 161,103,169,119, - 171,103,179,119, - 181,103,189,119, - 191,103,199,119, - 201,103,209,119, - 211,103,219,119, - 221,103,229,119, - 231,103,239,119, - 1,120, 9,136, // P - 11,120, 19,136, - 21,120, 29,136, - 31,120, 39,136, - 41,120, 49,136, - 51,120, 59,136, - 61,120, 69,136, - 71,120, 79,136, - 81,120, 89,136, - 91,120, 99,136, - 101,120,109,136, - 111,120,119,136, // [ - 121,120,129,136, - 131,120,139,136, - 141,120,149,136, - 151,120,159,136, // _ - - 161,120,169,136, - 171,120,179,136, // a - 181,120,189,136, - 191,120,199,136, - 201,120,209,136, - 211,120,219,136, - 221,120,229,136, - 231,120,239,136, - 1,137, 9,153, - 11,137, 19,153, - 21,137, 29,153, - 31,137, 39,153, - 41,137, 49,153, - 51,137, 59,153, - 61,137, 69,153, - 71,137, 79,153, // o - 81,137, 89,153, - 91,137, 99,153, - 101,137,109,153, - 111,137,119,153, - 121,137,129,153, - 131,137,139,153, - 141,137,149,153, - 151,137,159,153, - 161,137,169,153, - 171,137,179,153, - 181,137,189,153, - 191,137,199,153, - 201,137,209,153, - 211,137,219,153, - 221,137,229,153, // ~ - 231,137,239,153, - -#if _POLISH - 231,137,239,153, // 128 - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 1,154, 9,170, // 140 S´ - 231,137,239,153, - 231,137,239,153, - 11,154, 19,170, // 143 Z´ - - 231,137,239,153, // 144 - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 1,171, 9,187, // 156 s´ - 231,137,239,153, - 231,137,239,153, - 11,171, 19,187, // 159 z´ - - 231,137,239,153, // 160 - 231,137,239,153, - 231,137,239,153, - 21,154, 29,170, // 163 L/ - 231,137,239,153, - 31,154, 39,170, // 165 A, - 1, 86, 9,102, // 166 A6 ¦ (space) - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 41,154, 49,170, // 175 Zo - - 231,137,239,153, // 176 - 231,137,239,153, - 231,137,239,153, - 21,171, 29,187, // 179 l/ - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 31,171, 39,187, // 185 a, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 41,171, 49,187, // 191 zo - - 231,137,239,153, // 192 - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 51,154, 59,170, // 198 C´ - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 61,154, 69,170, // 202 E, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - - 231,137,239,153, // 208 - 71,154, 79,170, // 209 N´ - 231,137,239,153, - 81,171, 89,187, // 211 O´ - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - - 231,137,239,153, // 224 - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 51,171, 59,187, // 230 c´ - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 61,171, 69,187, // 234 e, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - - 231,137,239,153, // 240 - 71,171, 79,187, // 241 n´ - 231,137,239,153, - 81,171, 89,187, // 243 ó small - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, -#else - 231,137,239,153, // 128 - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - - 231,137,239,153, // 144 - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - - 231,137,239,153, // 160 - 231,137,239,153, // 161 A1 ! reverse - 231,137,239,153, - 231,137,239,153, // 163 A3 Å - 231,137,239,153, - 231,137,239,153, - 1, 86, 9,102, // 166 A6 ¦ (space) - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - - 231,137,239,153, // 176 - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, // 191 BF ? reverse - - 11,154, 19,170, // Å• big - 1,154, 9,170, // á big - 21,154, 29,170, // â big - 41,154, 49,170, // ă big - 31,154, 39,170, // ä big - 231,137,239,153, - 231,137,239,153, - 51,154, 59,170, // ç big - 71,154, 79,170, // Ä big - 61,154, 69,170, // é big - 81,154, 89,170, // Ä™ big - 91,154, 99,170, // ë big - 231,137,239,153, - 101,154,109,170, // í big - 121,154,129,170, // î big - 131,154,139,170, // Ä big - 231,137,239,153, - 141,154,149,170, // Å„ big - 231,137,239,153, - 151,154,159,170, // ó big - 171,154,179,170, // ô big - 231,137,239,153, - 181,154,189,170, // ö big - 231,137,239,153, - 231,137,239,153, - 211,154,219,170, // ů big - 201,154,209,170, // ú big - 221,154,229,170, // ű big - 231,154,239,170, // ü big - 231,137,239,153, - 231,137,239,153, - 241,154,249,170, // 223 DF German SS - - 11,171, 19,187, // Å• small - 1,171, 9,187, // á small - 21,171, 29,187, // â small - 41,171, 49,187, // ă small - 31,171, 39,187, // ä small - 231,137,239,153, - 231,137,239,153, - 51,171, 59,187, // ç small - 71,171, 79,187, // Ä small - 61,171, 69,187, // é small - 81,171, 89,187, // Ä™ small - 91,171, 99,187, // ë small - 231,137,239,153, - 111,171,119,187, // Ä› small - 121,171,129,187, // î small - 131,171,139,187, // Ä small - 231,137,239,153, - 141,171,149,187, // Å„ small - 231,137,239,153, - 151,171,159,187, // ó small - 171,171,179,187, // ô small - 231,137,239,153, - 181,171,189,187, // ö small - 231,137,239,153, - 231,137,239,153, - 211,171,219,187, // ů small - 201,171,209,187, // ú small - 221,171,229,187, // ű small - 231,171,239,187, // ü small - 231,137,239,153, - 231,137,239,153, - 231,137,239,153, -#endif -}; - - -// Returns the pointer to the table by the font. - -short* RetTable(FontType font) -{ - if ( font == FONT_COLOBOT ) return table_text_colobot; - else return table_text_courier; -} - - - -// Object's constructor. - -CText::CText(CInstanceManager* iMan, CD3DEngine* engine) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_TEXT, this); - - m_pD3DDevice = 0; - m_engine = engine; -} - -// Object's destructor. - -CText::~CText() -{ - m_iMan->DeleteInstance(CLASS_TEXT, this); -} - - -void CText::SetD3DDevice(LPDIRECT3DDEVICE7 device) -{ - m_pD3DDevice = device; -} - - -// Displays multi-font text. -// The vertical position is at the bottom of the box of the character. - -void CText::DrawText(char *string, char *format, int len, FPOINT pos, - float width, int justif, float size, float stretch, - int eol) -{ - float sw; - - if ( justif == 0 ) // center? - { - sw = RetStringWidth(string, format, len, size, stretch); - if ( sw > width ) sw = width; - pos.x -= sw/2.0f; - } - if ( justif < 0 ) // flag was left? - { - sw = RetStringWidth(string, format, len, size, stretch); - if ( sw > width ) sw = width; - pos.x -= sw; - } - DrawString(string, format, len, pos, width, size, stretch, eol); -} - -// Displays multi-font text. -// The vertical position is at the bottom of the box of the character. - -void CText::DrawText(char *string, char *format, FPOINT pos, float width, - int justif, float size, float stretch, - int eol) -{ - DrawText(string, format, strlen(string), pos, width, justif, size, stretch, eol); -} - -// Displays text. -// The vertical position is at the bottom of the box of the character. - -void CText::DrawText(char *string, int len, FPOINT pos, float width, - int justif, float size, float stretch, FontType font, - int eol) -{ - float sw; - - if ( justif == 0 ) // center? - { - sw = RetStringWidth(string, len, size, stretch, font); - if ( sw > width ) sw = width; - pos.x -= sw/2.0f; - } - if ( justif < 0 ) // flag was left? - { - sw = RetStringWidth(string, len, size, stretch, font); - if ( sw > width ) sw = width; - pos.x -= sw; - } - DrawString(string, len, pos, width, size, stretch, font, eol); -} - -// Displays text. -// The vertical position is at the bottom of the box of the character. - -void CText::DrawText(char *string, FPOINT pos, float width, - int justif, float size, float stretch, FontType font, - int eol) -{ - DrawText(string, strlen(string), pos, width, justif, size, stretch, font, eol); -} - - -// Returns the size of a multi-font text. - -void CText::DimText(char *string, char *format, int len, FPOINT pos, - int justif, float size, float stretch, - FPOINT &start, FPOINT &end) -{ - float sw; - - start = end = pos; - - sw = RetStringWidth(string, format, len, size, stretch); - end.x += sw; - if ( justif == 0 ) // center? - { - start.x -= sw/2.0f; - end.x -= sw/2.0f; - } - if ( justif < 0 ) // flag was left? - { - start.x -= sw; - end.x -= sw; - } - - start.y -= RetDescent(size, FONT_COLOBOT); - end.y += RetAscent(size, FONT_COLOBOT); -} - -// Returns the size of a multi-font text. - -void CText::DimText(char *string, char *format, FPOINT pos, int justif, - float size, float stretch, - FPOINT &start, FPOINT &end) -{ - DimText(string, format, strlen(string), pos, justif, size, stretch, start, end); -} - -// Returns the size of a text. - -void CText::DimText(char *string, int len, FPOINT pos, int justif, - float size, float stretch, FontType font, - FPOINT &start, FPOINT &end) -{ - float sw; - - start = end = pos; - - sw = RetStringWidth(string, len, size, stretch, font); - end.x += sw; - if ( justif == 0 ) // center? - { - start.x -= sw/2.0f; - end.x -= sw/2.0f; - } - if ( justif < 0 ) // flag was left? - { - start.x -= sw; - end.x -= sw; - } - - start.y -= RetDescent(size, font); - end.y += RetAscent(size, font); -} - -// Returns the size of a text. - -void CText::DimText(char *string, FPOINT pos, int justif, - float size, float stretch, FontType font, - FPOINT &start, FPOINT &end) -{ - DimText(string, strlen(string), pos, justif, size, stretch, font, start, end); -} - - -// Returns the height above the baseline. - -float CText::RetAscent(float size, FontType font) -{ - return (13.0f/256.0f)*(size/20.0f); -} - -// Returns the height below the baseline. - -float CText::RetDescent(float size, FontType font) -{ - return (3.0f/256.0f)*(size/20.0f); -} - -// Returns the total height of the character. - -float CText::RetHeight(float size, FontType font) -{ - return (16.0f/256.0f)*(size/20.0f); -} - - -// Returns the width of a string of multi-font characters. - -float CText::RetStringWidth(char *string, char *format, int len, - float size, float stretch) -{ - FontType font; - float st, tab, w, width = 0.0f; - short *table, *pt; - int i, c; - - for ( i=0 ; iRetEditIndentValue(); - w = tab-Mod(width, tab); - if ( w < tab*0.1f ) w += tab; - width += w; - continue; - } - - if ( c > 255 ) continue; - - pt = table+c*4; - st = stretch; - if ( font == FONT_COLOBOT && (c == 'O' || c == 'o') ) st = 0.8f; - width += (float)(pt[2]-pt[0])/256.0f*(size/20.0f)*st; - } - } - - return width; -} - -// Returns the width of a string of characters. - -float CText::RetStringWidth(char *string, int len, - float size, float stretch, FontType font) -{ - float st, tab, w, width = 0.0f; - short *table, *pt; - int i, c; - - table = RetTable(font); - for ( i=0 ; iRetEditIndentValue(); - w = tab-Mod(width, tab); - if ( w < tab*0.1f ) w += tab; - width += w; - continue; - } - - if ( c > 255 ) continue; - - pt = table+c*4; - st = stretch; - if ( font == FONT_COLOBOT && (c == 'O' || c == 'o') ) st = 0.8f; - width += (float)(pt[2]-pt[0])/256.0f*(size/20.0f)*st; - } - - return width; -} - -// Returns the width of a character. -// 'offset' is the current position in the line. - -float CText::RetCharWidth(int character, float offset, - float size, float stretch, FontType font) -{ - float st, tab, w; - short* pt; - - if ( font == FONT_BUTTON ) return (12.0f/256.0f)*(size/20.0f); - - if ( character == '\t' ) - { - pt = RetTable(font)+' '*4; - tab = (float)(pt[2]-pt[0])/256.0f*(size/20.0f)*stretch*m_engine->RetEditIndentValue(); - w = tab-Mod(offset, tab); - if ( w < tab*0.1f ) w += tab; - return w; - } - - if ( character > 255 ) return 0.0f; - - pt = RetTable(font)+character*4; - st = stretch; -#if !_NEWLOOK - if ( font == FONT_COLOBOT && (character == 'O' || character == 'o') ) st = 0.8f; -#endif - return (float)(pt[2]-pt[0])/256.0f*(size/20.0f)*st; -} - - -// Justifies a line of multi-font text. Returns the offset of the cut. - -int CText::Justif(char *string, char *format, int len, float width, - float size, float stretch) -{ - FontType font; - float pos; - int i, character, cut; - - pos = 0.0f; - cut = 0; - for ( i=0 ; i width ) - { - if ( cut == 0 ) return i; - else return cut; - } - } - return i; -} - -// Justify a line of text. Returns the offset of the cut. - -int CText::Justif(char *string, int len, float width, - float size, float stretch, FontType font) -{ - float pos; - int i, character, cut; - - pos = 0.0f; - cut = 0; - for ( i=0 ; i width ) - { - if ( cut == 0 ) return i; - else return cut; - } - } - return i; -} - -// Returns the most suitable position to a given offset (multi-font). - -int CText::Detect(char *string, char *format, int len, float offset, - float size, float stretch) -{ - FontType font; - float pos, width; - int i, character, cut; - - pos = 0.0f; - cut = 0; - for ( i=0 ; iSetTexture("textp.tga"); -#else - m_engine->SetTexture("text.tga"); -#endif - m_engine->SetState(D3DSTATETTw); - - font = FONT_COLOBOT; - - start = pos.x; - offset = 0.0f; - for ( i=0 ; i width ) // exceeds the maximum width? - { - cw = RetCharWidth(16, offset, size, stretch, font); - pos.x = start+width-cw; - DrawChar(16, pos, size, stretch, font); // > - break; - } - - if ( (format[i]&COLOR_MASK) != 0 ) - { - DrawColor(pos, size, cw, format[i]&COLOR_MASK); - } - DrawChar(c, pos, size, stretch, font); - offset += cw; - pos.x += cw; - } - - if ( eol != 0 ) - { - DrawChar(eol, pos, size, stretch, font); - } -} - -// Displays text. - -void CText::DrawString(char *string, int len, FPOINT pos, float width, - float size, float stretch, FontType font, - int eol) -{ - float start, offset, cw; - int i, c; - -#if _POLISH - m_engine->SetTexture("textp.tga"); -#else - m_engine->SetTexture("text.tga"); -#endif - m_engine->SetState(D3DSTATETTw); - - start = pos.x; - offset = 0.0f; - for ( i=0 ; i width ) // exceeds the maximum width? - { - cw = RetCharWidth(16, offset, size, stretch, font); - pos.x = start+width-cw; - DrawChar(16, pos, size, stretch, font); // > - break; - } - - DrawChar(c, pos, size, stretch, font); - offset += cw; - pos.x += cw; - } - - if ( eol != 0 ) - { - DrawChar(eol, pos, size, stretch, font); - } -} - -// Displays the link to a character. - -void CText::DrawColor(FPOINT pos, float size, float width, int color) -{ - D3DVERTEX2 vertex[4]; // 2 triangles - FPOINT p1, p2; - POINT dim; - D3DVECTOR n; - float h, u1, u2, v1, v2, dp; - int icon; - - icon = -1; - if ( color == COLOR_LINK ) icon = 9; // blue - if ( color == COLOR_TOKEN ) icon = 4; // orange - if ( color == COLOR_TYPE ) icon = 5; // green - if ( color == COLOR_CONST ) icon = 8; // red - if ( color == COLOR_REM ) icon = 6; // magenta - if ( color == COLOR_KEY ) icon = 10; // gray - if ( icon == -1 ) return; - - if ( color == COLOR_LINK ) - { - m_engine->SetState(D3DSTATENORMAL); - } - - dim = m_engine->RetDim(); - if ( dim.y <= 768.0f ) // 1024x768 or less? - { - h = 1.01f/dim.y; // 1 pixel - } - else // more than 1024x768? - { - h = 2.0f/dim.y; // 2 pixels - } - - p1.x = pos.x; - p2.x = pos.x + width; - - if ( color == COLOR_LINK ) - { - p1.y = pos.y; - p2.y = pos.y + h; // just emphasized - } - else - { -#if 1 - p1.y = pos.y; - p2.y = pos.y + (16.0f/256.0f)*(size/20.0f); -//? p2.y = pos.y + h*4.0f; // just emphasized thick -#else - p1.y = pos.y; - p2.y = pos.y + (16.0f/256.0f)*(size/20.0f)/4.0f; -#endif - } - - u1 = (16.0f/256.0f)*(icon%16); - v1 = (240.0f/256.0f); - u2 = (16.0f/256.0f)+u1; - v2 = (16.0f/256.0f)+v1; - - dp = 0.5f/256.0f; - u1 += dp; - v1 += dp; - u2 -= dp; - v2 -= dp; - - n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal - - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); - vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); - vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); - - if ( color == COLOR_LINK ) - { - m_engine->SetState(D3DSTATETTw); - } -} - -// Displays a character. - -void CText::DrawChar(int character, FPOINT pos, float size, - float stretch, FontType font) -{ - D3DVERTEX2 vertex[4]; // 2 triangles - FPOINT p1, p2; - D3DVECTOR n; - float width, height, u1, u2, v1, v2, dp; - short* pt; - - dp = 0.5f/256.0f; - n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal - - if ( font == FONT_BUTTON ) - { - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATENORMAL); - - p1.x = pos.x; - p1.y = pos.y; - p2.x = pos.x + (12.0f/256.0f)*(size/20.0f); - p2.y = pos.y + (16.0f/256.0f)*(size/20.0f); - - if ( character <= 64 || character >= 128+56 ) - { - u1 = 66.0f/256.0f; - v1 = 2.0f/256.0f; - u2 = 94.0f/256.0f; - v2 = 30.0f/256.0f; - } - else - { - u1 = 224.0f/256.0f; - v1 = 32.0f/256.0f; - u2 = 256.0f/256.0f; - v2 = 64.0f/256.0f; - } - - u1 += dp; - v1 += dp; - u2 -= dp; - v2 -= dp; - - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); - vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); - vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); - -//? p1.x += (12.0f/256.0f)*(size/20.0f)*0.1f; -//? p1.y += (16.0f/256.0f)*(size/20.0f)*0.1f; -//? p2.x -= (12.0f/256.0f)*(size/20.0f)*0.1f; -//? p2.y -= (16.0f/256.0f)*(size/20.0f)*0.1f; - - if ( character >= 64 && character < 64+64 ) - { - character -= 64; - m_engine->SetTexture("button2.tga"); - } - if ( character >= 128 && character < 128+64 ) - { - character -= 128; - m_engine->SetTexture("button3.tga"); - } - - m_engine->SetState(D3DSTATETTw); - - u1 = (32.0f/256.0f)*(character%8); - v1 = (32.0f/256.0f)*(character/8); // uv texture - u2 = (32.0f/256.0f)+u1; - v2 = (32.0f/256.0f)+v1; - - u1 += dp; - v1 += dp; - u2 -= dp; - v2 -= dp; - - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); - vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); - vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); - - -#if _POLISH - m_engine->SetTexture("textp.tga"); -#else - m_engine->SetTexture("text.tga"); -#endif - return; - } - - if ( character > 255 ) return; - -//? if ( character == '\t' ) character = ' '; // if tab, does not display -> - -#if !_NEWLOOK - if ( font == FONT_COLOBOT && (character == 'O' || character == 'o') ) - { - stretch = 0.8f; - } -#endif - if ( font == FONT_COURIER ) - { - stretch *= 1.2f; - } - - pt = RetTable(font)+character*4; - width = (float)(pt[2]-pt[0])/256.0f*stretch*0.9f; -//? width = (float)(pt[2]-pt[0])/256.0f*stretch; - height = (float)(pt[3]-pt[1])/256.0f; - -#if _NEWLOOK - pos.y += height*(size/20.0f)/17.0f; -#endif - p1.x = pos.x; - p1.y = pos.y; - p2.x = pos.x + width*(size/20.0f); - p2.y = pos.y + height*(size/20.0f); - - u1 = (float)pt[0]/256.0f; - v1 = (float)pt[1]/256.0f; - u2 = (float)pt[2]/256.0f; - v2 = (float)pt[3]/256.0f; - - if ( font == FONT_COLOBOT ) - { - u1 += dp; - u2 += dp; -#if _NEWLOOK - v2 += dp; -#endif - } - if ( font == FONT_COURIER ) - { - u1 -= dp; - u2 += dp*2.0f; - } - - - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); - vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); - vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); -} - diff --git a/src/text.h b/src/text.h deleted file mode 100644 index 4407039..0000000 --- a/src/text.h +++ /dev/null @@ -1,113 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// text.h - -#ifndef _TEXT_H_ -#define _TEXT_H_ - - -#include "d3dengine.h" - - -class CInstanceManager; - - - -#define SMALLFONT 10.0f -#define BIGFONT 15.0f - -#define NORMSTRETCH 0.8f - - - -enum FontType -{ - FONT_COLOBOT = 0, - FONT_COURIER = 1, - FONT_BUTTON = 2, -}; - -enum FontTitle -{ - TITLE_BIG = 0x04, - TITLE_NORM = 0x08, - TITLE_LITTLE = 0x0c, -}; - -enum FontColor -{ - COLOR_LINK = 0x10, - COLOR_TOKEN = 0x20, - COLOR_TYPE = 0x30, - COLOR_CONST = 0x40, - COLOR_REM = 0x50, - COLOR_KEY = 0x60, - COLOR_TABLE = 0x70, -}; - -#define FONT_MASK 0x03 -#define TITLE_MASK 0x0c -#define COLOR_MASK 0x70 -#define IMAGE_MASK 0x80 - - - -class CText -{ -public: - CText(CInstanceManager *iMan, CD3DEngine* engine); - ~CText(); - - void SetD3DDevice(LPDIRECT3DDEVICE7 device); - - void DrawText(char *string, char *format, int len, FPOINT pos, float width, int justif, float size, float stretch, int eol); - void DrawText(char *string, char *format, FPOINT pos, float width, int justif, float size, float stretch, int eol); - void DrawText(char *string, int len, FPOINT pos, float width, int justif, float size, float stretch, FontType font, int eol); - void DrawText(char *string, FPOINT pos, float width, int justif, float size, float stretch, FontType font, int eol); - void DimText(char *string, char *format, int len, FPOINT pos, int justif, float size, float stretch, FPOINT &start, FPOINT &end); - void DimText(char *string, char *format, FPOINT pos, int justif, float size, float stretch, FPOINT &start, FPOINT &end); - void DimText(char *string, int len, FPOINT pos, int justif, float size, float stretch, FontType font, FPOINT &start, FPOINT &end); - void DimText(char *string, FPOINT pos, int justif, float size, float stretch, FontType font, FPOINT &start, FPOINT &end); - - float RetAscent(float size, FontType font); - float RetDescent(float size, FontType font); - float RetHeight(float size, FontType font); - - float RetStringWidth(char *string, char *format, int len, float size, float stretch); - float RetStringWidth(char *string, int len, float size, float stretch, FontType font); - float RetCharWidth(int character, float offset, float size, float stretch, FontType font); - - int Justif(char *string, char *format, int len, float width, float size, float stretch); - int Justif(char *string, int len, float width, float size, float stretch, FontType font); - int Detect(char *string, char *format, int len, float offset, float size, float stretch); - int Detect(char *string, int len, float offset, float size, float stretch, FontType font); - -protected: - void DrawString(char *string, char *format, int len, FPOINT pos, float width, float size, float stretch, int eol); - void DrawString(char *string, int len, FPOINT pos, float width, float size, float stretch, FontType font, int eol); - void DrawColor(FPOINT pos, float size, float width, int color); - void DrawChar(int character, FPOINT pos, float size, float stretch, FontType font); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - LPDIRECT3DDEVICE7 m_pD3DDevice; - -}; - - -#endif //_TEXT_H_ diff --git a/src/tracks.txt b/src/tracks.txt deleted file mode 100644 index 8d80872..0000000 --- a/src/tracks.txt +++ /dev/null @@ -1,17 +0,0 @@ -Utilisation des tracks - - 1: data - 2: terre Terre - 3: tropica Tropica - 4: crystalium Crystalium - 5: saari Saari - 6: volcano Volcano - 7: centaury Centaury - 8: orpheon Orphéon - 9: terranova Terranova -10: lost perdu -11: win gagné -12: fox fin du jeu -13: shuffle - - -DR 12.06.01 diff --git a/src/traduc.txt b/src/traduc.txt deleted file mode 100644 index 73bbf55..0000000 --- a/src/traduc.txt +++ /dev/null @@ -1,151 +0,0 @@ -Types des objets COLOBOT ------------------------- - - - ... // sac de survie - - BaseCamp // fusée principale - Derrick // derrick - BotFactory // fabrique de véhicules - PowerStation // station de recharge - Converter // conversion minerai en titanium - RepairCenter // centre de réparation - DefenceTower // tour de défense - AlienNest // nid - ResearchCenter // centre de recherches - RadarStation // radar - PowerPlant // fabrique de piles - AutoLab // analyseur de matières organiques - NuclearPlant // centrale nucléaire - StartArea // départ - GoalArea // arrivée - ExchangePost // borne d'information - - TitaniumOre // minerai de titanium - UraniumOre // minerai d'uranium - Titanium // titanium - PowerPack // pile normale - NuclearPack // pile nucléaire - OrgaStuff // matière organique - BlackBox // boîte noire - TNT // explosif - - PowerSpot // énergie en sous-sol - TitaniumSpot // titanium en sous-sol - UraniumSpot // uranium en sous-sol - PathSpot // chemin - - TrainingRollerBot // véhicule d'entraînement : - TrainingCrawlerBot - TrainingJetBot - TrainingSpiderBot - - GrabberRollerBot // véhicule manipulateur : - GrabberCrawlerBot - GrabberJetBot - GrabberSpiderBot - - FireballRollerBot // véhicule de défense : - FireballCrawlerBot - FireballJetBot - FireballSpiderBot - - OrgaballRollerBot // véhicule de défense : - OrgaballCrawlerBot - OrgaballJetBot - OrgaballSpiderBot - - SnifferRollerBot // véhicule sondeur : - SnifferCrawlerBot - SnifferJetBot - SnifferSpiderBot - - ThumperBot // véhicule de terrassement - FazerBot // véhicule de défense - RecyclerBot // véhicule de récupération - ShieldBot // véhicule de protection - SubBot // sous-marin - TargetBot // cible d'entraînement - - Me // homme - Wiz // toto - - AlienBigLady // mère pondeuse - AlienEgg // oeuf - AlienAnt // fourmi - AlienSpider // araignée - AlienWasp // guèpe - AlienWorm // ver - - Wreck // épave de véhicule - Ruin // bâtiment en ruine - Firework // feu d'artifice - Mine // mine - Barrier // barrière - Greenery // plante - Tree // arbre - Quartz // quartz - MegaStalk // racine - ... // gravi-plante - - -Fonction du langage CBOT : - - Move // avance d'une certaine distance - Turn // tourne d'un certain angle - Goto // va à une coordonnée donnée - Motor // commande directe des moteurs gauche & droite - Jet // commande directe du réacteur - - Radar // détecte un objet - Direction // calcule une direction - Distance // calcule la distance entre deux points - Wait // attend - Produce // crée un objet - Message // affiche un message - - Grab // prend un objet avec le bras manipulateur - Drop // dépose un objet avec le bras manipulateur - Sniff // sonde le sous-sol - Receive // reçoit une information - Send // envoie une information - Thump // terraforme le terrain - Recycle // récupère une épave - Shield // actionne le bouclier de protection - Fire // tir avec un canon - Aim // hausse du canon - - -Classes : - - point // point avec coordonnées x,y,z - object // descriptif d'un objet - - -Descripteur d'un objet : - - category // catégorie de l'objet - energyPack // object pile - load // objet transporté - position // position x,y,z - direction // orientation - energyLevel // niveau d'énergie - shieldLevel // niveau du bouclier - altitude // hauteur par rapport au sol - - -Argument de la commande Manip( ) : - - InFront // prend ou dépose devant - Behind // prend ou dépose derrière - EnergyPack // prend ou dépose sa propre pile - - -Filtre pour la commande Radar( ) ; - - FilterNone // pas de filtre - FilterOnlyLanding // seulement les robots qui roulent - FilterOnlyFliying // seulement les robots qui volent - - -DR 14.03.01 diff --git a/src/ui/README.txt b/src/ui/README.txt new file mode 100644 index 0000000..4ffd8ec --- /dev/null +++ b/src/ui/README.txt @@ -0,0 +1,3 @@ +src/ui + +Contains modules responsible for displaying the user interface controls (from game menus and HUD). diff --git a/src/ui/button.cpp b/src/ui/button.cpp new file mode 100644 index 0000000..27fea9b --- /dev/null +++ b/src/ui/button.cpp @@ -0,0 +1,248 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "language.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "restext.h" +#include "button.h" + + + +#define DELAY1 0.4f +#define DELAY2 0.1f + + + +// Object's constructor. + +CButton::CButton(CInstanceManager* iMan) : CControl(iMan) +{ + m_bCapture = FALSE; + m_bImmediat = FALSE; + m_bRepeat = FALSE; + m_repeat = 0.0f; +} + +// Object's destructor. + +CButton::~CButton() +{ +} + + +// Creates a new button. + +BOOL CButton::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + CControl::Create(pos, dim, icon, eventMsg); + + if ( icon == -1 ) + { + char name[100]; + char* p; + + GetResource(RES_EVENT, eventMsg, name); + p = strchr(name, '\\'); + if ( p != 0 ) *p = 0; + SetName(name); + } + + return TRUE; +} + + +// Management of an event. + +BOOL CButton::EventProcess(const Event &event) +{ + if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; + if ( m_state & STATE_DEAD ) return TRUE; + + CControl::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + if ( m_bRepeat && m_repeat != 0.0f ) + { + m_repeat -= event.rTime; + if ( m_repeat <= 0.0f ) + { + m_repeat = DELAY2; + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + return FALSE; + } + } + } + + if ( event.event == EVENT_LBUTTONDOWN && + (m_state & STATE_VISIBLE) && + (m_state & STATE_ENABLE) ) + { + if ( CControl::Detect(event.pos) ) + { + m_bCapture = TRUE; + m_repeat = DELAY1; + + if ( m_bImmediat || m_bRepeat ) + { + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + } + return FALSE; + } + } + + if ( event.event == EVENT_MOUSEMOVE && m_bCapture ) + { + } + + if ( event.event == EVENT_LBUTTONUP && m_bCapture ) + { + if ( CControl::Detect(event.pos) ) + { + if ( !m_bImmediat && !m_bRepeat ) + { + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + } + } + + m_bCapture = FALSE; + m_repeat = 0.0f; + } + + return TRUE; +} + + +// Draw button. + +void CButton::Draw() +{ + FPOINT pos, dim, uv1, uv2; +#if !_NEWLOOK + float dp; +#endif + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + if ( m_state & STATE_WARNING ) // shading yellow-black? + { + pos.x = m_pos.x-( 8.0f/640.0f); + pos.y = m_pos.y-( 4.0f/480.0f); + dim.x = m_dim.x+(16.0f/640.0f); + dim.y = m_dim.y+( 8.0f/480.0f); + if ( m_state & STATE_SHADOW ) + { + DrawShadow(pos, dim); + } + DrawWarning(pos, dim); + } + + if ( m_state & STATE_SHADOW ) + { + DrawShadow(m_pos, m_dim); + } + + CControl::Draw(); + +#if !_NEWLOOK + if ( m_name[0] != 0 && // button with the name? + (m_state & STATE_CARD ) == 0 && + (m_state & STATE_SIMPLY) == 0 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + + dp = 0.5f/256.0f; + + uv1.x = 128.0f/256.0f; + uv1.y = 96.0f/256.0f; + uv2.x = 136.0f/256.0f; + uv2.y = 128.0f/256.0f; + + if ( (m_state & STATE_ENABLE) == 0 ) + { + uv1.x += 16.0f/256.0f; + uv2.x += 16.0f/256.0f; + } + + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + pos.y = m_pos.y+5.0f/480.0f; + dim.y = m_dim.y-10.0f/480.0f; + pos.x = m_pos.x+5.0f/640.0f; + dim.x = 3.0f/640.0f; + DrawIcon(pos, dim, uv1, uv2, 0.0f); + + uv1.x += 8.0f/256.0f; + uv2.x += 8.0f/256.0f; + pos.x = m_pos.x+m_dim.x-5.0f/640.0f-3.0f/640.0f; + DrawIcon(pos, dim, uv1, uv2, 0.0f); + } +#endif +} + + +// Management of immediate mode, which sends the event "press" +// before the mouse button is released. + +void CButton::SetImmediat(BOOL bImmediat) +{ + m_bImmediat = bImmediat; +} + +BOOL CButton::RetImmediat() +{ + return m_bImmediat; +} + + +// Mode management "autorepeat", when the button +// mouse is held down. + +void CButton::SetRepeat(BOOL bRepeat) +{ + m_bRepeat = bRepeat; +} + +BOOL CButton::RetRepeat() +{ + return m_bRepeat; +} + diff --git a/src/ui/button.h b/src/ui/button.h new file mode 100644 index 0000000..2d30eea --- /dev/null +++ b/src/ui/button.h @@ -0,0 +1,58 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// button.h + +#ifndef _BUTTON_H_ +#define _BUTTON_H_ + + +#include "control.h" + + +class CD3DEngine; + + + +class CButton : public CControl +{ +public: + CButton(CInstanceManager* iMan); + virtual ~CButton(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + + BOOL EventProcess(const Event &event); + + void Draw(); + + void SetImmediat(BOOL bRepeat); + BOOL RetImmediat(); + + void SetRepeat(BOOL bRepeat); + BOOL RetRepeat(); + +protected: + +protected: + BOOL m_bCapture; + BOOL m_bImmediat; + BOOL m_bRepeat; + float m_repeat; +}; + + +#endif //_BUTTON_H_ diff --git a/src/ui/check.cpp b/src/ui/check.cpp new file mode 100644 index 0000000..f485921 --- /dev/null +++ b/src/ui/check.cpp @@ -0,0 +1,168 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "restext.h" +#include "text.h" +#include "check.h" + + + + +// Object's constructor. + +CCheck::CCheck(CInstanceManager* iMan) : CControl(iMan) +{ +} + +// Object's destructor. + +CCheck::~CCheck() +{ +} + + +// Creates a new button. + +BOOL CCheck::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + char name[100]; + char* p; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + CControl::Create(pos, dim, icon, eventMsg); + + GetResource(RES_EVENT, eventMsg, name); + p = strchr(name, '\\'); + if ( p != 0 ) *p = 0; + SetName(name); + + return TRUE; +} + + +// Management of an event. + +BOOL CCheck::EventProcess(const Event &event) +{ + if ( m_state & STATE_DEAD ) return TRUE; + + CControl::EventProcess(event); + + if ( event.event == EVENT_LBUTTONDOWN && + (m_state & STATE_VISIBLE) && + (m_state & STATE_ENABLE) ) + { + if ( CControl::Detect(event.pos) ) + { + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + return FALSE; + } + } + + return TRUE; +} + + +// Draw button. + +void CCheck::Draw() +{ + FPOINT iDim, pos; + float zoomExt, zoomInt; + int icon; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + iDim = m_dim; + m_dim.x = m_dim.y*0.75f; // square + + if ( m_state & STATE_SHADOW ) + { + DrawShadow(m_pos, m_dim); + } + + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + + zoomExt = 1.00f; + zoomInt = 0.95f; + + icon = 2; + if ( m_state & STATE_DEFAULT ) + { + DrawPart(23, 1.3f, 0.0f); + + zoomExt *= 1.15f; + zoomInt *= 1.15f; + } + if ( m_state & STATE_HILIGHT ) + { + icon = 1; + } + if ( m_state & STATE_PRESS ) + { + icon = 3; + zoomInt *= 0.9f; + } + if ( (m_state & STATE_ENABLE) == 0 ) + { + icon = 7; + } + if ( m_state & STATE_DEAD ) + { + icon = 17; + } + DrawPart(icon, zoomExt, 0.0f); // draws the button + + if ( (m_state & STATE_DEAD) == 0 ) + { + m_engine->SetState(D3DSTATETTw); + + if ( m_state & STATE_CHECK ) + { + icon = 16; // seen + DrawPart(icon, zoomInt, 0.0f); // draw the icon + } + } + + m_dim = iDim; + + if ( m_state & STATE_DEAD ) return; + + // Draw the name. + pos.x = m_pos.x+m_dim.y/0.9f; + pos.y = m_pos.y+m_dim.y*0.50f; + pos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; + m_engine->RetText()->DrawText(m_name, pos, m_dim.x, 1, m_fontSize, m_fontStretch, m_fontType, 0); +} + + diff --git a/src/ui/check.h b/src/ui/check.h new file mode 100644 index 0000000..118b6cb --- /dev/null +++ b/src/ui/check.h @@ -0,0 +1,48 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// check.h + +#ifndef _CHECK_H_ +#define _CHECK_H_ + + +#include "control.h" + + +class CD3DEngine; + + + +class CCheck : public CControl +{ +public: + CCheck(CInstanceManager* iMan); + virtual ~CCheck(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + + BOOL EventProcess(const Event &event); + + void Draw(); + +protected: + +protected: +}; + + +#endif //_CHECK_H_ diff --git a/src/ui/color.cpp b/src/ui/color.cpp new file mode 100644 index 0000000..cf69b0d --- /dev/null +++ b/src/ui/color.cpp @@ -0,0 +1,226 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "language.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "restext.h" +#include "color.h" + + + +#define DELAY1 0.4f +#define DELAY2 0.1f + + + +// Object's constructor. + +CColor::CColor(CInstanceManager* iMan) : CControl(iMan) +{ + m_bRepeat = FALSE; + m_repeat = 0.0f; + + m_color.r = 0.0f; + m_color.g = 0.0f; + m_color.b = 0.0f; + m_color.a = 0.0f; +} + +// Object's destructor. + +CColor::~CColor() +{ +} + + +// Creates a new button. + +BOOL CColor::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + CControl::Create(pos, dim, icon, eventMsg); + + if ( icon == -1 ) + { + char name[100]; + char* p; + + GetResource(RES_EVENT, eventMsg, name); + p = strchr(name, '\\'); + if ( p != 0 ) *p = 0; + SetName(name); + } + + return TRUE; +} + + +// Management of an event. + +BOOL CColor::EventProcess(const Event &event) +{ + if ( m_state & STATE_DEAD ) return TRUE; + + CControl::EventProcess(event); + + if ( event.event == EVENT_FRAME && m_bRepeat ) + { + if ( m_repeat != 0.0f ) + { + m_repeat -= event.rTime; + if ( m_repeat <= 0.0f ) + { + m_repeat = DELAY2; + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + return FALSE; + } + } + } + + if ( event.event == EVENT_LBUTTONDOWN && + (m_state & STATE_VISIBLE) && + (m_state & STATE_ENABLE) ) + { + if ( CControl::Detect(event.pos) ) + { + m_repeat = DELAY1; + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + return FALSE; + } + } + + if ( event.event == EVENT_LBUTTONUP ) + { + m_repeat = 0.0f; + } + + return TRUE; +} + + +// Dessine le bouton. + +void CColor::Draw() +{ + LPDIRECT3DDEVICE7 device; + D3DLVERTEX vertex[4]; // 2 triangles + D3DCOLOR color; + FPOINT p1, p2; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + if ( m_state & STATE_SHADOW ) + { + DrawShadow(m_pos, m_dim); + } + + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + CControl::Draw(); + +#if _TEEN + color = ::RetColor(m_color); + + m_engine->SetTexture("xxx.tga"); // no texture + m_engine->SetState(D3DSTATENORMAL); + + device = m_engine->RetD3DDevice(); + + p1.x = m_pos.x+(4.0f/640.0f); + p1.y = m_pos.y+(4.0f/480.0f); + p2.x = m_pos.x+m_dim.x-(4.0f/640.0f); + p2.y = m_pos.y+m_dim.y-(4.0f/480.0f); + vertex[0] = D3DLVERTEX(D3DVECTOR(p1.x, p1.y, 0.0f), 0x00000000,0x00000000, 0.0f,0.0f); + vertex[1] = D3DLVERTEX(D3DVECTOR(p1.x, p2.y, 0.0f), 0x00000000,0x00000000, 0.0f,0.0f); + vertex[2] = D3DLVERTEX(D3DVECTOR(p2.x, p1.y, 0.0f), 0x00000000,0x00000000, 0.0f,0.0f); + vertex[3] = D3DLVERTEX(D3DVECTOR(p2.x, p2.y, 0.0f), 0x00000000,0x00000000, 0.0f,0.0f); + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, vertex, 4, NULL); + + p1.x = m_pos.x+(5.0f/640.0f); + p1.y = m_pos.y+(5.0f/480.0f); + p2.x = m_pos.x+m_dim.x-(5.0f/640.0f); + p2.y = m_pos.y+m_dim.y-(5.0f/480.0f); + vertex[0] = D3DLVERTEX(D3DVECTOR(p1.x, p1.y, 0.0f), color,0x00000000, 0.0f,0.0f); + vertex[1] = D3DLVERTEX(D3DVECTOR(p1.x, p2.y, 0.0f), color,0x00000000, 0.0f,0.0f); + vertex[2] = D3DLVERTEX(D3DVECTOR(p2.x, p1.y, 0.0f), color,0x00000000, 0.0f,0.0f); + vertex[3] = D3DLVERTEX(D3DVECTOR(p2.x, p2.y, 0.0f), color,0x00000000, 0.0f,0.0f); + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, vertex, 4, NULL); + + m_engine->AddStatisticTriangle(4); +#else + p1.x = m_pos.x+(3.0f/640.0f); + p1.y = m_pos.y+(3.0f/480.0f); + p2.x = m_pos.x+m_dim.x-(3.0f/640.0f); + p2.y = m_pos.y+m_dim.y-(3.0f/480.0f); + + color = ::RetColor(m_color); + + m_engine->SetTexture("xxx.tga"); // no texture + m_engine->SetState(D3DSTATENORMAL); + + vertex[0] = D3DLVERTEX(D3DVECTOR(p1.x, p1.y, 0.0f), color,0x00000000, 0.0f,0.0f); + vertex[1] = D3DLVERTEX(D3DVECTOR(p1.x, p2.y, 0.0f), color,0x00000000, 0.0f,0.0f); + vertex[2] = D3DLVERTEX(D3DVECTOR(p2.x, p1.y, 0.0f), color,0x00000000, 0.0f,0.0f); + vertex[3] = D3DLVERTEX(D3DVECTOR(p2.x, p2.y, 0.0f), color,0x00000000, 0.0f,0.0f); + + device = m_engine->RetD3DDevice(); + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); +#endif +} + + +void CColor::SetRepeat(BOOL bRepeat) +{ + m_bRepeat = bRepeat; +} + +BOOL CColor::RetRepeat() +{ + return m_bRepeat; +} + + +void CColor::SetColor(D3DCOLORVALUE color) +{ + m_color = color; +} + +D3DCOLORVALUE CColor::RetColor() +{ + return m_color; +} + + diff --git a/src/ui/color.h b/src/ui/color.h new file mode 100644 index 0000000..fec01c4 --- /dev/null +++ b/src/ui/color.h @@ -0,0 +1,58 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// color.h + +#ifndef _COLOR_H_ +#define _COLOR_H_ + + +#include "control.h" +#include "d3dengine.h" + + +class CD3DEngine; + + + +class CColor : public CControl +{ +public: + CColor(CInstanceManager* iMan); + virtual ~CColor(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + + BOOL EventProcess(const Event &event); + + void Draw(); + + void SetRepeat(BOOL bRepeat); + BOOL RetRepeat(); + + void SetColor(D3DCOLORVALUE color); + D3DCOLORVALUE RetColor(); + +protected: + +protected: + BOOL m_bRepeat; + float m_repeat; + D3DCOLORVALUE m_color; +}; + + +#endif //_COLOR_H_ diff --git a/src/ui/compass.cpp b/src/ui/compass.cpp new file mode 100644 index 0000000..92804c2 --- /dev/null +++ b/src/ui/compass.cpp @@ -0,0 +1,176 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "compass.h" + + + + +// Object's constructor. + +CCompass::CCompass(CInstanceManager* iMan) : CControl(iMan) +{ + m_dir = 0.0f; +} + +// Object's destructor. + +CCompass::~CCompass() +{ +} + + +// Creates a new button. + +BOOL CCompass::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + CControl::Create(pos, dim, icon, eventMsg); + return TRUE; +} + + +// Management of an event. + +BOOL CCompass::EventProcess(const Event &event) +{ + CControl::EventProcess(event); + + if ( event.event == EVENT_LBUTTONDOWN ) + { + if ( CControl::Detect(event.pos) ) + { + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + return FALSE; + } + } + + return TRUE; +} + + +// Draw button. + +void CCompass::Draw() +{ + LPDIRECT3DDEVICE7 device; + D3DVERTEX2 vertex[4]; // 2 triangles + FPOINT p1, p2, p3, c, uv1, uv2; + D3DVECTOR n; + float dp; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + device = m_engine->RetD3DDevice(); + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + + p1.x = m_pos.x; + p1.y = m_pos.y; + p2.x = m_pos.x + m_dim.x; + p2.y = m_pos.y + m_dim.y; + + c.x = (p1.x+p2.x)/2.0f; + c.y = (p1.y+p2.y)/2.0f; // center + + uv1.x = 64.0f/256.0f; + uv1.y = 32.0f/256.0f; + uv2.x = 96.0f/256.0f; + uv2.y = 64.0f/256.0f; + + dp = 0.5f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal + + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x,uv1.y); + vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y); + vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv2.x,uv1.y); + + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); + + if ( m_state & STATE_ENABLE ) + { + p1.x = c.x; + p1.y = c.y+m_dim.x*0.40f; + p1 = RotatePoint(c, m_dir, p1); + p1.x = c.x+(p1.x-c.x)*(m_dim.x/m_dim.y); + + p2.x = c.x+m_dim.x*0.20f; + p2.y = c.y-m_dim.x*0.40f; + p2 = RotatePoint(c, m_dir, p2); + p2.x = c.x+(p2.x-c.x)*(m_dim.x/m_dim.y); + + p3.x = c.x-m_dim.x*0.20f; + p3.y = c.y-m_dim.x*0.40f; + p3 = RotatePoint(c, m_dir, p3); + p3.x = c.x+(p3.x-c.x)*(m_dim.x/m_dim.y); + + uv1.x = 96.0f/256.0f; + uv1.y = 32.0f/256.0f; + uv2.x = 104.0f/256.0f; + uv2.y = 64.0f/256.0f; + + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv1.y); + vertex[1] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv1.x,uv2.y); + vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv2.x,uv2.y); + + device->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_VERTEX2, vertex, 3, NULL); + m_engine->AddStatisticTriangle(1); + } +} + + +// Management directions of the compass. + +void CCompass::SetDirection(float dir) +{ + m_dir = dir; +} + +float CCompass::RetDirection() +{ + return m_dir; +} + + diff --git a/src/ui/compass.h b/src/ui/compass.h new file mode 100644 index 0000000..1eed3d6 --- /dev/null +++ b/src/ui/compass.h @@ -0,0 +1,52 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// compass.h + +#ifndef _COMPASS_H_ +#define _COMPASS_H_ + + +#include "control.h" + + +class CD3DEngine; + + + +class CCompass : public CControl +{ +public: + CCompass(CInstanceManager* iMan); + virtual ~CCompass(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + + BOOL EventProcess(const Event &event); + + void Draw(); + + void SetDirection(float dir); + float RetDirection(); + +protected: + +protected: + float m_dir; +}; + + +#endif //_COMPASS_H_ diff --git a/src/ui/control.cpp b/src/ui/control.cpp new file mode 100644 index 0000000..6ba5cef --- /dev/null +++ b/src/ui/control.cpp @@ -0,0 +1,876 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "language.h" +#include "restext.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "robotmain.h" +#include "particule.h" +#include "misc.h" +#include "iman.h" +#include "text.h" +#include "sound.h" +#include "control.h" + + + + +// Object's constructor. + +CControl::CControl(CInstanceManager* iMan) +{ + m_iMan = iMan; + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + m_eventMsg = EVENT_NULL; + m_state = STATE_ENABLE|STATE_VISIBLE|STATE_GLINT; + m_fontSize = SMALLFONT; + m_fontStretch = NORMSTRETCH; + m_fontType = FONT_COLOBOT; + m_justif = 0; + m_name[0] = 0; + m_tooltip[0] = 0; + m_bFocus = FALSE; + m_bCapture = FALSE; + + m_bGlint = FALSE; + m_glintCorner1 = FPOINT(0.0f, 0.0f); + m_glintCorner2 = FPOINT(0.0f, 0.0f); + m_glintProgress = 999.0f; + m_glintMouse = FPOINT(0.0f, 0.0f); +} + +// Object's destructor. + +CControl::~CControl() +{ +} + + +// Creates a new button. +// pos: [0..1] + +BOOL CControl::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + char text[100]; + char* p; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + m_pos = pos; + m_dim = dim; + m_icon = icon; + m_eventMsg = eventMsg; + + pos.x = m_pos.x; + pos.y = m_pos.y+m_dim.y; + GlintCreate(pos); + + GetResource(RES_EVENT, m_eventMsg, text); + p = strchr(text, '\\'); + if ( p == 0 ) + { + if ( icon != -1 ) + { + strcpy(m_tooltip, text); + } + } + else + { + strcpy(m_tooltip, p+1); // text after "\\" + } + + return TRUE; +} + + +void CControl::SetPos(FPOINT pos) +{ + m_pos = pos; + + pos.x = m_pos.x; + pos.y = m_pos.y+m_dim.y; + GlintCreate(pos); +} + +FPOINT CControl::RetPos() +{ + return m_pos; +} + +void CControl::SetDim(FPOINT dim) +{ + FPOINT pos; + + m_dim = dim; + + pos.x = m_pos.x; + pos.y = m_pos.y+m_dim.y; + GlintCreate(pos); +} + +FPOINT CControl::RetDim() +{ + return m_dim; +} + + +// Modify an attribute of state. + +BOOL CControl::SetState(int state, BOOL bState) +{ + if ( bState ) m_state |= state; + else m_state &= ~state; + return TRUE; +} + +// Sets an attribute of state. + +BOOL CControl::SetState(int state) +{ + m_state |= state; + return TRUE; +} + +// Removes an attribute of state. + +BOOL CControl::ClearState(int state) +{ + m_state &= ~state; + return TRUE; +} + +// Tests an attribute of state. + +BOOL CControl::TestState(int state) +{ + return (m_state & state) ? TRUE:FALSE; +} + +// Returns all attributes of state. + +int CControl::RetState() +{ + return m_state; +} + + +// Management icon. + +void CControl::SetIcon(int icon) +{ + m_icon = icon; +} + +int CControl::RetIcon() +{ + return m_icon; +} + + +// Management of the button name. + +void CControl::SetName(char* name, BOOL bTooltip) +{ + char* p; + + if ( bTooltip ) + { + p = strchr(name, '\\'); + if ( p == 0 ) + { + strncpy(m_name, name, 100); + m_name[100-1] = 0; + } + else + { + char buffer[100]; + + strncpy(m_tooltip, p+1, 100); // text after "\\" + m_tooltip[100-1] = 0; + + strncpy(buffer, name, 100); + buffer[100-1] = 0; + p = strchr(buffer, '\\'); + if ( p != 0 ) *p = 0; + strncpy(m_name, buffer, 100); + m_name[100-1] = 0; + } + } + else + { + strncpy(m_name, name, 100); + m_name[100-1] = 0; + } +} + +char* CControl::RetName() +{ + return m_name; +} + + +// Management of the mode of justification (-1,0,1). + +void CControl::SetJustif(int mode) +{ + m_justif = mode; +} + +int CControl::RetJustif() +{ + return m_justif; +} + + +// Management of the size of the font. + +void CControl::SetFontSize(float size) +{ + m_fontSize = size; +} + +float CControl::RetFontSize() +{ + return m_fontSize; +} + + +// Management of the stretch of font. + +void CControl::SetFontStretch(float stretch) +{ + m_fontStretch = stretch; +} + +float CControl::RetFontStretch() +{ + return m_fontStretch; +} + + +// Choice of the font. + +void CControl::SetFontType(FontType font) +{ + m_fontType = font; +} + +FontType CControl::RetFontType() +{ + return m_fontType; +} + + +// Specifies the tooltip. + +BOOL CControl::SetTooltip(char* name) +{ + strcpy(m_tooltip, name); + return TRUE; +} + +BOOL CControl::GetTooltip(FPOINT pos, char* name) +{ + if ( m_tooltip[0] == 0 ) return FALSE; + if ( (m_state & STATE_VISIBLE) == 0 ) return FALSE; + if ( (m_state & STATE_ENABLE) == 0 ) return FALSE; + if ( m_state & STATE_DEAD ) return FALSE; + if ( !Detect(pos) ) return FALSE; + + strcpy(name, m_tooltip); + return TRUE; +} + + +// Management of the focus. + +void CControl::SetFocus(BOOL bFocus) +{ + m_bFocus = bFocus; +} + +BOOL CControl::RetFocus() +{ + return m_bFocus; +} + + +// Returns the event associated with the control. + +EventMsg CControl::RetEventMsg() +{ + return m_eventMsg; +} + + +// Management of an event. + +BOOL CControl::EventProcess(const Event &event) +{ + if ( m_state & STATE_DEAD ) return TRUE; + + if ( event.event == EVENT_FRAME && m_bGlint ) + { + GlintFrame(event); + } + + if ( event.event == EVENT_MOUSEMOVE ) + { + m_glintMouse = event.pos; + + if ( Detect(event.pos) ) + { + if ( (m_state & STATE_VISIBLE) && + (m_state & STATE_ENABLE ) ) + { + m_engine->SetMouseType(D3DMOUSEHAND); + } + SetState(STATE_HILIGHT); + } + else + { + ClearState(STATE_HILIGHT); + } + } + + if ( event.event == EVENT_LBUTTONDOWN ) + { + if ( Detect(event.pos) ) + { + m_bCapture = TRUE; + SetState(STATE_PRESS); + } + } + + if ( event.event == EVENT_MOUSEMOVE && m_bCapture ) + { + if ( Detect(event.pos) ) + { + SetState(STATE_PRESS); + } + else + { + ClearState(STATE_PRESS); + } + } + + if ( event.event == EVENT_LBUTTONUP && m_bCapture ) + { + m_bCapture = FALSE; + ClearState(STATE_PRESS); + } + + return TRUE; +} + + +// Removes the reflection. + +void CControl::GlintDelete() +{ + m_bGlint = FALSE; +} + +// Creates a reflection for that button. + +void CControl::GlintCreate(FPOINT ref, BOOL bLeft, BOOL bUp) +{ + float offset; + + offset = 8.0f/640.0f; + if ( offset > m_dim.x/4.0f) offset = m_dim.x/4.0f; + + if ( bLeft ) + { + m_glintCorner1.x = ref.x; + m_glintCorner2.x = ref.x+offset; + } + else + { + m_glintCorner1.x = ref.x-offset; + m_glintCorner2.x = ref.x; + } + + offset = 8.0f/480.0f; + if ( offset > m_dim.y/4.0f) offset = m_dim.y/4.0f; + + if ( bUp ) + { + m_glintCorner1.y = ref.y-offset; + m_glintCorner2.y = ref.y; + } + else + { + m_glintCorner1.y = ref.y; + m_glintCorner2.y = ref.y+offset; + } + + m_bGlint = TRUE; +} + +// Management of reflection. + +void CControl::GlintFrame(const Event &event) +{ + D3DVECTOR pos, speed; + FPOINT dim; + + if ( (m_state & STATE_GLINT ) == 0 || + (m_state & STATE_ENABLE ) == 0 || + (m_state & STATE_VISIBLE) == 0 ) return; + + if ( !m_main->RetGlint() ) return; + + m_glintProgress += event.rTime; + + if ( m_glintProgress >= 2.0f && Detect(m_glintMouse) ) + { + pos.x = m_glintCorner1.x + (m_glintCorner2.x-m_glintCorner1.x)*Rand(); + pos.y = m_glintCorner1.y + (m_glintCorner2.y-m_glintCorner1.y)*Rand(); + pos.z = 0.0f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + dim.x = ((15.0f+Rand()*15.0f)/640.0f); + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, PARTICONTROL, + 1.0f, 0.0f, 0.0f, SH_INTERFACE); + + m_glintProgress = 0.0f; + } +} + + +// Draw button. + +void CControl::Draw() +{ + FPOINT pos; + float zoomExt, zoomInt; + int icon; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + + zoomExt = 1.00f; + zoomInt = 0.95f; + + if ( m_icon >= 128 ) + { + zoomInt = 0.80f; + } + + icon = 2; + if ( m_state & STATE_CARD ) + { + icon = 26; + } + if ( m_state & STATE_DEFAULT ) + { + DrawPart(23, 1.3f, 0.0f); + + zoomExt *= 1.15f; + zoomInt *= 1.15f; + } + if ( m_state & STATE_HILIGHT ) + { + icon = 1; + } + if ( m_state & STATE_CHECK ) + { + if ( m_state & STATE_CARD ) + { + icon = 27; + } + else + { + icon = 0; + } + } + if ( m_state & STATE_PRESS ) + { + icon = 3; + zoomInt *= 0.9f; + } + if ( (m_state & STATE_ENABLE) == 0 ) + { + icon = 7; + } + if ( m_state & STATE_DEAD ) + { + icon = 17; + } + + if ( m_state & STATE_OKAY ) + { + m_engine->SetTexture("button3.tga"); + icon = 3; // yellow with green point pressed + } + + if ( m_name[0] == 0 ) // button without name? + { +//? DrawPart(icon, zoomExt, 0.0f); + DrawPart(icon, zoomExt, 8.0f/256.0f); + + if ( m_state & STATE_DEAD ) return; + + icon = m_icon; + if ( icon >= 192 ) + { + icon -= 192; +#if _POLISH + m_engine->SetTexture("textp.tga"); +#else + m_engine->SetTexture("text.tga"); +#endif + m_engine->SetState(D3DSTATETTw); + } + else if ( icon >= 128 ) + { + icon -= 128; + m_engine->SetTexture("button3.tga"); + m_engine->SetState(D3DSTATETTw); + } + else if ( icon >= 64 ) + { + icon -= 64; + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + } + else + { + m_engine->SetState(D3DSTATETTw); + } + if ( icon != -1 ) + { + DrawPart(icon, zoomInt, 0.0f); + } + } + else // button with the name? + { + DrawPart(icon, 1.0f, 8.0f/256.0f); + + if ( m_state & STATE_DEAD ) return; + + if ( m_justif < 0 ) + { + pos.x = m_pos.x+m_dim.x-m_dim.y*0.5f; + pos.y = m_pos.y+m_dim.y*0.5f; + pos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2; + m_engine->RetText()->DrawText(m_name, pos, m_dim.x, m_justif, m_fontSize, m_fontStretch, m_fontType, 0); + } + else if ( m_justif > 0 ) + { + pos.x = m_pos.x+m_dim.y*0.5f; + pos.y = m_pos.y+m_dim.y*0.5f; + pos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; + m_engine->RetText()->DrawText(m_name, pos, m_dim.x, m_justif, m_fontSize, m_fontStretch, m_fontType, 0); + } + else + { + pos.x = m_pos.x+m_dim.x*0.5f; + pos.y = m_pos.y+m_dim.y*0.5f; + pos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; + m_engine->RetText()->DrawText(m_name, pos, m_dim.x, m_justif, m_fontSize, m_fontStretch, m_fontType, 0); + } + } +} + +// Draw the vertex array. + +void CControl::DrawPart(int icon, float zoom, float ex) +{ + FPOINT p1, p2, c, uv1, uv2; + float dp; + + p1.x = m_pos.x; + p1.y = m_pos.y; + p2.x = m_pos.x + m_dim.x; + p2.y = m_pos.y + m_dim.y; + + if ( (m_state & STATE_CARD ) && + (m_state & STATE_CHECK) ) + { + p2.y += (2.0f/480.0f); // a bit above + } + + c.x = (p1.x+p2.x)/2.0f; + c.y = (p1.y+p2.y)/2.0f; // center + + p1.x = (p1.x-c.x)*zoom + c.x; + p1.y = (p1.y-c.y)*zoom + c.y; + p2.x = (p2.x-c.x)*zoom + c.x; + p2.y = (p2.y-c.y)*zoom + c.y; + + p2.x -= p1.x; + p2.y -= p1.y; + + uv1.x = (32.0f/256.0f)*(icon%8); + uv1.y = (32.0f/256.0f)*(icon/8); // uv texture + uv2.x = (32.0f/256.0f)+uv1.x; + uv2.y = (32.0f/256.0f)+uv1.y; + + dp = 0.5f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + DrawIcon(p1, p2, uv1, uv2, ex); +} + +// Draws an icon made up of a rectangular (if x = 0) +// or 3 pieces. + +void CControl::DrawIcon(FPOINT pos, FPOINT dim, FPOINT uv1, FPOINT uv2, + float ex) +{ + LPDIRECT3DDEVICE7 device; + D3DVERTEX2 vertex[8]; // 6 triangles + FPOINT p1, p2, p3, p4; + D3DVECTOR n; + + device = m_engine->RetD3DDevice(); + + p1.x = pos.x; + p1.y = pos.y; + p2.x = pos.x + dim.x; + p2.y = pos.y + dim.y; + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal + + if ( ex == 0.0f ) // one piece? + { + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x,uv1.y); + vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y); + vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv2.x,uv1.y); + + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); + } + else // 3 pieces? + { + if ( dim.x >= dim.y ) + { + p3.x = p1.x + ex*dim.y/(uv2.y-uv1.y); + p4.x = p2.x - ex*dim.y/(uv2.y-uv1.y); + + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x, uv2.y); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x, uv1.y); + vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p1.y, 0.0f), n, uv1.x+ex,uv2.y); + vertex[3] = D3DVERTEX2(D3DVECTOR(p3.x, p2.y, 0.0f), n, uv1.x+ex,uv1.y); + vertex[4] = D3DVERTEX2(D3DVECTOR(p4.x, p1.y, 0.0f), n, uv2.x-ex,uv2.y); + vertex[5] = D3DVERTEX2(D3DVECTOR(p4.x, p2.y, 0.0f), n, uv2.x-ex,uv1.y); + vertex[6] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x, uv2.y); + vertex[7] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv2.x, uv1.y); + + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL); + m_engine->AddStatisticTriangle(6); + } + else + { + p3.y = p1.y + ex*dim.x/(uv2.x-uv1.x); + p4.y = p2.y - ex*dim.x/(uv2.x-uv1.x); + + vertex[0] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y ); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y ); + vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p3.y, 0.0f), n, uv2.x,uv2.y-ex); + vertex[3] = D3DVERTEX2(D3DVECTOR(p1.x, p3.y, 0.0f), n, uv1.x,uv2.y-ex); + vertex[4] = D3DVERTEX2(D3DVECTOR(p2.x, p4.y, 0.0f), n, uv2.x,uv1.y+ex); + vertex[5] = D3DVERTEX2(D3DVECTOR(p1.x, p4.y, 0.0f), n, uv1.x,uv1.y+ex); + vertex[6] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv2.x,uv1.y ); + vertex[7] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x,uv1.y ); + + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL); + m_engine->AddStatisticTriangle(6); + } + } +} + +// Draws a rectangular icon made up of 9 pieces. + +void CControl::DrawIcon(FPOINT pos, FPOINT dim, FPOINT uv1, FPOINT uv2, + FPOINT corner, float ex) +{ + LPDIRECT3DDEVICE7 device; + D3DVERTEX2 vertex[8]; // 6 triangles + FPOINT p1, p2, p3, p4; + D3DVECTOR n; + + device = m_engine->RetD3DDevice(); + + p1.x = pos.x; + p1.y = pos.y; + p2.x = pos.x + dim.x; + p2.y = pos.y + dim.y; + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal + + if ( corner.x > dim.x/2.0f ) corner.x = dim.x/2.0f; + if ( corner.y > dim.y/2.0f ) corner.y = dim.y/2.0f; + + p1.x = pos.x; + p1.y = pos.y; + p2.x = pos.x + dim.x; + p2.y = pos.y + dim.y; + p3.x = p1.x + corner.x; + p3.y = p1.y + corner.y; + p4.x = p2.x - corner.x; + p4.y = p2.y - corner.y; + + // Bottom horizontal band. + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x, uv2.y ); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p3.y, 0.0f), n, uv1.x, uv2.y-ex); + vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p1.y, 0.0f), n, uv1.x+ex,uv2.y ); + vertex[3] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv1.x+ex,uv2.y-ex); + vertex[4] = D3DVERTEX2(D3DVECTOR(p4.x, p1.y, 0.0f), n, uv2.x-ex,uv2.y ); + vertex[5] = D3DVERTEX2(D3DVECTOR(p4.x, p3.y, 0.0f), n, uv2.x-ex,uv2.y-ex); + vertex[6] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x, uv2.y ); + vertex[7] = D3DVERTEX2(D3DVECTOR(p2.x, p3.y, 0.0f), n, uv2.x, uv2.y-ex); + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL); + m_engine->AddStatisticTriangle(6); + + // Central horizontal band. + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p3.y, 0.0f), n, uv1.x, uv2.y-ex); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p4.y, 0.0f), n, uv1.x, uv1.y+ex); + vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv1.x+ex,uv2.y-ex); + vertex[3] = D3DVERTEX2(D3DVECTOR(p3.x, p4.y, 0.0f), n, uv1.x+ex,uv1.y+ex); + vertex[4] = D3DVERTEX2(D3DVECTOR(p4.x, p3.y, 0.0f), n, uv2.x-ex,uv2.y-ex); + vertex[5] = D3DVERTEX2(D3DVECTOR(p4.x, p4.y, 0.0f), n, uv2.x-ex,uv1.y+ex); + vertex[6] = D3DVERTEX2(D3DVECTOR(p2.x, p3.y, 0.0f), n, uv2.x, uv2.y-ex); + vertex[7] = D3DVERTEX2(D3DVECTOR(p2.x, p4.y, 0.0f), n, uv2.x, uv1.y+ex); + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL); + m_engine->AddStatisticTriangle(6); + + // Top horizontal band. + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p4.y, 0.0f), n, uv1.x, uv1.y+ex); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x, uv1.y ); + vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p4.y, 0.0f), n, uv1.x+ex,uv1.y+ex); + vertex[3] = D3DVERTEX2(D3DVECTOR(p3.x, p2.y, 0.0f), n, uv1.x+ex,uv1.y ); + vertex[4] = D3DVERTEX2(D3DVECTOR(p4.x, p4.y, 0.0f), n, uv2.x-ex,uv1.y+ex); + vertex[5] = D3DVERTEX2(D3DVECTOR(p4.x, p2.y, 0.0f), n, uv2.x-ex,uv1.y ); + vertex[6] = D3DVERTEX2(D3DVECTOR(p2.x, p4.y, 0.0f), n, uv2.x, uv1.y+ex); + vertex[7] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv2.x, uv1.y ); + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL); + m_engine->AddStatisticTriangle(6); +} + +// Draw round the hatch of a button. + +void CControl::DrawWarning(FPOINT pos, FPOINT dim) +{ + FPOINT uv1, uv2; + float dp; + + dp = 0.5f/256.0f; + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + + uv1.x = 64.0f/256.0f; + uv1.y = 208.0f/256.0f; + uv2.x = 160.0f/256.0f; + uv2.y = 224.0f/256.0f; + + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + if ( dim.x < dim.y*4.0f ) + { + dim.y /= 2.0f; + DrawIcon(pos, dim, uv1, uv2); + pos.y += dim.y; + DrawIcon(pos, dim, uv1, uv2); + } + else + { + dim.x /= 2.0f; + dim.y /= 2.0f; + DrawIcon(pos, dim, uv1, uv2); + pos.x += dim.x; + DrawIcon(pos, dim, uv1, uv2); + pos.x -= dim.x; + pos.y += dim.y; + DrawIcon(pos, dim, uv1, uv2); + pos.x += dim.x; + DrawIcon(pos, dim, uv1, uv2); + } +} + +// Draw the shade under a button. + +void CControl::DrawShadow(FPOINT pos, FPOINT dim, float deep) +{ + FPOINT uv1, uv2, corner; + float dp; + + dp = 0.5f/256.0f; + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + + pos.x += deep*0.010f*0.75f; + pos.y -= deep*0.015f; + dim.x += deep*0.005f*0.75f; + dim.y += deep*0.005f; + + uv1.x = 192.0f/256.0f; + uv1.y = 32.0f/256.0f; + uv2.x = 224.0f/256.0f; + uv2.y = 64.0f/256.0f; + + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + corner.x = 10.0f/640.0f; + corner.y = 10.0f/480.0f; + + DrawIcon(pos, dim, uv1, uv2, corner, 6.0f/256.0f); +} + + +// Detects whether a position is in the button. + +BOOL CControl::Detect(FPOINT pos) +{ + return ( pos.x >= m_pos.x && + pos.x <= m_pos.x+m_dim.x && + pos.y >= m_pos.y && + pos.y <= m_pos.y+m_dim.y ); +} + + diff --git a/src/ui/control.h b/src/ui/control.h new file mode 100644 index 0000000..619cef2 --- /dev/null +++ b/src/ui/control.h @@ -0,0 +1,137 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// control.h + +#ifndef _CONTROL_H_ +#define _CONTROL_H_ + + +#include "text.h" +#include "struct.h" +#include "event.h" + + +class CInstanceManager; +class CEvent; +class CD3DEngine; +class CRobotMain; +class CParticule; +class CSound; + + +#define STATE_ENABLE (1<<0) // active +#define STATE_CHECK (1<<1) // pressed +#define STATE_HILIGHT (1<<2) // overflown by mouse +#define STATE_PRESS (1<<3) // pressed by mouse +#define STATE_VISIBLE (1<<4) // visible +#define STATE_DEAD (1<<5) // inaccessible (x) +#define STATE_DEFAULT (1<<6) // actuated by RETURN +#define STATE_OKAY (1<<7) // green point at the bottom right +#define STATE_SHADOW (1<<8) // shadow +#define STATE_GLINT (1<<9) // dynamic reflection +#define STATE_CARD (1<<10) // tab +#define STATE_EXTEND (1<<11) // extended mode +#define STATE_SIMPLY (1<<12) // undecorated +#define STATE_FRAME (1<<13) // framework highlighting +#define STATE_WARNING (1<<14) // framework hatched yellow / black +#define STATE_VALUE (1<<15) // displays the value +#define STATE_RUN (1<<16) // running program + + + +class CControl +{ +public: + CControl(CInstanceManager* iMan); + virtual ~CControl(); + + virtual BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + + virtual BOOL EventProcess(const Event &event); + + virtual void SetPos(FPOINT pos); + virtual FPOINT RetPos(); + virtual void SetDim(FPOINT dim); + virtual FPOINT RetDim(); + virtual BOOL SetState(int state, BOOL bState); + virtual BOOL SetState(int state); + virtual BOOL ClearState(int state); + virtual BOOL TestState(int state); + virtual int RetState(); + virtual void SetIcon(int icon); + virtual int RetIcon(); + virtual void SetName(char* name, BOOL bTooltip=TRUE); + virtual char* RetName(); + virtual void SetJustif(int mode); + virtual int RetJustif(); + virtual void SetFontSize(float size); + virtual float RetFontSize(); + virtual void SetFontStretch(float stretch); + virtual float RetFontStretch(); + virtual void SetFontType(FontType font); + virtual FontType RetFontType(); + virtual BOOL SetTooltip(char* name); + virtual BOOL GetTooltip(FPOINT pos, char* name); + virtual void SetFocus(BOOL bFocus); + virtual BOOL RetFocus(); + + virtual EventMsg RetEventMsg(); + + virtual void Draw(); + +protected: + void GlintDelete(); + void GlintCreate(FPOINT ref, BOOL bLeft=TRUE, BOOL bUp=TRUE); + void GlintFrame(const Event &event); + void DrawPart(int icon, float zoom, float ex); + void DrawIcon(FPOINT pos, FPOINT dim, FPOINT uv1, FPOINT uv2, float ex=0.0f); + void DrawIcon(FPOINT pos, FPOINT dim, FPOINT uv1, FPOINT uv2, FPOINT corner, float ex); + void DrawWarning(FPOINT pos, FPOINT dim); + void DrawShadow(FPOINT pos, FPOINT dim, float deep=1.0f); + virtual BOOL Detect(FPOINT pos); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CEvent* m_event; + CRobotMain* m_main; + CParticule* m_particule; + CSound* m_sound; + + FPOINT m_pos; // corner upper / left + FPOINT m_dim; // dimensions + int m_icon; + EventMsg m_eventMsg; // message to send when clicking + int m_state; // states (STATE_ *) + float m_fontSize; // size of the button name + float m_fontStretch; // stretch of the font + FontType m_fontType; // type of font + int m_justif; // type of justification (-1,0,1) + char m_name[100]; // name of the button + char m_tooltip[100]; // name of tooltip + BOOL m_bFocus; + BOOL m_bCapture; + + BOOL m_bGlint; + FPOINT m_glintCorner1; + FPOINT m_glintCorner2; + float m_glintProgress; + FPOINT m_glintMouse; +}; + + +#endif //_CONTROL_H_ diff --git a/src/ui/displayinfo.cpp b/src/ui/displayinfo.cpp new file mode 100644 index 0000000..473a805 --- /dev/null +++ b/src/ui/displayinfo.cpp @@ -0,0 +1,1222 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// displayinfo.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "language.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "restext.h" +#include "math3d.h" +#include "robotmain.h" +#include "camera.h" +#include "object.h" +#include "motion.h" +#include "motiontoto.h" +#include "interface.h" +#include "button.h" +#include "slider.h" +#include "edit.h" +#include "group.h" +#include "window.h" +#include "particule.h" +#include "light.h" +#include "text.h" +#include "cbottoken.h" +#include "displayinfo.h" + + + + +// Object's constructor. + +CDisplayInfo::CDisplayInfo(CInstanceManager* iMan) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_STUDIO, this); + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); + m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); + m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); + + m_bInfoMaximized = TRUE; + m_bInfoMinimized = FALSE; + + m_infoFinalPos = m_infoActualPos = m_infoNormalPos = FPOINT(0.00f, 0.00f); + m_infoFinalDim = m_infoActualPos = m_infoNormalDim = FPOINT(1.00f, 1.00f); + + m_lightSuppl = -1; + m_toto = 0; +} + +// Object's destructor. + +CDisplayInfo::~CDisplayInfo() +{ + m_iMan->DeleteInstance(CLASS_STUDIO, this); +} + + +// Management of an event. + +BOOL CDisplayInfo::EventProcess(const Event &event) +{ + CWindow* pw; + CEdit* edit; + CSlider* slider; + CMotionToto* toto; + + if ( event.event == EVENT_FRAME ) + { + EventFrame(event); + HyperUpdate(); + } + + if ( event.event == EVENT_MOUSEMOVE ) + { + if ( m_toto != 0 ) + { + toto = (CMotionToto*)m_toto->RetMotion(); + if ( toto != 0 ) + { + toto->SetMousePos(event.pos); + } + } + } + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw != 0 ) + { + if ( event.event == pw->RetEventMsgClose() ) + { + Event newEvent = event; + newEvent.event = EVENT_OBJECT_INFOOK; + m_event->AddEvent(newEvent); + } + + if ( event.event == EVENT_SATCOM_HUSTON ) + { + ChangeIndexButton(SATCOM_HUSTON); + } + if ( event.event == EVENT_SATCOM_SAT ) + { + ChangeIndexButton(SATCOM_SAT); + } +//? if ( event.event == EVENT_SATCOM_OBJECT ) +//? { +//? ChangeIndexButton(SATCOM_OBJECT); +//? } + if ( event.event == EVENT_SATCOM_LOADING ) + { + ChangeIndexButton(SATCOM_LOADING); + } + if ( event.event == EVENT_SATCOM_PROG ) + { + ChangeIndexButton(SATCOM_PROG); + } + if ( event.event == EVENT_SATCOM_SOLUCE ) + { + ChangeIndexButton(SATCOM_SOLUCE); + } + + if ( event.event == EVENT_HYPER_HOME || + event.event == EVENT_HYPER_PREV || + event.event == EVENT_HYPER_NEXT ) + { + edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); + if ( edit != 0 ) + { + edit->HyperGo(event.event); + HyperUpdate(); + } + } + + if ( event.event == EVENT_HYPER_SIZE1 ) // size 1? + { + m_main->SetFontSize(9.0f); + slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); + if ( slider != 0 ) slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f); + ViewDisplayInfo(); + } + if ( event.event == EVENT_HYPER_SIZE2 ) // size 2? + { + m_main->SetFontSize(10.0f); + slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); + if ( slider != 0 ) slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f); + ViewDisplayInfo(); + } + if ( event.event == EVENT_HYPER_SIZE3 ) // size 3? + { + m_main->SetFontSize(12.0f); + slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); + if ( slider != 0 ) slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f); + ViewDisplayInfo(); + } + if ( event.event == EVENT_HYPER_SIZE4 ) // size 4? + { + m_main->SetFontSize(15.0f); + slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); + if ( slider != 0 ) slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f); + ViewDisplayInfo(); + } + + if ( event.event == EVENT_STUDIO_SIZE ) // size? + { + slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); + if ( slider == 0 ) return FALSE; + m_main->SetFontSize(9.0f+slider->RetVisibleValue()*6.0f); + ViewDisplayInfo(); + } + + if ( event.event == EVENT_HYPER_COPY ) // copy ? + { + edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); + if ( edit != 0 ) + { + edit->Copy(); + } + } + + if ( event.event == EVENT_LBUTTONDOWN || + event.event == EVENT_LBUTTONUP ) + { + UpdateCopyButton(); + } + + if ( event.event == EVENT_WINDOW4 ) // window moved? + { + m_infoNormalPos = m_infoActualPos = m_infoFinalPos = pw->RetPos(); + m_infoNormalDim = m_infoActualDim = m_infoFinalDim = pw->RetDim(); + AdjustDisplayInfo(m_infoActualPos, m_infoActualDim); + } + if ( event.event == pw->RetEventMsgReduce() ) + { + if ( m_bInfoMinimized ) + { + m_infoFinalPos = m_infoNormalPos; + m_infoFinalDim = m_infoNormalDim; + m_bInfoMinimized = FALSE; + m_bInfoMaximized = FALSE; + } + else + { + m_infoFinalPos.x = 0.00f; + m_infoFinalPos.y = -0.34f; + m_infoFinalDim.x = 1.00f; + m_infoFinalDim.y = 0.40f; + m_bInfoMinimized = TRUE; + m_bInfoMaximized = FALSE; + } +//? m_main->SetEditFull(m_bInfoMaximized); + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw != 0 ) + { + pw->SetMaximized(m_bInfoMaximized); + pw->SetMinimized(m_bInfoMinimized); + } + } + if ( event.event == pw->RetEventMsgFull() ) + { + if ( m_bInfoMaximized ) + { + m_infoFinalPos = m_infoNormalPos; + m_infoFinalDim = m_infoNormalDim; + m_bInfoMinimized = FALSE; + m_bInfoMaximized = FALSE; + } + else + { + m_infoFinalPos.x = 0.00f; + m_infoFinalPos.y = 0.00f; + m_infoFinalDim.x = 1.00f; + m_infoFinalDim.y = 1.00f; + m_bInfoMinimized = FALSE; + m_bInfoMaximized = TRUE; + } +//? m_main->SetEditFull(m_bInfoMaximized); + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw != 0 ) + { + pw->SetMaximized(m_bInfoMaximized); + pw->SetMinimized(m_bInfoMinimized); + } + } + } + return TRUE; +} + + +// The brain is changing by time. + +BOOL CDisplayInfo::EventFrame(const Event &event) +{ + float time; + + if ( m_infoFinalPos.x != m_infoActualPos.x || + m_infoFinalPos.y != m_infoActualPos.y || + m_infoFinalDim.x != m_infoActualDim.x || + m_infoFinalDim.y != m_infoActualDim.y ) + { + time = event.rTime*20.0f; + m_infoActualPos.x += (m_infoFinalPos.x-m_infoActualPos.x)*time; + m_infoActualPos.y += (m_infoFinalPos.y-m_infoActualPos.y)*time; + m_infoActualDim.x += (m_infoFinalDim.x-m_infoActualDim.x)*time; + m_infoActualDim.y += (m_infoFinalDim.y-m_infoActualDim.y)*time; + AdjustDisplayInfo(m_infoActualPos, m_infoActualDim); + } + + return TRUE; +} + + +// Updates the buttons for hyperlinks. + +void CDisplayInfo::HyperUpdate() +{ + CWindow* pw; + CEdit* edit; + CButton* button; + BOOL bEnable; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw == 0 ) return; + edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); + if ( edit == 0 ) return; + + button = (CButton*)pw->SearchControl(EVENT_HYPER_HOME); + if ( button != 0 ) + { + bEnable = edit->HyperTest(EVENT_HYPER_HOME); + button->SetState(STATE_ENABLE, bEnable); + } + + button = (CButton*)pw->SearchControl(EVENT_HYPER_PREV); + if ( button != 0 ) + { + bEnable = edit->HyperTest(EVENT_HYPER_PREV); + button->SetState(STATE_ENABLE, bEnable); + } + + button = (CButton*)pw->SearchControl(EVENT_HYPER_NEXT); + if ( button != 0 ) + { + bEnable = edit->HyperTest(EVENT_HYPER_NEXT); + button->SetState(STATE_ENABLE, bEnable); + } +} + + +// Beginning of the display of information. + +void CDisplayInfo::StartDisplayInfo(char *filename, int index, BOOL bSoluce) +{ + D3DLIGHT7 light; + FPOINT pos, dim; + CWindow* pw; + CEdit* edit; + CButton* button; + CSlider* slider; + CMotionToto* toto; + + m_index = index; + m_bSoluce = bSoluce; + +//? CreateObjectsFile(); + + m_bEditLock = m_main->RetEditLock(); + if ( m_bEditLock ) // edition running program? + { + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw != 0 ) + { + pw->ClearState(STATE_ENABLE); // CStudio inactive + } + } + + m_main->SetEditLock(TRUE, FALSE); + m_main->SetEditFull(FALSE); + m_bInitPause = m_engine->RetPause(); + m_engine->SetPause(TRUE); + m_infoCamera = m_camera->RetType(); + m_camera->SetType(CAMERA_INFO); + + pos = m_infoActualPos = m_infoFinalPos; + dim = m_infoActualDim = m_infoFinalDim; + pw = m_interface->CreateWindows(pos, dim, 4, EVENT_WINDOW4); + if ( pw == 0 ) return; +//? pw->SetClosable(TRUE); +//? GetResource(RES_TEXT, RT_DISINFO_TITLE, res); +//? pw->SetName(res); +//? pw->SetMinDim(FPOINT(0.56f, 0.40f)); +//? pw->SetMaximized(m_bInfoMaximized); +//? pw->SetMinimized(m_bInfoMinimized); +//? m_main->SetEditFull(m_bInfoMaximized); + + edit = pw->CreateEdit(pos, dim, 0, EVENT_EDIT1); + if ( edit == 0 ) return; + edit->SetState(STATE_SHADOW); + edit->SetMultiFont(TRUE); + edit->SetMaxChar(10000); + edit->SetFontType(FONT_COLOBOT); + edit->SetSoluceMode(bSoluce); + edit->ReadText(filename); + edit->HyperHome(filename); + edit->SetEditCap(FALSE); // just to see! + edit->SetHiliteCap(FALSE); + edit->SetFocus(TRUE); + + ViewDisplayInfo(); + + button = pw->CreateButton(pos, dim, 128+57, EVENT_SATCOM_HUSTON); + button->SetState(STATE_SHADOW); +#if _TEEN +#if !_ENGLISH + button = pw->CreateButton(pos, dim, 46, EVENT_SATCOM_SAT); +#endif +#else + button = pw->CreateButton(pos, dim, 128+58, EVENT_SATCOM_SAT); +#endif + button->SetState(STATE_SHADOW); +//? button = pw->CreateButton(pos, dim, 128+59, EVENT_SATCOM_OBJECT); +//? button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 53, EVENT_SATCOM_LOADING); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 128+60, EVENT_SATCOM_PROG); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 20, EVENT_SATCOM_SOLUCE); + button->SetState(STATE_SHADOW); + + pw->CreateGroup(pos, dim, 18, EVENT_LABEL1); // arrow > + pw->CreateGroup(pos, dim, 19, EVENT_LABEL2); // symbol SatCom + + button = pw->CreateButton(pos, dim, 55, EVENT_HYPER_PREV); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 48, EVENT_HYPER_NEXT); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 30, EVENT_HYPER_HOME); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 82, EVENT_HYPER_SIZE1); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 83, EVENT_HYPER_SIZE2); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 90, EVENT_HYPER_SIZE3); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 91, EVENT_HYPER_SIZE4); + button->SetState(STATE_SHADOW); + slider = pw->CreateSlider(pos, dim, 0, EVENT_STUDIO_SIZE); + slider->SetState(STATE_SHADOW); + slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f); + button = pw->CreateButton(pos, dim, 61, EVENT_HYPER_COPY); + button->SetState(STATE_SHADOW); + HyperUpdate(); + + button = pw->CreateButton(pos, dim, -1, EVENT_OBJECT_INFOOK); + button->SetState(STATE_SHADOW); + button->SetState(STATE_SIMPLY); + button->SetState(STATE_DEFAULT); + pw->CreateGroup(pos, dim, 21, EVENT_LABEL3); // symbol stand-by + + AdjustDisplayInfo(m_infoActualPos, m_infoActualDim); + UpdateIndexButton(); + + m_engine->SetDrawWorld(FALSE); // doesn't draw anything in the interface + m_engine->SetDrawFront(TRUE); // toto draws on the interface + m_particule->SetFrameUpdate(SH_WORLD, FALSE); // particles break into world + + m_toto = SearchToto(); + if ( m_toto != 0 ) + { + m_toto->SetDrawFront(TRUE); + + toto = (CMotionToto*)m_toto->RetMotion(); + if ( toto != 0 ) + { + toto->StartDisplayInfo(); + } + } + + ZeroMemory(&light, sizeof(light)); + light.dltType = D3DLIGHT_DIRECTIONAL; + light.dcvDiffuse.r = 1.0f; + light.dcvDiffuse.g = 1.0f; + light.dcvDiffuse.b = 1.0f; + light.dvDirection = D3DVECTOR(1.0f, 0.0f, 1.0f); + m_lightSuppl = m_light->CreateLight(); + m_light->SetLight(m_lightSuppl, light); + m_light->SetLightExcluType(m_lightSuppl, TYPETERRAIN); +} + +// Repositions all controls editing. + +void CDisplayInfo::AdjustDisplayInfo(FPOINT wpos, FPOINT wdim) +{ + CWindow* pw; + CEdit* edit; + CButton* button; + CSlider* slider; + CGroup* group; + FPOINT pos, dim; + + wpos.x = 50.0f/640.0f; + wpos.y = 30.0f/480.0f; + wdim.x = 540.0f/640.0f; + wdim.y = 420.0f/480.0f; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw != 0 ) + { + pw->SetPos(wpos); + pw->SetDim(wdim); + wdim = pw->RetDim(); + } + + pos.x = (50.0f+10.0f)/640.0f; + pos.y = (30.0f+10.0f+24.0f+10.0f+324.0f-48.0f)/480.0f; + dim.x = 48.0f/640.0f; + dim.y = 48.0f/480.0f; + button = (CButton*)pw->SearchControl(EVENT_SATCOM_HUSTON); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.y -= (48.0f+4.0f)/480.0f; + button = (CButton*)pw->SearchControl(EVENT_SATCOM_SAT); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } +//? pos.y -= (48.0f+4.0f)/480.0f; +//? button = (CButton*)pw->SearchControl(EVENT_SATCOM_OBJECT); +//? if ( button != 0 ) +//? { +//? button->SetPos(pos); +//? button->SetDim(dim); +//? } + pos.y -= (48.0f+4.0f)/480.0f; + button = (CButton*)pw->SearchControl(EVENT_SATCOM_LOADING); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.y -= (48.0f+4.0f)/480.0f; + button = (CButton*)pw->SearchControl(EVENT_SATCOM_PROG); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.y -= (48.0f+4.0f)/480.0f; + button = (CButton*)pw->SearchControl(EVENT_SATCOM_SOLUCE); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + + pos.x = (50.0f+10.0f+5.0f)/640.0f; + pos.y = (30.0f+10.0f+4.0f)/480.0f; + dim.x = (48.0f-10.0f)/640.0f; + dim.y = 24.0f/480.0f; + button = (CButton*)pw->SearchControl(EVENT_OBJECT_INFOOK); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + + pos.x = (50.0f+10.0f+48.0f+10.0f)/640.0f; + pos.y = (30.0f+10.0f)/480.0f; + dim.x = 462.0f/640.0f; + dim.y = 358.0f/480.0f; + edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); + if ( edit != 0 ) + { + edit->SetPos(pos); + edit->SetDim(dim); + } + + pos.x = (50.0f+10.0f+48.0f+10.0f)/640.0f; + pos.y = (30.0f+10.0f+358.0f+10.0f)/480.0f; + dim.x = 32.0f/640.0f; + dim.y = 32.0f/480.0f; + button = (CButton*)pw->SearchControl(EVENT_HYPER_PREV); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x += 35.0f/640.0f; + button = (CButton*)pw->SearchControl(EVENT_HYPER_NEXT); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x += 35.0f/640.0f; + button = (CButton*)pw->SearchControl(EVENT_HYPER_HOME); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + + pos.x += 50.0f/640.0f; + button = (CButton*)pw->SearchControl(EVENT_HYPER_SIZE1); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x += 35.0f/640.0f; + button = (CButton*)pw->SearchControl(EVENT_HYPER_SIZE2); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x += 35.0f/640.0f; + button = (CButton*)pw->SearchControl(EVENT_HYPER_SIZE3); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x += 35.0f/640.0f; + button = (CButton*)pw->SearchControl(EVENT_HYPER_SIZE4); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x += 35.0f/640.0f; + dim.x = 18.0f/640.0f; + slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); + if ( slider != 0 ) + { + slider->SetPos(pos); + slider->SetDim(dim); + } + pos.x += 50.0f/640.0f; + dim.x = 32.0f/640.0f; + button = (CButton*)pw->SearchControl(EVENT_HYPER_COPY); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + + pos.x = (50.0f+10.0f)/640.0f; + pos.y = (30.0f+10.0f+24.0f+10.0f+324.0f+6.0f)/480.0f; + dim.x = 48.0f/640.0f; + dim.y = 40.0f/480.0f; + group = (CGroup*)pw->SearchControl(EVENT_LABEL2); // symbol SatCom + if ( group != 0 ) + { + group->SetPos(pos); + group->SetDim(dim); + } + + pos.x = (50.0f+10.0f+14.0f)/640.0f; + pos.y = (30.0f+10.0f+6.0f)/480.0f; + dim.x = 20.0f/640.0f; + dim.y = 20.0f/480.0f; + group = (CGroup*)pw->SearchControl(EVENT_LABEL3); // symbol stand-by + if ( group != 0 ) + { + group->SetPos(pos); + group->SetDim(dim); + } +} + +// Change the index button. + +void CDisplayInfo::ChangeIndexButton(int index) +{ + CWindow* pw; + CEdit* edit; + char* filename; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw == 0 ) return; + + if ( m_index != -1 ) + { + m_main->SetDisplayInfoPosition(m_index, RetPosition()); + } + m_index = index; + + edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); + if ( edit != 0 ) + { + filename = m_main->RetDisplayInfoName(m_index); + edit->ReadText(filename); + edit->HyperHome(filename); + SetPosition(m_main->RetDisplayInfoPosition(m_index)); + } + + UpdateIndexButton(); +} + +// Adapts the index buttons. + +void CDisplayInfo::UpdateIndexButton() +{ + CWindow* pw; + CButton* button; + CGroup* group; + CEdit* edit; + FPOINT pos, dim; + char* filename; + char* loading; + + static int table[SATCOM_MAX] = + { + 0, // SATCOM_HUSTON + 1, // SATCOM_SAT + -1, // SATCOM_OBJECT + 2, // SATCOM_LOADING + 3, // SATCOM_PROG + 4, // SATCOM_SOLUCE + }; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw == 0 ) return; + + button = (CButton*)pw->SearchControl(EVENT_SATCOM_HUSTON); + if ( button != 0 ) + { + button->SetState(STATE_CHECK, m_index==SATCOM_HUSTON); + filename = m_main->RetDisplayInfoName(SATCOM_HUSTON); + button->SetState(STATE_VISIBLE, filename[0]!=0); + } + + button = (CButton*)pw->SearchControl(EVENT_SATCOM_SAT); + if ( button != 0 ) + { + button->SetState(STATE_CHECK, m_index==SATCOM_SAT); + filename = m_main->RetDisplayInfoName(SATCOM_SAT); + button->SetState(STATE_VISIBLE, filename[0]!=0); + } + +//? button = (CButton*)pw->SearchControl(EVENT_SATCOM_OBJECT); +//? if ( button != 0 ) +//? { +//? button->SetState(STATE_CHECK, m_index==SATCOM_OBJECT); +//? filename = m_main->RetDisplayInfoName(SATCOM_OBJECT); +//? button->SetState(STATE_VISIBLE, filename[0]!=0); +//? } + + loading = 0; + button = (CButton*)pw->SearchControl(EVENT_SATCOM_LOADING); + if ( button != 0 ) + { + button->SetState(STATE_CHECK, m_index==SATCOM_LOADING); + loading = m_main->RetDisplayInfoName(SATCOM_LOADING); + button->SetState(STATE_VISIBLE, loading[0]!=0); + } + + button = (CButton*)pw->SearchControl(EVENT_SATCOM_PROG); + if ( button != 0 ) + { + button->SetState(STATE_CHECK, m_index==SATCOM_PROG); + filename = m_main->RetDisplayInfoName(SATCOM_PROG); + button->SetState(STATE_VISIBLE, filename[0]!=0 && (m_index==SATCOM_LOADING||m_index==SATCOM_PROG||(loading!=0&&loading[0]==0))); + } + + button = (CButton*)pw->SearchControl(EVENT_SATCOM_SOLUCE); + if ( button != 0 ) + { + button->SetState(STATE_CHECK, m_index==SATCOM_SOLUCE); + filename = m_main->RetDisplayInfoName(SATCOM_SOLUCE); + button->SetState(STATE_VISIBLE, filename[0]!=0 && m_bSoluce); + } + + group = (CGroup*)pw->SearchControl(EVENT_LABEL1); + if ( group != 0 ) + { + if ( m_index == -1 ) + { + group->ClearState(STATE_VISIBLE); + } + else + { + group->SetState(STATE_VISIBLE); + + pos.x = (50.0f+10.0f+48.0f-3.0f)/640.0f; + pos.y = (30.0f+10.0f+24.0f+10.0f+324.0f-48.0f-1.0f)/480.0f; + pos.y -= (48.0f+4.0f)/480.0f*table[m_index]; + dim.x = 15.0f/640.0f; + dim.y = 48.0f/480.0f; + group->SetPos(pos); + group->SetDim(dim); + } + } + +#if 0 + button = (CButton*)pw->SearchControl(EVENT_HYPER_COPY); + if ( button != 0 ) + { + button->SetState(STATE_VISIBLE, m_index==SATCOM_LOADING); + } +#endif + + edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); + if ( edit != 0 ) + { +//? edit->SetHiliteCap(m_index==SATCOM_LOADING); + edit->SetHiliteCap(TRUE); + } + + UpdateCopyButton(); +} + +// Adjusts the copy button. + +void CDisplayInfo::UpdateCopyButton() +{ + CWindow* pw; + CButton* button; + CEdit* edit; + int c1, c2; + +//? if ( m_index != SATCOM_LOADING ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw == 0 ) return; + + button = (CButton*)pw->SearchControl(EVENT_HYPER_COPY); + if ( button == 0 ) return; + + edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); + if ( edit == 0 ) return; + + edit->GetCursor(c1, c2); + button->SetState(STATE_ENABLE, c1!=c2); + +} + +// End of the display of information. + +void CDisplayInfo::StopDisplayInfo() +{ + CWindow* pw; + CMotionToto* toto; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw == 0 ) return; + + m_interface->DeleteControl(EVENT_WINDOW4); + + if ( m_bEditLock ) // editing running program? + { + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw != 0 ) + { + pw->SetState(STATE_ENABLE); // CStudio operating + } + } + else + { + if ( !m_bInitPause ) m_engine->SetPause(FALSE); + m_main->SetEditLock(FALSE, FALSE); + } + m_camera->SetType(m_infoCamera); + + m_engine->SetDrawWorld(TRUE); // draws all on the interface + m_engine->SetDrawFront(FALSE); // draws nothing on the interface + m_particule->SetFrameUpdate(SH_WORLD, TRUE); + m_particule->FlushParticule(SH_FRONT); + m_particule->FlushParticule(SH_INTERFACE); + + if ( m_toto != 0 ) + { + toto = (CMotionToto*)m_toto->RetMotion(); + if ( toto != 0 ) + { + toto->StopDisplayInfo(); + } + } + + m_light->DeleteLight(m_lightSuppl); + m_lightSuppl = -1; +} + + +// Specifies the position. + +void CDisplayInfo::SetPosition(int pos) +{ + CWindow* pw; + CEdit* edit; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw == 0 ) return; + + edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); + if ( edit == 0 ) return; + + edit->SetFirstLine(pos); +} + +// Returns the position. + +int CDisplayInfo::RetPosition() +{ + CWindow* pw; + CEdit* edit; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw == 0 ) return 0; + + edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); + if ( edit == 0 ) return 0; + + return edit->RetFirstLine(); +} + + + +// Changing the size of the display of information. + +void CDisplayInfo::ViewDisplayInfo() +{ + CWindow* pw; + CEdit* edit; + POINT dim; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw == 0 ) return; + + edit = (CEdit*)pw->SearchControl(EVENT_EDIT1); + if ( edit == 0 ) return; + + dim = m_engine->RetDim(); + edit->SetFontSize(m_main->RetFontSize()/(dim.x/640.0f)); +} + +// Returns the object human. + +CObject* CDisplayInfo::SearchToto() +{ + ObjectType type; + CObject* pObj; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type == OBJECT_TOTO ) + { + return pObj; + } + } + return 0; +} + + +// Creating the list of objects. + +typedef struct +{ + int total; + ObjectType type; +} +ObjectList; + +void ObjectAdd(ObjectList list[], ObjectType type) +{ + int i; + + for ( i=0 ; i<200 ; i++ ) + { + if ( list[i].total == 0 ) + { + list[i].total ++; + list[i].type = type; + list[i+1].total = 0; + return; + } + if ( list[i].type == type ) + { + list[i].total ++; + return; + } + } +} + +void ObjectWrite(FILE* file, ObjectList list[], int i) +{ + char line[100]; + char res[100]; + char* p; + + if ( list[i].total < 10 ) + { + sprintf(line, "\\c; %dx \\n;\\l;", list[i].total); + } + else + { + sprintf(line, "\\c;%dx \\n;\\l;", list[i].total); + } + + GetResource(RES_OBJECT, list[i].type, res); + if ( res[0] == 0 ) return; + strcat(line, res); + + strcat(line, "\\u "); + p = RetHelpFilename(list[i].type); + if ( p[0] == 0 ) return; + strcat(line, p+5); // skip "help\" + p = strstr(line, ".txt"); + if ( p != 0 ) *p = 0; + strcat(line, ";\n"); + fputs(line, file); +} + +// Creates the file containing the list of objects. + +void CDisplayInfo::CreateObjectsFile() +{ + FILE* file; + CObject* pObj; + ObjectType type; + ObjectList list[200]; + char line[100]; + int i; + BOOL bRadar, bAtLeast; + + file = fopen("help\\objects.txt", "w"); + if ( file == 0 ) return; + + list[0].total = 0; // empty list + bRadar = FALSE; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetActif() ) continue; + if ( !pObj->RetSelectable() ) continue; + if ( pObj->RetProxyActivate() ) continue; + + type = pObj->RetType(); + if ( type == OBJECT_NULL ) continue; + if ( type == OBJECT_FIX ) continue; + + ObjectAdd(list, type); + + if ( type == OBJECT_RADAR ) bRadar = TRUE; + } + + if ( bRadar ) + { + GetResource(RES_TEXT, RT_SATCOM_LIST, line); + fputs(line, file); + bAtLeast = FALSE; + for ( i=0 ; i<200 ; i++ ) + { + if ( list[i].total == 0 ) break; // end of the list? + + if ( list[i].type == OBJECT_BASE || + list[i].type == OBJECT_HUMAN ) + { + ObjectWrite(file, list, i); + bAtLeast = TRUE; + } + } + if ( !bAtLeast ) + { + GetResource(RES_TEXT, RT_SATCOM_NULL, line); + fputs(line, file); + } + + strcpy(line, "\n"); + fputs(line, file); + GetResource(RES_TEXT, RT_SATCOM_BOT, line); + fputs(line, file); + bAtLeast = FALSE; + for ( i=0 ; i<200 ; i++ ) + { + if ( list[i].total == 0 ) break; // end of the list? + + if ( list[i].type == OBJECT_MOBILEwt || + list[i].type == OBJECT_MOBILEtt || + list[i].type == OBJECT_MOBILEft || + list[i].type == OBJECT_MOBILEit || + list[i].type == OBJECT_MOBILEwa || + list[i].type == OBJECT_MOBILEta || + list[i].type == OBJECT_MOBILEfa || + list[i].type == OBJECT_MOBILEia || + list[i].type == OBJECT_MOBILEwc || + list[i].type == OBJECT_MOBILEtc || + list[i].type == OBJECT_MOBILEfc || + list[i].type == OBJECT_MOBILEic || + list[i].type == OBJECT_MOBILEwi || + list[i].type == OBJECT_MOBILEti || + list[i].type == OBJECT_MOBILEfi || + list[i].type == OBJECT_MOBILEii || + list[i].type == OBJECT_MOBILEws || + list[i].type == OBJECT_MOBILEts || + list[i].type == OBJECT_MOBILEfs || + list[i].type == OBJECT_MOBILEis || + list[i].type == OBJECT_MOBILErt || + list[i].type == OBJECT_MOBILErc || + list[i].type == OBJECT_MOBILErr || + list[i].type == OBJECT_MOBILErs || + list[i].type == OBJECT_MOBILEsa || + list[i].type == OBJECT_MOBILEtg || + list[i].type == OBJECT_MOBILEdr ) + { + ObjectWrite(file, list, i); + bAtLeast = TRUE; + } + } + if ( !bAtLeast ) + { + GetResource(RES_TEXT, RT_SATCOM_NULL, line); + fputs(line, file); + } + + strcpy(line, "\n"); + fputs(line, file); + GetResource(RES_TEXT, RT_SATCOM_BUILDING, line); + fputs(line, file); + bAtLeast = FALSE; + for ( i=0 ; i<200 ; i++ ) + { + if ( list[i].total == 0 ) break; // end of the list? + + if ( list[i].type == OBJECT_DERRICK || + list[i].type == OBJECT_FACTORY || + list[i].type == OBJECT_STATION || + list[i].type == OBJECT_CONVERT || + list[i].type == OBJECT_REPAIR || + list[i].type == OBJECT_DESTROYER|| + list[i].type == OBJECT_TOWER || + list[i].type == OBJECT_NEST || + list[i].type == OBJECT_RESEARCH || + list[i].type == OBJECT_RADAR || + list[i].type == OBJECT_ENERGY || + list[i].type == OBJECT_LABO || + list[i].type == OBJECT_NUCLEAR || + list[i].type == OBJECT_START || + list[i].type == OBJECT_END || + list[i].type == OBJECT_INFO || + list[i].type == OBJECT_PARA || + list[i].type == OBJECT_TARGET1 || + list[i].type == OBJECT_TARGET2 || + list[i].type == OBJECT_SAFE || + list[i].type == OBJECT_HUSTON ) + { + ObjectWrite(file, list, i); + bAtLeast = TRUE; + } + } + if ( !bAtLeast ) + { + GetResource(RES_TEXT, RT_SATCOM_NULL, line); + fputs(line, file); + } + + strcpy(line, "\n"); + fputs(line, file); + GetResource(RES_TEXT, RT_SATCOM_FRET, line); + fputs(line, file); + bAtLeast = FALSE; + for ( i=0 ; i<200 ; i++ ) + { + if ( list[i].total == 0 ) break; // end of the list? + + if ( list[i].type == OBJECT_STONE || + list[i].type == OBJECT_URANIUM || + list[i].type == OBJECT_METAL || + list[i].type == OBJECT_POWER || + list[i].type == OBJECT_ATOMIC || + list[i].type == OBJECT_BULLET || + list[i].type == OBJECT_BBOX || + list[i].type == OBJECT_TNT ) + { + ObjectWrite(file, list, i); + bAtLeast = TRUE; + } + } + if ( !bAtLeast ) + { + GetResource(RES_TEXT, RT_SATCOM_NULL, line); + fputs(line, file); + } + + strcpy(line, "\n"); + fputs(line, file); + GetResource(RES_TEXT, RT_SATCOM_ALIEN, line); + fputs(line, file); + bAtLeast = FALSE; + for ( i=0 ; i<200 ; i++ ) + { + if ( list[i].total == 0 ) break; // end of the list? + + if ( list[i].type == OBJECT_MOTHER || + list[i].type == OBJECT_ANT || + list[i].type == OBJECT_BEE || + list[i].type == OBJECT_WORM || + list[i].type == OBJECT_SPIDER ) + { + ObjectWrite(file, list, i); + bAtLeast = TRUE; + } + } + if ( !bAtLeast ) + { + GetResource(RES_TEXT, RT_SATCOM_NULL, line); + fputs(line, file); + } + } + else + { + GetResource(RES_TEXT, RT_SATCOM_ERROR1, line); + fputs(line, file); + GetResource(RES_TEXT, RT_SATCOM_ERROR2, line); + fputs(line, file); + } + + strcpy(line, "\n"); + fputs(line, file); + + fclose(file); +} + + diff --git a/src/ui/displayinfo.h b/src/ui/displayinfo.h new file mode 100644 index 0000000..61b87ee --- /dev/null +++ b/src/ui/displayinfo.h @@ -0,0 +1,92 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// displayinfo.h + +#ifndef _DISPLAYINFO_H_ +#define _DISPLAYINFO_H_ + + +#include "struct.h" +#include "camera.h" + + +class CInstanceManager; +class CD3DEngine; +class CEvent; +class CRobotMain; +class CCamera; +class CInterface; +class CObject; +class CParticule; +class CLight; + + +class CDisplayInfo +{ +public: + CDisplayInfo(CInstanceManager* iMan); + ~CDisplayInfo(); + + BOOL EventProcess(const Event &event); + + void StartDisplayInfo(char *filename, int index, BOOL bSoluce); + void StopDisplayInfo(); + + void SetPosition(int pos); + int RetPosition(); + +protected: + BOOL EventFrame(const Event &event); + void HyperUpdate(); + void AdjustDisplayInfo(FPOINT wpos, FPOINT wdim); + void ChangeIndexButton(int index); + void UpdateIndexButton(); + void UpdateCopyButton(); + void ViewDisplayInfo(); + CObject* SearchToto(); + void CreateObjectsFile(); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CEvent* m_event; + CRobotMain* m_main; + CCamera* m_camera; + CInterface* m_interface; + CParticule* m_particule; + CLight* m_light; + + BOOL m_bInfoMaximized; + BOOL m_bInfoMinimized; + + int m_index; + CameraType m_infoCamera; + FPOINT m_infoNormalPos; + FPOINT m_infoNormalDim; + FPOINT m_infoActualPos; + FPOINT m_infoActualDim; + FPOINT m_infoFinalPos; + FPOINT m_infoFinalDim; + int m_lightSuppl; + BOOL m_bEditLock; + BOOL m_bInitPause; + BOOL m_bSoluce; + CObject* m_toto; +}; + + +#endif //_DISPLAYINFO_H_ diff --git a/src/ui/displaytext.cpp b/src/ui/displaytext.cpp new file mode 100644 index 0000000..a56bf9f --- /dev/null +++ b/src/ui/displaytext.cpp @@ -0,0 +1,615 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// displaytext.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "event.h" +#include "misc.h" +#include "restext.h" +#include "iman.h" +#include "object.h" +#include "motion.h" +#include "motiontoto.h" +#include "interface.h" +#include "button.h" +#include "label.h" +#include "window.h" +#include "group.h" +#include "text.h" +#include "sound.h" +#include "displaytext.h" + + + +#define FONTSIZE 12.0f + + + +// Object's constructor. + +CDisplayText::CDisplayText(CInstanceManager* iMan) +{ + int i; + + m_iMan = iMan; + m_iMan->AddInstance(CLASS_DISPLAYTEXT, this); + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + + for ( i=0 ; iDeleteInstance(CLASS_DISPLAYTEXT, this); +} + + +// Destroys the object. + +void CDisplayText::DeleteObject() +{ + m_interface->DeleteControl(EVENT_WINDOW2); +} + + +// Management of an event. + +BOOL CDisplayText::EventProcess(const Event &event) +{ + int i; + + if ( m_engine->RetPause() ) return TRUE; + + if ( event.event == EVENT_FRAME ) + { + for ( i=0 ; i 0.0f ) break; + if ( !ClearLastText() ) break; + } + } + + return TRUE; +} + + +// Displays an error. + +void CDisplayText::DisplayError(Error err, CObject* pObj, float time) +{ + D3DVECTOR pos; + float h, d; + + if ( pObj == 0 ) return; + + pos = pObj->RetPosition(0); + h = RetIdealHeight(pObj); + d = RetIdealDist(pObj); + DisplayError(err, pos, h, d, time); +} + +// Displays an error. + +void CDisplayText::DisplayError(Error err, D3DVECTOR goal, float height, + float dist, float time) +{ + TextType type; + char text[100]; + + if ( err == ERR_OK ) return; + +#if 0 + type = TT_INFO; + if ( err < INFO_FIRST ) + { + type = TT_ERROR; + } + if ( err == ERR_TOWER_POWER || + err == ERR_RESEARCH_POWER || + err == ERR_ENERGY_EMPTY || + err == ERR_LABO_NULL || + err == ERR_NUCLEAR_EMPTY || + err == ERR_CONVERT_EMPTY ) + { + type = TT_WARNING; + } +#else + type = TT_WARNING; + if ( err >= INFO_FIRST ) + { + type = TT_INFO; + } + if ( err == ERR_BAT_VIRUS || + err == ERR_VEH_VIRUS || + err == ERR_DELETEMOBILE || + err == ERR_DELETEBUILDING || + err == ERR_TOOMANY || + err == INFO_LOST ) + { + type = TT_ERROR; + } +#endif + + GetResource(RES_ERR, err, text); + DisplayText(text, goal, height, dist, time, type); +} + +// Displays text. + +void CDisplayText::DisplayText(char *text, CObject* pObj, + float time, TextType type) +{ + D3DVECTOR pos; + float h, d; + + if ( pObj == 0 ) return; + + pos = pObj->RetPosition(0); + h = RetIdealHeight(pObj); + d = RetIdealDist(pObj); + DisplayText(text, pos, h, d, time, type); +} + +// Displays text. + +void CDisplayText::DisplayText(char *text, D3DVECTOR goal, float height, + float dist, float time, TextType type) +{ + CObject* toto; + CMotion* motion; + CWindow* pw; + CButton* button; + CGroup* group; + CLabel* label; + FPOINT pos, ppos, dim; + Sound sound; + float hLine, hBox; + int nLine, icon, i; + + if ( !m_bEnable ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); + if ( pw == 0 ) + { + pos.x = 0.0f; + pos.y = 0.0f; + dim.x = 0.0f; + dim.y = 0.0f; + pw = m_interface->CreateWindows(pos, dim, 10, EVENT_WINDOW2); + } + + hBox = 0.045f; + hLine = m_engine->RetText()->RetHeight(FONTSIZE, FONT_COLOBOT); + + nLine = 0; + for ( i=0 ; iSearchControl(EventMsg(EVENT_DT_GROUP0+i)); + if ( group == 0 ) break; + nLine ++; + } + + if ( nLine == MAXDTLINE ) + { + ClearLastText(); + nLine --; + } + + pos.x = 0.10f; + pos.y = 0.92f-hBox-hBox*nLine; + dim.x = 0.80f; + dim.y = hBox; + + icon = 1; // yellow + if ( type == TT_ERROR ) icon = 9; // red + if ( type == TT_WARNING ) icon = 10; // blue + if ( type == TT_INFO ) icon = 8; // green + if ( type == TT_MESSAGE ) icon = 11; // yellow + pw->CreateGroup(pos, dim, icon, EventMsg(EVENT_DT_GROUP0+nLine)); + + pw->SetTrashEvent(FALSE); + + ppos = pos; + ppos.y -= hLine/2.0f; + label = pw->CreateLabel(ppos, dim, -1, EventMsg(EVENT_DT_LABEL0+nLine), text); + if ( label != 0 ) + { + label->SetFontSize(FONTSIZE); + } + + dim.x = dim.y*0.75f; + pos.x -= dim.x; + button = pw->CreateButton(pos, dim, 14, EventMsg(EVENT_DT_VISIT0+nLine)); + + if ( goal.x == 0.0f && + goal.y == 0.0f && + goal.z == 0.0f ) + { + button->ClearState(STATE_ENABLE); + } + + m_bExist[nLine] = TRUE; + m_visitGoal[nLine] = goal; + m_visitDist[nLine] = dist; + m_visitHeight[nLine] = height; + m_time[nLine] = time*m_delayFactor; + + toto = SearchToto(); + if ( toto != 0 ) + { + motion = toto->RetMotion(); + if ( motion != 0 ) + { + if ( type == TT_ERROR ) + { + motion->SetAction(MT_ERROR, 4.0f); + } + if ( type == TT_WARNING ) + { + motion->SetAction(MT_WARNING, 4.0f); + } + if ( type == TT_INFO ) + { + motion->SetAction(MT_INFO, 4.0f); + } + if ( type == TT_MESSAGE ) + { + motion->SetAction(MT_MESSAGE, 4.0f); + } + } + } + + if ( m_bHide ) + { + HideText(m_bHide); // hide all + } + else + { + sound = SOUND_CLICK; + if ( type == TT_ERROR ) sound = SOUND_ERROR; + if ( type == TT_WARNING ) sound = SOUND_WARNING; + if ( type == TT_INFO ) sound = SOUND_INFO; + if ( type == TT_MESSAGE ) sound = SOUND_MESSAGE; + + if ( sound != SOUND_CLICK ) + { + m_sound->Play(sound); + } + } +} + +// Clears all text. + +void CDisplayText::ClearText() +{ + CWindow* pw; + int i; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); + + for ( i=0 ; iDeleteControl(EventMsg(EVENT_DT_GROUP0+i)); + pw->DeleteControl(EventMsg(EVENT_DT_LABEL0+i)); + pw->DeleteControl(EventMsg(EVENT_DT_VISIT0+i)); + } + m_bExist[i] = FALSE; + m_visitGoal[i] = D3DVECTOR(0.0f, 0.0f, 0.0f); + m_visitDist[i] = 0.0f; + m_visitHeight[i] = 0.0f; + m_time[i] = 0.0f; + } +} + +// Hides or shows all texts. + +void CDisplayText::HideText(BOOL bHide) +{ + CWindow* pw; + CGroup* pg; + CLabel* pl; + CButton* pb; + int i; + + m_bHide = bHide; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); + if ( pw == 0 ) return; + + for ( i=0 ; iSearchControl(EventMsg(EVENT_DT_GROUP0+i)); + if ( pg != 0 ) + { + pg->SetState(STATE_VISIBLE, !bHide); + } + + pl = (CLabel* )pw->SearchControl(EventMsg(EVENT_DT_LABEL0+i)); + if ( pl != 0 ) + { + pl->SetState(STATE_VISIBLE, !bHide); + } + + pb = (CButton*)pw->SearchControl(EventMsg(EVENT_DT_VISIT0+i)); + if ( pb != 0 ) + { + pb->SetState(STATE_VISIBLE, !bHide); + } + } +} + +// Removes the last text (top of the list). + +BOOL CDisplayText::ClearLastText() +{ + CWindow *pw; + CButton *pb1, *pb2; + CGroup *pg1, *pg2; + CLabel *pl1, *pl2; + int i; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); + if ( pw == 0 ) return FALSE; + + pb2 = (CButton*)pw->SearchControl(EVENT_DT_VISIT0); + if ( pb2 == 0 ) return FALSE; // same not of first-line + pg2 = (CGroup*)pw->SearchControl(EVENT_DT_GROUP0); + if ( pg2 == 0 ) return FALSE; + pl2 = (CLabel*)pw->SearchControl(EVENT_DT_LABEL0); + if ( pl2 == 0 ) return FALSE; + + for ( i=0 ; iSearchControl(EventMsg(EVENT_DT_VISIT0+i+1)); + if ( pb2 == 0 ) break; + + pg2 = (CGroup*)pw->SearchControl(EventMsg(EVENT_DT_GROUP0+i+1)); + if ( pg2 == 0 ) break; + + pl2 = (CLabel*)pw->SearchControl(EventMsg(EVENT_DT_LABEL0+i+1)); + if ( pl2 == 0 ) break; + + pb1->SetState(STATE_ENABLE, pb2->TestState(STATE_ENABLE)); + pg1->SetIcon(pg2->RetIcon()); + pl1->SetName(pl2->RetName()); + + m_time[i] = m_time[i+1]; + m_visitGoal[i] = m_visitGoal[i+1]; + m_visitDist[i] = m_visitDist[i+1]; + m_visitHeight[i] = m_visitHeight[i+1]; // shift + } + + pw->DeleteControl(EventMsg(EVENT_DT_VISIT0+i)); + pw->DeleteControl(EventMsg(EVENT_DT_GROUP0+i)); + pw->DeleteControl(EventMsg(EVENT_DT_LABEL0+i)); + m_bExist[i] = FALSE; + return TRUE; +} + + +// Specifies the factor of time. + +void CDisplayText::SetDelay(float factor) +{ + m_delayFactor = factor; +} + + +// Enables the display of text. + +void CDisplayText::SetEnable(BOOL bEnable) +{ + m_bEnable = bEnable; +} + + +// Returns the goal during a visit. + +D3DVECTOR CDisplayText::RetVisitGoal(EventMsg event) +{ + int i; + + i = event-EVENT_DT_VISIT0; + if ( i < 0 || i >= MAXDTLINE ) return D3DVECTOR(0.0f, 0.0f, 0.0f); + return m_visitGoal[i]; +} + +// Returns the distance during a visit. + +float CDisplayText::RetVisitDist(EventMsg event) +{ + int i; + + i = event-EVENT_DT_VISIT0; + if ( i < 0 || i >= MAXDTLINE ) return 0.0f; + return m_visitDist[i]; +} + +// Returns the height on a visit. + +float CDisplayText::RetVisitHeight(EventMsg event) +{ + int i; + + i = event-EVENT_DT_VISIT0; + if ( i < 0 || i >= MAXDTLINE ) return 0.0f; + return m_visitHeight[i]; +} + + +// Ranges from ideal visit for a given object. + +float CDisplayText::RetIdealDist(CObject* pObj) +{ + ObjectType type; + + if ( pObj == 0 ) return 40.0f; + + type = pObj->RetType(); + if ( type == OBJECT_PORTICO ) return 200.0f; + if ( type == OBJECT_BASE ) return 200.0f; + if ( type == OBJECT_NUCLEAR ) return 100.0f; + if ( type == OBJECT_PARA ) return 100.0f; + if ( type == OBJECT_SAFE ) return 100.0f; + if ( type == OBJECT_TOWER ) return 80.0f; + + return 60.0f; +} + +// Returns the height of ideal visit for a given object. + +float CDisplayText::RetIdealHeight(CObject* pObj) +{ + ObjectType type; + + if ( pObj == 0 ) return 5.0f; + + type = pObj->RetType(); + if ( type == OBJECT_DERRICK ) return 35.0f; + if ( type == OBJECT_FACTORY ) return 22.0f; + if ( type == OBJECT_REPAIR ) return 30.0f; + if ( type == OBJECT_DESTROYER) return 30.0f; + if ( type == OBJECT_STATION ) return 13.0f; + if ( type == OBJECT_CONVERT ) return 20.0f; + if ( type == OBJECT_TOWER ) return 30.0f; + if ( type == OBJECT_RESEARCH ) return 22.0f; + if ( type == OBJECT_RADAR ) return 19.0f; + if ( type == OBJECT_INFO ) return 19.0f; + if ( type == OBJECT_ENERGY ) return 20.0f; + if ( type == OBJECT_LABO ) return 16.0f; + if ( type == OBJECT_NUCLEAR ) return 40.0f; + if ( type == OBJECT_PARA ) return 40.0f; + if ( type == OBJECT_SAFE ) return 20.0f; + + return 15.0f; +} + + +// Removes all visits. + +void CDisplayText::ClearVisit() +{ + CWindow* pw; + CButton* pb; + int i; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); + if ( pw == 0 ) return; + + for ( i=0 ; iSearchControl(EventMsg(EVENT_DT_VISIT0+i)); + if ( pb == 0 ) break; + pb->SetIcon(14); // eyes + } +} + +// Puts a button in "visit". + +void CDisplayText::SetVisit(EventMsg event) +{ + CWindow* pw; + CButton* pb; + int i; + + i = event-EVENT_DT_VISIT0; + if ( i < 0 || i >= MAXDTLINE ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); + if ( pw == 0 ) return; + pb = (CButton*)pw->SearchControl(EventMsg(EVENT_DT_VISIT0+i)); + if ( pb == 0 ) return; + pb->SetIcon(48); // > +} + +// Indicates whether a button is set to "visit". + +BOOL CDisplayText::IsVisit(EventMsg event) +{ + CWindow* pw; + CButton* pb; + int i; + + i = event-EVENT_DT_VISIT0; + if ( i < 0 || i >= MAXDTLINE ) return FALSE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); + if ( pw == 0 ) return FALSE; + pb = (CButton*)pw->SearchControl(EventMsg(EVENT_DT_VISIT0+i)); + if ( pb == 0 ) return FALSE; + return (pb->RetIcon() == 48); // > ? +} + + +// Returns the object toto. + +CObject* CDisplayText::SearchToto() +{ + ObjectType type; + CObject* pObj; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type == OBJECT_TOTO ) + { + return pObj; + } + } + return 0; +} + diff --git a/src/ui/displaytext.h b/src/ui/displaytext.h new file mode 100644 index 0000000..6a54e1f --- /dev/null +++ b/src/ui/displaytext.h @@ -0,0 +1,96 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// displaytext.h + +#ifndef _DISPLAYTEXT_H_ +#define _DISPLAYTEXT_H_ + + +#include "d3dengine.h" + + +class CInstanceManager; +class CD3DEngine; +class CInterface; +class CObject; +class CSound; + + +enum TextType +{ + TT_ERROR = 1, + TT_WARNING = 2, + TT_INFO = 3, + TT_MESSAGE = 4, +}; + +#define MAXDTLINE 4 + + +class CDisplayText +{ +public: + CDisplayText(CInstanceManager* iMan); + ~CDisplayText(); + + void DeleteObject(); + + BOOL EventProcess(const Event &event); + + void DisplayError(Error err, CObject* pObj, float time=10.0f); + void DisplayError(Error err, D3DVECTOR goal, float height=15.0f, float dist=60.0f, float time=10.0f); + void DisplayText(char *text, CObject* pObj, float time=10.0f, TextType type=TT_INFO); + void DisplayText(char *text, D3DVECTOR goal, float height=15.0f, float dist=60.0f, float time=10.0f, TextType type=TT_INFO); + void HideText(BOOL bHide); + void ClearText(); + BOOL ClearLastText(); + void SetDelay(float factor); + void SetEnable(BOOL bEnable); + + D3DVECTOR RetVisitGoal(EventMsg event); + float RetVisitDist(EventMsg event); + float RetVisitHeight(EventMsg event); + + float RetIdealDist(CObject* pObj); + float RetIdealHeight(CObject* pObj); + + void ClearVisit(); + void SetVisit(EventMsg event); + BOOL IsVisit(EventMsg event); + +protected: + CObject* SearchToto(); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CInterface* m_interface; + CSound* m_sound; + + BOOL m_bExist[MAXDTLINE]; + float m_time[MAXDTLINE]; + D3DVECTOR m_visitGoal[MAXDTLINE]; + float m_visitDist[MAXDTLINE]; + float m_visitHeight[MAXDTLINE]; + + BOOL m_bHide; + BOOL m_bEnable; + float m_delayFactor; +}; + + +#endif //_DISPLAYTEXT_H_ diff --git a/src/ui/edit.cpp b/src/ui/edit.cpp new file mode 100644 index 0000000..f15b0c2 --- /dev/null +++ b/src/ui/edit.cpp @@ -0,0 +1,3318 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// edit.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "language.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "restext.h" +#include "scroll.h" +#include "text.h" +#include "edit.h" + + +#define MARGX (5.0f/640.0f) +#define MARGY (5.0f/480.0f) +#define MARGYS (4.0f/480.0f) +#define MARGY1 (1.0f/480.0f) +#define DELAY_DBCLICK 0.3f // time limit for double-click +#define DELAY_SCROLL 0.1f // time limit for scroll +#define BIG_FONT 1.6f // expansion for \b; + + + + +// Indicates whether a character is a space. + +BOOL IsSpace(int character) +{ + return ( character == ' ' || + character == '\t' || + character == '\n' ); +} + +// Indicates whether a character is part of a word. + +BOOL IsWord(int character) +{ + char c; + + c = tolower(RetNoAccent(character)); + + return ( (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || + c == '_' ); +} + +// Indicates whether a character is a word separator. + +BOOL IsSep(int character) +{ + if ( IsSpace(character) ) return FALSE; + return !IsWord(character); +} + + + +// Object's constructor. + +CEdit::CEdit(CInstanceManager* iMan) : CControl(iMan) +{ + FPOINT pos; + int i; + + m_maxChar = 100; + m_text = (char*)malloc(sizeof(char)*(m_maxChar+1)); + m_format = 0; + m_len = 0; + + m_fontType = FONT_COURIER; + m_scroll = 0; + m_bEdit = TRUE; + m_bHilite = TRUE; + m_bInsideScroll = TRUE; + m_bCapture = FALSE; + m_bDisplaySpec = FALSE; + m_bSoluce = FALSE; + m_bGeneric = FALSE; + m_bAutoIndent = FALSE; + m_cursor1 = 0; + m_cursor2 = 0; + m_column = 0; + m_imageTotal = 0; + + HyperFlush(); + + for ( i=0 ; iCreate(pos, dim, -1, EVENT_NULL); + MoveAdjust(); + } + + return TRUE; +} + + +void CEdit::SetPos(FPOINT pos) +{ + CControl::SetPos(pos); + MoveAdjust(); +} + +void CEdit::SetDim(FPOINT dim) +{ + CControl::SetDim(dim); + MoveAdjust(); +} + +void CEdit::MoveAdjust() +{ + FPOINT pos, dim; + float height; + + m_lineDescent = m_engine->RetText()->RetDescent(m_fontSize, m_fontType); + m_lineAscent = m_engine->RetText()->RetAscent(m_fontSize, m_fontType); + m_lineHeight = m_engine->RetText()->RetHeight(m_fontSize, m_fontType); + + height = m_dim.y-(m_bMulti?MARGY*2.0f:MARGY1); + m_lineVisible = (int)(height/m_lineHeight); + + if ( m_scroll != 0 ) + { + if ( m_bInsideScroll ) + { + pos.x = m_pos.x+m_dim.x-MARGX-SCROLL_WIDTH; + pos.y = m_pos.y+MARGYS; + dim.x = SCROLL_WIDTH; + dim.y = m_dim.y-MARGYS*2.0f; + } + else + { + pos.x = m_pos.x+m_dim.x-SCROLL_WIDTH; + pos.y = m_pos.y; + dim.x = SCROLL_WIDTH; + dim.y = m_dim.y; + } + m_scroll->SetPos(pos); + m_scroll->SetDim(dim); + } + + Justif(); + + if ( m_lineFirst > m_lineTotal-m_lineVisible ) + { + m_lineFirst = m_lineTotal-m_lineVisible; + if ( m_lineFirst < 0 ) m_lineFirst = 0; + } + + pos.x = m_pos.x+m_dim.x-(m_bMulti?SCROLL_WIDTH:0.0f); + pos.y = m_pos.y; + GlintCreate(pos, FALSE, FALSE); +} + + +// Management of an event. + +BOOL CEdit::EventProcess(const Event &event) +{ + BOOL bShift, bControl; + + if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; + + if ( event.event == EVENT_KEYDOWN && + event.param == VK_WHEELUP && + Detect(event.pos) ) + { + Scroll(m_lineFirst-3, TRUE); + return TRUE; + } + if ( event.event == EVENT_KEYDOWN && + event.param == VK_WHEELDOWN && + Detect(event.pos) ) + { + Scroll(m_lineFirst+3, TRUE); + return TRUE; + } + + CControl::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + m_time += event.rTime; + m_timeBlink += event.rTime; + } + + if ( event.event == EVENT_MOUSEMOVE ) + { + if ( Detect(event.pos) && + event.pos.x < m_pos.x+m_dim.x-(m_bMulti?MARGX+SCROLL_WIDTH:0.0f) ) + { + if ( m_bEdit ) + { + m_engine->SetMouseType(D3DMOUSEEDIT); + } + else + { + if ( IsLinkPos(event.pos) ) + { + m_engine->SetMouseType(D3DMOUSEHAND); + } + else + { + m_engine->SetMouseType(D3DMOUSENORM); + } + } + } + } + + if ( m_scroll != 0 && !m_bGeneric ) + { + m_scroll->EventProcess(event); + + if ( event.event == m_scroll->RetEventMsg() ) + { + Scroll(); + return TRUE; + } + } + + if ( event.event == EVENT_KEYDOWN && m_bFocus ) + { + bShift = (event.keyState&KS_SHIFT); + bControl = (event.keyState&KS_CONTROL); + + if ( (event.param == 'X' && !bShift && bControl) || + (event.param == VK_DELETE && bShift && !bControl) ) + { + Cut(); + return TRUE; + } + if ( (event.param == 'C' && !bShift && bControl) || + (event.param == VK_INSERT && !bShift && bControl) ) + { + Copy(); + return TRUE; + } + if ( (event.param == 'V' && !bShift && bControl) || + (event.param == VK_INSERT && bShift && !bControl) ) + { + Paste(); + return TRUE; + } + + if ( event.param == 'A' && !bShift && bControl ) + { + SetCursor(999999, 0); + return TRUE; + } + + if ( event.param == 'O' && !bShift && bControl ) + { + Event newEvent; + m_event->MakeEvent(newEvent, EVENT_STUDIO_OPEN); + m_event->AddEvent(newEvent); + } + if ( event.param == 'S' && !bShift && bControl ) + { + Event newEvent; + m_event->MakeEvent(newEvent, EVENT_STUDIO_SAVE); + m_event->AddEvent(newEvent); + } + + if ( event.param == 'Z' && !bShift && bControl ) + { + Undo(); + return TRUE; + } + + if ( event.param == 'U' && !bShift && bControl ) + { + if ( MinMaj(FALSE) ) return TRUE; + } + if ( event.param == 'U' && bShift && bControl ) + { + if ( MinMaj(TRUE) ) return TRUE; + } + + if ( event.param == VK_TAB && !bShift && !bControl && !m_bAutoIndent ) + { + if ( Shift(FALSE) ) return TRUE; + } + if ( event.param == VK_TAB && bShift && !bControl && !m_bAutoIndent ) + { + if ( Shift(TRUE) ) return TRUE; + } + + if ( m_bEdit ) + { + if ( event.param == VK_LEFT ) + { + MoveChar(-1, bControl, bShift); + return TRUE; + } + if ( event.param == VK_RIGHT ) + { + MoveChar(1, bControl, bShift); + return TRUE; + } + if ( event.param == VK_UP ) + { + MoveLine(-1, bControl, bShift); + return TRUE; + } + if ( event.param == VK_DOWN ) + { + MoveLine(1, bControl, bShift); + return TRUE; + } + + if ( event.param == VK_PRIOR ) // PageUp ? + { + MoveLine(-(m_lineVisible-1), bControl, bShift); + return TRUE; + } + if ( event.param == VK_NEXT ) // PageDown ? + { + MoveLine(m_lineVisible-1, bControl, bShift); + return TRUE; + } + } + else + { + if ( event.param == VK_LEFT || + event.param == VK_UP ) + { + Scroll(m_lineFirst-1, TRUE); + return TRUE; + } + if ( event.param == VK_RIGHT || + event.param == VK_DOWN ) + { + Scroll(m_lineFirst+1, TRUE); + return TRUE; + } + + if ( event.param == VK_PRIOR ) // PageUp ? + { + Scroll(m_lineFirst-(m_lineVisible-1), TRUE); + return TRUE; + } + if ( event.param == VK_NEXT ) // PageDown ? + { + Scroll(m_lineFirst+(m_lineVisible-1), TRUE); + return TRUE; + } + } + + if ( event.param == VK_HOME ) + { + MoveHome(bControl, bShift); + return TRUE; + } + if ( event.param == VK_END ) + { + MoveEnd(bControl, bShift); + return TRUE; + } + + if ( event.param == VK_BACK ) // backspace ( <- ) ? + { + Delete(-1); + SendModifEvent(); + return TRUE; + } + if ( event.param == VK_DELETE ) + { + Delete(1); + SendModifEvent(); + return TRUE; + } + + if ( event.param == VK_RETURN ) + { + Insert('\n'); + SendModifEvent(); + return TRUE; + } + if ( event.param == VK_TAB ) + { + Insert('\t'); + SendModifEvent(); + return TRUE; + } + } + + if ( event.event == EVENT_CHAR && m_bFocus ) + { + if ( event.param >= ' ' && event.param <= 255 ) + { + Insert((char)event.param); + SendModifEvent(); + return TRUE; + } + } + + if ( event.event == EVENT_FOCUS ) + { + if ( event.param == m_eventMsg ) + { + m_bFocus = TRUE; + } + else + { + m_bFocus = FALSE; + } + } + + if ( event.event == EVENT_LBUTTONDOWN ) + { + m_mouseFirstPos = event.pos; + m_mouseLastPos = event.pos; + if ( Detect(event.pos) ) + { + if ( event.pos.x < m_pos.x+m_dim.x-(m_bMulti?MARGX+SCROLL_WIDTH:0.0f) ) + { + MouseClick(event.pos); + if ( m_bEdit || m_bHilite ) m_bCapture = TRUE; + } + m_bFocus = TRUE; + } + else + { + m_bFocus = FALSE; + } + } + + if ( event.event == EVENT_MOUSEMOVE && m_bCapture ) + { + m_mouseLastPos = event.pos; + MouseMove(event.pos); + } + + if ( event.event == EVENT_FRAME && m_bCapture ) + { + MouseMove(m_mouseLastPos); + } + + if ( event.event == EVENT_LBUTTONUP ) + { + if ( Detect(event.pos) ) + { + if ( event.pos.x < m_pos.x+m_dim.x-(m_bMulti?MARGX+SCROLL_WIDTH:0.0f) ) + { + MouseRelease(m_mouseFirstPos); + } + } + if ( m_bCapture ) + { + if ( m_timeLastClick+DELAY_DBCLICK > m_time ) // double-click ? + { + MouseDoubleClick(event.pos); + } + m_timeLastClick = m_time; + m_bCapture = FALSE; + } + } + + return TRUE; +} + + +// Sends an event to indicate that the text was modified. + +void CEdit::SendModifEvent() +{ + Event newEvent; + + m_event->MakeEvent(newEvent, m_eventMsg); + m_event->AddEvent(newEvent); +} + + +// Detects whether the mouse is over a hyperlink character. + +BOOL CEdit::IsLinkPos(FPOINT pos) +{ + int i; + + if ( m_format == 0 ) return FALSE; + + i = MouseDetect(pos); + if ( i == -1 ) return FALSE; + if ( i >= m_len ) return FALSE; + + if ( (m_format[i]&COLOR_MASK) == COLOR_LINK ) return TRUE; + return FALSE; +} + + +// Positions the cursor after a double click. + +void CEdit::MouseDoubleClick(FPOINT mouse) +{ + int i, character; + + if ( m_bMulti ) // Multi-line? + { + i = MouseDetect(mouse); + if ( i == -1 ) return; + + while ( i > 0 ) + { + character = (unsigned char)m_text[i-1]; + if ( !IsWord(character) ) break; + i --; + } + m_cursor2 = i; + + while ( i < m_len ) + { + character = (unsigned char)m_text[i]; + if ( !IsWord(character) ) break; + i ++; + } + m_cursor1 = i; + } + else // single-line? + { + m_cursor2 = 0; + m_cursor1 = m_len; // selects all + } + + m_bUndoForce = TRUE; + + Justif(); + ColumnFix(); +} + +// Positions the cursor when clicked. + +void CEdit::MouseClick(FPOINT mouse) +{ + int i; + + i = MouseDetect(mouse); + if ( i == -1 ) return; + + if ( m_bEdit || m_bHilite ) + { + m_cursor1 = i; + m_cursor2 = i; + m_bUndoForce = TRUE; + m_timeBlink = 0.0f; // lights the cursor immediately + ColumnFix(); + } +} + +// Positions the cursor when clicked released. + +void CEdit::MouseRelease(FPOINT mouse) +{ + int i, j, rank; + + i = MouseDetect(mouse); + if ( i == -1 ) return; + + if ( !m_bEdit ) + { + if ( m_format != 0 && i < m_len && m_cursor1 == m_cursor2 && + (m_format[i]&COLOR_MASK) == COLOR_LINK ) + { + rank = -1; + for ( j=0 ; j<=i ; j++ ) + { + if ( (j == 0 || (m_format[j-1]&COLOR_MASK) != COLOR_LINK) && + (m_format[j+0]&COLOR_MASK) == COLOR_LINK ) + { + rank ++; + } + } + HyperJump(m_link[rank].name, m_link[rank].marker); + } + } +} + +// Positions the cursor after movement. + +void CEdit::MouseMove(FPOINT mouse) +{ + int i; + + if ( m_bMulti && + m_timeLastScroll+DELAY_SCROLL <= m_time ) + { + if ( mouse.y > m_pos.y+m_dim.y ) // above? + { + Scroll(m_lineFirst-1, FALSE); + mouse.y = m_pos.y+m_dim.y-MARGY-m_lineHeight/2.0f; + } + if ( mouse.y < m_pos.y ) // lower? + { + Scroll(m_lineFirst+1, FALSE); + mouse.y = m_pos.y+m_dim.y-MARGY-m_lineVisible*m_lineHeight+m_lineHeight/2.0f; + } + m_timeLastScroll = m_time; + } + + i = MouseDetect(mouse); + if ( i != -1 ) + { + m_cursor1 = i; + m_bUndoForce = TRUE; + m_timeBlink = 0.0f; // lights the cursor immediately + ColumnFix(); + } +} + +// Positions the cursor when clicked. + +int CEdit::MouseDetect(FPOINT mouse) +{ + FPOINT pos; + float indentLength, offset, size; + int i, len, c; + BOOL bTitle; + + if ( m_bAutoIndent ) + { + indentLength = m_engine->RetText()->RetCharWidth(' ', 0.0f, m_fontSize, m_fontStretch, m_fontType) + * m_engine->RetEditIndentValue(); + } + + pos.y = m_pos.y+m_dim.y-m_lineHeight-(m_bMulti?MARGY:MARGY1); + for ( i=m_lineFirst ; i= m_lineFirst+m_lineVisible ) break; + + pos.x = m_pos.x+(10.0f/640.0f); + if ( m_bAutoIndent ) + { + pos.x += indentLength*m_lineIndent[i]; + } + offset = mouse.x-pos.x; + + if ( bTitle ) pos.y -= m_lineHeight; + + if ( mouse.y > pos.y ) + { + len = m_lineOffset[i+1] - m_lineOffset[i]; + + if ( m_format == 0 ) + { + c = m_engine->RetText()->Detect(m_text+m_lineOffset[i], + len, offset, m_fontSize, + m_fontStretch, m_fontType); + } + else + { + size = m_fontSize; + if ( bTitle ) size *= BIG_FONT; + + c = m_engine->RetText()->Detect(m_text+m_lineOffset[i], + m_format+m_lineOffset[i], + len, offset, size, + m_fontStretch); + } + return m_lineOffset[i]+c; + } + + if ( bTitle ) i ++; + pos.y -= m_lineHeight; + } + return -1; +} + + +// Clears all history. + +void CEdit::HyperFlush() +{ + m_historyTotal = 0; + m_historyCurrent = -1; +} + +// Indicates which is the home page. + +void CEdit::HyperHome(char *filename) +{ + HyperFlush(); + HyperAdd(filename, 0); +} + +// Performs a hyper jump through a link. + +void CEdit::HyperJump(char *name, char *marker) +{ + char filename[100]; + char sMarker[100]; + int i, line, pos; + + if ( m_historyCurrent >= 0 ) + { + m_history[m_historyCurrent].firstLine = m_lineFirst; + } + + strcpy(sMarker, marker); + +//? sprintf(filename, "help\\%s.txt", name); + if ( name[0] == '%' ) + { + UserDir(filename, name, ""); + strcat(filename, ".txt"); + } + else + { + sprintf(filename, "help\\%s.txt", name); + } + if ( ReadText(filename) ) + { + Justif(); + + line = 0; + for ( i=0 ; i= m_lineOffset[i] ) + { + line = i; + } + } + break; + } + } + + SetFirstLine(line); + HyperAdd(filename, line); + } +} + +// Adds text to the history of visited. + +BOOL CEdit::HyperAdd(char *filename, int firstLine) +{ + if ( m_historyCurrent >= EDITHISTORYMAX-1 ) return FALSE; + + m_historyCurrent ++; + strcpy(m_history[m_historyCurrent].filename, filename); + m_history[m_historyCurrent].firstLine = firstLine; + + m_historyTotal = m_historyCurrent+1; + return TRUE; +} + +// Indicates whether a button EVENT_HYPER_ * is active or not. + +BOOL CEdit::HyperTest(EventMsg event) +{ + if ( event == EVENT_HYPER_HOME ) + { + return ( m_historyCurrent > 0 ); + } + + if ( event == EVENT_HYPER_PREV ) + { + return ( m_historyCurrent > 0 ); + } + + if ( event == EVENT_HYPER_NEXT ) + { + return ( m_historyCurrent < m_historyTotal-1 ); + } + + return FALSE; +} + +// Performs the action corresponding to a button EVENT_HYPER_ *. + +BOOL CEdit::HyperGo(EventMsg event) +{ + if ( !HyperTest(event) ) return FALSE; + + m_history[m_historyCurrent].firstLine = m_lineFirst; + + if ( event == EVENT_HYPER_HOME ) + { + m_historyCurrent = 0; + } + + if ( event == EVENT_HYPER_PREV ) + { + m_historyCurrent --; + } + + if ( event == EVENT_HYPER_NEXT ) + { + m_historyCurrent ++; + } + + ReadText(m_history[m_historyCurrent].filename); + Justif(); + SetFirstLine(m_history[m_historyCurrent].firstLine); + return TRUE; +} + + +// Draw the editable line. + +void CEdit::Draw() +{ + FPOINT pos, ppos, dim, start, end; + float size, indentLength; + int i, j, beg, len, c1, c2, o1, o2, eol, iIndex, line; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + if ( m_state & STATE_SHADOW ) + { + DrawShadow(m_pos, m_dim); + } + + pos.x = m_pos.x; + pos.y = m_pos.y; + dim.x = m_dim.x; + if ( !m_bInsideScroll ) dim.x -= m_bMulti?SCROLL_WIDTH:0.0f; + dim.y = m_dim.y; + DrawBack(pos, dim); // background + + // Displays all lines. + c1 = m_cursor1; + c2 = m_cursor2; + if ( c1 > c2 ) Swap(c1, c2); // always c1 <= c2 + + if ( m_bInsideScroll ) + { + dim.x -= m_bMulti?SCROLL_WIDTH:0.0f + (1.0f/640.0f); + } + + if ( m_bAutoIndent ) + { + indentLength = m_engine->RetText()->RetCharWidth(' ', 0.0f, m_fontSize, m_fontStretch, m_fontType) + * m_engine->RetEditIndentValue(); + } + + pos.y = m_pos.y+m_dim.y-m_lineHeight-(m_bMulti?MARGY:MARGY1); + for ( i=m_lineFirst ; i= m_lineFirst+m_lineVisible ) break; + + pos.x = m_pos.x+(10.0f/640.0f); + if ( m_bAutoIndent ) + { + for ( j=0 ; jRetText()->DrawText(&s, 1, pos, 1.0f, 1, m_fontSize, m_fontStretch, m_fontType, 0); + pos.x += indentLength; + } + } + + beg = m_lineOffset[i]; + len = m_lineOffset[i+1] - m_lineOffset[i]; + + ppos = pos; + size = m_fontSize; + + // Headline \b;? + if ( beg+len < m_len && m_format != 0 && + (m_format[beg]&TITLE_MASK) == TITLE_BIG ) + { + start.x = ppos.x-MARGX; + end.x = dim.x-MARGX*2.0f; + start.y = ppos.y-(m_bMulti?0.0f:MARGY1)-m_lineHeight*(BIG_FONT-1.0f); + end.y = m_lineHeight*BIG_FONT; + DrawPart(start, end, 2); // blue gradient background -> + + size *= BIG_FONT; + ppos.y -= m_lineHeight*(BIG_FONT-1.0f); + } + + // As \t;? + if ( beg+len < m_len && m_format != 0 && + (m_format[beg]&TITLE_MASK) == TITLE_NORM ) + { + start.x = ppos.x-MARGX; + end.x = dim.x-MARGX*2.0f; + start.y = ppos.y-(m_bMulti?0.0f:MARGY1); + end.y = m_lineHeight; + DrawPart(start, end, 2); // blue gradient background -> + } + + // Subtitle \s;? + if ( beg+len < m_len && m_format != 0 && + (m_format[beg]&TITLE_MASK) == TITLE_LITTLE ) + { + start.x = ppos.x-MARGX; + end.x = dim.x-MARGX*2.0f; + start.y = ppos.y-(m_bMulti?0.0f:MARGY1); + end.y = m_lineHeight; + DrawPart(start, end, 3); // yellow background gradient -> + } + + // Table \tab;? + if ( beg+len < m_len && m_format != 0 && + (m_format[beg]&COLOR_MASK) == COLOR_TABLE ) + { + start.x = ppos.x-MARGX; + end.x = dim.x-MARGX*2.0f; + start.y = ppos.y-(m_bMulti?0.0f:MARGY1); + end.y = m_lineHeight; + DrawPart(start, end, 11); // fond orange d�grad� -> + } + + // Image \image; ? + if ( beg+len < m_len && m_format != 0 && + (m_format[beg]&IMAGE_MASK) != 0 ) + { + line = 1; + while ( true ) // includes the image slices + { + if ( i+line >= m_lineTotal || + i+line >= m_lineFirst+m_lineVisible || + (m_format[beg+line]&IMAGE_MASK) == 0 ) break; + line ++; + } + + iIndex = m_text[beg]; // character = index in m_image + pos.y -= m_lineHeight*(line-1); + DrawImage(pos, m_image[iIndex].name, + m_image[iIndex].width*(m_fontSize/SMALLFONT), + m_image[iIndex].offset, m_image[iIndex].height*line, line); + pos.y -= m_lineHeight; + i += line-1; + continue; + } + + if ( ((m_bEdit && m_bFocus && m_bHilite) || + (!m_bEdit && m_bHilite) ) && + c1 != c2 && beg <= c2 && beg+len >= c1 ) // selected area? + { + o1 = c1; if ( o1 < beg ) o1 = beg; + o2 = c2; if ( o2 > beg+len ) o2 = beg+len; + + if ( m_format == 0 ) + { + start.x = ppos.x+m_engine->RetText()->RetStringWidth(m_text+beg, o1-beg, size, m_fontStretch, m_fontType); + end.x = m_engine->RetText()->RetStringWidth(m_text+o1, o2-o1, size, m_fontStretch, m_fontType); + } + else + { + start.x = ppos.x+m_engine->RetText()->RetStringWidth(m_text+beg, m_format+beg, o1-beg, size, m_fontStretch); + end.x = m_engine->RetText()->RetStringWidth(m_text+o1, m_format+o1, o2-o1, size, m_fontStretch); + } + + start.y = ppos.y-(m_bMulti?0.0f:MARGY1); + end.y = m_lineHeight; + if ( m_format != 0 && (m_format[beg]&TITLE_MASK) == TITLE_BIG ) end.y *= BIG_FONT; + DrawPart(start, end, 1); // plain yellow background + } + + eol = 16; // > + if ( len > 0 && m_text[beg+len-1] == '\n' ) + { + len --; // does not display the '\ n' + eol = 0; // nothing + } + if ( beg+len >= m_len ) + { + eol = 2; // square (eot) + } + if ( !m_bMulti || !m_bDisplaySpec ) eol = 0; + if ( m_format == 0 ) + { + m_engine->RetText()->DrawText(m_text+beg, len, ppos, m_dim.x, 1, size, m_fontStretch, m_fontType, eol); + } + else + { + m_engine->RetText()->DrawText(m_text+beg, m_format+beg, len, ppos, m_dim.x, 1, size, m_fontStretch, eol); + } + + pos.y -= m_lineHeight; + + if ( i < m_lineTotal-2 && m_lineOffset[i+1] == m_lineOffset[i+2] ) + { + pos.y -= m_lineHeight; // double jump line \b; + i ++; + } + } + + // Shows the cursor. + if ( (m_bEdit && m_bFocus && m_bHilite && Mod(m_timeBlink, 1.0f) <= 0.5f) ) // it blinks + { + pos.y = m_pos.y+m_dim.y-m_lineHeight-(m_bMulti?MARGY:MARGY1*2.0f); + for ( i=m_lineFirst ; iRetText()->DimText(m_text+m_lineOffset[i], len, + pos, 1, size, + m_fontStretch, m_fontType, + start, end); + } + else + { + m_engine->RetText()->DimText(m_text+m_lineOffset[i], + m_format+m_lineOffset[i], + len, pos, 1, size, + m_fontStretch, + start, end); + } + + pos.x = end.x; + break; + } + pos.y -= m_lineHeight; + } + pos.x -= 1.0f/640.0f; + dim.x = 2.0f/640.0f; + dim.y = m_lineHeight; + DrawPart(pos, dim, 0); // red + } + + if ( m_scroll != 0 && !m_bGeneric ) + { + m_scroll->Draw(); + } +} + +// Draw an image part. + +void CEdit::DrawImage(FPOINT pos, char *name, float width, + float offset, float height, int nbLine) +{ + FPOINT uv1, uv2, dim; + float dp; + char filename[100]; + +//? sprintf(filename, "diagram\\%s.bmp", name); + UserDir(filename, name, "diagram"); + strcat(filename, ".bmp"); + + m_engine->SetTexture(filename); + m_engine->SetState(D3DSTATENORMAL); + + uv1.x = 0.0f; + uv2.x = 1.0f; + uv1.y = offset; + uv2.y = offset+height; + + dp = 0.5f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + dim.x = width; + dim.y = m_lineHeight*nbLine; + DrawIcon(pos, dim, uv1, uv2); +} + +// Draw the background. + +void CEdit::DrawBack(FPOINT pos, FPOINT dim) +{ + FPOINT uv1,uv2, corner; + float dp; + + if ( m_bGeneric ) return; + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + + if ( m_bMulti ) + { + uv1.x = 128.0f/256.0f; // light blue + uv1.y = 64.0f/256.0f; + uv2.x = 160.0f/256.0f; + uv2.y = 96.0f/256.0f; + } + else + { + uv1.x = 160.0f/256.0f; // medium blue + uv1.y = 192.0f/256.0f; + uv2.x = 192.0f/256.0f; + uv2.y = 224.0f/256.0f; + } + if ( m_icon == 1 ) + { + uv1.x = 192.0f/256.0f; // orange + uv1.y = 96.0f/256.0f; + uv2.x = 224.0f/256.0f; + uv2.y = 128.0f/256.0f; + } + + dp = 0.5f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + if ( m_bMulti ) + { + corner.x = 10.0f/640.0f; + corner.y = 10.0f/480.0f; + DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); + } + else + { + DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); + } +} + +// Draws an icon background. + +void CEdit::DrawPart(FPOINT pos, FPOINT dim, int icon) +{ + FPOINT uv1, uv2; + float dp; + +#if _POLISH + m_engine->SetTexture("textp.tga"); +#else + m_engine->SetTexture("text.tga"); +#endif + m_engine->SetState(D3DSTATENORMAL); + + uv1.x = (16.0f/256.0f)*(icon%16); + uv1.y = (240.0f/256.0f); + uv2.x = (16.0f/256.0f)+uv1.x; + uv2.y = (16.0f/256.0f)+uv1.y; + + dp = 0.5f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + DrawIcon(pos, dim, uv1, uv2); +} + + +// Give the text to edit. + +void CEdit::SetText(char *text, BOOL bNew) +{ + int i, j, font; + BOOL bBOL; + + if ( !bNew ) UndoMemorize(OPERUNDO_SPEC); + + m_len = strlen(text); + if ( m_len > m_maxChar ) m_len = m_maxChar; + + if ( m_format == 0 ) + { + if ( m_bAutoIndent ) + { + j = 0; + bBOL = TRUE; + for ( i=0 ; i max ) max = max-1; + + strncpy(buffer, m_text, max); + buffer[max] = 0; +} + +// Returns the length of the text. + +int CEdit::RetTextLength() +{ + return m_len; +} + + + +// Returns a name in a command. +// \x nom1 nom2 nom3; + +void GetNameParam(char *cmd, int rank, char *buffer) +{ + int i; + + for ( i=0 ; iFreeTexture(filename); + } +} + +// Reads the texture of an image. + +void CEdit::LoadImage(char *name) +{ + char filename[100]; + +//? sprintf(filename, "diagram\\%s.bmp", name); + UserDir(filename, name, "diagram"); + strcat(filename, ".bmp"); + m_engine->LoadTexture(filename); +} + +// Read from a text file. + +BOOL CEdit::ReadText(char *filename, int addSize) +{ + FILE *file = NULL; + char *buffer; + int len, i, j, n, font, iIndex, iLines, iCount, iLink, res; + char iName[50]; + char text[50]; + float iWidth; + KeyRank key; + BOOL bInSoluce, bBOL; + + if ( filename[0] == 0 ) return FALSE; + file = fopen(filename, "rb"); + if ( file == NULL ) return FALSE; + + fseek(file, 0, SEEK_END); + len = ftell(file); + fseek(file, 0, SEEK_SET); + + m_maxChar = len+addSize+100; + m_len = len; + m_cursor1 = 0; + m_cursor2 = 0; + + FreeImage(); + delete m_text; + m_text = (char*)malloc(sizeof(char)*(m_maxChar+1)); + buffer = (char*)malloc(sizeof(char)*(m_maxChar+1)); + fread(buffer, 1, len, file); + + if ( m_format != 0 ) + { + delete m_format; + m_format = (char*)malloc(sizeof(char)*m_maxChar); + } + + fclose(file); + + bInSoluce = FALSE; + font = m_fontType; + iIndex = 0; + iLink = 0; + m_imageTotal = 0; + m_markerTotal = 0; + i = j = 0; + bBOL = TRUE; + while ( i < m_len ) + { + if ( m_bAutoIndent ) + { + if ( buffer[i] == '\t' ) + { + if ( !bBOL ) + { + m_text[j] = buffer[i]; + if ( m_format != 0 ) m_format[j] = font; + j ++; + } + i ++; + continue; // removes the tabs + } + bBOL = ( buffer[i] == '\n' || buffer[i] == '\r' ); + } + + if ( buffer[i] == '\r' ) // removes \ r + { + i ++; + } + else if ( m_format != 0 && buffer[i] == '\\' && buffer[i+2] == ';' ) + { + if ( buffer[i+1] == 'n' ) // normal ? + { + if ( m_bSoluce || !bInSoluce ) + { + font &= ~FONT_MASK; + font |= FONT_COLOBOT; + } + i += 3; + } + else if ( buffer[i+1] == 'c' ) // cbot ? + { + if ( m_bSoluce || !bInSoluce ) + { + font &= ~FONT_MASK; + font |= FONT_COURIER; + } + i += 3; + } + else if ( buffer[i+1] == 'b' ) // big title ? + { + if ( m_bSoluce || !bInSoluce ) + { + font &= ~TITLE_MASK; + font |= TITLE_BIG; + } + i += 3; + } + else if ( buffer[i+1] == 't' ) // title ? + { + if ( m_bSoluce || !bInSoluce ) + { + font &= ~TITLE_MASK; + font |= TITLE_NORM; + } + i += 3; + } + else if ( buffer[i+1] == 's' ) // subtitle ? + { + if ( m_bSoluce || !bInSoluce ) + { + font &= ~TITLE_MASK; + font |= TITLE_LITTLE; + } + i += 3; + } + else if ( buffer[i+1] == 'l' ) // link ? + { + if ( m_bSoluce || !bInSoluce ) + { + font &= ~COLOR_MASK; + font |= COLOR_LINK; + } + i += 3; + } + else + { + i += 3; + } + } + else if ( m_format != 0 && + buffer[i+0] == '\\' && // \u marker name; ? + buffer[i+1] == 'u' && + buffer[i+2] == ' ' ) + { + if ( m_bSoluce || !bInSoluce ) + { + if ( iLink < EDITLINKMAX ) + { + GetNameParam(buffer+i+3, 0, m_link[iLink].name); + GetNameParam(buffer+i+3, 1, m_link[iLink].marker); + iLink ++; + } + font &= ~COLOR_MASK; + } + i += strchr(buffer+i, ';')-(buffer+i)+1; + } + else if ( m_format != 0 && + buffer[i+0] == '\\' && // \m marker; ? + buffer[i+1] == 'm' && + buffer[i+2] == ' ' ) + { + if ( m_bSoluce || !bInSoluce ) + { + if ( m_markerTotal < EDITLINKMAX ) + { + GetNameParam(buffer+i+3, 0, m_marker[m_markerTotal].name); + m_marker[m_markerTotal].pos = j; + m_markerTotal ++; + } + } + i += strchr(buffer+i, ';')-(buffer+i)+1; + } + else if ( m_format != 0 && + buffer[i+0] == '\\' && // \image name lx ly; ? + buffer[i+1] == 'i' && + buffer[i+2] == 'm' && + buffer[i+3] == 'a' && + buffer[i+4] == 'g' && + buffer[i+5] == 'e' && + buffer[i+6] == ' ' ) + { + if ( m_bSoluce || !bInSoluce ) + { +#if _DEMO + strcpy(iName, "demo"); +#else + GetNameParam(buffer+i+7, 0, iName); +#endif +//? iWidth = m_lineHeight*RetValueParam(buffer+i+7, 1); + iWidth = (float)RetValueParam(buffer+i+7, 1); + iWidth *= m_engine->RetText()->RetHeight(SMALLFONT, FONT_COLOBOT); + iLines = RetValueParam(buffer+i+7, 2); + LoadImage(iName); + + // A part of image per line of text. + for ( iCount=0 ; iCountRetKey(key, 0); + if ( res != 0 ) + { + if ( GetResource(RES_KEY, res, iName) ) + { + m_text[j] = ' '; + m_format[j] = font; + j ++; + n = 0; + while ( iName[n] != 0 ) + { + m_text[j] = iName[n++]; + m_format[j] = font; + j ++; + } + m_text[j] = ' '; + m_format[j] = font; + j ++; + + res = m_engine->RetKey(key, 1); + if ( res != 0 ) + { + if ( GetResource(RES_KEY, res, iName) ) + { + GetResource(RES_TEXT, RT_KEY_OR, text); + n = 0; + while ( text[n] != 0 ) + { + m_text[j] = text[n++]; + m_format[j] = font&~COLOR_MASK; + j ++; + } + n = 0; + while ( iName[n] != 0 ) + { + m_text[j] = iName[n++]; + m_format[j] = font; + j ++; + } + m_text[j] = ' '; + m_format[j] = font; + j ++; + } + } + while ( buffer[i++] != ';' ); + continue; + } + } + } + m_text[j] = '?'; + m_format[j] = font; + j ++; + } + while ( buffer[i++] != ';' ); + } + else + { + if ( m_bSoluce || !bInSoluce ) + { + m_text[j] = buffer[i]; + if ( m_format != 0 ) m_format[j] = font; + j ++; + } + i ++; + + font &= ~TITLE_MASK; // reset title + + if ( (font&COLOR_MASK) == COLOR_TABLE ) + { + font &= ~COLOR_TABLE; + } + } + } + m_len = j; + m_imageTotal = iIndex; + + delete buffer; + + Justif(); + ColumnFix(); + return TRUE; +} + +// Writes all the text in a file. + +BOOL CEdit::WriteText(char *filename) +{ + FILE* file; + char buffer[1000+20]; + int i, j, k, n; + float iDim; + + if ( filename[0] == 0 ) return FALSE; + file = fopen(filename, "wb"); + if ( file == NULL ) return FALSE; + + if ( m_bAutoIndent ) + { + iDim = m_dim.x; + m_dim.x = 1000.0f; // puts an infinite width! + Justif(); + } + + i = j = k = 0; + while ( m_text[i] != 0 && i < m_len ) + { + if ( m_bAutoIndent && i == m_lineOffset[k] ) + { + for ( n=0 ; n= 1000-1 ) + { + fwrite(buffer, 1, j, file); + j = 0; + } + + i ++; + } + if ( j > 0 ) + { + fwrite(buffer, 1, j, file); + } + + fclose(file); + + if ( m_bAutoIndent ) + { + m_dim.x = iDim; // presents the initial width + Justif(); + } + + return TRUE; +} + + +// Manage the number of max characters editable. + +void CEdit::SetMaxChar(int max) +{ + m_maxChar = max; + FreeImage(); + delete m_text; + m_text = (char*)malloc(sizeof(char)*(m_maxChar+1)); + + if ( m_format != 0 ) + { + delete m_format; + m_format = (char*)malloc(sizeof(char)*m_maxChar); + } + + m_len = 0; + m_cursor1 = 0; + m_cursor2 = 0; + Justif(); + UndoFlush(); +} + +int CEdit::RetMaxChar() +{ + return m_maxChar; +} + + +// Mode management "editable". + +void CEdit::SetEditCap(BOOL bMode) +{ + m_bEdit = bMode; +} + +BOOL CEdit::RetEditCap() +{ + return m_bEdit; +} + +// Mode management "hilitable" (that's the franch). + +void CEdit::SetHiliteCap(BOOL bEnable) +{ + m_bHilite = bEnable; +} + +BOOL CEdit::RetHiliteCap() +{ + return m_bHilite; +} + +// Lift in / out connection. + +void CEdit::SetInsideScroll(BOOL bInside) +{ + m_bInsideScroll = bInside; +} + +BOOL CEdit::RetInsideScroll() +{ + return m_bInsideScroll; +} + +// Specifies whether to display the links showing the solution. + +void CEdit::SetSoluceMode(BOOL bSoluce) +{ + m_bSoluce = bSoluce; +} + +BOOL CEdit::RetSoluceMode() +{ + return m_bSoluce; +} + +// Indicates whether the text is a defile that generic. + +void CEdit::SetGenericMode(BOOL bGeneric) +{ + m_bGeneric = bGeneric; +} + +BOOL CEdit::RetGenericMode() +{ + return m_bGeneric; +} + + +// Management of automatic indentation mode with {}. + +void CEdit::SetAutoIndent(BOOL bMode) +{ + m_bAutoIndent = bMode; +} + +BOOL CEdit::RetAutoIndent() +{ + return m_bAutoIndent; +} + + + +// Moves the cursors. + +void CEdit::SetCursor(int cursor1, int cursor2) +{ + if ( cursor1 > m_len ) cursor1 = m_len; + if ( cursor2 > m_len ) cursor2 = m_len; + + m_cursor1 = cursor1; + m_cursor2 = cursor2; + m_bUndoForce = TRUE; + ColumnFix(); +} + +// Returns the sliders. + +void CEdit::GetCursor(int &cursor1, int &cursor2) +{ + cursor1 = m_cursor1; + cursor2 = m_cursor2; +} + + +// Displayed line modifies the first. + +void CEdit::SetFirstLine(int rank) +{ + Scroll(rank, TRUE); +} + +// Returns the first displayed line. + +int CEdit::RetFirstLine() +{ + if ( m_historyTotal > 0 ) + { + if ( m_historyCurrent == 0 ) + { + return m_lineFirst; + } + else + { + return m_history[0].firstLine; + } + } + return m_lineFirst; +} + + +// Shows the selected area. + +void CEdit::ShowSelect() +{ + int cursor1, cursor2, line; + + if ( m_cursor1 < m_cursor2 ) + { + cursor1 = m_cursor1; + cursor2 = m_cursor2; + } + else + { + cursor1 = m_cursor2; + cursor2 = m_cursor1; + } + + line = RetCursorLine(cursor2); + if ( line >= m_lineFirst+m_lineVisible ) + { + line -= m_lineVisible-1; + if ( line < 0 ) line = 0; + Scroll(line, FALSE); + } + + line = RetCursorLine(cursor1); + if ( line < m_lineFirst ) + { + Scroll(line, FALSE); + } +} + + +// Management of the display mode of special characters. + +void CEdit::SetDisplaySpec(BOOL bDisplay) +{ + m_bDisplaySpec = bDisplay; +} + +BOOL CEdit::RetDisplaySpec() +{ + return m_bDisplaySpec; +} + + +// Multi-fonts mode management. + +void CEdit::SetMultiFont(BOOL bMulti) +{ + if ( bMulti ) + { + delete m_format; + m_format = (char*)malloc(sizeof(char)*m_maxChar); + memset(m_format, 0, m_maxChar); + } + else + { + delete m_format; + m_format = 0; + } +} + +BOOL CEdit::RetMultiFont() +{ + return ( m_format != 0 ); +} + + +// Management of the character size. + +void CEdit::SetFontSize(float size) +{ + CControl::SetFontSize(size); + + MoveAdjust(); +} + + +// Moves according to the visible lift. + +void CEdit::Scroll() +{ + float value; + + if ( m_scroll != 0 ) + { + value = m_scroll->RetVisibleValue(); + value *= m_lineTotal-m_lineVisible; + Scroll((int)(value+0.5f), TRUE); + } +} + +// Moves according to the visible lift. + +void CEdit::Scroll(int pos, BOOL bAdjustCursor) +{ + int max, line; + + m_lineFirst = pos; + + if ( m_lineFirst < 0 ) m_lineFirst = 0; + + max = m_lineTotal-m_lineVisible; + if ( max < 0 ) max = 0; + if ( m_lineFirst > max ) m_lineFirst = max; + + line = RetCursorLine(m_cursor1); + + if ( bAdjustCursor && m_bEdit ) + { + // Cursor too high? + if ( line < m_lineFirst ) + { + MoveLine(m_lineFirst-line, FALSE, FALSE); + return; + } + + // Cursor too low? + if ( line >= m_lineFirst+m_lineVisible ) + { + MoveLine(m_lineFirst+m_lineVisible-line-1, FALSE, FALSE); + return; + } + } + + Justif(); +} + +// Moves the cursor to the beginning of the line. + +void CEdit::MoveHome(BOOL bWord, BOOL bSelect) +{ + int begin, tab; + + if ( bWord ) + { + m_cursor1 = 0; + } + else + { + begin = m_cursor1; + while ( begin > 0 && m_text[begin-1] != '\n' ) + { + begin --; + } + + tab = begin; + while ( tab < m_len && (m_text[tab] == '\t' || m_text[tab] == ' ') ) + { + tab ++; + } + + if ( m_cursor1 == tab ) + { + m_cursor1 = begin; + } + else + { + m_cursor1 = tab; + } + } + if ( !bSelect ) m_cursor2 = m_cursor1; + + m_bUndoForce = TRUE; + Justif(); + ColumnFix(); +} + +// Moves the cursor to the end of the line. + +void CEdit::MoveEnd(BOOL bWord, BOOL bSelect) +{ + if ( bWord ) + { + m_cursor1 = m_len; + } + else + { + while ( m_cursor1 < m_len && m_text[m_cursor1] != '\n' ) + { + m_cursor1 ++; + } + } + if ( !bSelect ) m_cursor2 = m_cursor1; + + m_bUndoForce = TRUE; + Justif(); + ColumnFix(); +} + +// Moves the cursor through characters. + +void CEdit::MoveChar(int move, BOOL bWord, BOOL bSelect) +{ + int character; + + if ( move == -1 ) // back? + { + if ( bWord ) + { + while ( m_cursor1 > 0 ) + { + character = (unsigned char)m_text[m_cursor1-1]; + if ( !IsSpace(character) ) break; + m_cursor1 --; + } + + if ( m_cursor1 > 0 ) + { + character = (unsigned char)m_text[m_cursor1-1]; + if ( IsSpace(character) ) + { + while ( m_cursor1 > 0 ) + { + character = (unsigned char)m_text[m_cursor1-1]; + if ( !IsSpace(character) ) break; + m_cursor1 --; + } + } + else if ( IsWord(character) ) + { + while ( m_cursor1 > 0 ) + { + character = (unsigned char)m_text[m_cursor1-1]; + if ( !IsWord(character) ) break; + m_cursor1 --; + } + } + else if ( IsSep(character) ) + { + while ( m_cursor1 > 0 ) + { + character = (unsigned char)m_text[m_cursor1-1]; + if ( !IsSep(character) ) break; + m_cursor1 --; + } + } + } + } + else + { + m_cursor1 --; + if ( m_cursor1 < 0 ) m_cursor1 = 0; + } + } + + if ( move == 1 ) // advance? + { + if ( bWord ) + { + if ( m_cursor1 < m_len ) + { + character = (unsigned char)m_text[m_cursor1]; + if ( IsSpace(character) ) + { + while ( m_cursor1 < m_len ) + { + character = (unsigned char)m_text[m_cursor1]; + if ( !IsSpace(character) ) break; + m_cursor1 ++; + } + } + else if ( IsWord(character) ) + { + while ( m_cursor1 < m_len ) + { + character = (unsigned char)m_text[m_cursor1]; + if ( !IsWord(character) ) break; + m_cursor1 ++; + } + } + else if ( IsSep(character) ) + { + while ( m_cursor1 < m_len ) + { + character = (unsigned char)m_text[m_cursor1]; + if ( !IsSep(character) ) break; + m_cursor1 ++; + } + } + } + + while ( m_cursor1 < m_len ) + { + character = (unsigned char)m_text[m_cursor1]; + if ( !IsSpace(character) ) break; + m_cursor1 ++; + } + } + else + { + m_cursor1 ++; + if ( m_cursor1 > m_len ) m_cursor1 = m_len; + } + } + + if ( !bSelect ) m_cursor2 = m_cursor1; + + m_bUndoForce = TRUE; + Justif(); + ColumnFix(); +} + +// Moves the cursor lines. + +void CEdit::MoveLine(int move, BOOL bWord, BOOL bSelect) +{ + float column, indentLength; + int i, line, c; + + if ( move == 0 ) return; + + for ( i=0 ; i>move ; i-- ) // back? + { + while ( m_cursor1 > 0 && m_text[m_cursor1-1] != '\n' ) + { + m_cursor1 --; + } + if ( m_cursor1 != 0 ) + { + m_cursor1 --; + while ( m_cursor1 > 0 ) + { + if ( m_text[--m_cursor1] == '\n' ) + { + m_cursor1 ++; + break; + } + } + } + } + + for ( i=0 ; iRetText()->RetCharWidth(' ', 0.0f, m_fontSize, m_fontStretch, m_fontType) + * m_engine->RetEditIndentValue(); + column -= indentLength*m_lineIndent[line]; + } + + if ( m_format == 0 ) + { + c = m_engine->RetText()->Detect(m_text+m_lineOffset[line], + m_lineOffset[line+1]-m_lineOffset[line], + column, m_fontSize, + m_fontStretch, m_fontType); + } + else + { + c = m_engine->RetText()->Detect(m_text+m_lineOffset[line], + m_format+m_lineOffset[line], + m_lineOffset[line+1]-m_lineOffset[line], + column, m_fontSize, m_fontStretch); + } + + m_cursor1 = m_lineOffset[line]+c; + if ( !bSelect ) m_cursor2 = m_cursor1; + + m_bUndoForce = TRUE; + Justif(); +} + +// Sets the horizontal position. + +void CEdit::ColumnFix() +{ + float indentLength; + int line; + + line = RetCursorLine(m_cursor1); + + if ( m_format == 0 ) + { + m_column = m_engine->RetText()->RetStringWidth + ( + m_text+m_lineOffset[line], + m_cursor1-m_lineOffset[line], + m_fontSize, m_fontStretch, m_fontType + ); + } + else + { + m_column = m_engine->RetText()->RetStringWidth + ( + m_text+m_lineOffset[line], + m_format+m_lineOffset[line], + m_cursor1-m_lineOffset[line], + m_fontSize, m_fontStretch + ); + } + + if ( m_bAutoIndent ) + { + indentLength = m_engine->RetText()->RetCharWidth(' ', 0.0f, m_fontSize, m_fontStretch, m_fontType) + * m_engine->RetEditIndentValue(); + m_column += indentLength*m_lineIndent[line]; + } +} + + +// Cut the selected characters or entire line. + +BOOL CEdit::Cut() +{ + HGLOBAL hg; + char* text; + char c; + int c1, c2, start, len, i, j; + + if ( !m_bEdit ) return FALSE; + + c1 = m_cursor1; + c2 = m_cursor2; + if ( c1 > c2 ) Swap(c1, c2); // always c1 <= c2 + + if ( c1 == c2 ) + { + while ( c1 > 0 ) + { + if ( m_text[c1-1] == '\n' ) break; + c1 --; + } + while ( c2 < m_len ) + { + c2 ++; + if ( m_text[c2-1] == '\n' ) break; + } + } + + if ( c1 == c2 ) return FALSE; + + start = c1; + len = c2-c1; + + if ( !(hg = GlobalAlloc(GMEM_DDESHARE, len*2+1)) ) + { + return FALSE; + } + if ( !(text = (char*)GlobalLock(hg)) ) + { + GlobalFree(hg); + return FALSE; + } + + j = 0; + for ( i=start ; i c2 ) Swap(c1, c2); // always c1 <= c2 + + if ( c1 == c2 ) + { + while ( c1 > 0 ) + { + if ( m_text[c1-1] == '\n' ) break; + c1 --; + } + while ( c2 < m_len ) + { + c2 ++; + if ( m_text[c2-1] == '\n' ) break; + } + } + + if ( c1 == c2 ) return FALSE; + + start = c1; + len = c2-c1; + + if ( !(hg = GlobalAlloc(GMEM_DDESHARE, len*2+1)) ) + { + return FALSE; + } + if ( !(text = (char*)GlobalLock(hg)) ) + { + GlobalFree(hg); + return FALSE; + } + + j = 0; + for ( i=start ; iRetEditIndentValue() ; i++ ) + { + InsertOne(' '); + } + } + else + { + InsertOne(character); + } + } + else + { + InsertOne(character); + } + + Justif(); + ColumnFix(); +} + +// Inserts a plain character. + +void CEdit::InsertOne(char character) +{ + int i; + + if ( !m_bEdit ) return; + if ( !m_bMulti && character == '\n' ) return; + + if ( m_cursor1 != m_cursor2 ) + { + DeleteOne(0); // deletes the selected characters + } + + if ( m_len >= m_maxChar ) return; + + for ( i=m_len ; i>=m_cursor1 ; i-- ) + { + m_text[i] = m_text[i-1]; // shoot + + if ( m_format != 0 ) + { + m_format[i] = m_format[i-1]; // shoot + } + } + + m_len ++; + + m_text[m_cursor1] = character; + + if ( m_format != 0 ) + { + m_format[m_cursor1] = 0; + } + + m_cursor1++; + m_cursor2 = m_cursor1; +} + +// Deletes the character left of cursor or all selected characters. + +void CEdit::Delete(int dir) +{ + if ( !m_bEdit ) return; + + UndoMemorize(OPERUNDO_DELETE); + DeleteOne(dir); + + Justif(); + ColumnFix(); +} + +// Deletes the character left of cursor or all selected plain characters. + +void CEdit::DeleteOne(int dir) +{ + int i, end, hole; + + if ( !m_bEdit ) return; + + if ( m_cursor1 == m_cursor2 ) + { + if ( dir < 0 ) + { + if ( m_cursor1 == 0 ) return; + m_cursor1 --; + } + else + { + if ( m_cursor2 == m_len ) return; + m_cursor2 ++; + } + } + + if ( m_cursor1 > m_cursor2 ) Swap(m_cursor1, m_cursor2); + hole = m_cursor2-m_cursor1; + end = m_len-hole; + for ( i=m_cursor1 ; i 0 ) + { + if ( m_text[i-1] == '\n' ) return nb; + if ( m_text[i-1] != '\t' ) return -1; + nb ++; + i --; + } + return nb; +} + +// Adds or removes qq tabs. + +void CEdit::IndentTabAdjust(int number) +{ + int i; + + for ( i=0 ; inumber ; i-- ) // delete? + { + DeleteOne(-1); + } +} + + +// Indent the left or right the entire selection. + +BOOL CEdit::Shift(BOOL bLeft) +{ + BOOL bInvert = FALSE; + int c1, c2, i; + + if ( m_cursor1 == m_cursor2 ) return FALSE; + + UndoMemorize(OPERUNDO_SPEC); + + c1 = m_cursor1; + c2 = m_cursor2; + if ( c1 > c2 ) + { + Swap(c1, c2); // always c1 <= c2 + bInvert = TRUE; + } + + if ( c1 > 0 ) + { + if ( m_text[c1-1] != '\n' ) return FALSE; + } + if ( c2 < m_len ) + { + if ( m_text[c2-1] != '\n' ) return FALSE; + } + + if ( bLeft ) // shifts left? + { + i = c1; + while ( i < c2 ) + { + if ( m_text[i] == '\t' ) + { + m_cursor1 = i; + m_cursor2 = i+1; + DeleteOne(0); + c2 --; + } + while ( i < c2 && m_text[i++] != '\n' ); + } + } + else // shifts right? + { + i = c1; + while ( i < c2 ) + { + m_cursor1 = m_cursor2 = i; + InsertOne('\t'); + c2 ++; + while ( i < c2 && m_text[i++] != '\n' ); + } + } + + if ( bInvert ) Swap(c1, c2); + m_cursor1 = c1; + m_cursor2 = c2; + + Justif(); + ColumnFix(); + SendModifEvent(); + return TRUE; +} + +// Min conversion <-> shift the selection. + +BOOL CEdit::MinMaj(BOOL bMaj) +{ + int c1, c2, i, character; + + if ( m_cursor1 == m_cursor2 ) return FALSE; + + UndoMemorize(OPERUNDO_SPEC); + + c1 = m_cursor1; + c2 = m_cursor2; + if ( c1 > c2 ) Swap(c1, c2); // alwyas c1 <= c2 + + for ( i=c1 ; iRetText()->RetCharWidth(' ', 0.0f, m_fontSize, m_fontStretch, m_fontType) + * m_engine->RetEditIndentValue(); + } + + bString = bRem = FALSE; + i = 0; + while ( TRUE ) + { + bDual = FALSE; + + width = m_dim.x-(10.0f/640.0f)*2.0f-(m_bMulti?MARGX*2.0f+SCROLL_WIDTH:0.0f); + if ( m_bAutoIndent ) + { + width -= indentLength*m_lineIndent[m_lineTotal-1]; + } + + if ( m_format == 0 ) + { + i += m_engine->RetText()->Justif(m_text+i, m_len-i, width, + m_fontSize, m_fontStretch, + m_fontType); + } + else + { + size = m_fontSize; + + if ( (m_format[i]&TITLE_MASK) == TITLE_BIG ) // headline? + { + size *= BIG_FONT; + bDual = TRUE; + } + + if ( (m_format[i]&IMAGE_MASK) != 0 ) // image part? + { + i ++; // jumps just a character (index in m_image) + } + else + { + i += m_engine->RetText()->Justif(m_text+i, m_format+i, + m_len-i, width, + size, m_fontStretch); + } + } + + if ( i >= m_len ) break; + + if ( m_bAutoIndent ) + { + for ( j=m_lineOffset[m_lineTotal-1] ; j= EDITLINEMAX-2 ) break; + } + if ( m_len > 0 && m_text[m_len-1] == '\n' ) + { + m_lineOffset[m_lineTotal] = m_len; + m_lineIndent[m_lineTotal] = 0; + m_lineTotal ++; + } + m_lineOffset[m_lineTotal] = m_len; + m_lineIndent[m_lineTotal] = 0; + + if ( m_bAutoIndent ) + { + for ( i=0 ; i<=m_lineTotal ; i++ ) + { + if ( m_text[m_lineOffset[i]] == '}' ) + { + if ( m_lineIndent[i] > 0 ) m_lineIndent[i] --; + } + } + } + + if ( m_bMulti ) + { + if ( m_bEdit ) + { + line = RetCursorLine(m_cursor1); + if ( line < m_lineFirst ) + { + m_lineFirst = line; + } + if ( line >= m_lineFirst+m_lineVisible ) + { + m_lineFirst = line-m_lineVisible+1; + } + } + } + else + { + m_lineFirst = 0; + } + + if ( m_scroll != 0 ) + { + if ( m_lineTotal <= m_lineVisible ) + { + m_scroll->SetVisibleRatio(1.0f); + m_scroll->SetVisibleValue(0.0f); + m_scroll->SetArrowStep(0.0f); + } + else + { + value = (float)m_lineVisible/m_lineTotal; + m_scroll->SetVisibleRatio(value); + + value = (float)m_lineFirst/(m_lineTotal-m_lineVisible); + m_scroll->SetVisibleValue(value); + + value = (float)1.0f/(m_lineTotal-m_lineVisible); + m_scroll->SetArrowStep(value); + } + } + + m_timeBlink = 0.0f; // lights the cursor immediately +} + +// Returns the rank of the line where the cursor is located. + +int CEdit::RetCursorLine(int cursor) +{ + int line, i; + + line = 0; + for ( i=0 ; i= m_lineOffset[i] ) + { + line = i; + } + } + return line; +} + + +// Flush the buffer undo. + +void CEdit::UndoFlush() +{ + int i; + + for ( i=0 ; i=1 ; i-- ) + { + m_undo[i] = m_undo[i-1]; + } + + len = m_len; + if ( len == 0 ) len ++; + m_undo[0].text = (char*)malloc(sizeof(char)*(len+1)); + memcpy(m_undo[0].text, m_text, m_len); + m_undo[0].len = m_len; + + m_undo[0].cursor1 = m_cursor1; + m_undo[0].cursor2 = m_cursor2; + m_undo[0].lineFirst = m_lineFirst; +} + +// Back to previous state. + +BOOL CEdit::UndoRecall() +{ + int i; + + if ( m_undo[0].text == 0 ) return FALSE; + + m_len = m_undo[0].len; + memcpy(m_text, m_undo[0].text, m_len); + + m_cursor1 = m_undo[0].cursor1; + m_cursor2 = m_undo[0].cursor2; + m_lineFirst = m_undo[0].lineFirst; + + for ( i=0 ; i multi-line + BOOL m_bEdit; // TRUE -> editable + BOOL m_bHilite; // TRUE -> hilitable + BOOL m_bInsideScroll; // TRUE -> lift as part + BOOL m_bDisplaySpec; // TRUE -> displays the special characters + BOOL m_bMultiFont; // TRUE -> more fonts possible + BOOL m_bSoluce; // TRUE -> shows the links-solution + BOOL m_bGeneric; // TRUE -> generic that defile + BOOL m_bAutoIndent; // TRUE -> automatic indentation + float m_lineHeight; // height of a row + float m_lineAscent; // height above the baseline + float m_lineDescent; // height below the baseline + int m_lineVisible; // total number of viewable lines + int m_lineFirst; // the first line displayed + int m_lineTotal; // number lines used (in m_lineOffset) + int m_lineOffset[EDITLINEMAX]; + char m_lineIndent[EDITLINEMAX]; + int m_imageTotal; + ImageLine m_image[EDITIMAGEMAX]; + HyperLink m_link[EDITLINKMAX]; + int m_markerTotal; + HyperMarker m_marker[EDITLINKMAX]; + int m_historyTotal; + int m_historyCurrent; + HyperHistory m_history[EDITHISTORYMAX]; + float m_time; // absolute time + float m_timeBlink; + float m_timeLastClick; + float m_timeLastScroll; + FPOINT m_mouseFirstPos; + FPOINT m_mouseLastPos; + float m_column; + + BOOL m_bCapture; + + BOOL m_bUndoForce; + OperUndo m_undoOper; + EditUndo m_undo[EDITUNDOMAX]; +}; + + +#endif //_EDIT_H_ diff --git a/src/ui/editvalue.cpp b/src/ui/editvalue.cpp new file mode 100644 index 0000000..ce8515c --- /dev/null +++ b/src/ui/editvalue.cpp @@ -0,0 +1,380 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// editvalue.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "edit.h" +#include "button.h" +#include "editvalue.h" + + + + +// Object's constructor. + +CEditValue::CEditValue(CInstanceManager* iMan) : CControl(iMan) +{ + m_edit = 0; + m_buttonUp = 0; + m_buttonDown = 0; + + m_type = EVT_100; // % + m_stepValue = 0.1f; // 10% + m_minValue = 0.0f; // 0% + m_maxValue = 1.0f; // 100% +} + +// Object's destructor. + +CEditValue::~CEditValue() +{ + delete m_edit; + delete m_buttonUp; + delete m_buttonDown; +} + + +// Creates a new button. + +BOOL CEditValue::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CEdit* pe; + CButton* pc; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + CControl::Create(pos, dim, icon, eventMsg); + + GlintDelete(); + + m_edit = new CEdit(m_iMan); + pe = (CEdit*)m_edit; + pe->Create(pos, dim, 0, EVENT_NULL); + pe->SetMaxChar(4); + + m_buttonUp = new CButton(m_iMan); + pc = (CButton*)m_buttonUp; + pc->Create(pos, dim, 49, EVENT_NULL); // ^ + pc->SetRepeat(TRUE); + + m_buttonDown = new CButton(m_iMan); + pc = (CButton*)m_buttonDown; + pc->Create(pos, dim, 50, EVENT_NULL); // v + pc->SetRepeat(TRUE); + + MoveAdjust(); + return TRUE; +} + + +void CEditValue::SetPos(FPOINT pos) +{ + CControl::SetPos(pos); + MoveAdjust(); +} + +void CEditValue::SetDim(FPOINT dim) +{ + CControl::SetDim(dim); + MoveAdjust(); +} + +void CEditValue::MoveAdjust() +{ + FPOINT pos, dim; + + if ( m_edit != 0 ) + { + pos.x = m_pos.x; + pos.y = m_pos.y; + dim.x = m_dim.x-m_dim.y*0.6f; + dim.y = m_dim.y; + m_edit->SetPos(pos); + m_edit->SetDim(dim); + } + + if ( m_buttonUp != 0 ) + { + pos.x = m_pos.x+m_dim.x-m_dim.y*0.6f; + pos.y = m_pos.y+m_dim.y*0.5f; + dim.x = m_dim.y*0.6f; + dim.y = m_dim.y*0.5f; + m_buttonUp->SetPos(pos); + m_buttonUp->SetDim(dim); + } + + if ( m_buttonDown != 0 ) + { + pos.x = m_pos.x+m_dim.x-m_dim.y*0.6f; + pos.y = m_pos.y; + dim.x = m_dim.y*0.6f; + dim.y = m_dim.y*0.5f; + m_buttonDown->SetPos(pos); + m_buttonDown->SetDim(dim); + } +} + + +// Management of an event. + +BOOL CEditValue::EventProcess(const Event &event) +{ + float value; + + CControl::EventProcess(event); + + if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; + if ( (m_state & STATE_ENABLE) == 0 ) return TRUE; + + if ( m_edit != 0 ) + { + if ( m_edit->RetFocus() && + event.event == EVENT_KEYDOWN && + event.param == VK_RETURN ) + { + value = RetValue(); + if ( value > m_maxValue ) value = m_maxValue; + if ( value < m_minValue ) value = m_minValue; + SetValue(value, TRUE); + HiliteValue(event); + } + if ( !m_edit->EventProcess(event) ) return FALSE; + + if ( event.event == m_edit->RetEventMsg() ) + { + Event newEvent; + m_event->MakeEvent(newEvent, m_eventMsg); + m_event->AddEvent(newEvent); + } + } + + if ( m_buttonUp != 0 ) + { + if ( event.event == m_buttonUp->RetEventMsg() ) + { + value = RetValue()+m_stepValue; + if ( value > m_maxValue ) value = m_maxValue; + SetValue(value, TRUE); + HiliteValue(event); + } + if ( !m_buttonUp->EventProcess(event) ) return FALSE; + } + + if ( m_buttonDown != 0 ) + { + if ( event.event == m_buttonDown->RetEventMsg() ) + { + value = RetValue()-m_stepValue; + if ( value < m_minValue ) value = m_minValue; + SetValue(value, TRUE); + HiliteValue(event); + } + if ( !m_buttonDown->EventProcess(event) ) return FALSE; + } + + if ( event.event == EVENT_KEYDOWN && + event.param == VK_WHEELUP && + Detect(event.pos) ) + { + value = RetValue()+m_stepValue; + if ( value > m_maxValue ) value = m_maxValue; + SetValue(value, TRUE); + HiliteValue(event); + } + if ( event.event == EVENT_KEYDOWN && + event.param == VK_WHEELDOWN && + Detect(event.pos) ) + { + value = RetValue()-m_stepValue; + if ( value < m_minValue ) value = m_minValue; + SetValue(value, TRUE); + HiliteValue(event); + } + + return TRUE; +} + + +// Puts in evidence the edited value. + +void CEditValue::HiliteValue(const Event &event) +{ + int pos; + + if ( m_edit == 0 ) return; + + pos = m_edit->RetTextLength(); + if ( m_type == EVT_100 && pos > 0 ) + { + pos --; // not only selects the "%" + } + + m_edit->SetCursor(pos, 0); + m_edit->SetFocus(TRUE); + + Event newEvent = event; + newEvent.event = EVENT_FOCUS; + newEvent.param = m_edit->RetEventMsg(); + m_event->AddEvent(newEvent); // defocus the other objects +} + + +// Draw button. + +void CEditValue::Draw() +{ + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + if ( m_state & STATE_SHADOW ) + { + DrawShadow(m_pos, m_dim); + } + + if ( m_edit != 0 ) + { + m_edit->Draw(); + } + if ( m_buttonUp != 0 ) + { + m_buttonUp->Draw(); + } + if ( m_buttonDown != 0 ) + { + m_buttonDown->Draw(); + } +} + + +// Choosing the type of value. + +void CEditValue::SetType(EditValueType type) +{ + m_type = type; +} + +EditValueType CEditValue::RetType() +{ + return m_type; +} + + +// Changes the value. + +void CEditValue::SetValue(float value, BOOL bSendMessage) +{ + char text[100]; + + if ( m_edit == 0 ) return; + + text[0] = 0; + + if ( m_type == EVT_INT ) + { + sprintf(text, "%d", (int)value); + } + + if ( m_type == EVT_FLOAT ) + { + sprintf(text, "%.2f", value); + } + + if ( m_type == EVT_100 ) + { + sprintf(text, "%d%%", (int)(value*100.0f)); + } + + m_edit->SetText(text); + + if ( bSendMessage ) + { + Event newEvent; + m_event->MakeEvent(newEvent, m_eventMsg); + m_event->AddEvent(newEvent); + } +} + +// Return the edited value. + +float CEditValue::RetValue() +{ + char text[100]; + float value; + + if ( m_edit == 0 ) 0.0f; + + m_edit->GetText(text, 100); + sscanf(text, "%f", &value); + + if ( m_type == EVT_100 ) + { + value = (value+0.5f)/100.0f; + if ( value < 0.01f ) value = 0.0f; // less than 1%? + } + + return value; +} + + +// Management not for buttons. + +void CEditValue::SetStepValue(float value) +{ + m_stepValue = value; +} + +float CEditValue::RetStepValue() +{ + return m_stepValue; +} + + +// Management of the minimum value. + +void CEditValue::SetMinValue(float value) +{ + m_minValue = value; +} + +float CEditValue::RetMinValue() +{ + return m_minValue; +} + + +// Management of the maximum value. + +void CEditValue::SetMaxValue(float value) +{ + m_maxValue = value; +} + +float CEditValue::RetMaxValue() +{ + return m_maxValue; +} + diff --git a/src/ui/editvalue.h b/src/ui/editvalue.h new file mode 100644 index 0000000..3203b8b --- /dev/null +++ b/src/ui/editvalue.h @@ -0,0 +1,85 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// editvalue.h + +#ifndef _EDITVALUE_H_ +#define _EDITVALUE_H_ + + +#include "control.h" + + +enum EditValueType +{ + EVT_INT = 1, // integer + EVT_FLOAT = 2, // float value + EVT_100 = 3, // percent (0 .. 1) +}; + + +class CD3DEngine; +class CEdit; +class CButton; + + + +class CEditValue : public CControl +{ +public: + CEditValue(CInstanceManager* iMan); + virtual ~CEditValue(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + + void SetPos(FPOINT pos); + void SetDim(FPOINT dim); + + BOOL EventProcess(const Event &event); + void Draw(); + + void SetType(EditValueType type); + EditValueType RetType(); + + void SetValue(float value, BOOL bSendMessage=FALSE); + float RetValue(); + + void SetStepValue(float value); + float RetStepValue(); + + void SetMinValue(float value); + float RetMinValue(); + + void SetMaxValue(float value); + float RetMaxValue(); + +protected: + void MoveAdjust(); + void HiliteValue(const Event &event); + +protected: + CEdit* m_edit; + CButton* m_buttonUp; + CButton* m_buttonDown; + + EditValueType m_type; + float m_stepValue; + float m_minValue; + float m_maxValue; +}; + + +#endif //_EDITVALUE_H_ diff --git a/src/ui/gauge.cpp b/src/ui/gauge.cpp new file mode 100644 index 0000000..420cebf --- /dev/null +++ b/src/ui/gauge.cpp @@ -0,0 +1,159 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// gauge.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "gauge.h" + + + + +// Object's constructor. + +CGauge::CGauge(CInstanceManager* iMan) : CControl(iMan) +{ + m_level = 0.0f; +} + +// Object's destructor. + +CGauge::~CGauge() +{ +} + + +// Creates a new button. + +BOOL CGauge::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + CControl::Create(pos, dim, icon, eventMsg); + return TRUE; +} + + +// Management of an event. + +BOOL CGauge::EventProcess(const Event &event) +{ + CControl::EventProcess(event); + + if ( event.event == EVENT_LBUTTONDOWN ) + { + if ( CControl::Detect(event.pos) ) + { + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + return FALSE; + } + } + + return TRUE; +} + + +// Draw the gauge. + +void CGauge::Draw() +{ + FPOINT pos, dim, ddim, uv1, uv2, corner; + float dp; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + + dp = 0.5f/256.0f; + + pos = m_pos; + dim = m_dim; + + uv1.x = 32.0f/256.0f; + uv1.y = 32.0f/256.0f; + uv2.x = 64.0f/256.0f; + uv2.y = 64.0f/256.0f; + + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + corner.x = 10.0f/640.0f; + corner.y = 10.0f/480.0f; + + DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); + + + pos.x += 3.0f/640.0f; + pos.y += 3.0f/480.0f; + dim.x -= 6.0f/640.0f; + dim.y -= 6.0f/480.0f; + + if ( m_dim.x < m_dim.y ) // vertical gauge? + { + uv1.x = (0.0f+m_icon*16.0f)/256.0f; + uv2.x = uv1.x+16.0f/256.0f; + uv1.y = 128.0f/256.0f+m_level*(64.0f/256.0f); + uv2.y = uv1.y+64.0f/256.0f; + } + else // horizontal gauge? + { + uv1.x = 64.0f/256.0f+(1.0f-m_level)*(64.0f/256.0f); + uv2.x = uv1.x+64.0f/256.0f; + uv1.y = (128.0f+m_icon*16.0f)/256.0f; + uv2.y = uv1.y+16.0f/256.0f; + } + + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + DrawIcon(pos, dim, uv1, uv2); +} + + +// Management of level of the gauge. + +void CGauge::SetLevel(float level) +{ + if ( level < 0.0f ) level = 0.0f; + if ( level > 1.0f ) level = 1.0f; + m_level = level; +} + +float CGauge::RetLevel() +{ + return m_level; +} + + diff --git a/src/ui/gauge.h b/src/ui/gauge.h new file mode 100644 index 0000000..9895d75 --- /dev/null +++ b/src/ui/gauge.h @@ -0,0 +1,52 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// gauge.h + +#ifndef _GAUGE_H_ +#define _GAUGE_H_ + + +#include "control.h" + + +class CD3DEngine; + + + +class CGauge : public CControl +{ +public: + CGauge(CInstanceManager* iMan); + virtual ~CGauge(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + + BOOL EventProcess(const Event &event); + + void Draw(); + + void SetLevel(float level); + float RetLevel(); + +protected: + +protected: + float m_level; +}; + + +#endif //_GAUGE_H_ diff --git a/src/ui/group.cpp b/src/ui/group.cpp new file mode 100644 index 0000000..f49fd69 --- /dev/null +++ b/src/ui/group.cpp @@ -0,0 +1,646 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// group.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "restext.h" +#include "group.h" + + + + +// Object's constructor. + +CGroup::CGroup(CInstanceManager* iMan) : CControl(iMan) +{ +} + +// Object's destructor. + +CGroup::~CGroup() +{ +} + + +// Creates a new button. + +BOOL CGroup::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + CControl::Create(pos, dim, icon, eventMsg); + + if ( icon == -1 ) + { + char name[100]; + char* p; + + GetResource(RES_EVENT, eventMsg, name); + p = strchr(name, '\\'); + if ( p != 0 ) *p = 0; + SetName(name); + } + + return TRUE; +} + + +// Management of an event. + +BOOL CGroup::EventProcess(const Event &event) +{ + return TRUE; +} + + +// Draw button. + +void CGroup::Draw() +{ + FPOINT uv1,uv2, corner, pos, dim; + float dp; + int icon; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + if ( m_state & STATE_SHADOW ) + { + DrawShadow(m_pos, m_dim); + } + + dp = 0.5f/256.0f; + + if ( m_icon == 0 ) // hollow frame? + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 160.0f/256.0f; + uv1.y = 192.0f/256.0f; // u-v texture + uv2.x = 192.0f/256.0f; + uv2.y = 224.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 10.0f/640.0f; + corner.y = 10.0f/480.0f; + DrawIcon(m_pos, m_dim, uv1, uv2, corner, 8.0f/256.0f); + } + if ( m_icon == 1 ) // orange solid opaque? + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 104.0f/256.0f; + uv1.y = 48.0f/256.0f; + uv2.x = 112.0f/256.0f; + uv2.y = 64.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(m_pos, m_dim, uv1, uv2); + } + if ( m_icon == 2 ) // orange degrade -> transparent? + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + uv1.x = 112.0f/256.0f; + uv1.y = 48.0f/256.0f; + uv2.x = 120.0f/256.0f; + uv2.y = 64.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(m_pos, m_dim, uv1, uv2); + } + if ( m_icon == 3 ) // transparent gradient -> gray? + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + uv1.x = 120.0f/256.0f; + uv1.y = 48.0f/256.0f; + uv2.x = 128.0f/256.0f; + uv2.y = 64.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(m_pos, m_dim, uv1, uv2); + } + if ( m_icon == 4 ) // degrade blue corner? + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + uv1.x = 192.0f/256.0f; + uv1.y = 128.0f/256.0f; + uv2.x = 224.0f/256.0f; + uv2.y = 160.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(m_pos, m_dim, uv1, uv2); + } + if ( m_icon == 5 ) // degrade orange corner? + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + uv1.x = 224.0f/256.0f; + uv1.y = 128.0f/256.0f; + uv2.x = 256.0f/256.0f; + uv2.y = 160.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(m_pos, m_dim, uv1, uv2); + } + if ( m_icon == 6 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 0.0f/256.0f; // brown transparent + uv1.y = 75.0f/256.0f; + uv2.x = 64.0f/256.0f; + uv2.y = 128.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 4.0f/640.0f; + corner.y = 4.0f/480.0f; + DrawIcon(m_pos, m_dim, uv1, uv2, corner, 8.0f/256.0f); + } + if ( m_icon == 7 ) + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 64.0f/256.0f; + uv1.y = 0.0f/256.0f; + uv2.x = 96.0f/256.0f; + uv2.y = 32.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(m_pos, m_dim, uv1, uv2, 8.0f/256.0f); + } + if ( m_icon == 8 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 64.0f/256.0f; // green transparent + uv1.y = 160.0f/256.0f; + uv2.x = 160.0f/256.0f; + uv2.y = 176.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(m_pos, m_dim, uv1, uv2, 8.0f/256.0f); + } + if ( m_icon == 9 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 64.0f/256.0f; // red transparent + uv1.y = 176.0f/256.0f; + uv2.x = 160.0f/256.0f; + uv2.y = 192.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(m_pos, m_dim, uv1, uv2, 8.0f/256.0f); + } + if ( m_icon == 10 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 64.0f/256.0f; // blue transparent + uv1.y = 192.0f/256.0f; + uv2.x = 160.0f/256.0f; + uv2.y = 208.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(m_pos, m_dim, uv1, uv2, 8.0f/256.0f); + } + if ( m_icon == 11 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 64.0f/256.0f; // yellow transparent + uv1.y = 224.0f/256.0f; + uv2.x = 160.0f/256.0f; + uv2.y = 240.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(m_pos, m_dim, uv1, uv2, 8.0f/256.0f); + } + if ( m_icon == 12 ) // viewfinder cross? + { + dim.x = m_dim.x/2.0f; + dim.y = m_dim.y/2.0f; + + m_engine->SetTexture("mouse.tga"); + m_engine->SetState(D3DSTATETTb); + pos.x = m_pos.x-m_dim.x/300.0f; + pos.y = m_pos.y+m_dim.y/300.0f+dim.y; + uv1.x = 0.5f/256.0f; + uv1.y = 192.5f/256.0f; + uv2.x = 63.5f/256.0f; + uv2.y = 255.5f/256.0f; + DrawIcon(pos, dim, uv1, uv2); // ul + pos.x += dim.x; + Swap(uv1.x, uv2.x); + DrawIcon(pos, dim, uv1, uv2); // ur + pos.y -= dim.y; + Swap(uv1.y, uv2.y); + DrawIcon(pos, dim, uv1, uv2); // dr + pos.x -= dim.x; + Swap(uv1.x, uv2.x); + DrawIcon(pos, dim, uv1, uv2); // dl + + m_engine->SetState(D3DSTATETTw); + pos.x = m_pos.x+m_dim.x/300.0f; + pos.y = m_pos.y-m_dim.y/300.0f+dim.y; + uv1.x = 64.5f/256.0f; + uv1.y = 192.5f/256.0f; + uv2.x = 127.5f/256.0f; + uv2.y = 255.5f/256.0f; + DrawIcon(pos, dim, uv1, uv2); // ul + pos.x += dim.x; + Swap(uv1.x, uv2.x); + DrawIcon(pos, dim, uv1, uv2); // ur + pos.y -= dim.y; + Swap(uv1.y, uv2.y); + DrawIcon(pos, dim, uv1, uv2); // dr + pos.x -= dim.x; + Swap(uv1.x, uv2.x); + DrawIcon(pos, dim, uv1, uv2); // dl + } + if ( m_icon == 13 ) // corner upper / left? + { + m_engine->SetTexture("mouse.tga"); + m_engine->SetState(D3DSTATETTb); + pos.x = m_pos.x-m_dim.x/150.0f; + pos.y = m_pos.y+m_dim.y/150.0f; + uv1.x = 128.5f/256.0f; + uv1.y = 192.5f/256.0f; + uv2.x = 191.5f/256.0f; + uv2.y = 255.5f/256.0f; + DrawIcon(pos, m_dim, uv1, uv2); + + m_engine->SetState(D3DSTATETTw); + pos.x = m_pos.x+m_dim.x/150.0f; + pos.y = m_pos.y-m_dim.y/150.0f; + uv1.x = 192.5f/256.0f; + uv1.y = 192.5f/256.0f; + uv2.x = 255.5f/256.0f; + uv2.y = 255.5f/256.0f; + DrawIcon(pos, m_dim, uv1, uv2); + } + if ( m_icon == 14 ) // corner upper / right? + { + m_engine->SetTexture("mouse.tga"); + m_engine->SetState(D3DSTATETTb); + pos.x = m_pos.x-m_dim.x/150.0f; + pos.y = m_pos.y+m_dim.y/150.0f; + uv2.x = 128.5f/256.0f; + uv1.y = 192.5f/256.0f; + uv1.x = 191.5f/256.0f; + uv2.y = 255.5f/256.0f; + DrawIcon(pos, m_dim, uv1, uv2); + + m_engine->SetState(D3DSTATETTw); + pos.x = m_pos.x+m_dim.x/150.0f; + pos.y = m_pos.y-m_dim.y/150.0f; + uv2.x = 192.5f/256.0f; + uv1.y = 192.5f/256.0f; + uv1.x = 255.5f/256.0f; + uv2.y = 255.5f/256.0f; + DrawIcon(pos, m_dim, uv1, uv2); + } + if ( m_icon == 15 ) // corner lower / left? + { + m_engine->SetTexture("mouse.tga"); + m_engine->SetState(D3DSTATETTb); + pos.x = m_pos.x-m_dim.x/150.0f; + pos.y = m_pos.y+m_dim.y/150.0f; + uv1.x = 128.5f/256.0f; + uv2.y = 192.5f/256.0f; + uv2.x = 191.5f/256.0f; + uv1.y = 255.5f/256.0f; + DrawIcon(pos, m_dim, uv1, uv2); + + m_engine->SetState(D3DSTATETTw); + pos.x = m_pos.x+m_dim.x/150.0f; + pos.y = m_pos.y-m_dim.y/150.0f; + uv1.x = 192.5f/256.0f; + uv2.y = 192.5f/256.0f; + uv2.x = 255.5f/256.0f; + uv1.y = 255.5f/256.0f; + DrawIcon(pos, m_dim, uv1, uv2); + } + if ( m_icon == 16 ) // corner lower / left? + { + m_engine->SetTexture("mouse.tga"); + m_engine->SetState(D3DSTATETTb); + pos.x = m_pos.x-m_dim.x/150.0f; + pos.y = m_pos.y+m_dim.y/150.0f; + uv2.x = 128.5f/256.0f; + uv2.y = 192.5f/256.0f; + uv1.x = 191.5f/256.0f; + uv1.y = 255.5f/256.0f; + DrawIcon(pos, m_dim, uv1, uv2); + + m_engine->SetState(D3DSTATETTw); + pos.x = m_pos.x+m_dim.x/150.0f; + pos.y = m_pos.y-m_dim.y/150.0f; + uv2.x = 192.5f/256.0f; + uv2.y = 192.5f/256.0f; + uv1.x = 255.5f/256.0f; + uv1.y = 255.5f/256.0f; + DrawIcon(pos, m_dim, uv1, uv2); + } + if ( m_icon == 17 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 0.0f/256.0f; // blue frame + uv1.y = 75.0f/256.0f; + uv2.x = 64.0f/256.0f; + uv2.y = 128.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 6.0f/640.0f; + corner.y = 6.0f/480.0f; + DrawIcon(m_pos, m_dim, uv1, uv2, corner, 2.0f/256.0f); + } + if ( m_icon == 18 ) // arrow> for SatCom? + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATETTw); + uv1.x = 0.0f/256.0f; // > + uv1.y = 192.0f/256.0f; + uv2.x = 32.0f/256.0f; + uv2.y = 224.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(m_pos, m_dim, uv1, uv2); + } + if ( m_icon == 19 ) // SatCom symbol? + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATETTw); + uv1.x = 224.0f/256.0f; // SatCom symbol + uv1.y = 224.0f/256.0f; + uv2.x = 256.0f/256.0f; + uv2.y = 256.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(m_pos, m_dim, uv1, uv2); + } + if ( m_icon == 20 ) // solid blue background? + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATETTw); + uv1.x = 224.0f/256.0f; + uv1.y = 32.0f/256.0f; + uv2.x = 256.0f/256.0f; + uv2.y = 64.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(m_pos, m_dim, uv1, uv2); + } + if ( m_icon == 21 ) // stand-by symbol? + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + uv1.x = 160.0f/256.0f; + uv1.y = 32.0f/256.0f; + uv2.x = 192.0f/256.0f; + uv2.y = 64.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(m_pos, m_dim, uv1, uv2); + } + if ( m_icon == 22 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 64.0f/256.0f; // opaque yellow + uv1.y = 224.0f/256.0f; + uv2.x = 160.0f/256.0f; + uv2.y = 240.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 5.0f/640.0f; + corner.y = 5.0f/480.0f; + DrawIcon(m_pos, m_dim, uv1, uv2, corner, 3.0f/256.0f); + } + + if ( m_icon == 23 ) + { + m_engine->SetTexture("button3.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 64.0f/256.0f; // yellow + uv1.y = 192.0f/256.0f; + uv2.x = 80.0f/256.0f; + uv2.y = 208.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 4.0f/640.0f; + corner.y = 4.0f/480.0f; + DrawIcon(m_pos, m_dim, uv1, uv2, corner, 2.0f/256.0f); + } + if ( m_icon == 24 ) + { + m_engine->SetTexture("button3.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 80.0f/256.0f; // orange + uv1.y = 192.0f/256.0f; + uv2.x = 96.0f/256.0f; + uv2.y = 208.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 4.0f/640.0f; + corner.y = 4.0f/480.0f; + DrawIcon(m_pos, m_dim, uv1, uv2, corner, 2.0f/256.0f); + } + if ( m_icon == 25 ) + { + m_engine->SetTexture("button3.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 64.0f/256.0f; // orange + uv1.y = 208.0f/256.0f; + uv2.x = 80.0f/256.0f; + uv2.y = 224.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 4.0f/640.0f; + corner.y = 4.0f/480.0f; + DrawIcon(m_pos, m_dim, uv1, uv2, corner, 2.0f/256.0f); + } + if ( m_icon == 26 ) + { + m_engine->SetTexture("button3.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 80.0f/256.0f; // red + uv1.y = 208.0f/256.0f; + uv2.x = 96.0f/256.0f; + uv2.y = 224.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 4.0f/640.0f; + corner.y = 4.0f/480.0f; + DrawIcon(m_pos, m_dim, uv1, uv2, corner, 2.0f/256.0f); + } + if ( m_icon == 27 ) + { + m_engine->SetTexture("button3.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 32.0f/256.0f; + uv1.y = 0.0f/256.0f; + uv2.x = 64.0f/256.0f; + uv2.y = 32.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(m_pos, m_dim, uv1, uv2); + } + + if ( m_icon >= 100 && m_icon <= 120 ) // building? + { + pos = m_pos; + dim = m_dim; + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 32.0f/256.0f; + uv1.y = 32.0f/256.0f; + uv2.x = uv1.x+32.0f/256.0f; + uv2.y = uv1.y+32.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2); + + m_engine->SetTexture("button3.tga"); + m_engine->SetState(D3DSTATENORMAL); + pos.x += 8.0f/640.0f; + pos.y += 8.0f/480.0f; + dim.x -= 16.0f/640.0f; + dim.y -= 16.0f/480.0f; + uv1.x = 32.0f/256.0f; + uv1.y = 0.0f/256.0f; + uv2.x = uv1.x+32.0f/256.0f; + uv2.y = uv1.y+32.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2); + + m_engine->SetState(D3DSTATENORMAL); + pos.x += 2.0f/640.0f; + pos.y += 2.0f/480.0f; + dim.x -= 4.0f/640.0f; + dim.y -= 4.0f/480.0f; + uv1.x = 0.0f/256.0f; + uv1.y = 0.0f/256.0f; + uv2.x = uv1.x+32.0f/256.0f; + uv2.y = uv1.y+32.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2); + + m_engine->SetState(D3DSTATETTb); + pos.x += 8.0f/640.0f; + pos.y += 8.0f/480.0f; + dim.x -= 16.0f/640.0f; + dim.y -= 16.0f/480.0f; + if ( m_icon == 100 ) icon = 43; // base ? + if ( m_icon == 101 ) icon = 32; // factory ? + if ( m_icon == 102 ) icon = 35; // research ? + if ( m_icon == 103 ) icon = 34; // convert ? + if ( m_icon == 104 ) icon = 36; // station ? + if ( m_icon == 105 ) icon = 40; // radar ? + if ( m_icon == 106 ) icon = 41; // repair ? + if ( m_icon == 107 ) icon = 37; // tower ? + if ( m_icon == 108 ) icon = 39; // energy ? + if ( m_icon == 109 ) icon = 33; // derrick ? + if ( m_icon == 110 ) icon = 42; // nuclear ? + if ( m_icon == 111 ) icon = 38; // labo ? + if ( m_icon == 112 ) icon = 44; // info ? + if ( m_icon == 113 ) icon = 46; // lightning protection ? + if ( m_icon == 114 ) icon = 47; // vault ? + if ( m_icon == 115 ) icon = 48; // control center? + uv1.x = (32.0f/256.0f)*(icon%8); + uv1.y = (32.0f/256.0f)*(icon/8); // uv texture + uv2.x = uv1.x+32.0f/256.0f; + uv2.y = uv1.y+32.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2); + } +} + + diff --git a/src/ui/group.h b/src/ui/group.h new file mode 100644 index 0000000..6dab275 --- /dev/null +++ b/src/ui/group.h @@ -0,0 +1,48 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// group.h + +#ifndef _GROUP_H_ +#define _GROUP_H_ + + +#include "control.h" + + +class CD3DEngine; + + + +class CGroup : public CControl +{ +public: + CGroup(CInstanceManager* iMan); + virtual ~CGroup(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + + BOOL EventProcess(const Event &event); + + void Draw(); + +protected: + +protected: +}; + + +#endif //_GROUP_H_ diff --git a/src/ui/image.cpp b/src/ui/image.cpp new file mode 100644 index 0000000..974216a --- /dev/null +++ b/src/ui/image.cpp @@ -0,0 +1,157 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// image.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "restext.h" +#include "image.h" + + + + +// Object's constructor. + +CImage::CImage(CInstanceManager* iMan) : CControl(iMan) +{ + m_filename[0] = 0; +} + +// Object's destructor. + +CImage::~CImage() +{ + if ( m_filename[0] != 0 ) + { + m_engine->FreeTexture(m_filename); + } +} + + +// Creates a new button. + +BOOL CImage::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + CControl::Create(pos, dim, icon, eventMsg); + + if ( icon == -1 ) + { + char name[100]; + char* p; + + GetResource(RES_EVENT, eventMsg, name); + p = strchr(name, '\\'); + if ( p != 0 ) *p = 0; + SetName(name); + } + + return TRUE; +} + + +// Specifies the name of the image display. + +void CImage::SetFilenameImage(char *name) +{ + if ( m_filename[0] != 0 ) + { + m_engine->FreeTexture(m_filename); + } + + strcpy(m_filename, name); +} + +char* CImage::RetFilenameImage() +{ + return m_filename; +} + + +// Management of an event. + +BOOL CImage::EventProcess(const Event &event) +{ + return TRUE; +} + + +// Draws button. + +void CImage::Draw() +{ + FPOINT uv1,uv2, corner, pos, dim; + float dp; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + if ( m_state & STATE_SHADOW ) + { + DrawShadow(m_pos, m_dim); + } + + dp = 0.5f/256.0f; + + if ( m_icon == 0 ) // hollow frame? + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 160.0f/256.0f; + uv1.y = 192.0f/256.0f; // u-v texture + uv2.x = 192.0f/256.0f; + uv2.y = 224.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 10.0f/640.0f; + corner.y = 10.0f/480.0f; + DrawIcon(m_pos, m_dim, uv1, uv2, corner, 8.0f/256.0f); + } + + if ( m_filename[0] != 0 ) // displays an image? + { + m_engine->LoadTexture(m_filename); + m_engine->SetTexture(m_filename); + m_engine->SetState(D3DSTATENORMAL); + pos = m_pos; + dim = m_dim; + pos.x += 5.0f/640.0f; + pos.y += 5.0f/480.0f; + dim.x -= 10.0f/640.0f; + dim.y -= 10.0f/480.0f; + uv1.x = 0.0f; + uv1.y = 0.0f; + uv2.x = 1.0f; + uv2.y = 1.0f; + DrawIcon(pos, dim, uv1, uv2); + } +} + + diff --git a/src/ui/image.h b/src/ui/image.h new file mode 100644 index 0000000..7545ac0 --- /dev/null +++ b/src/ui/image.h @@ -0,0 +1,52 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// image.h + +#ifndef _IMAGE_H_ +#define _IMAGE_H_ + + +#include "control.h" + + +class CD3DEngine; + + + +class CImage : public CControl +{ +public: + CImage(CInstanceManager* iMan); + virtual ~CImage(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + + BOOL EventProcess(const Event &event); + + void Draw(); + + void SetFilenameImage(char *name); + char* RetFilenameImage(); + +protected: + +protected: + char m_filename[100]; +}; + + +#endif //_IMAGE_H_ diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp new file mode 100644 index 0000000..fe1f112 --- /dev/null +++ b/src/ui/interface.cpp @@ -0,0 +1,607 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// interface.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "control.h" +#include "button.h" +#include "color.h" +#include "check.h" +#include "key.h" +#include "group.h" +#include "image.h" +#include "label.h" +#include "edit.h" +#include "editvalue.h" +#include "scroll.h" +#include "slider.h" +#include "list.h" +#include "shortcut.h" +#include "compass.h" +#include "target.h" +#include "map.h" +#include "window.h" +#include "camera.h" +#include "interface.h" + + + + +// Object's constructor. + +CInterface::CInterface(CInstanceManager* iMan) +{ + int i; + + m_iMan = iMan; + m_iMan->AddInstance(CLASS_INTERFACE, this); + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_camera = 0; + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new button. + +CButton* CInterface::CreateButton(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CButton* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new button. + +CColor* CInterface::CreateColor(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CColor* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new button. + +CCheck* CInterface::CreateCheck(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CCheck* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new button. + +CKey* CInterface::CreateKey(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CKey* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new button. + +CGroup* CInterface::CreateGroup(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CGroup* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new button. + +CImage* CInterface::CreateImage(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CImage* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new label. + +CLabel* CInterface::CreateLabel(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, + char *name) +{ + CLabel* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg); + pc->SetName(name); + return pc; + } + } + return 0; +} + +// Creates a new pave editable. + +CEdit* CInterface::CreateEdit(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CEdit* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new pave editable. + +CEditValue* CInterface::CreateEditValue(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CEditValue* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new lift. + +CScroll* CInterface::CreateScroll(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CScroll* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new cursor. + +CSlider* CInterface::CreateSlider(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CSlider* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new list. + +CList* CInterface::CreateList(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, + float expand) +{ + CList* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg, expand); + return pc; + } + } + return 0; +} + +// Creates a new shortcut. + +CShortcut* CInterface::CreateShortcut(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CShortcut* ps; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg); + return ps; + } + } + return 0; +} + +// Creates a new compass. + +CCompass* CInterface::CreateCompass(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CCompass* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new target. + +CTarget* CInterface::CreateTarget(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CTarget* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new map. + +CMap* CInterface::CreateMap(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CMap* pm; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=10 ; iCreate(pos, dim, icon, eventMsg); + return pm; + } + } + return 0; +} + +// Removes a control. + +BOOL CInterface::DeleteControl(EventMsg eventMsg) +{ + int i; + + for ( i=0 ; iRetEventMsg() ) + { + delete m_table[i]; + m_table[i] = 0; + return TRUE; + } + } + } + return FALSE; +} + +// Gives a control. + +CControl* CInterface::SearchControl(EventMsg eventMsg) +{ + int i; + + for ( i=0 ; iRetEventMsg() ) + { + return m_table[i]; + } + } + } + return 0; +} + +// Management of an event. + +BOOL CInterface::EventProcess(const Event &event) +{ + int i; + + if ( event.event == EVENT_MOUSEMOVE ) + { + if ( m_camera == 0 ) + { + m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); + } + m_engine->SetMouseType(m_camera->RetMouseDef(event.pos)); + } + + for ( i=MAXCONTROL-1 ; i>=0 ; i-- ) + { + if ( m_table[i] != 0 && + m_table[i]->TestState(STATE_ENABLE) ) + { + if ( !m_table[i]->EventProcess(event) ) + { + return FALSE; + } + } + } + + return TRUE; +} + + +// Gives the tooltip binding to the window. + +BOOL CInterface::GetTooltip(FPOINT pos, char* name) +{ + int i; + + for ( i=MAXCONTROL-1 ; i>=0 ; i-- ) + { + if ( m_table[i] != 0 ) + { + if ( m_table[i]->GetTooltip(pos, name) ) + { + return TRUE; + } + } + } + return FALSE; +} + + +// Draws all buttons. + +void CInterface::Draw() +{ + D3DMATERIAL7 material; + int i; + + ZeroMemory( &material, sizeof(D3DMATERIAL7) ); + material.diffuse.r = 1.0f; + material.diffuse.g = 1.0f; + material.diffuse.b = 1.0f; + material.ambient.r = 0.5f; + material.ambient.g = 0.5f; + material.ambient.b = 0.5f; + m_engine->SetMaterial(material); + + for ( i=0 ; i=0 ; i-- ) + { + if ( m_table[i] != 0 ) + { + m_table[i]->Draw(); + } + } +} + + diff --git a/src/ui/interface.h b/src/ui/interface.h new file mode 100644 index 0000000..4a8f202 --- /dev/null +++ b/src/ui/interface.h @@ -0,0 +1,93 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// interface.h + +#ifndef _INTERFACE_H_ +#define _INTERFACE_H_ + + +class CInstanceManager; +class CD3DEngine; +class CControl; +class CWindow; +class CButton; +class CColor; +class CCheck; +class CKey; +class CGroup; +class CImage; +class CLabel; +class CEdit; +class CEditValue; +class CScroll; +class CSlider; +class CList; +class CShortcut; +class CMap; +class CGauge; +class CCompass; +class CTarget; +class CCamera; + + +#define MAXCONTROL 100 + + +class CInterface +{ +public: + CInterface(CInstanceManager* iMan); + ~CInterface(); + + BOOL EventProcess(const Event &event); + BOOL GetTooltip(FPOINT pos, char* name); + + void Flush(); + CWindow* CreateWindows(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CButton* CreateButton(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CColor* CreateColor(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CCheck* CreateCheck(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CKey* CreateKey(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CGroup* CreateGroup(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CImage* CreateImage(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CLabel* CreateLabel(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, char *name); + CEdit* CreateEdit(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CEditValue* CreateEditValue(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CScroll* CreateScroll(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CSlider* CreateSlider(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CList* CreateList(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, float expand=1.2f); + CShortcut* CreateShortcut(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CCompass* CreateCompass(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CTarget* CreateTarget(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CMap* CreateMap(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + BOOL DeleteControl(EventMsg eventMsg); + CControl* SearchControl(EventMsg eventMsg); + + void Draw(); + +protected: + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CCamera* m_camera; + + CControl* m_table[MAXCONTROL]; +}; + + +#endif //_INTERFACE_H_ diff --git a/src/ui/key.cpp b/src/ui/key.cpp new file mode 100644 index 0000000..c59dac3 --- /dev/null +++ b/src/ui/key.cpp @@ -0,0 +1,290 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// key.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "restext.h" +#include "sound.h" +#include "text.h" +#include "key.h" + + + + +// Constructs the name of a button. + +void GetKeyName(char *name, int key) +{ + if ( !GetResource(RES_KEY, key, name) ) + { + if ( (key >= '0' && key <= '9') || + (key >= 'A' && key <= 'Z') || + (key >= 'a' && key <= 'z') ) + { + name[0] = key; + name[1] = 0; + } + else + { + sprintf(name, "Code %d", key); + } + } +} + + + + +// Object's constructor. + +CKey::CKey(CInstanceManager* iMan) : CControl(iMan) +{ + m_key[0] = 0; + m_key[1] = 0; + m_bCatch = FALSE; +} + +// Object's destructor. + +CKey::~CKey() +{ +} + + +// Creates a new button. + +BOOL CKey::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + char name[100]; + char* p; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + CControl::Create(pos, dim, icon, eventMsg); + + GetResource(RES_EVENT, eventMsg, name); + p = strchr(name, '\\'); + if ( p != 0 ) *p = 0; + SetName(name); + + return TRUE; +} + + +// Management of an event. + +BOOL CKey::EventProcess(const Event &event) +{ + if ( m_state & STATE_DEAD ) return TRUE; + + CControl::EventProcess(event); + + if ( event.event == EVENT_LBUTTONDOWN ) + { + if ( Detect(event.pos) ) + { + m_bCatch = TRUE; + } + else + { + m_bCatch = FALSE; + } + } + + if ( event.event == EVENT_KEYDOWN && m_bCatch ) + { + m_bCatch = FALSE; + + if ( TestKey(event.param) ) // impossible ? + { + m_sound->Play(SOUND_TZOING); + } + else + { + if ( event.param == m_key[0] || + event.param == m_key[1] ) + { + m_key[0] = event.param; + m_key[1] = 0; + } + else + { + m_key[1] = m_key[0]; + m_key[0] = event.param; + } + m_sound->Play(SOUND_CLICK); + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + } + return FALSE; + } + + return TRUE; +} + + +// Seeks when a key is already used. + +BOOL CKey::TestKey(int key) +{ + int i, j; + + if ( key == VK_PAUSE || + key == VK_SNAPSHOT ) return TRUE; // blocked key + + for ( i=0 ; i<20 ; i++ ) + { + for ( j=0 ; j<2 ; j++ ) + { + if ( key == m_engine->RetKey(i, j) ) // key used? + { + m_engine->SetKey(i, j, 0); // nothing! + } + } + + if ( m_engine->RetKey(i, 0) == 0 ) // first free option? + { + m_engine->SetKey(i, 0, m_engine->RetKey(i, 1)); // shift + m_engine->SetKey(i, 1, 0); + } + } + + return FALSE; // not used +} + + +// Draws button. + +void CKey::Draw() +{ + FPOINT iDim, pos; + float zoomExt, zoomInt, h; + int icon; + char text[100]; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + iDim = m_dim; + m_dim.x = 200.0f/640.0f; + + if ( m_state & STATE_SHADOW ) + { + DrawShadow(m_pos, m_dim); + } + + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + + zoomExt = 1.00f; + zoomInt = 0.95f; + + icon = 2; + if ( m_key[0] == 0 && + m_key[1] == 0 ) // no shortcut? + { + icon = 3; + } + if ( m_state & STATE_DEFAULT ) + { + DrawPart(23, 1.3f, 0.0f); + + zoomExt *= 1.15f; + zoomInt *= 1.15f; + } + if ( m_state & STATE_HILIGHT ) + { + icon = 1; + } + if ( m_state & STATE_CHECK ) + { + icon = 0; + } + if ( m_state & STATE_PRESS ) + { + icon = 3; + zoomInt *= 0.9f; + } + if ( (m_state & STATE_ENABLE) == 0 ) + { + icon = 7; + } + if ( m_state & STATE_DEAD ) + { + icon = 17; + } + if ( m_bCatch ) + { + icon = 23; + } + DrawPart(icon, zoomExt, 8.0f/256.0f); // draws the button + + h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; + + GetKeyName(text, m_key[0]); + if ( m_key[1] != 0 ) + { + GetResource(RES_TEXT, RT_KEY_OR, text+strlen(text)); + GetKeyName(text+strlen(text), m_key[1]); + } + + pos.x = m_pos.x+m_dim.x*0.5f; + pos.y = m_pos.y+m_dim.y*0.5f; + pos.y -= h; + m_engine->RetText()->DrawText(text, pos, m_dim.x, 0, m_fontSize, m_fontStretch, m_fontType, 0); + + m_dim = iDim; + + if ( m_state & STATE_DEAD ) return; + + // Draws the name. + pos.x = m_pos.x+(214.0f/640.0f); + pos.y = m_pos.y+m_dim.y*0.5f; + pos.y -= h; + m_engine->RetText()->DrawText(m_name, pos, m_dim.x, 1, m_fontSize, m_fontStretch, m_fontType, 0); +} + + + +void CKey::SetKey(int option, int key) +{ + if ( option < 0 || + option > 1 ) return; + + m_key[option] = key; +} + +int CKey::RetKey(int option) +{ + if ( option < 0 || + option > 1 ) return 0; + + return m_key[option]; +} + diff --git a/src/ui/key.h b/src/ui/key.h new file mode 100644 index 0000000..f292425 --- /dev/null +++ b/src/ui/key.h @@ -0,0 +1,54 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// key.h + +#ifndef _KEY_H_ +#define _KEY_H_ + + +#include "control.h" + + +class CD3DEngine; + + + +class CKey : public CControl +{ +public: + CKey(CInstanceManager* iMan); + virtual ~CKey(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + + BOOL EventProcess(const Event &event); + + void Draw(); + + void SetKey(int option, int key); + int RetKey(int option); + +protected: + BOOL TestKey(int key); + +protected: + int m_key[2]; + BOOL m_bCatch; +}; + + +#endif //_KEY_H_ diff --git a/src/ui/label.cpp b/src/ui/label.cpp new file mode 100644 index 0000000..46d0099 --- /dev/null +++ b/src/ui/label.cpp @@ -0,0 +1,95 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// label.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "text.h" +#include "label.h" + + + + +// Object's constructor. + +CLabel::CLabel(CInstanceManager* iMan) : CControl(iMan) +{ +} + +// Object's destructor. + +CLabel::~CLabel() +{ +} + + +// Creates a new button. + +BOOL CLabel::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + CControl::Create(pos, dim, icon, eventMsg); + return TRUE; +} + + +// Management of an event. + +BOOL CLabel::EventProcess(const Event &event) +{ +//? CControl::EventProcess(event); + return TRUE; +} + + +// Draws button. + +void CLabel::Draw() +{ + FPOINT pos; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + pos.y = m_pos.y+m_dim.y/2.0f; + + if ( m_justif > 0 ) + { + pos.x = m_pos.x; + } + if ( m_justif == 0 ) + { + pos.x = m_pos.x+m_dim.x/2.0f; + } + if ( m_justif < 0 ) + { + pos.x = m_pos.x+m_dim.x; + } + m_engine->RetText()->DrawText(m_name, pos, m_dim.x, m_justif, m_fontSize, m_fontStretch, m_fontType, 0); +} + diff --git a/src/ui/label.h b/src/ui/label.h new file mode 100644 index 0000000..c36a758 --- /dev/null +++ b/src/ui/label.h @@ -0,0 +1,48 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// label.h + +#ifndef _LABEL_H_ +#define _LABEL_H_ + + +#include "control.h" + + +class CD3DEngine; + + + +class CLabel : public CControl +{ +public: + CLabel(CInstanceManager* iMan); + virtual ~CLabel(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + + BOOL EventProcess(const Event &event); + + void Draw(); + +protected: + +protected: +}; + + +#endif //_LABEL_H_ diff --git a/src/ui/list.cpp b/src/ui/list.cpp new file mode 100644 index 0000000..08b09c0 --- /dev/null +++ b/src/ui/list.cpp @@ -0,0 +1,870 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// list.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "button.h" +#include "scroll.h" +#include "text.h" +#include "list.h" + + + +#define MARGING 4.0f + + + +// Object's constructor. + +CList::CList(CInstanceManager* iMan) : CControl(iMan) +{ + int i; + + for ( i=0 ; iCreate(pos, dim, 0, EVENT_NULL); + m_eventScroll = m_scroll->RetEventMsg(); + + return MoveAdjust(); +} + +// Adjusted after a change of dimensions. + +BOOL CList::MoveAdjust() +{ + FPOINT ipos, idim, ppos, ddim; + float marging, h; + int i; + + for ( i=0 ; iRetText()->RetHeight(m_fontSize, m_fontType)*m_expand; + + m_displayLine = (int)(idim.y/h); + if ( m_displayLine == 0 ) return FALSE; + if ( m_displayLine > LISTMAXDISPLAY ) m_displayLine = LISTMAXDISPLAY; + idim.y = h*m_displayLine; + m_dim.y = idim.y+marging*2.0f/480.f; + + ppos.x = ipos.x; + ppos.y = ipos.y+idim.y-h; + ddim.x = idim.x-SCROLL_WIDTH; + ddim.y = h; + for ( i=0 ; iCreate(ppos, ddim, -1, EVENT_NULL); + m_button[i]->SetJustif(1); + m_button[i]->SetState(STATE_SIMPLY); + m_button[i]->SetFontType(m_fontType); + m_button[i]->SetFontSize(m_fontSize); + ppos.y -= h; + + m_eventButton[i] = m_button[i]->RetEventMsg(); + } + + if ( m_scroll != 0 ) + { + ppos.x = ipos.x+idim.x-SCROLL_WIDTH; + ppos.y = ipos.y; + ddim.x = SCROLL_WIDTH; + ddim.y = idim.y; + m_scroll->SetPos(ppos); + m_scroll->SetDim(ddim); + } + + UpdateScroll(); + UpdateButton(); + return TRUE; +} + + +// Returns the message of a button. + +EventMsg CList::RetEventMsgButton(int i) +{ + if ( i < 0 || i >= m_displayLine ) return EVENT_NULL; + if ( m_button[i] == 0 ) return EVENT_NULL; + return m_button[i]->RetEventMsg(); +} + +// Returns the message from the elevator. + +EventMsg CList::RetEventMsgScroll() +{ + if ( m_scroll == 0 ) return EVENT_NULL; + return m_scroll->RetEventMsg(); +} + + +void CList::SetPos(FPOINT pos) +{ + CControl::SetPos(pos); +} + +void CList::SetDim(FPOINT dim) +{ + m_dim = dim; + MoveAdjust(); + CControl::SetDim(dim); +} + + +BOOL CList::SetState(int state, BOOL bState) +{ + int i; + + if ( state & STATE_ENABLE ) + { + for ( i=0 ; iSetState(state, bState); + } + if ( m_scroll != 0 ) m_scroll->SetState(state, bState); + } + + return CControl::SetState(state, bState); +} + +BOOL CList::SetState(int state) +{ + int i; + + if ( state & STATE_ENABLE ) + { + for ( i=0 ; iSetState(state); + } + if ( m_scroll != 0 ) m_scroll->SetState(state); + } + + return CControl::SetState(state); +} + +BOOL CList::ClearState(int state) +{ + int i; + + if ( state & STATE_ENABLE ) + { + for ( i=0 ; iClearState(state); + } + if ( m_scroll != 0 ) m_scroll->ClearState(state); + } + + return CControl::ClearState(state); +} + + +// Management of an event. + +BOOL CList::EventProcess(const Event &event) +{ + int i; + + if ( m_bBlink && // blinks? + event.event == EVENT_FRAME ) + { + i = m_selectLine-m_firstLine; + + if ( i >= 0 && i < 4 && + m_button[i] != 0 ) + { + m_blinkTime += event.rTime; + if ( Mod(m_blinkTime, 0.7f) < 0.3f ) + { + m_button[i]->ClearState(STATE_ENABLE); + m_button[i]->ClearState(STATE_CHECK); + } + else + { + m_button[i]->SetState(STATE_ENABLE); + m_button[i]->SetState(STATE_CHECK); + } + } + } + + if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; + if ( (m_state & STATE_ENABLE) == 0 ) return TRUE; + + if ( event.event == EVENT_KEYDOWN && + event.param == VK_WHEELUP && + Detect(event.pos) ) + { + if ( m_firstLine > 0 ) m_firstLine --; + UpdateScroll(); + UpdateButton(); + return TRUE; + } + if ( event.event == EVENT_KEYDOWN && + event.param == VK_WHEELDOWN && + Detect(event.pos) ) + { + if ( m_firstLine < m_totalLine-m_displayLine ) m_firstLine ++; + UpdateScroll(); + UpdateButton(); + return TRUE; + } + + CControl::EventProcess(event); + + if ( event.event == EVENT_MOUSEMOVE && Detect(event.pos) ) + { + m_engine->SetMouseType(D3DMOUSENORM); + for ( i=0 ; i= m_totalLine ) break; + if ( m_button[i] != 0 ) + { + m_button[i]->EventProcess(event); + } + } + } + + if ( m_bSelectCap ) + { + for ( i=0 ; i= m_totalLine ) break; + if ( m_button[i] != 0 ) + { + if ( !m_button[i]->EventProcess(event) ) return FALSE; + + if ( event.event == m_eventButton[i] ) + { + SetSelect(m_firstLine+i); + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); // selected line changes + } + } + } + } + + if ( m_scroll != 0 ) + { + if ( !m_scroll->EventProcess(event) ) return FALSE; + + if ( event.event == m_eventScroll ) + { + MoveScroll(); + UpdateButton(); + } + } + + return TRUE; +} + + +// Draws the list. + +void CList::Draw() +{ + FPOINT uv1, uv2, corner, pos, dim, ppos, ddim; + float dp; + int i, j; + char text[100]; + char *pb, *pe; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + if ( m_state & STATE_SHADOW ) + { + DrawShadow(m_pos, m_dim); + } + + dp = 0.5f/256.0f; + + if ( m_icon != -1 ) + { + dim = m_dim; + + if ( m_icon == 0 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + + uv1.x = 128.0f/256.0f; + uv1.y = 64.0f/256.0f; // u-v texture + uv2.x = 160.0f/256.0f; + uv2.y = 96.0f/256.0f; + } + else + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + + uv1.x = 132.0f/256.0f; + uv1.y = 68.0f/256.0f; // u-v texture + uv2.x = 156.0f/256.0f; + uv2.y = 92.0f/256.0f; + + if ( m_button[0] != 0 ) + { + dim = m_button[0]->RetDim(); + dim.y *= m_displayLine; // background sounds spot behind + } + } + + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + corner.x = 10.0f/640.0f; + corner.y = 10.0f/480.0f; + DrawIcon(m_pos, dim, uv1, uv2, corner, 8.0f/256.0f); + } + + if ( m_totalLine < m_displayLine ) // no buttons to the bottom? + { + i = m_totalLine; + if ( m_button[i] != 0 ) + { + pos = m_button[i]->RetPos(); + dim = m_button[i]->RetDim(); + pos.y += dim.y*1.1f; + dim.y *= 0.4f; + pos.y -= dim.y; + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + uv1.x = 120.0f/256.0f; + uv1.y = 64.0f/256.0f; + uv2.x = 128.0f/256.0f; + uv2.y = 48.0f/256.0f; + uv1.x += dp; + uv1.y -= dp; + uv2.x -= dp; + uv2.y += dp; + DrawIcon(pos, dim, uv1, uv2); // ch'tite shadow cute (?) + } + } + + for ( i=0 ; i= m_totalLine ) break; + + if ( m_button[i] != 0 ) + { + if ( !m_bBlink && i+m_firstLine < m_totalLine ) + { + m_button[i]->SetState(STATE_ENABLE, m_enable[i+m_firstLine] && (m_state & STATE_ENABLE) ); + } + m_button[i]->Draw(); // draws a box without text + + // draws text in the box + pos = m_button[i]->RetPos(); + dim = m_button[i]->RetDim(); + if ( m_tabs[0] == 0.0f ) + { + ppos.x = pos.x+dim.y*0.5f; + ppos.y = pos.y+dim.y*0.5f; + ppos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; + ddim.x = dim.x-dim.y; + DrawCase(m_text[i+m_firstLine], ppos, ddim.x, 1); + } + else + { + ppos.x = pos.x+dim.y*0.5f; + ppos.y = pos.y+dim.y*0.5f; + ppos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; + pb = m_text[i+m_firstLine]; + for ( j=0 ; j<10 ; j++ ) + { + pe = strchr(pb, '\t'); + if ( pe == 0 ) + { + strcpy(text, pb); + } + else + { + strncpy(text, pb, pe-pb); + text[pe-pb] = 0; + } + DrawCase(text, ppos, m_tabs[j], m_justifs[j]); + + if ( pe == 0 ) break; + ppos.x += m_tabs[j]; + pb = pe+1; + } + } + + if ( (m_state & STATE_EXTEND) && i < m_totalLine ) + { + pos = m_button[i]->RetPos(); + dim = m_button[i]->RetDim(); + pos.x += dim.x-dim.y*0.75f; + dim.x = dim.y*0.75f; + pos.x += 2.0f/640.0f; + pos.y += 2.0f/480.0f; + dim.x -= 4.0f/640.0f; + dim.y -= 4.0f/480.0f; + + if ( m_check[i+m_firstLine] ) + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 64.0f/256.0f; + uv1.y = 0.0f/256.0f; + uv2.x = 96.0f/256.0f; + uv2.y = 32.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2); // square shape + + m_engine->SetState(D3DSTATETTw); + uv1.x = 0.0f/256.0f; // v + uv1.y = 64.0f/256.0f; + uv2.x = 32.0f/256.0f; + uv2.y = 96.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2); // draws v + } + else + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATETTw); + if ( i+m_firstLine == m_selectLine ) + { + uv1.x =224.0f/256.0f; // < + uv1.y =192.0f/256.0f; + uv2.x =256.0f/256.0f; + uv2.y =224.0f/256.0f; + } + else + { + uv1.x = 96.0f/256.0f; // x + uv1.y = 32.0f/256.0f; + uv2.x =128.0f/256.0f; + uv2.y = 64.0f/256.0f; + } + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2); // draws x + } + } + } + } + + if ( m_scroll != 0 ) + { + m_scroll->Draw(); // draws the lift + } +} + +// Displays text in a box. + +void CList::DrawCase(char *text, FPOINT pos, float width, int justif) +{ + if ( justif == 1 ) + { + m_engine->RetText()->DrawText(text, pos, width, 1, m_fontSize, m_fontStretch, m_fontType, 0); + } + else if ( justif == 0 ) + { + pos.x += width/2.0f; + m_engine->RetText()->DrawText(text, pos, width, 0, m_fontSize, m_fontStretch, m_fontType, 0); + } + else + { + pos.x += width; + m_engine->RetText()->DrawText(text, pos, width, -1, m_fontSize, m_fontStretch, m_fontType, 0); + } +} + + +// Empty the list completely. + +void CList::Flush() +{ + m_totalLine = 0; + m_selectLine = -1; + m_firstLine = 0; + UpdateButton(); + UpdateScroll(); +} + + +// Specifies the total number of lines. + +void CList::SetTotal(int i) +{ + m_totalLine = i; +} + +// Returns the total number of lines. + +int CList::RetTotal() +{ + return m_totalLine; +} + + +// Selects a line. + +void CList::SetSelect(int i) +{ + if ( m_bSelectCap ) + { + m_selectLine = i; + } + else + { + m_firstLine = i; + UpdateScroll(); + } + + UpdateButton(); +} + +// Returns the selected line. + +int CList::RetSelect() +{ + if ( m_bSelectCap ) + { + return m_selectLine; + } + else + { + return m_firstLine; + } +} + + +// Management of capability has a select box. + +void CList::SetSelectCap(BOOL bEnable) +{ + m_bSelectCap = bEnable; +} + +BOOL CList::RetSelectCap() +{ + return m_bSelectCap; +} + + +// Blink a line. + +void CList::SetBlink(BOOL bEnable) +{ + int i; + + m_bBlink = bEnable; + m_blinkTime = 0.0f; + + i = m_selectLine-m_firstLine; + + if ( i >= 0 && i < 4 && + m_button[i] != 0 ) + { + if ( !bEnable ) + { + m_button[i]->SetState(STATE_CHECK); + m_button[i]->ClearState(STATE_ENABLE); + } + } +} + +BOOL CList::RetBlink() +{ + return m_bBlink; +} + + +// Specifies the text of a line. + +void CList::SetName(int i, char* name) +{ + if ( i < 0 || i >= LISTMAXTOTAL ) return; + + if ( i >= m_totalLine ) + { + m_totalLine = i+1; // expands the list + } + + if ( name[0] == 0 ) + { + strcpy(m_text[i], " "); + } + else + { + strcpy(m_text[i], name); + } + UpdateButton(); + UpdateScroll(); +} + +// Returns the text of a line. + +char* CList::RetName(int i) +{ + if ( i < 0 || i >= m_totalLine ) return 0; + + return m_text[i]; +} + + +// Specifies the bit "check" for a box. + +void CList::SetCheck(int i, BOOL bMode) +{ + if ( i < 0 || i >= m_totalLine ) return; + + m_check[i] = bMode; +} + +// Returns the bit "check" for a box. + +BOOL CList::RetCheck(int i) +{ + if ( i < 0 || i >= m_totalLine ) return FALSE; + + return m_check[i]; +} + + +// Specifies the bit "enable" for a box. + +void CList::SetEnable(int i, BOOL bMode) +{ + if ( i < 0 || i >= m_totalLine ) return; + + m_enable[i] = bMode; +} + +// Returns the bit "enable" for a box. + +BOOL CList::RetEnable(int i) +{ + if ( i < 0 || i >= m_totalLine ) return FALSE; + + return m_enable[i]; +} + + +// Management of the position of the tabs. + +void CList::SetTabs(int i, float pos, int justif) +{ + if ( i < 0 || i >= 10 ) return; + m_tabs[i] = pos; + m_justifs[i] = justif; +} + +float CList::RetTabs(int i) +{ + if ( i < 0 || i >= 10 ) return 0.0f; + return m_tabs[i]; +} + + +// Moves the lift to see the list of the selected line. + +void CList::ShowSelect(BOOL bFixed) +{ + int sel; + + if ( bFixed && + m_selectLine >= m_firstLine && + m_selectLine < m_firstLine+m_displayLine ) return; // all good + + sel = m_selectLine; + + // Down from 1/2 * h. + sel += m_displayLine/2; + if ( sel > m_totalLine-1 ) sel = m_totalLine-1; + + // Back to h-1. + sel -= m_displayLine-1; + if ( sel < 0 ) sel = 0; + + m_firstLine = sel; + + UpdateButton(); + UpdateScroll(); +} + + +// Updates all button names. + +void CList::UpdateButton() +{ + int state, i, j; + + state = CControl::RetState(); + + j = m_firstLine; + for ( i=0 ; iSetState(STATE_CHECK, (j == m_selectLine)); + + if ( j < m_totalLine ) + { +//? m_button[i]->SetName(m_text[j]); + m_button[i]->SetName(" "); // blank button + m_button[i]->SetState(STATE_ENABLE, (state & STATE_ENABLE)); + } + else + { + m_button[i]->SetName(" "); // blank button + m_button[i]->ClearState(STATE_ENABLE); + } + j ++; + } +} + +// Updates the lift. + +void CList::UpdateScroll() +{ + float ratio, value, step; + + if ( m_scroll == 0 ) return; + + if ( m_totalLine <= m_displayLine ) + { + ratio = 1.0f; + value = 0.0f; + step = 0.0f; + } + else + { + ratio = (float)m_displayLine/m_totalLine; + if ( ratio > 1.0f ) ratio = 1.0f; + + value = (float)m_firstLine/(m_totalLine-m_displayLine); + if ( value < 0.0f ) value = 0.0f; + if ( value > 1.0f ) value = 1.0f; + + step = (float)1.0f/(m_totalLine-m_displayLine); + if ( step < 0.0f ) step = 0.0f; + } + + m_scroll->SetVisibleRatio(ratio); + m_scroll->SetVisibleValue(value); + m_scroll->SetArrowStep(step); +} + +// Update when the lift is moving. + +void CList::MoveScroll() +{ + float pos; + int n; + + if ( m_scroll == 0 ) return; + + n = m_totalLine-m_displayLine; + pos = m_scroll->RetVisibleValue(); + pos += m_scroll->RetArrowStep()/2.0f; // it's magic! + m_firstLine = (int)(pos*n); + if ( m_firstLine < 0 ) m_firstLine = 0; + if ( m_firstLine > n ) m_firstLine = n; +} + + diff --git a/src/ui/list.h b/src/ui/list.h new file mode 100644 index 0000000..43d155f --- /dev/null +++ b/src/ui/list.h @@ -0,0 +1,117 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// list.h + +#ifndef _LIST_H_ +#define _LIST_H_ + + +#include "control.h" +#include "event.h" + + +class CD3DEngine; +class CButton; +class CScroll; + + +#define LISTMAXDISPLAY 20 // maximum number of visible lines +#define LISTMAXTOTAL 100 // maximum total number of lines + + + +class CList : public CControl +{ +public: + CList(CInstanceManager* iMan); + ~CList(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, float expand); + + void SetPos(FPOINT pos); + void SetDim(FPOINT dim); + + BOOL SetState(int state, BOOL bState); + BOOL SetState(int state); + BOOL ClearState(int state); + + BOOL EventProcess(const Event &event); + void Draw(); + + void Flush(); + + void SetTotal(int i); + int RetTotal(); + + void SetSelect(int i); + int RetSelect(); + + void SetSelectCap(BOOL bEnable); + BOOL RetSelectCap(); + + void SetBlink(BOOL bEnable); + BOOL RetBlink(); + + void SetName(int i, char* name); + char* RetName(int i); + + void SetCheck(int i, BOOL bMode); + BOOL RetCheck(int i); + + void SetEnable(int i, BOOL bEnable); + BOOL RetEnable(int i); + + void SetTabs(int i, float pos, int justif=1); + float RetTabs(int i); + + void ShowSelect(BOOL bFixed); + + EventMsg RetEventMsgButton(int i); + EventMsg RetEventMsgScroll(); + +protected: + BOOL MoveAdjust(); + void UpdateButton(); + void UpdateScroll(); + void MoveScroll(); + void DrawCase(char *text, FPOINT pos, float width, int justif); + +protected: + CButton* m_button[LISTMAXDISPLAY]; + CScroll* m_scroll; + + EventMsg m_eventButton[LISTMAXDISPLAY]; + EventMsg m_eventScroll; + + float m_expand; + int m_totalLine; // total number of lines + int m_displayLine; // number of visible lines + int m_selectLine; // selected line + int m_firstLine; // first visible line + BOOL m_bBlink; + BOOL m_bSelectCap; + float m_blinkTime; + float m_tabs[10]; + int m_justifs[10]; + + char m_text[LISTMAXTOTAL][100]; + char m_check[LISTMAXTOTAL]; + char m_enable[LISTMAXTOTAL]; +}; + + +#endif //_LIST_H_ diff --git a/src/ui/maindialog.cpp b/src/ui/maindialog.cpp new file mode 100644 index 0000000..a216cd9 --- /dev/null +++ b/src/ui/maindialog.cpp @@ -0,0 +1,6937 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// maindialog.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "global.h" +#include "language.h" +#include "event.h" +#include "misc.h" +#include "profile.h" +#include "iman.h" +#include "restext.h" +#include "math3d.h" +#include "particule.h" +#include "interface.h" +#include "button.h" +#include "color.h" +#include "check.h" +#include "key.h" +#include "group.h" +#include "image.h" +#include "scroll.h" +#include "slider.h" +#include "list.h" +#include "label.h" +#include "window.h" +#include "edit.h" +#include "editvalue.h" +#include "text.h" +#include "camera.h" +#include "sound.h" +#include "cmdtoken.h" +#include "robotmain.h" +#include "maindialog.h" + + + +#define KEY_VISIBLE 6 // number of visible keys redefinable + +#if _SCHOOL & _TEEN +#define KEY_TOTAL 13 // total number of keys redefinable +#else +#define KEY_TOTAL 21 // total number of keys redefinable +#endif + +#define WELCOME_LENGTH 6.0f + + + +static int perso_color[3*10*3] = +{ + // hair: + 193, 221, 226, // white + 255, 255, 181, // yellow + 204, 155, 84, // blond + 165, 48, 10, // red + 140, 75, 84, // brown + 83, 64, 51, // brown + 90, 95, 85, // black + 85, 48, 9, // brown + 60, 0, 23, // black + 0, 0, 0, // + // spacesuit: + 203, 206, 204, // dirty white + 0, 205, 203, // bluish + 108, 176, 0, // greenish + 207, 207, 32, // yellow + 170, 141, 0, // orange + 108, 84, 0, // brown + 0, 84, 136, // bluish + 56, 61, 146, // bluish + 56, 56, 56, // black + 0, 0, 0, // + // strips: + 255, 255, 255, // white + 255, 255, 0, // yellow + 255, 132, 1, // orange + 255, 0, 255, // magenta + 255, 0, 0, // red + 0, 255, 0, // green + 0, 255, 255, // cyan + 0, 0, 255, // blue + 70, 51, 84, // dark + 0, 0, 0, // +}; + + +#if _NET +// Check if the key "school" is present in the registry. + +BOOL SchoolCheck() +{ + HKEY key; + char buffer[100]; + LONG i; + DWORD type, len; + + i = RegOpenKeyEx(HKEY_LOCAL_MACHINE, +#if _NEWLOOK + "Software\\Epsitec\\CeeBot\\Setup", +#else + "Software\\Epsitec\\Colobot\\Setup", +#endif + 0, KEY_READ, &key); + if ( i != ERROR_SUCCESS ) return FALSE; + + type = REG_SZ; + len = sizeof(buffer); + i = RegQueryValueEx(key, "School", NULL, &type, (LPBYTE)buffer, &len); + if ( i != ERROR_SUCCESS || type != REG_SZ ) return FALSE; + + if ( strcmp(buffer, "ToBoLoC") != 0 ) return FALSE; + + return TRUE; +} +#endif + + +// Constructor of robot application. + +CMainDialog::CMainDialog(CInstanceManager* iMan) +{ + int i; + + m_iMan = iMan; + m_iMan->AddInstance(CLASS_DIALOG, this); + + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); + m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + + m_phase = PHASE_NAME; + m_phaseSetup = PHASE_SETUPg; + m_phaseTerm = PHASE_TRAINER; + m_sceneRead[0] = 0; + m_stackRead[0] = 0; + m_sceneName[0] = 0; + m_sceneRank = 0; + m_bSceneSoluce = FALSE; + m_bSimulSetup = FALSE; +#if _NET + m_accessEnable = SchoolCheck(); + m_accessMission= FALSE; + m_accessUser = FALSE; +#else + m_accessEnable = TRUE; + m_accessMission= TRUE; + m_accessUser = TRUE; +#endif + m_bDeleteGamer = TRUE; + + for ( i=0 ; i<10 ; i++ ) + { + m_chap[i] = 0; + m_sel[i] = 0; + } + m_index = 0; + m_maxList = 0; + + ZeroMemory(&m_perso, sizeof(GamerPerso)); + DefPerso(); + + m_bTooltip = TRUE; + m_bGlint = TRUE; + m_bRain = TRUE; + m_bSoluce4 = TRUE; + m_bMovies = TRUE; + m_bNiceReset = TRUE; + m_bHimselfDamage = TRUE; +#if _TEEN + m_bCameraScroll = FALSE; +#else + m_bCameraScroll = TRUE; +#endif + m_bCameraInvertX = FALSE; + m_bCameraInvertY = FALSE; + m_bEffect = TRUE; + m_shotDelay = 0; + + m_glintMouse = FPOINT(0.0f, 0.0f); + m_glintTime = 1000.0f; + + for ( i=0 ; i<10 ; i++ ) + { + m_partiPhase[i] = 0; + m_partiTime[i] = 0.0f; + } + + strcpy(m_sceneDir, "scene"); + strcpy(m_savegameDir, "savegame"); + strcpy(m_publicDir, "program"); + strcpy(m_userDir, "user"); + strcpy(m_filesDir, "files"); + + m_bDialog = FALSE; +} + +// Destructor of robot application. + +CMainDialog::~CMainDialog() +{ +} + + +// Changes phase. + +void CMainDialog::ChangePhase(Phase phase) +{ + CWindow* pw; + CEdit* pe; + CEditValue* pv; + CLabel* pl; + CList* pli; + CCheck* pc; + CScroll* ps; + CSlider* psl; + CButton* pb; + CColor* pco; + CGroup* pg; + CImage* pi; + FPOINT pos, dim, ddim; + float ox, oy, sx, sy; + char name[100]; + char* gamer; + int res, i, j; + + m_camera->SetType(CAMERA_DIALOG); + m_engine->SetOverFront(FALSE); + m_engine->SetOverColor(RetColor(0.0f), D3DSTATETCb); + + if ( phase == PHASE_TERM ) + { + phase = m_phaseTerm; + } + m_phase = phase; // copy the info to CRobotMain + m_phaseTime = 0.0f; + + dim.x = 32.0f/640.0f; + dim.y = 32.0f/480.0f; + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = (32.0f+2.0f)/640.0f; + sy = (32.0f+2.0f)/480.0f; + + if ( m_phase == PHASE_INIT ) + { + pos.x = 0.35f; + pos.y = 0.10f; + ddim.x = 0.30f; + ddim.y = 0.80f; +#if _TEEN + pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5); +#else + pw = m_interface->CreateWindows(pos, ddim, 10, EVENT_WINDOW5); +#endif + GetResource(RES_TEXT, RT_TITLE_INIT, name); + pw->SetName(name); + + pos.x = 0.35f; + pos.y = 0.60f; + ddim.x = 0.30f; + ddim.y = 0.30f; + pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner + pos.x = 0.35f; + pos.y = 0.10f; + ddim.x = 0.30f; + ddim.y = 0.30f; + pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner + +#if _SCHOOL + ddim.x = 0.20f; + ddim.y = dim.y*2.4f; + pos.x = 0.40f; + pos.y = oy+sy*7.9f; + pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // orange + pg->SetState(STATE_SHADOW); + pos.y = oy+sy*3.9f; + pg = pw->CreateGroup(pos, ddim, 25, EVENT_LABEL1); // orange + pg->SetState(STATE_SHADOW); + ddim.y = dim.y*1.2f; + pos.y = oy+sy*1.9f; + pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // red + pg->SetState(STATE_SHADOW); +#else + ddim.x = 0.20f; + ddim.y = dim.y*2.4f; + pos.x = 0.40f; + if ( m_accessEnable && m_accessMission ) + { + pos.y = oy+sy*9.1f; + pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // yellow + pg->SetState(STATE_SHADOW); + } + pos.y = oy+sy*6.8f; + pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // orange + pg->SetState(STATE_SHADOW); + pos.y = oy+sy*3.9f; + pg = pw->CreateGroup(pos, ddim, 25, EVENT_LABEL1); // orange + pg->SetState(STATE_SHADOW); + ddim.y = dim.y*1.2f; + pos.y = oy+sy*1.9f; + pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // red + pg->SetState(STATE_SHADOW); +#endif + +#if _SCHOOL + ddim.x = 0.18f; + ddim.y = dim.y*1; + pos.x = 0.41f; + pos.y = oy+sy*9.1f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_TRAINER); + pb->SetState(STATE_SHADOW); + + pos.y = oy+sy*8.0f; +#if _TEEN + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_TEEN); +#else + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_DEFI); +#endif +#if _CEEBOTDEMO + pb->ClearState(STATE_ENABLE); +#endif + pb->SetState(STATE_SHADOW); +#else + ddim.x = 0.18f; + ddim.y = dim.y*1; + pos.x = 0.41f; + + if ( m_accessEnable && m_accessMission ) + { + pos.y = oy+sy*10.3f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_MISSION); + pb->SetState(STATE_SHADOW); + + pos.y = oy+sy*9.2f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_FREE); + pb->SetState(STATE_SHADOW); + } + + pos.y = oy+sy*8.0f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_TRAINER); + pb->SetState(STATE_SHADOW); + + pos.y = oy+sy*6.9f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_DEFI); + pb->SetState(STATE_SHADOW); +#endif + + if ( m_engine->RetSetupMode() ) + { + pos.y = oy+sy*5.1f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUP); + pb->SetState(STATE_SHADOW); + } + + pos.y = oy+sy*4.0f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NAME); + pb->SetState(STATE_SHADOW); + + pos.y = oy+sy*2.0f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_QUIT); + pb->SetState(STATE_SHADOW); + +#if !_DEMO & !_SCHOOL + if ( m_accessEnable && m_accessUser ) + { + pos.x = 447.0f/640.0f; + pos.y = 313.0f/480.0f; + ddim.x = 0.09f; +#if _POLISH + pos.x -= 5.0f/640.0f; + ddim.x += 10.0f/640.0f; +#endif + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_USER); + pb->SetState(STATE_SHADOW); + } +#endif + + if ( m_engine->RetDebugMode() ) + { + pos.x = 139.0f/640.0f; + pos.y = 313.0f/480.0f; + ddim.x = 0.09f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PROTO); + pb->SetState(STATE_SHADOW); + } + + pos.x = 0.40f; + ddim.x = 0.20f; + pos.y = 26.0f/480.0f; + ddim.y = 12.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 1, EVENT_LABEL1); + pg->SetState(STATE_SHADOW); + pos.y -= 5.0f/480.0f; +#if _WG + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, " "); +#else +#if _NEWLOOK + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, "www.epsitec.ch"); +#else + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, "www.ceebot.com"); +#endif +#endif + pl->SetFontType(FONT_COURIER); + pl->SetFontSize(8.0f); + + m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE); + m_engine->SetBackForce(TRUE); + } + + if ( m_phase == PHASE_NAME ) + { + pos.x = 0.10f; + pos.y = 0.10f; + ddim.x = 0.80f; + ddim.y = 0.80f; + pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5); + GetResource(RES_TEXT, RT_TITLE_NAME, name); + pw->SetName(name); + +#if _NEWLOOK + pos.x = 80.0f/640.0f; + pos.y = 93.0f/480.0f; + ddim.x = 285.0f/640.0f; + ddim.y = 266.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue + pg->SetState(STATE_SHADOW); + pos.x = 372.0f/640.0f; + ddim.x = 188.0f/640.0f; + pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet + pg->SetState(STATE_SHADOW); +#endif + + pos.x = 0.10f; + pos.y = 0.40f; + ddim.x = 0.50f; + ddim.y = 0.50f; + pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner + pos.x = 0.40f; + pos.y = 0.10f; + ddim.x = 0.50f; + ddim.y = 0.50f; + pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner + + pos.x = 60.0f/640.0f; + pos.y = 313.0f/480.0f; + ddim.x = 120.0f/640.0f; + ddim.y = 32.0f/480.0f; + GetResource(RES_EVENT, EVENT_INTERFACE_NLABEL, name); + pl = pw->CreateLabel(pos, ddim, -1, EVENT_INTERFACE_NLABEL, name); + pl->SetJustif(-1); + + pos.x = 200.0f/640.0f; + pos.y = 320.0f/480.0f; + ddim.x = 160.0f/640.0f; + ddim.y = 32.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 7, EVENT_LABEL1); + pg->SetState(STATE_SHADOW); + + pos.x = 207.0f/640.0f; + pos.y = 328.0f/480.0f; + ddim.x = 144.0f/640.0f; + ddim.y = 18.0f/480.0f; + pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_NEDIT); + pe->SetMaxChar(15); + gamer = m_main->RetGamerName(); + if ( gamer[0] == 0 ) + { + GetResource(RES_TEXT, RT_NAME_DEFAULT, name); + } + else + { + strcpy(name, gamer); + } + pe->SetText(name); + pe->SetCursor(strlen(name), 0); + pe->SetFocus(TRUE); + + pos.x = 380.0f/640.0f; + pos.y = 320.0f/480.0f; + ddim.x =100.0f/640.0f; + ddim.y = 32.0f/480.0f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NOK); + pb->SetState(STATE_SHADOW); + +#if !_TEEN + pos.x = 380.0f/640.0f; + pos.y = 250.0f/480.0f; + ddim.x =100.0f/640.0f; + ddim.y = 52.0f/480.0f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PERSO); + pb->SetState(STATE_SHADOW); +#endif + + pos.x = 200.0f/640.0f; + pos.y = 150.0f/480.0f; + ddim.x = 160.0f/640.0f; + ddim.y = 160.0f/480.0f; + pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_NLIST); + pli->SetState(STATE_SHADOW); + + if ( m_bDeleteGamer ) + { + pos.x = 200.0f/640.0f; + pos.y = 100.0f/480.0f; + ddim.x = 160.0f/640.0f; + ddim.y = 32.0f/480.0f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NDELETE); + pb->SetState(STATE_SHADOW); + } + + pos.x = 380.0f/640.0f; + pos.y = 100.0f/480.0f; + ddim.x =100.0f/640.0f; + ddim.y = 32.0f/480.0f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NCANCEL); + pb->SetState(STATE_SHADOW); + + ReadNameList(); + UpdateNameList(); + UpdateNameControl(); + UpdateNameFace(); + + m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE); + m_engine->SetBackForce(TRUE); + } + + if ( m_phase == PHASE_PERSO ) + { + pos.x = 0.10f; + pos.y = 0.10f; + ddim.x = 0.80f; + ddim.y = 0.80f; + pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5); + GetResource(RES_TEXT, RT_TITLE_PERSO, name); + pw->SetName(name); + +#if _NEWLOOK + pos.x = 95.0f/640.0f; + pos.y = 66.0f/480.0f; + ddim.x = 443.0f/640.0f; + ddim.y = 42.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet + pg->SetState(STATE_SHADOW); +#endif + + pos.x = 0.10f; + pos.y = 0.40f; + ddim.x = 0.50f; + ddim.y = 0.50f; + pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner + pos.x = 0.40f; + pos.y = 0.10f; + ddim.x = 0.50f; + ddim.y = 0.50f; + pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner + + pos.x = 95.0f/640.0f; + pos.y = 108.0f/480.0f; + ddim.x = 220.0f/640.0f; + ddim.y = 274.0f/480.0f; + pw->CreateGroup(pos, ddim, 17, EVENT_NULL); // frame + + pos.x = 100.0f/640.0f; + pos.y = 364.0f/480.0f; + ddim.x = 210.0f/640.0f; + ddim.y = 14.0f/480.0f; + pw->CreateGroup(pos, ddim, 3, EVENT_NULL); // transparent -> gray + + pos.x = 120.0f/640.0f; + pos.y = 364.0f/480.0f; + ddim.x = 80.0f/640.0f; + ddim.y = 28.0f/480.0f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PHEAD); + pb->SetState(STATE_SHADOW); + pb->SetState(STATE_CARD); + + pos.x = 210.0f/640.0f; + pos.y = 364.0f/480.0f; + ddim.x = 80.0f/640.0f; + ddim.y = 28.0f/480.0f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PBODY); + pb->SetState(STATE_SHADOW); + pb->SetState(STATE_CARD); + + pos.x = 100.0f/640.0f; + pos.y = 354.0f/480.0f; + ddim.x = 210.0f/640.0f; + ddim.y = 10.0f/480.0f; + pw->CreateGroup(pos, ddim, 1, EVENT_INTERFACE_GLINTb); // orange bar + pos.x = 100.0f/640.0f; + pos.y = 154.0f/480.0f; + ddim.x = 210.0f/640.0f; + ddim.y = 200.0f/480.0f; + pw->CreateGroup(pos, ddim, 2, EVENT_INTERFACE_GLINTu); // orange -> transparent + + // Face + pos.x = 340.0f/640.0f; + pos.y = 356.0f/480.0f; + ddim.x = 200.0f/640.0f; + ddim.y = 16.0f/480.0f; + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL11, ""); + pl->SetJustif(1); + + pos.x = 340.0f/640.0f; + pos.y = 312.0f/480.0f; + ddim.x = 44.0f/640.0f; + ddim.y = 44.0f/480.0f; + pb = pw->CreateButton(pos, ddim, 43, EVENT_INTERFACE_PFACE1); + pb->SetState(STATE_SHADOW); + pos.x += 50.0f/640.0f; + pb = pw->CreateButton(pos, ddim, 46, EVENT_INTERFACE_PFACE4); + pb->SetState(STATE_SHADOW); + pos.x += 50.0f/640.0f; + pb = pw->CreateButton(pos, ddim, 45, EVENT_INTERFACE_PFACE3); + pb->SetState(STATE_SHADOW); + pos.x += 50.0f/640.0f; + pb = pw->CreateButton(pos, ddim, 44, EVENT_INTERFACE_PFACE2); + pb->SetState(STATE_SHADOW); + + // Glasses + pos.x = 340.0f/640.0f; + pos.y = 270.0f/480.0f; + ddim.x = 200.0f/640.0f; + ddim.y = 16.0f/480.0f; + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL12, ""); + pl->SetJustif(1); + + pos.x = 340.0f/640.0f; + pos.y = 240.0f/480.0f; + ddim.x = 30.0f/640.0f; + ddim.y = 30.0f/480.0f; + for ( i=0 ; i<6 ; i++ ) + { + int ti[6] = {11, 179, 180, 181, 182, 183}; + pb = pw->CreateButton(pos, ddim, ti[i], (EventMsg)(EVENT_INTERFACE_PGLASS0+i)); + pb->SetState(STATE_SHADOW); + pos.x += (30.0f+2.8f)/640.0f; + } + + // Color A + pos.x = 340.0f/640.0f; + pos.y = 300.0f/480.0f; + ddim.x = 200.0f/640.0f; + ddim.y = 16.0f/480.0f; + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL14, ""); + pl->SetJustif(1); + + pos.y = 282.0f/480.0f; + ddim.x = 18.0f/640.0f; + ddim.y = 18.0f/480.0f; + for ( j=0 ; j<3 ; j++ ) + { + pos.x = 340.0f/640.0f; + for ( i=0 ; i<3 ; i++ ) + { + pco = pw->CreateColor(pos, ddim, -1, (EventMsg)(EVENT_INTERFACE_PC0a+j*3+i)); + pco->SetState(STATE_SHADOW); + pos.x += 20.0f/640.0f; + } + pos.y -= 20.0f/480.0f; + } + + pos.x = 420.0f/640.0f; + pos.y = 282.0f/480.0f; + ddim.x = 100.0f/640.0f; + ddim.y = 18.0f/480.0f; + for ( i=0 ; i<3 ; i++ ) + { + psl = pw->CreateSlider(pos, ddim, 0, (EventMsg)(EVENT_INTERFACE_PCRa+i)); + psl->SetState(STATE_SHADOW); + psl->SetLimit(0.0f, 255.0f); + psl->SetArrowStep(16.0f); + pos.y -= 20.0f/480.0f; + } + + // Color B + pos.x = 340.0f/640.0f; + pos.y = 192.0f/480.0f; + ddim.x = 200.0f/640.0f; + ddim.y = 16.0f/480.0f; + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL13, ""); + pl->SetJustif(1); + + pos.y = 174.0f/480.0f; + ddim.x = 18.0f/640.0f; + ddim.y = 18.0f/480.0f; + for ( j=0 ; j<3 ; j++ ) + { + pos.x = 340.0f/640.0f; + for ( i=0 ; i<3 ; i++ ) + { + pco = pw->CreateColor(pos, ddim, -1, (EventMsg)(EVENT_INTERFACE_PC0b+j*3+i)); + pco->SetState(STATE_SHADOW); + pos.x += 20.0f/640.0f; + } + pos.y -= 20.0f/480.0f; + } + + pos.x = 420.0f/640.0f; + pos.y = 174.0f/480.0f; + ddim.x = 100.0f/640.0f; + ddim.y = 18.0f/480.0f; + for ( i=0 ; i<3 ; i++ ) + { + psl = pw->CreateSlider(pos, ddim, 0, (EventMsg)(EVENT_INTERFACE_PCRb+i)); + psl->SetState(STATE_SHADOW); + psl->SetLimit(0.0f, 255.0f); + psl->SetArrowStep(16.0f); + pos.y -= 20.0f/480.0f; + } + + // Rotation + pos.x = 100.0f/640.0f; + pos.y = 113.0f/480.0f; + ddim.x = 20.0f/640.0f; + ddim.y = 20.0f/480.0f; + pb = pw->CreateButton(pos, ddim, 55, EVENT_INTERFACE_PLROT); // < + pb->SetState(STATE_SHADOW); + pb->SetRepeat(TRUE); + + pos.x = 290.0f/640.0f; + pos.y = 113.0f/480.0f; + ddim.x = 20.0f/640.0f; + ddim.y = 20.0f/480.0f; + pb = pw->CreateButton(pos, ddim, 48, EVENT_INTERFACE_PRROT); // > + pb->SetState(STATE_SHADOW); + pb->SetRepeat(TRUE); + + pos.x = 100.0f/640.0f; + pos.y = 70.0f/480.0f; + ddim.x = 100.0f/640.0f; + ddim.y = 32.0f/480.0f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_POK); + pb->SetState(STATE_SHADOW); + + pos.x = 210.0f/640.0f; + pos.y = 70.0f/480.0f; + ddim.x =100.0f/640.0f; + ddim.y = 32.0f/480.0f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PCANCEL); + pb->SetState(STATE_SHADOW); + + pos.x = 340.0f/640.0f; + pos.y = 70.0f/480.0f; + ddim.x =194.0f/640.0f; + ddim.y = 32.0f/480.0f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PDEF); + pb->SetState(STATE_SHADOW); + + m_persoCopy = m_perso; + m_persoTab = 0; + m_persoAngle = -0.6f; + UpdatePerso(); + m_main->ScenePerso(); + CameraPerso(); + } + + if ( m_phase == PHASE_TRAINER || + m_phase == PHASE_DEFI || + m_phase == PHASE_MISSION || + m_phase == PHASE_FREE || + m_phase == PHASE_TEEN || + m_phase == PHASE_USER || + m_phase == PHASE_PROTO ) + { + if ( m_phase == PHASE_TRAINER ) m_index = 0; + if ( m_phase == PHASE_DEFI ) m_index = 1; + if ( m_phase == PHASE_MISSION ) m_index = 2; + if ( m_phase == PHASE_FREE ) m_index = 3; + if ( m_phase == PHASE_USER ) m_index = 4; + if ( m_phase == PHASE_PROTO ) m_index = 5; + if ( m_phase == PHASE_TEEN ) m_index = 6; + + if ( m_phase == PHASE_FREE ) + { + strcpy(m_sceneName, "scene"); + ReadGamerInfo(); + m_accessChap = RetChapPassed(); + } + + if ( m_phase == PHASE_TRAINER ) strcpy(m_sceneName, "train"); + if ( m_phase == PHASE_DEFI ) strcpy(m_sceneName, "defi" ); + if ( m_phase == PHASE_MISSION ) strcpy(m_sceneName, "scene"); + if ( m_phase == PHASE_FREE ) strcpy(m_sceneName, "free"); + if ( m_phase == PHASE_TEEN ) strcpy(m_sceneName, "teen"); + if ( m_phase == PHASE_USER ) strcpy(m_sceneName, "user"); + if ( m_phase == PHASE_PROTO ) strcpy(m_sceneName, "proto"); + + ReadGamerInfo(); + + pos.x = 0.10f; + pos.y = 0.10f; + ddim.x = 0.80f; + ddim.y = 0.80f; + pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5); + pw->SetClosable(TRUE); + if ( m_phase == PHASE_TRAINER ) res = RT_TITLE_TRAINER; + if ( m_phase == PHASE_DEFI ) res = RT_TITLE_DEFI; + if ( m_phase == PHASE_MISSION ) res = RT_TITLE_MISSION; + if ( m_phase == PHASE_FREE ) res = RT_TITLE_FREE; + if ( m_phase == PHASE_TEEN ) res = RT_TITLE_TEEN; + if ( m_phase == PHASE_USER ) res = RT_TITLE_USER; + if ( m_phase == PHASE_PROTO ) res = RT_TITLE_PROTO; + GetResource(RES_TEXT, res, name); + pw->SetName(name); + +#if _NEWLOOK + pos.x = 100.0f/640.0f; + pos.y = 226.0f/480.0f; + ddim.x = 216.0f/640.0f; + ddim.y = 160.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue + pg->SetState(STATE_SHADOW); + pos.x = 322.0f/640.0f; + pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // cyan + pg->SetState(STATE_SHADOW); + + pos.x = 100.0f/640.0f; + pos.y = 122.0f/480.0f; + ddim.x = 438.0f/640.0f; + ddim.y = 98.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 25, EVENT_LABEL1); // green + pg->SetState(STATE_SHADOW); + pos.y = 66.0f/480.0f; + ddim.y = 42.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet + pg->SetState(STATE_SHADOW); +#endif + + pos.x = 0.10f; + pos.y = 0.40f; + ddim.x = 0.50f; + ddim.y = 0.50f; + pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner + pos.x = 0.40f; + pos.y = 0.10f; + ddim.x = 0.50f; + ddim.y = 0.50f; + pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner + + // Displays a list of chapters: + pos.x = ox+sx*3; + pos.y = oy+sy*10.5f; + ddim.x = dim.x*7.5f; + ddim.y = dim.y*0.6f; + if ( m_phase == PHASE_TRAINER ) res = RT_PLAY_CHAPt; + if ( m_phase == PHASE_DEFI ) res = RT_PLAY_CHAPd; + if ( m_phase == PHASE_MISSION ) res = RT_PLAY_CHAPm; + if ( m_phase == PHASE_FREE ) res = RT_PLAY_CHAPf; + if ( m_phase == PHASE_TEEN ) res = RT_PLAY_CHAPte; + if ( m_phase == PHASE_USER ) res = RT_PLAY_CHAPu; + if ( m_phase == PHASE_PROTO ) res = RT_PLAY_CHAPp; + GetResource(RES_TEXT, res, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL11, name); + pl->SetJustif(1); + + pos.y = oy+sy*6.7f; + ddim.y = dim.y*4.5f; + ddim.x = dim.x*6.5f; + pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_CHAP); + pli->SetState(STATE_SHADOW); + UpdateSceneChap(m_chap[m_index]); + if ( m_phase != PHASE_USER ) pli->SetState(STATE_EXTEND); + + // Displays a list of missions: + pos.x = ox+sx*9.5f; + pos.y = oy+sy*10.5f; + ddim.x = dim.x*7.5f; + ddim.y = dim.y*0.6f; + if ( m_phase == PHASE_TRAINER ) res = RT_PLAY_LISTt; + if ( m_phase == PHASE_DEFI ) res = RT_PLAY_LISTd; + if ( m_phase == PHASE_MISSION ) res = RT_PLAY_LISTm; + if ( m_phase == PHASE_FREE ) res = RT_PLAY_LISTf; + if ( m_phase == PHASE_TEEN ) res = RT_PLAY_LISTk; + if ( m_phase == PHASE_USER ) res = RT_PLAY_LISTu; + if ( m_phase == PHASE_PROTO ) res = RT_PLAY_LISTp; + GetResource(RES_TEXT, res, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL12, name); + pl->SetJustif(1); + + pos.y = oy+sy*6.7f; + ddim.y = dim.y*4.5f; + ddim.x = dim.x*6.5f; + pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_LIST); + pli->SetState(STATE_SHADOW); + UpdateSceneList(m_chap[m_index], m_sel[m_index]); + if ( m_phase != PHASE_USER ) pli->SetState(STATE_EXTEND); + pos = pli->RetPos(); + ddim = pli->RetDim(); + + // Displays the summary: + pos.x = ox+sx*3; + pos.y = oy+sy*5.4f; + ddim.x = dim.x*6.5f; + ddim.y = dim.y*0.6f; + GetResource(RES_TEXT, RT_PLAY_RESUME, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL13, name); + pl->SetJustif(1); + + pos.x = ox+sx*3; + pos.y = oy+sy*3.6f; + ddim.x = dim.x*13.4f; + ddim.y = dim.y*1.9f; + pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_RESUME); + pe->SetState(STATE_SHADOW); + pe->SetMaxChar(500); + pe->SetEditCap(FALSE); // just to see + pe->SetHiliteCap(FALSE); + + // Button displays the "soluce": + if ( m_phase != PHASE_TRAINER && + m_phase != PHASE_FREE && + m_phase != PHASE_TEEN ) + { + pos.x = ox+sx*9.5f; + pos.y = oy+sy*5.8f; + ddim.x = dim.x*6.5f; + ddim.y = dim.y*0.5f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SOLUCE); + pc->SetState(STATE_SHADOW); + pc->ClearState(STATE_CHECK); + } + m_bSceneSoluce = FALSE; + + UpdateSceneResume((m_chap[m_index]+1)*100+(m_sel[m_index]+1)); + + if ( m_phase == PHASE_MISSION || + m_phase == PHASE_FREE || + m_phase == PHASE_USER ) + { + pos.x = ox+sx*9.5f; + pos.y = oy+sy*2; + ddim.x = dim.x*3.7f; + ddim.y = dim.y*1; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PLAY); + pb->SetState(STATE_SHADOW); + if ( m_maxList == 0 ) + { + pb->ClearState(STATE_ENABLE); + } + + pos.x += dim.x*4.0f; + ddim.x = dim.x*2.5f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_READ); + pb->SetState(STATE_SHADOW); + if ( !IsIOReadScene() ) // no file to read? + { + pb->ClearState(STATE_ENABLE); + } + } + else + { + pos.x = ox+sx*9.5f; + pos.y = oy+sy*2; + ddim.x = dim.x*6.5f; + ddim.y = dim.y*1; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PLAY); + pb->SetState(STATE_SHADOW); + if ( m_maxList == 0 ) + { + pb->ClearState(STATE_ENABLE); + } + } + + pos.x = ox+sx*3; + ddim.x = dim.x*4; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_BACK); + pb->SetState(STATE_SHADOW); + + m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE); + m_engine->SetBackForce(TRUE); + } + + if ( m_phase == PHASE_SETUPd || + m_phase == PHASE_SETUPg || + m_phase == PHASE_SETUPp || + m_phase == PHASE_SETUPc || + m_phase == PHASE_SETUPs || + m_phase == PHASE_SETUPds || + m_phase == PHASE_SETUPgs || + m_phase == PHASE_SETUPps || + m_phase == PHASE_SETUPcs || + m_phase == PHASE_SETUPss ) + { + if ( m_phase == PHASE_SETUPds ) + { + m_phaseSetup = PHASE_SETUPd; + m_bSimulSetup = TRUE; + } + else if ( m_phase == PHASE_SETUPgs ) + { + m_phaseSetup = PHASE_SETUPg; + m_bSimulSetup = TRUE; + } + else if ( m_phase == PHASE_SETUPps ) + { + m_phaseSetup = PHASE_SETUPp; + m_bSimulSetup = TRUE; + } + else if ( m_phase == PHASE_SETUPcs ) + { + m_phaseSetup = PHASE_SETUPc; + m_bSimulSetup = TRUE; + } + else if ( m_phase == PHASE_SETUPss ) + { + m_phaseSetup = PHASE_SETUPs; + m_bSimulSetup = TRUE; + } + else + { + m_phaseSetup = m_phase; + m_bSimulSetup = FALSE; + } + + pos.x = 0.10f; + pos.y = 0.10f; + ddim.x = 0.80f; + ddim.y = 0.80f; + pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5); + pw->SetClosable(TRUE); + GetResource(RES_TEXT, RT_TITLE_SETUP, name); + pw->SetName(name); + + pos.x = 0.70f; + pos.y = 0.10f; + ddim.x = 0.20f; + ddim.y = 0.20f; + pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner + + pos.x = 0.10f; + ddim.x = 0.80f; + pos.y = 0.76f; + ddim.y = 0.05f; + pw->CreateGroup(pos, ddim, 3, EVENT_NULL); // transparent -> gray + +#if _NEWLOOK + if ( m_phase == PHASE_SETUPd || // setup/display ? + m_phase == PHASE_SETUPds ) + { + pos.x = 100.0f/640.0f; + pos.y = 130.0f/480.0f; + ddim.x = 216.0f/640.0f; + ddim.y = 212.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue + pg->SetState(STATE_SHADOW); + pos.x = 324.0f/640.0f; + pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // cyan + pg->SetState(STATE_SHADOW); + } + if ( m_phase == PHASE_SETUPg || // setup/graphic ? + m_phase == PHASE_SETUPgs ) + { + pos.x = 100.0f/640.0f; + pos.y = 130.0f/480.0f; + ddim.x = 174.0f/640.0f; + ddim.y = 212.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue + pg->SetState(STATE_SHADOW); + pos.x = 282.0f/640.0f; + ddim.x = 258.0f/640.0f; + pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // cyan + pg->SetState(STATE_SHADOW); + } + if ( m_phase == PHASE_SETUPp || // setup/game ? + m_phase == PHASE_SETUPps ) + { + pos.x = 100.0f/640.0f; + pos.y = 130.0f/480.0f; + ddim.x = 226.0f/640.0f; + ddim.y = 212.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue + pg->SetState(STATE_SHADOW); + pos.x = 334.0f/640.0f; + ddim.x = 206.0f/640.0f; + pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // cyan + pg->SetState(STATE_SHADOW); + } + if ( m_phase == PHASE_SETUPc || // setup/command ? + m_phase == PHASE_SETUPcs ) + { + pos.x = 100.0f/640.0f; + pos.y = 125.0f/480.0f; + ddim.x = 440.0f/640.0f; + ddim.y = 222.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue + pg->SetState(STATE_SHADOW); + } + if ( m_phase == PHASE_SETUPs || // setup/sound ? + m_phase == PHASE_SETUPss ) + { + pos.x = 100.0f/640.0f; + pos.y = 130.0f/480.0f; + ddim.x = 216.0f/640.0f; + ddim.y = 212.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue + pg->SetState(STATE_SHADOW); + pos.x = 324.0f/640.0f; + pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // cyan + pg->SetState(STATE_SHADOW); + } + + pos.x = 100.0f/640.0f; + pos.y = 66.0f/480.0f; + ddim.x = 440.0f/640.0f; + ddim.y = 42.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet + pg->SetState(STATE_SHADOW); +#endif + + ddim.x = 0.78f/5-0.01f; + ddim.y = 0.06f; + pos.x = 0.115f; + pos.y = 0.76f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPd); + pb->SetState(STATE_SHADOW); + pb->SetState(STATE_CARD); + pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPd || m_phase == PHASE_SETUPds)); + + pos.x += ddim.x+0.01f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPg); + pb->SetState(STATE_SHADOW); + pb->SetState(STATE_CARD); + pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPg || m_phase == PHASE_SETUPgs)); + + pos.x += ddim.x+0.01f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPp); + pb->SetState(STATE_SHADOW); + pb->SetState(STATE_CARD); + pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPp || m_phase == PHASE_SETUPps)); + + pos.x += ddim.x+0.01f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPc); + pb->SetState(STATE_SHADOW); + pb->SetState(STATE_CARD); + pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPc || m_phase == PHASE_SETUPcs)); + + pos.x += ddim.x+0.01f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPs); + pb->SetState(STATE_SHADOW); + pb->SetState(STATE_CARD); + pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPs || m_phase == PHASE_SETUPss)); + + pos.x = 0.10f; + ddim.x = 0.80f; + pos.y = 0.34f; + ddim.y = 0.42f; + pw->CreateGroup(pos, ddim, 2, EVENT_INTERFACE_GLINTu); // orange -> transparent + pos.x = 0.10f+(6.0f/640.0f); + ddim.x = 0.80f-(11.0f/640.0f); + pos.y = 0.74f; + ddim.y = 0.02f; + pw->CreateGroup(pos, ddim, 1, EVENT_INTERFACE_GLINTb); // orange bar + + ddim.x = dim.x*4; + ddim.y = dim.y*1; + pos.x = ox+sx*3; + pos.y = oy+sy*2; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_BACK); + pb->SetState(STATE_SHADOW); + + if ( !m_bSimulSetup ) + { + m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE); + m_engine->SetBackForce(TRUE); + } + } + + if ( m_phase == PHASE_SETUPd || // setup/display ? + m_phase == PHASE_SETUPds ) + { + pos.x = ox+sx*3; + pos.y = oy+sy*9; + ddim.x = dim.x*6; + ddim.y = dim.y*1; + GetResource(RES_TEXT, RT_SETUP_DEVICE, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name); + pl->SetJustif(1); + + pos.x = ox+sx*3; + pos.y = oy+sy*5.2f; + ddim.x = dim.x*6; + ddim.y = dim.y*4.5f; + pli = pw->CreateList(pos, ddim, 0, EVENT_LIST1); + pli->SetState(STATE_SHADOW); + UpdateDisplayDevice(); + + pos.x = ox+sx*10; + pos.y = oy+sy*9; + ddim.x = dim.x*6; + ddim.y = dim.y*1; + GetResource(RES_TEXT, RT_SETUP_MODE, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL2, name); + pl->SetJustif(1); + + m_setupFull = m_engine->RetFullScreen(); + pos.x = ox+sx*10; + pos.y = oy+sy*5.2f; + ddim.x = dim.x*6; + ddim.y = dim.y*4.5f; + pli = pw->CreateList(pos, ddim, 0, EVENT_LIST2); + pli->SetState(STATE_SHADOW); + UpdateDisplayMode(); + pli->SetState(STATE_ENABLE, m_setupFull); + + ddim.x = dim.x*4; + ddim.y = dim.y*0.5f; + pos.x = ox+sx*3; + pos.y = oy+sy*4.1f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_FULL); + pc->SetState(STATE_SHADOW); + pc->SetState(STATE_CHECK, m_setupFull); + + ddim.x = dim.x*6; + ddim.y = dim.y*1; + pos.x = ox+sx*10; + pos.y = oy+sy*2; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_APPLY); + pb->SetState(STATE_SHADOW); + UpdateApply(); + } + + if ( m_phase == PHASE_SETUPg || // setup/graphic ? + m_phase == PHASE_SETUPgs ) + { + ddim.x = dim.x*6; + ddim.y = dim.y*0.5f; + pos.x = ox+sx*3; + pos.y = 0.65f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SHADOW); + pc->SetState(STATE_SHADOW); + pos.y -= 0.048f; + if ( !m_bSimulSetup ) + { + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_GROUND); + pc->SetState(STATE_SHADOW); + if ( m_engine->IsVideo8MB() ) pc->ClearState(STATE_ENABLE); + } + pos.y -= 0.048f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_DIRTY); + pc->SetState(STATE_SHADOW); + pos.y -= 0.048f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SKY); + pc->SetState(STATE_SHADOW); + if ( m_engine->IsVideo8MB() ) pc->ClearState(STATE_ENABLE); + pos.y -= 0.048f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_LENS); + pc->SetState(STATE_SHADOW); + pos.y -= 0.048f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_PLANET); + pc->SetState(STATE_SHADOW); + pos.y -= 0.048f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_FOG); + pc->SetState(STATE_SHADOW); + pos.y -= 0.048f; + if ( !m_bSimulSetup ) + { + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_LIGHT); + pc->SetState(STATE_SHADOW); + } + + pos.x = ox+sx*8.5f; + pos.y = 0.65f; + ddim.x = dim.x*2.2f; + ddim.y = 18.0f/480.0f; + pv = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_PARTI); + pv->SetState(STATE_SHADOW); + pv->SetMinValue(0.0f); + pv->SetMaxValue(2.0f); + pos.x += 0.13f; + pos.y -= 0.015f; + ddim.x = 0.40f; + GetResource(RES_EVENT, EVENT_INTERFACE_PARTI, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL10, name); + pl->SetJustif(1); + + pos.x = ox+sx*8.5f; + pos.y = 0.59f; + ddim.x = dim.x*2.2f; + ddim.y = 18.0f/480.0f; + pv = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_CLIP); + pv->SetState(STATE_SHADOW); + pv->SetMinValue(0.5f); + pv->SetMaxValue(2.0f); + pos.x += 0.13f; + pos.y -= 0.015f; + ddim.x = 0.40f; + GetResource(RES_EVENT, EVENT_INTERFACE_CLIP, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL11, name); + pl->SetJustif(1); + + pos.x = ox+sx*8.5f; + pos.y = 0.53f; + ddim.x = dim.x*2.2f; + ddim.y = 18.0f/480.0f; + pv = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_DETAIL); + pv->SetState(STATE_SHADOW); + pv->SetMinValue(0.0f); + pv->SetMaxValue(2.0f); + pos.x += 0.13f; + pos.y -= 0.015f; + ddim.x = 0.40f; + GetResource(RES_EVENT, EVENT_INTERFACE_DETAIL, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL12, name); + pl->SetJustif(1); + + if ( !m_bSimulSetup ) + { + pos.x = ox+sx*8.5f; + pos.y = 0.47f; + ddim.x = dim.x*2.2f; + ddim.y = 18.0f/480.0f; + pv = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_GADGET); + pv->SetState(STATE_SHADOW); + pv->SetMinValue(0.0f); + pv->SetMaxValue(1.0f); + pos.x += 0.13f; + pos.y -= 0.015f; + ddim.x = 0.40f; + GetResource(RES_EVENT, EVENT_INTERFACE_GADGET, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL13, name); + pl->SetJustif(1); + } + +#if 0 + if ( !m_bSimulSetup ) + { + pos.x = ox+sx*8.5f; + pos.y = 0.41f; + ddim.x = dim.x*2.2f; + ddim.y = 18.0f/480.0f; + pv = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_TEXTURE); + pv->SetState(STATE_SHADOW); + pv->SetType(EVT_INT); + pv->SetMinValue(0.0f); + pv->SetMaxValue(2.0f); + pv->SetStepValue(1.0f); + pos.x += 0.13f; + pos.y -= 0.015f; + ddim.x = 0.40f; + GetResource(RES_EVENT, EVENT_INTERFACE_TEXTURE, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL14, name); + pl->SetJustif(1); + } +#endif + + ddim.x = dim.x*2; + ddim.y = dim.y*1; + pos.x = ox+sx*10; + pos.y = oy+sy*2; +#if _POLISH + ddim.x += 20.0f/640.0f; + pos.x -= 20.0f/640.0f*3.0f; +#endif + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_MIN); + pb->SetState(STATE_SHADOW); + pos.x += ddim.x; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NORM); + pb->SetState(STATE_SHADOW); + pos.x += ddim.x; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_MAX); + pb->SetState(STATE_SHADOW); + + UpdateSetupButtons(); + } + + if ( m_phase == PHASE_SETUPp || // setup/game ? + m_phase == PHASE_SETUPps ) + { + ddim.x = dim.x*6; + ddim.y = dim.y*0.5f; + pos.x = ox+sx*3; + pos.y = 0.65f; +//? pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_TOTO); +//? pc->SetState(STATE_SHADOW); +//? pos.y -= 0.048f; +#if _SCHOOL + #if _EDU + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SOLUCE4); + pc->SetState(STATE_SHADOW); + pos.y -= 0.048f; + #endif +#else + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_MOVIES); + pc->SetState(STATE_SHADOW); + pos.y -= 0.048f; +#endif + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SCROLL); + pc->SetState(STATE_SHADOW); + pos.y -= 0.048f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_INVERTX); + pc->SetState(STATE_SHADOW); + pos.y -= 0.048f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_INVERTY); + pc->SetState(STATE_SHADOW); + pos.y -= 0.048f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_EFFECT); + pc->SetState(STATE_SHADOW); +//? pos.y -= 0.048f; +//? pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_NICERST); +//? pc->SetState(STATE_SHADOW); +//? pos.y -= 0.048f; +//? pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_HIMSELF); +//? pc->SetState(STATE_SHADOW); + + ddim.x = dim.x*6; + ddim.y = dim.y*0.5f; + pos.x = ox+sx*10; + pos.y = 0.65f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_TOOLTIP); + pc->SetState(STATE_SHADOW); + pos.y -= 0.048f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_GLINT); + pc->SetState(STATE_SHADOW); + pos.y -= 0.048f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_RAIN); + pc->SetState(STATE_SHADOW); + pos.y -= 0.048f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_MOUSE); + pc->SetState(STATE_SHADOW); + pos.y -= 0.048f; + pos.y -= 0.048f; + if ( !m_bSimulSetup ) + { + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_EDITMODE); + pc->SetState(STATE_SHADOW); + } + pos.y -= 0.048f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_EDITVALUE); + pc->SetState(STATE_SHADOW); + + UpdateSetupButtons(); + } + + if ( m_phase == PHASE_SETUPc || // setup/commands ? + m_phase == PHASE_SETUPcs ) + { + pos.x = ox+sx*3; + pos.y = 320.0f/480.0f; + ddim.x = dim.x*15.0f; + ddim.y = 18.0f/480.0f; + GetResource(RES_TEXT, RT_SETUP_KEY1, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_INTERFACE_KINFO1, name); + pl->SetJustif(1); + + pos.x = ox+sx*3; + pos.y = 302.0f/480.0f; + ddim.x = dim.x*15.0f; + ddim.y = 18.0f/480.0f; + GetResource(RES_TEXT, RT_SETUP_KEY2, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_INTERFACE_KINFO2, name); + pl->SetJustif(1); + + ddim.x = 428.0f/640.0f; + ddim.y = 128.0f/480.0f; + pos.x = 105.0f/640.0f; + pos.y = 164.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 0, EVENT_INTERFACE_KGROUP); + pg->ClearState(STATE_ENABLE); + pg->SetState(STATE_DEAD); + pg->SetState(STATE_SHADOW); + + ddim.x = 18.0f/640.0f; + ddim.y = (20.0f/480.0f)*KEY_VISIBLE; + pos.x = 510.0f/640.0f; + pos.y = 168.0f/480.0f; + ps = pw->CreateScroll(pos, ddim, -1, EVENT_INTERFACE_KSCROLL); + ps->SetVisibleRatio((float)KEY_VISIBLE/KEY_TOTAL); + ps->SetArrowStep(1.0f/((float)KEY_TOTAL-KEY_VISIBLE)); + UpdateKey(); + + ddim.x = dim.x*6; + ddim.y = dim.y*0.5f; + pos.x = ox+sx*3; + pos.y = 130.0f/480.0f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_JOYSTICK); + pc->SetState(STATE_SHADOW); + + ddim.x = dim.x*6; + ddim.y = dim.y*1; + pos.x = ox+sx*10; + pos.y = oy+sy*2; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_KDEF); + pb->SetState(STATE_SHADOW); + + UpdateSetupButtons(); + } + + if ( m_phase == PHASE_SETUPs || // setup/sound ? + m_phase == PHASE_SETUPss ) + { + pos.x = ox+sx*3; + pos.y = 0.55f; + ddim.x = dim.x*4.0f; + ddim.y = 18.0f/480.0f; + psl = pw->CreateSlider(pos, ddim, 0, EVENT_INTERFACE_VOLSOUND); + psl->SetState(STATE_SHADOW); + psl->SetLimit(0.0f, MAXVOLUME); + psl->SetArrowStep(1.0f); + pos.y += ddim.y; + GetResource(RES_EVENT, EVENT_INTERFACE_VOLSOUND, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name); + pl->SetJustif(1); + +#if (_FULL | _NET) & _SOUNDTRACKS + pos.x = ox+sx*3; + pos.y = 0.40f; + ddim.x = dim.x*4.0f; + ddim.y = 18.0f/480.0f; + psl = pw->CreateSlider(pos, ddim, 0, EVENT_INTERFACE_VOLMUSIC); + psl->SetState(STATE_SHADOW); + psl->SetLimit(0.0f, MAXVOLUME); + psl->SetArrowStep(1.0f); + pos.y += ddim.y; + GetResource(RES_EVENT, EVENT_INTERFACE_VOLMUSIC, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL2, name); + pl->SetJustif(1); +#endif + + ddim.x = dim.x*6; + ddim.y = dim.y*0.5f; + pos.x = ox+sx*10; + pos.y = 0.55f; + pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SOUND3D); + pc->SetState(STATE_SHADOW); + + ddim.x = dim.x*3; + ddim.y = dim.y*1; + pos.x = ox+sx*10; + pos.y = oy+sy*2; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SILENT); + pb->SetState(STATE_SHADOW); + pos.x += ddim.x; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NOISY); + pb->SetState(STATE_SHADOW); + + UpdateSetupButtons(); + } + + if ( m_phase == PHASE_WRITE || + m_phase == PHASE_WRITEs ) + { + pos.x = 0.10f; + pos.y = 0.10f; + ddim.x = 0.80f; + ddim.y = 0.80f; + pw = m_interface->CreateWindows(pos, ddim, 13, EVENT_WINDOW5); + pw->SetClosable(TRUE); + GetResource(RES_TEXT, RT_TITLE_WRITE, name); + pw->SetName(name); + + pos.x = 0.10f; + pos.y = 0.40f; + ddim.x = 0.50f; + ddim.y = 0.50f; + pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner + pos.x = 0.40f; + pos.y = 0.10f; + ddim.x = 0.50f; + ddim.y = 0.50f; + pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner + +#if _NEWLOOK + pos.x = 100.0f/640.0f; + pos.y = 66.0f/480.0f; + ddim.x = 438.0f/640.0f; + ddim.y = 42.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet + pg->SetState(STATE_SHADOW); +#endif + + pos.x = 290.0f/640.0f; + ddim.x = 245.0f/640.0f; + + pos.y = 146.0f/480.0f; + ddim.y = 18.0f/480.0f; + GetResource(RES_EVENT, EVENT_INTERFACE_IOLABEL, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_INTERFACE_IOLABEL, name); + pl->SetJustif(1); + + pos.y = 130.0f/480.0f; + ddim.y = 18.0f/480.0f; + pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_IONAME); + pe->SetState(STATE_SHADOW); + pe->SetFontType(FONT_COLOBOT); + pe->SetMaxChar(35); + IOReadName(); + + pos.y = 190.0f/480.0f; + ddim.y = 190.0f/480.0f; + pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_IOLIST); + pli->SetState(STATE_SHADOW); + + pos.y = oy+sy*2; + ddim.y = dim.y*1; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_IOWRITE); + pb->SetState(STATE_SHADOW); + + pos.x = 105.0f/640.0f; + pos.y = 190.0f/480.0f; + ddim.x = 170.0f/640.0f; + ddim.y = dim.y*1; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_IODELETE); + pb->SetState(STATE_SHADOW); + + pos.x = 105.0f/640.0f; + pos.y = 250.0f/480.0f; + ddim.x = 170.0f/640.0f; + ddim.y = 128.0f/480.0f; + pi = pw->CreateImage(pos, ddim, 0, EVENT_INTERFACE_IOIMAGE); + pi->SetState(STATE_SHADOW); + + ddim.x = dim.x*4; + ddim.y = dim.y*1; + pos.x = ox+sx*3; + pos.y = oy+sy*2; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_BACK); + pb->SetState(STATE_SHADOW); + + IOReadList(); + IOUpdateList(); + } + + if ( m_phase == PHASE_READ || + m_phase == PHASE_READs ) + { + pos.x = 0.10f; + pos.y = 0.10f; + ddim.x = 0.80f; + ddim.y = 0.80f; + pw = m_interface->CreateWindows(pos, ddim, 14, EVENT_WINDOW5); + pw->SetClosable(TRUE); + GetResource(RES_TEXT, RT_TITLE_READ, name); + pw->SetName(name); + + pos.x = 0.10f; + pos.y = 0.40f; + ddim.x = 0.50f; + ddim.y = 0.50f; + pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner + pos.x = 0.40f; + pos.y = 0.10f; + ddim.x = 0.50f; + ddim.y = 0.50f; + pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner + +#if _NEWLOOK + pos.x = 100.0f/640.0f; + pos.y = 66.0f/480.0f; + ddim.x = 438.0f/640.0f; + ddim.y = 42.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet + pg->SetState(STATE_SHADOW); +#endif + + pos.x = 290.0f/640.0f; + ddim.x = 245.0f/640.0f; + + pos.y = 160.0f/480.0f; + ddim.y = 190.0f/480.0f; + pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_IOLIST); + pli->SetState(STATE_SHADOW); + + pos.y = oy+sy*2; + ddim.y = dim.y*1; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_IOREAD); + pb->SetState(STATE_SHADOW); + if ( m_phase == PHASE_READs ) + { + pb->SetState(STATE_WARNING); + } + + pos.x = 105.0f/640.0f; + pos.y = 160.0f/480.0f; + ddim.x = 170.0f/640.0f; + ddim.y = dim.y*1; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_IODELETE); + pb->SetState(STATE_SHADOW); + + pos.x = 105.0f/640.0f; + pos.y = 220.0f/480.0f; + ddim.x = 170.0f/640.0f; + ddim.y = 128.0f/480.0f; + pi = pw->CreateImage(pos, ddim, 0, EVENT_INTERFACE_IOIMAGE); + pi->SetState(STATE_SHADOW); + + ddim.x = dim.x*4; + ddim.y = dim.y*1; + pos.x = ox+sx*3; + pos.y = oy+sy*2; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_BACK); + pb->SetState(STATE_SHADOW); + + IOReadList(); + IOUpdateList(); + + if ( m_phase == PHASE_READ ) + { + m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE); + m_engine->SetBackForce(TRUE); + } + } + + if ( m_phase == PHASE_LOADING ) + { + pos.x = 0.35f; + pos.y = 0.10f; + ddim.x = 0.30f; + ddim.y = 0.80f; +#if _TEEN + pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5); +#else + pw = m_interface->CreateWindows(pos, ddim, 10, EVENT_WINDOW5); +#endif + pw->SetName(" "); + + pos.x = 0.35f; + pos.y = 0.60f; + ddim.x = 0.30f; + ddim.y = 0.30f; + pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner + pos.x = 0.35f; + pos.y = 0.10f; + ddim.x = 0.30f; + ddim.y = 0.30f; + pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner + + pos.x = 254.0f/640.0f; + pos.y = 208.0f/480.0f; + ddim.x = 132.0f/640.0f; + ddim.y = 42.0f/480.0f; + pg = pw->CreateGroup(pos, ddim, 22, EVENT_NULL); + pg->SetState(STATE_SHADOW); + + pos.x = 220.0f/640.0f; + pos.y = 210.0f/480.0f; + ddim.x = 200.0f/640.0f; + ddim.y = 20.0f/480.0f; + GetResource(RES_TEXT, RT_DIALOG_LOADING, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name); + pl->SetFontSize(12.0f); + pl->SetJustif(0); + + m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE); + m_engine->SetBackForce(TRUE); + + m_loadingCounter = 1; // enough time to display! + } + + if ( m_phase == PHASE_WELCOME1 ) + { + m_sound->StopMusic(); + m_sound->PlayMusic(11, FALSE); + + pos.x = 0.0f; + pos.y = 0.0f; + ddim.x = 0.0f; + ddim.y = 0.0f; + pw = m_interface->CreateWindows(pos, ddim, -1, EVENT_WINDOW5); + + m_engine->SetOverColor(RetColor(1.0f), D3DSTATETCb); + m_engine->SetOverFront(TRUE); + +#if _FRENCH + m_engine->SetBackground("alsyd.tga", 0,0, 0,0, TRUE, FALSE); +#endif +#if _POLISH + m_engine->SetBackground("manta.tga", 0,0, 0,0, TRUE, FALSE); +#endif +#if _WG + m_engine->SetBackground("wg.tga", 0,0, 0,0, TRUE, FALSE); +#endif + m_engine->SetBackForce(TRUE); + } + if ( m_phase == PHASE_WELCOME2 ) + { +#if _ENGLISH + m_sound->StopMusic(); + m_sound->PlayMusic(11, FALSE); +#endif +#if _POLISH + m_sound->StopMusic(); + m_sound->PlayMusic(11, FALSE); +#endif + + pos.x = 0.0f; + pos.y = 0.0f; + ddim.x = 0.0f; + ddim.y = 0.0f; + pw = m_interface->CreateWindows(pos, ddim, -1, EVENT_WINDOW5); + + m_engine->SetOverColor(RetColor(1.0f), D3DSTATETCb); + m_engine->SetOverFront(TRUE); + + m_engine->SetBackground("colobot.tga", 0,0, 0,0, TRUE, FALSE); + m_engine->SetBackForce(TRUE); + } + if ( m_phase == PHASE_WELCOME3 ) + { + pos.x = 0.0f; + pos.y = 0.0f; + ddim.x = 0.0f; + ddim.y = 0.0f; + pw = m_interface->CreateWindows(pos, ddim, -1, EVENT_WINDOW5); + + m_engine->SetOverColor(RetColor(0.0f), D3DSTATETCw); + m_engine->SetOverFront(TRUE); + +#if _FRENCH + m_engine->SetBackground("epsitecf.tga", 0,0, 0,0, TRUE, FALSE); +#endif +#if _ENGLISH + m_engine->SetBackground("epsitece.tga", 0,0, 0,0, TRUE, FALSE); +#endif +#if _GERMAN | _WG + m_engine->SetBackground("epsitecd.tga", 0,0, 0,0, TRUE, FALSE); +#endif +#if _POLISH + m_engine->SetBackground("epsitecp.tga", 0,0, 0,0, TRUE, FALSE); +#endif + m_engine->SetBackForce(TRUE); + } + + if ( m_phase == PHASE_GENERIC ) + { + pos.x = 0.0f; + pos.y = 0.0f; + ddim.x = 0.0f; + ddim.y = 0.0f; + pw = m_interface->CreateWindows(pos, ddim, -1, EVENT_WINDOW5); + +#if _FULL | _NET + pos.x = 80.0f/640.0f; + pos.y = 240.0f/480.0f; + ddim.x = 490.0f/640.0f; + ddim.y = 110.0f/480.0f; + pe = pw->CreateEdit(pos, ddim, 0, EVENT_EDIT1); + pe->SetGenericMode(TRUE); + pe->SetEditCap(FALSE); + pe->SetHiliteCap(FALSE); + pe->SetFontType(FONT_COURIER); + pe->SetFontSize(8.0f); + pe->ReadText("help\\authors.txt"); + + pos.x = 80.0f/640.0f; + pos.y = 140.0f/480.0f; + ddim.x = 490.0f/640.0f; + ddim.y = 100.0f/480.0f; + pe = pw->CreateEdit(pos, ddim, 0, EVENT_EDIT2); + pe->SetGenericMode(TRUE); + pe->SetEditCap(FALSE); + pe->SetHiliteCap(FALSE); + pe->SetFontType(FONT_COURIER); + pe->SetFontSize(6.5f); + pe->ReadText("help\\licences.txt"); +#endif +#if _SCHOOL +#if _CEEBOTDEMO + pos.x = 80.0f/640.0f; + pos.y = 210.0f/480.0f; + ddim.x = 490.0f/640.0f; + ddim.y = 150.0f/480.0f; +#else + pos.x = 80.0f/640.0f; + pos.y = 200.0f/480.0f; + ddim.x = 490.0f/640.0f; + ddim.y = 150.0f/480.0f; +#endif + pe = pw->CreateEdit(pos, ddim, 0, EVENT_EDIT1); + pe->SetGenericMode(TRUE); + pe->SetEditCap(FALSE); + pe->SetHiliteCap(FALSE); + pe->SetFontType(FONT_COURIER); + pe->SetFontSize(8.0f); + pe->ReadText("help\\authors.txt"); +#endif +#if _DEMO +//? pos.x = 80.0f/640.0f; +//? pos.y = 240.0f/480.0f; +//? ddim.x = 490.0f/640.0f; +//? ddim.y = 110.0f/480.0f; +//? pe = pw->CreateEdit(pos, ddim, 0, EVENT_EDIT1); +//? pe->SetGenericMode(TRUE); +//? pe->SetEditCap(FALSE); +//? pe->SetHiliteCap(FALSE); +//? pe->SetFontType(FONT_COURIER); +//? pe->SetFontSize(8.0f); +//? pe->ReadText("help\\demo.txt"); + +//? pos.x = 80.0f/640.0f; +//? pos.y = 140.0f/480.0f; +//? ddim.x = 490.0f/640.0f; +//? ddim.y = 100.0f/480.0f; +//? pe = pw->CreateEdit(pos, ddim, 0, EVENT_EDIT2); +//? pe->SetGenericMode(TRUE); +//? pe->SetEditCap(FALSE); +//? pe->SetHiliteCap(FALSE); +//? pe->SetFontType(FONT_COURIER); +//? pe->SetFontSize(8.0f); +//? pe->ReadText("help\\authors.txt"); +#endif + +#if !_DEMO + pos.x = 40.0f/640.0f; + pos.y = 83.0f/480.0f; + ddim.x = 246.0f/640.0f; + ddim.y = 16.0f/480.0f; + GetResource(RES_TEXT, RT_GENERIC_DEV1, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name); + pl->SetFontType(FONT_COURIER); + pl->SetFontSize(8.0f); + + pos.y = 13.0f/480.0f; + GetResource(RES_TEXT, RT_GENERIC_DEV2, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL2, name); + pl->SetFontType(FONT_COURIER); + pl->SetFontSize(8.0f); + + pos.x = 355.0f/640.0f; + pos.y = 83.0f/480.0f; + ddim.x = 246.0f/640.0f; + ddim.y = 16.0f/480.0f; + GetResource(RES_TEXT, RT_GENERIC_EDIT1, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL3, name); + pl->SetFontType(FONT_COURIER); + pl->SetFontSize(8.0f); + + pos.y = 13.0f/480.0f; + GetResource(RES_TEXT, RT_GENERIC_EDIT2, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL4, name); + pl->SetFontType(FONT_COURIER); + pl->SetFontSize(8.0f); +#endif + +#if _DEMO + pos.x = 481.0f/640.0f; + pos.y = 51.0f/480.0f; + ddim.x = 30.0f/640.0f; + ddim.y = 30.0f/480.0f; + pb = pw->CreateButton(pos, ddim, 49, EVENT_INTERFACE_ABORT); + pb->SetState(STATE_SHADOW); +#else + pos.x = 306.0f/640.0f; + pos.y = 17.0f/480.0f; + ddim.x = 30.0f/640.0f; + ddim.y = 30.0f/480.0f; + pb = pw->CreateButton(pos, ddim, 49, EVENT_INTERFACE_ABORT); + pb->SetState(STATE_SHADOW); +#endif + +#if _NEWLOOK +#if _CEEBOTDEMO +#if _TEEN + m_engine->SetBackground("genedt.tga", 0,0, 0,0, TRUE, TRUE); +#else + m_engine->SetBackground("geneda.tga", 0,0, 0,0, TRUE, TRUE); +#endif +#else + m_engine->SetBackground("genern.tga", 0,0, 0,0, TRUE, TRUE); +#endif +#else +#if _FRENCH +#if _DEMO + m_engine->SetBackground("genedf.tga", 0,0, 0,0, TRUE, TRUE); +#else + m_engine->SetBackground("generf.tga", 0,0, 0,0, TRUE, TRUE); +#endif +#endif +#if _ENGLISH +#if _DEMO + m_engine->SetBackground("genede.tga", 0,0, 0,0, TRUE, TRUE); +#else + m_engine->SetBackground("genere.tga", 0,0, 0,0, TRUE, TRUE); +#endif +#endif +#if _GERMAN +#if _DEMO + m_engine->SetBackground("genedd.tga", 0,0, 0,0, TRUE, TRUE); +#else + m_engine->SetBackground("genere.tga", 0,0, 0,0, TRUE, TRUE); +#endif +#endif +#if _WG +#if _DEMO + m_engine->SetBackground("genedd.tga", 0,0, 0,0, TRUE, TRUE); +#else + m_engine->SetBackground("generd.tga", 0,0, 0,0, TRUE, TRUE); +#endif +#endif +#if _POLISH +#if _DEMO + m_engine->SetBackground("genedp.tga", 0,0, 0,0, TRUE, TRUE); +#else + m_engine->SetBackground("generp.tga", 0,0, 0,0, TRUE, TRUE); +#endif +#endif +#endif + m_engine->SetBackForce(TRUE); + } + + if ( m_phase == PHASE_INIT || + m_phase == PHASE_NAME || + m_phase == PHASE_TRAINER || + m_phase == PHASE_DEFI || + m_phase == PHASE_MISSION || + m_phase == PHASE_FREE || + m_phase == PHASE_TEEN || + m_phase == PHASE_USER || + m_phase == PHASE_PROTO || + m_phase == PHASE_SETUPd || + m_phase == PHASE_SETUPg || + m_phase == PHASE_SETUPp || + m_phase == PHASE_SETUPc || + m_phase == PHASE_SETUPs || + m_phase == PHASE_READ || + m_phase == PHASE_LOADING ) + { +#if _SCHOOL +#if _TEEN + pos.x = 50.0f/640.0f; + pos.y = 430.0f/480.0f; + ddim.x = 200.0f/640.0f; + ddim.y = 10.0f/480.0f; +#else + pos.x = 450.0f/640.0f; + pos.y = 0.0f/480.0f; + ddim.x = 170.0f/640.0f; + ddim.y = 9.0f/480.0f; +#endif +#else + pos.x = 540.0f/640.0f; + pos.y = 9.0f/480.0f; + ddim.x = 90.0f/640.0f; + ddim.y = 10.0f/480.0f; +#endif + GetResource(RES_TEXT, RT_VERSION_ID, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name); + pl->SetFontType(FONT_COURIER); + pl->SetFontSize(9.0f); + } + + m_engine->LoadAllTexture(); +} + + +// Processing an event. +// Returns FALSE if the event has been processed completely. + +BOOL CMainDialog::EventProcess(const Event &event) +{ + CWindow* pw; + CList* pl; + CButton* pb; + CCheck* pc; + Event newEvent; + float welcomeLength; + + if ( event.event == EVENT_FRAME ) + { + m_phaseTime += event.rTime; + +//? if ( m_phase == PHASE_WELCOME1 ) welcomeLength = WELCOME_LENGTH+2.0f; +//? else welcomeLength = WELCOME_LENGTH; + welcomeLength = WELCOME_LENGTH; + + if ( m_phase == PHASE_WELCOME1 || + m_phase == PHASE_WELCOME2 || + m_phase == PHASE_WELCOME3 ) + { + float intensity; + int mode = D3DSTATETCb; + + if ( m_phaseTime < 1.5f ) + { + intensity = 1.0f-(m_phaseTime-0.5f); + } + else if ( m_phaseTime < welcomeLength-1.0f ) + { + intensity = 0.0f; + } + else + { + intensity = m_phaseTime-(welcomeLength-1.0f); + } + if ( intensity < 0.0f ) intensity = 0.0f; + if ( intensity > 1.0f ) intensity = 1.0f; + + if ( (m_phase == PHASE_WELCOME2 && m_phaseTime > welcomeLength/2.0f) || + m_phase == PHASE_WELCOME3 ) + { + intensity = 1.0f-intensity; + mode = D3DSTATETCw; + } + + m_engine->SetOverColor(RetColor(intensity), mode); + } + + if ( m_phase == PHASE_WELCOME1 && m_phaseTime >= welcomeLength ) + { + ChangePhase(PHASE_WELCOME2); + return TRUE; + } + if ( m_phase == PHASE_WELCOME2 && m_phaseTime >= welcomeLength ) + { + ChangePhase(PHASE_WELCOME3); + return TRUE; + } + if ( m_phase == PHASE_WELCOME3 && m_phaseTime >= welcomeLength ) + { + ChangePhase(PHASE_NAME); + return TRUE; + } + + if ( m_shotDelay > 0 && !m_bDialog ) // screenshot done? + { + m_shotDelay --; + if ( m_shotDelay == 0 ) + { + m_engine->WriteScreenShot(m_shotName, 320, 240); +//? m_engine->WriteScreenShot(m_shotName, 160, 120); + } + } + + if ( m_phase == PHASE_LOADING ) + { + if ( m_loadingCounter == 0 ) + { + m_main->ChangePhase(PHASE_SIMUL); + } + m_loadingCounter --; + return FALSE; + } + + m_glintTime += event.rTime; + GlintMove(); // moves reflections + + FrameParticule(event.rTime); + + if ( m_bDialog ) // this dialogue? + { + FrameDialog(event.rTime); + } + + return TRUE; + } + + if ( event.event == EVENT_MOUSEMOVE ) + { + m_glintMouse = event.pos; + NiceParticule(event.pos, event.keyState&KS_MLEFT); + } + + if ( m_bDialog ) // this dialogue? + { + m_interface->EventProcess(event); + + if ( event.event == EVENT_DIALOG_OK || + (event.event == EVENT_KEYDOWN && event.param == VK_RETURN ) ) + { + StopDialog(); + if ( m_phase == PHASE_NAME ) + { + NameDelete(); + } + if ( m_phase == PHASE_INIT ) + { +//? m_event->MakeEvent(newEvent, EVENT_QUIT); +//? m_event->AddEvent(newEvent); + m_main->ChangePhase(PHASE_GENERIC); + } + if ( m_phase == PHASE_SIMUL ) + { + if ( m_bDialogDelete ) + { + m_main->DeleteObject(); + } + else + { + m_main->ChangePhase(PHASE_TERM); + } + } + } + if ( event.event == EVENT_DIALOG_CANCEL || + (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE ) ) + { + StopDialog(); + } + if ( event.event == EVENT_INTERFACE_SETUP ) + { + StopDialog(); + StartSuspend(); + if ( m_phaseSetup == PHASE_SETUPd ) ChangePhase(PHASE_SETUPds); + if ( m_phaseSetup == PHASE_SETUPg ) ChangePhase(PHASE_SETUPgs); + if ( m_phaseSetup == PHASE_SETUPp ) ChangePhase(PHASE_SETUPps); + if ( m_phaseSetup == PHASE_SETUPc ) ChangePhase(PHASE_SETUPcs); + if ( m_phaseSetup == PHASE_SETUPs ) ChangePhase(PHASE_SETUPss); + } + if ( event.event == EVENT_INTERFACE_AGAIN ) + { + StopDialog(); + m_main->ChangePhase(PHASE_LOADING); + } + if ( event.event == EVENT_INTERFACE_WRITE ) + { + StopDialog(); + StartSuspend(); + ChangePhase(PHASE_WRITEs); + } + if ( event.event == EVENT_INTERFACE_READ ) + { + StopDialog(); + StartSuspend(); + ChangePhase(PHASE_READs); + } + + return FALSE; + } + + if ( !m_engine->RetMouseHide() && + !m_interface->EventProcess(event) ) + { + return FALSE; + } + + if ( m_phase == PHASE_INIT ) + { + switch( event.event ) + { + case EVENT_KEYDOWN: + if ( event.param == VK_ESCAPE ) + { +//? StartQuit(); // would you leave? + m_sound->Play(SOUND_TZOING); + m_main->ChangePhase(PHASE_GENERIC); + } + break; + + case EVENT_INTERFACE_QUIT: +//? StartQuit(); // would you leave? + m_sound->Play(SOUND_TZOING); + m_main->ChangePhase(PHASE_GENERIC); + break; + + case EVENT_INTERFACE_TRAINER: + m_main->ChangePhase(PHASE_TRAINER); + break; + + case EVENT_INTERFACE_DEFI: + m_main->ChangePhase(PHASE_DEFI); + break; + + case EVENT_INTERFACE_MISSION: + m_main->ChangePhase(PHASE_MISSION); + break; + + case EVENT_INTERFACE_FREE: + m_main->ChangePhase(PHASE_FREE); + break; + + case EVENT_INTERFACE_TEEN: + m_main->ChangePhase(PHASE_TEEN); + break; + + case EVENT_INTERFACE_USER: + m_main->ChangePhase(PHASE_USER); + break; + + case EVENT_INTERFACE_PROTO: + m_main->ChangePhase(PHASE_PROTO); + break; + + case EVENT_INTERFACE_SETUP: + m_main->ChangePhase(m_phaseSetup); + break; + + case EVENT_INTERFACE_NAME: + m_main->ChangePhase(PHASE_NAME); + break; + } + return FALSE; + } + + if ( m_phase == PHASE_NAME ) + { + switch( event.event ) + { + case EVENT_KEYDOWN: + if ( event.param == VK_RETURN ) + { + NameSelect(); + } + if ( event.param == VK_ESCAPE ) + { + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) break; + pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_NCANCEL); + if ( pb == 0 ) break; + if ( pb->TestState(STATE_ENABLE) ) + { + m_main->ChangePhase(PHASE_INIT); + } + } + break; + + case EVENT_INTERFACE_NEDIT: + UpdateNameList(); + UpdateNameControl(); + break; + + case EVENT_INTERFACE_NLIST: + UpdateNameEdit(); + break; + + case EVENT_INTERFACE_NOK: + NameSelect(); + break; + + case EVENT_INTERFACE_PERSO: + NameSelect(); + m_main->ChangePhase(PHASE_PERSO); + break; + + case EVENT_INTERFACE_NCANCEL: + m_main->ChangePhase(PHASE_INIT); + break; + + case EVENT_INTERFACE_NDELETE: + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) break; + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); + if ( pl == 0 ) break; + StartDeleteGame(pl->RetName(pl->RetSelect())); + break; + } + } + + if ( m_phase == PHASE_PERSO ) + { + switch( event.event ) + { + case EVENT_KEYDOWN: + if ( event.param == VK_RETURN ) + { + m_main->ChangePhase(PHASE_INIT); + } + if ( event.param == VK_ESCAPE ) + { + m_main->ChangePhase(PHASE_NAME); + } + break; + + case EVENT_INTERFACE_PHEAD: + m_persoTab = 0; + UpdatePerso(); + m_main->ScenePerso(); + CameraPerso(); + break; + case EVENT_INTERFACE_PBODY: + m_persoTab = 1; + UpdatePerso(); + m_main->ScenePerso(); + CameraPerso(); + break; + + case EVENT_INTERFACE_PFACE1: + case EVENT_INTERFACE_PFACE2: + case EVENT_INTERFACE_PFACE3: + case EVENT_INTERFACE_PFACE4: + m_perso.face = event.event-EVENT_INTERFACE_PFACE1; + WriteGamerPerso(m_main->RetGamerName()); + UpdatePerso(); + m_main->ScenePerso(); + break; + + case EVENT_INTERFACE_PGLASS0: + case EVENT_INTERFACE_PGLASS1: + case EVENT_INTERFACE_PGLASS2: + case EVENT_INTERFACE_PGLASS3: + case EVENT_INTERFACE_PGLASS4: + case EVENT_INTERFACE_PGLASS5: + case EVENT_INTERFACE_PGLASS6: + case EVENT_INTERFACE_PGLASS7: + case EVENT_INTERFACE_PGLASS8: + case EVENT_INTERFACE_PGLASS9: + m_perso.glasses = event.event-EVENT_INTERFACE_PGLASS0; + WriteGamerPerso(m_main->RetGamerName()); + UpdatePerso(); + m_main->ScenePerso(); + break; + + case EVENT_INTERFACE_PC0a: + case EVENT_INTERFACE_PC1a: + case EVENT_INTERFACE_PC2a: + case EVENT_INTERFACE_PC3a: + case EVENT_INTERFACE_PC4a: + case EVENT_INTERFACE_PC5a: + case EVENT_INTERFACE_PC6a: + case EVENT_INTERFACE_PC7a: + case EVENT_INTERFACE_PC8a: + case EVENT_INTERFACE_PC9a: + FixPerso(event.event-EVENT_INTERFACE_PC0a, 0); + WriteGamerPerso(m_main->RetGamerName()); + UpdatePerso(); + m_main->ScenePerso(); + break; + + case EVENT_INTERFACE_PC0b: + case EVENT_INTERFACE_PC1b: + case EVENT_INTERFACE_PC2b: + case EVENT_INTERFACE_PC3b: + case EVENT_INTERFACE_PC4b: + case EVENT_INTERFACE_PC5b: + case EVENT_INTERFACE_PC6b: + case EVENT_INTERFACE_PC7b: + case EVENT_INTERFACE_PC8b: + case EVENT_INTERFACE_PC9b: + FixPerso(event.event-EVENT_INTERFACE_PC0b, 1); + WriteGamerPerso(m_main->RetGamerName()); + UpdatePerso(); + m_main->ScenePerso(); + break; + + case EVENT_INTERFACE_PCRa: + case EVENT_INTERFACE_PCGa: + case EVENT_INTERFACE_PCBa: + case EVENT_INTERFACE_PCRb: + case EVENT_INTERFACE_PCGb: + case EVENT_INTERFACE_PCBb: + ColorPerso(); + WriteGamerPerso(m_main->RetGamerName()); + UpdatePerso(); + m_main->ScenePerso(); + break; + + case EVENT_INTERFACE_PDEF: + DefPerso(); + WriteGamerPerso(m_main->RetGamerName()); + UpdatePerso(); + m_main->ScenePerso(); + break; + + case EVENT_INTERFACE_PLROT: + m_persoAngle += 0.2f; + break; + case EVENT_INTERFACE_PRROT: + m_persoAngle -= 0.2f; + break; + + case EVENT_INTERFACE_POK: + m_main->ChangePhase(PHASE_INIT); + break; + + case EVENT_INTERFACE_PCANCEL: + m_perso = m_persoCopy; + WriteGamerPerso(m_main->RetGamerName()); + m_main->ChangePhase(PHASE_NAME); + break; + } + } + + if ( m_phase == PHASE_TRAINER || + m_phase == PHASE_DEFI || + m_phase == PHASE_MISSION || + m_phase == PHASE_FREE || + m_phase == PHASE_TEEN || + m_phase == PHASE_USER || + m_phase == PHASE_PROTO ) + { + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return FALSE; + + if ( event.event == pw->RetEventMsgClose() || + event.event == EVENT_INTERFACE_BACK || + (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) ) + { + m_main->ChangePhase(PHASE_INIT); + return FALSE; + } + } + + if ( m_phase == PHASE_TRAINER || + m_phase == PHASE_DEFI || + m_phase == PHASE_MISSION || + m_phase == PHASE_FREE || + m_phase == PHASE_TEEN || + m_phase == PHASE_USER || + m_phase == PHASE_PROTO ) + { + switch( event.event ) + { + case EVENT_INTERFACE_CHAP: + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_CHAP); + if ( pl == 0 ) break; + m_chap[m_index] = pl->RetSelect(); + UpdateSceneList(m_chap[m_index], m_sel[m_index]); + UpdateSceneResume((m_chap[m_index]+1)*100+(m_sel[m_index]+1)); + break; + + case EVENT_INTERFACE_LIST: + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_LIST); + if ( pl == 0 ) break; + m_sel[m_index] = pl->RetSelect(); + UpdateSceneResume((m_chap[m_index]+1)*100+(m_sel[m_index]+1)); + break; + + case EVENT_INTERFACE_SOLUCE: + pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_SOLUCE); + if ( pb == 0 ) break; + m_bSceneSoluce = !m_bSceneSoluce; + pb->SetState(STATE_CHECK, m_bSceneSoluce); + break; + + case EVENT_INTERFACE_PLAY: + if ( m_phase == PHASE_PROTO && m_chap[m_index] == 0 && m_sel[m_index] == 0 ) + { + m_main->ChangePhase(PHASE_MODEL); + break; + } + m_sceneRank = (m_chap[m_index]+1)*100+(m_sel[m_index]+1); + m_phaseTerm = m_phase; + m_main->ChangePhase(PHASE_LOADING); + break; + + case EVENT_INTERFACE_READ: + m_phaseTerm = m_phase; + m_main->ChangePhase(PHASE_READ); + break; + } + return FALSE; + } + + if ( m_phase == PHASE_SETUPd || + m_phase == PHASE_SETUPg || + m_phase == PHASE_SETUPp || + m_phase == PHASE_SETUPc || + m_phase == PHASE_SETUPs ) + { + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return FALSE; + + if ( event.event == pw->RetEventMsgClose() || + event.event == EVENT_INTERFACE_BACK || + (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) ) + { + SetupMemorize(); + m_engine->ApplyChange(); + m_main->ChangePhase(PHASE_INIT); + return FALSE; + } + + switch( event.event ) + { + case EVENT_INTERFACE_SETUPd: + m_main->ChangePhase(PHASE_SETUPd); + break; + + case EVENT_INTERFACE_SETUPg: + m_main->ChangePhase(PHASE_SETUPg); + break; + + case EVENT_INTERFACE_SETUPp: + m_main->ChangePhase(PHASE_SETUPp); + break; + + case EVENT_INTERFACE_SETUPc: + m_main->ChangePhase(PHASE_SETUPc); + break; + + case EVENT_INTERFACE_SETUPs: + m_main->ChangePhase(PHASE_SETUPs); + break; + } + } + + if ( m_phase == PHASE_SETUPds || + m_phase == PHASE_SETUPgs || + m_phase == PHASE_SETUPps || + m_phase == PHASE_SETUPcs || + m_phase == PHASE_SETUPss ) + { + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return FALSE; + + if ( event.event == pw->RetEventMsgClose() || + event.event == EVENT_INTERFACE_BACK || + (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) ) + { + SetupMemorize(); + m_engine->ApplyChange(); + m_interface->DeleteControl(EVENT_WINDOW5); + ChangePhase(PHASE_SIMUL); + StopSuspend(); + return FALSE; + } + + switch( event.event ) + { + case EVENT_INTERFACE_SETUPd: + ChangePhase(PHASE_SETUPds); + break; + + case EVENT_INTERFACE_SETUPg: + ChangePhase(PHASE_SETUPgs); + break; + + case EVENT_INTERFACE_SETUPp: + ChangePhase(PHASE_SETUPps); + break; + + case EVENT_INTERFACE_SETUPc: + ChangePhase(PHASE_SETUPcs); + break; + + case EVENT_INTERFACE_SETUPs: + ChangePhase(PHASE_SETUPss); + break; + } + } + + if ( m_phase == PHASE_SETUPd || // setup/display ? + m_phase == PHASE_SETUPds ) + { + switch( event.event ) + { + case EVENT_LIST1: + case EVENT_LIST2: + UpdateApply(); + break; + + case EVENT_INTERFACE_FULL: + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) break; + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_FULL); + if ( pc == 0 ) break; + pl = (CList*)pw->SearchControl(EVENT_LIST2); + if ( pl == 0 ) break; + if ( pc->TestState(STATE_CHECK) ) + { + pc->ClearState(STATE_CHECK); // window + pl->ClearState(STATE_ENABLE); + } + else + { + pc->SetState(STATE_CHECK); // fullscreen + pl->SetState(STATE_ENABLE); + } + UpdateApply(); + break; + + case EVENT_INTERFACE_APPLY: + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) break; + pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_APPLY); + if ( pb == 0 ) break; + pb->ClearState(STATE_PRESS); + pb->ClearState(STATE_HILIGHT); + ChangeDisplay(); + UpdateApply(); + break; + } + return FALSE; + } + + if ( m_phase == PHASE_SETUPg || // setup/graphic ? + m_phase == PHASE_SETUPgs ) + { + switch( event.event ) + { + case EVENT_INTERFACE_SHADOW: + m_engine->SetShadow(!m_engine->RetShadow()); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_GROUND: + m_engine->SetGroundSpot(!m_engine->RetGroundSpot()); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_DIRTY: + m_engine->SetDirty(!m_engine->RetDirty()); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_FOG: + m_engine->SetFog(!m_engine->RetFog()); + m_camera->SetOverBaseColor(RetColor(RetColor(0.0f))); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_LENS: + m_engine->SetLensMode(!m_engine->RetLensMode()); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_SKY: + m_engine->SetSkyMode(!m_engine->RetSkyMode()); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_PLANET: + m_engine->SetPlanetMode(!m_engine->RetPlanetMode()); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_LIGHT: + m_engine->SetLightMode(!m_engine->RetLightMode()); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_PARTI: + case EVENT_INTERFACE_CLIP: + case EVENT_INTERFACE_DETAIL: + case EVENT_INTERFACE_GADGET: + case EVENT_INTERFACE_TEXTURE: + ChangeSetupButtons(); + break; + + case EVENT_INTERFACE_MIN: + ChangeSetupQuality(-1); + UpdateSetupButtons(); + break; + case EVENT_INTERFACE_NORM: + ChangeSetupQuality(0); + UpdateSetupButtons(); + break; + case EVENT_INTERFACE_MAX: + ChangeSetupQuality(1); + UpdateSetupButtons(); + break; + } + return FALSE; + } + + if ( m_phase == PHASE_SETUPp || // setup/game ? + m_phase == PHASE_SETUPps ) + { + switch( event.event ) + { + case EVENT_INTERFACE_TOTO: + m_engine->SetTotoMode(!m_engine->RetTotoMode()); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_TOOLTIP: + m_bTooltip = !m_bTooltip; + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_GLINT: + m_bGlint = !m_bGlint; + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_RAIN: + m_bRain = !m_bRain; + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_MOUSE: + m_engine->SetNiceMouse(!m_engine->RetNiceMouse()); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_EDITMODE: + m_engine->SetEditIndentMode(!m_engine->RetEditIndentMode()); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_EDITVALUE: + if ( m_engine->RetEditIndentValue() == 2 ) + { + m_engine->SetEditIndentValue(4); + } + else + { + m_engine->SetEditIndentValue(2); + } + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_SOLUCE4: + m_bSoluce4 = !m_bSoluce4; + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_MOVIES: + m_bMovies = !m_bMovies; + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_NICERST: + m_bNiceReset = !m_bNiceReset; + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_HIMSELF: + m_bHimselfDamage = !m_bHimselfDamage; + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_SCROLL: + m_bCameraScroll = !m_bCameraScroll; + m_camera->SetCameraScroll(m_bCameraScroll); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_INVERTX: + m_bCameraInvertX = !m_bCameraInvertX; + m_camera->SetCameraInvertX(m_bCameraInvertX); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_INVERTY: + m_bCameraInvertY = !m_bCameraInvertY; + m_camera->SetCameraInvertY(m_bCameraInvertY); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_EFFECT: + m_bEffect = !m_bEffect; + m_camera->SetEffect(m_bEffect); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + } + return FALSE; + } + + if ( m_phase == PHASE_SETUPc || // setup/commands ? + m_phase == PHASE_SETUPcs ) + { + switch( event.event ) + { + case EVENT_INTERFACE_KSCROLL: + UpdateKey(); + break; + + case EVENT_INTERFACE_KLEFT: + case EVENT_INTERFACE_KRIGHT: + case EVENT_INTERFACE_KUP: + case EVENT_INTERFACE_KDOWN: + case EVENT_INTERFACE_KGUP: + case EVENT_INTERFACE_KGDOWN: + case EVENT_INTERFACE_KCAMERA: + case EVENT_INTERFACE_KDESEL: + case EVENT_INTERFACE_KACTION: + case EVENT_INTERFACE_KNEAR: + case EVENT_INTERFACE_KAWAY: + case EVENT_INTERFACE_KNEXT: + case EVENT_INTERFACE_KHUMAN: + case EVENT_INTERFACE_KQUIT: + case EVENT_INTERFACE_KHELP: + case EVENT_INTERFACE_KPROG: + case EVENT_INTERFACE_KCBOT: + case EVENT_INTERFACE_KSPEED10: + case EVENT_INTERFACE_KSPEED15: + case EVENT_INTERFACE_KSPEED20: + case EVENT_INTERFACE_KSPEED30: + case EVENT_INTERFACE_KVISIT: + ChangeKey(event.event); + UpdateKey(); + break; + + case EVENT_INTERFACE_KDEF: + m_engine->ResetKey(); + UpdateKey(); + break; + + case EVENT_INTERFACE_JOYSTICK: + m_engine->SetJoystick(!m_engine->RetJoystick()); + UpdateSetupButtons(); + break; + } + return FALSE; + } + + if ( m_phase == PHASE_SETUPs || // setup/sound ? + m_phase == PHASE_SETUPss ) + { + switch( event.event ) + { + case EVENT_INTERFACE_VOLSOUND: + case EVENT_INTERFACE_VOLMUSIC: + ChangeSetupButtons(); + break; + + case EVENT_INTERFACE_SOUND3D: + m_sound->SetSound3D(!m_sound->RetSound3D()); + ChangeSetupButtons(); + UpdateSetupButtons(); + break; + + case EVENT_INTERFACE_SILENT: + m_sound->SetAudioVolume(0); + m_sound->SetMidiVolume(0); + UpdateSetupButtons(); + break; + case EVENT_INTERFACE_NOISY: + m_sound->SetAudioVolume(MAXVOLUME); + m_sound->SetMidiVolume(MAXVOLUME*3/4); + UpdateSetupButtons(); + break; + } + return FALSE; + } + + if ( m_phase == PHASE_READ ) + { + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return FALSE; + + if ( event.event == pw->RetEventMsgClose() || + event.event == EVENT_INTERFACE_BACK || + (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) ) + { + ChangePhase(m_phaseTerm); + } + + if ( event.event == EVENT_INTERFACE_IOLIST ) + { + IOUpdateList(); + } + if ( event.event == EVENT_INTERFACE_IODELETE ) + { + IODeleteScene(); + IOUpdateList(); + } + if ( event.event == EVENT_INTERFACE_IOREAD ) + { + if ( IOReadScene() ) + { + m_main->ChangePhase(PHASE_LOADING); + } + } + + return FALSE; + } + + if ( m_phase == PHASE_WRITEs || + m_phase == PHASE_READs ) + { + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return FALSE; + + if ( event.event == pw->RetEventMsgClose() || + event.event == EVENT_INTERFACE_BACK || + (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) ) + { + m_interface->DeleteControl(EVENT_WINDOW5); + ChangePhase(PHASE_SIMUL); + StopSuspend(); + } + + if ( event.event == EVENT_INTERFACE_IOLIST ) + { + IOUpdateList(); + } + if ( event.event == EVENT_INTERFACE_IODELETE ) + { + IODeleteScene(); + IOUpdateList(); + } + if ( event.event == EVENT_INTERFACE_IOWRITE ) + { + IOWriteScene(); + m_interface->DeleteControl(EVENT_WINDOW5); + ChangePhase(PHASE_SIMUL); + StopSuspend(); + } + if ( event.event == EVENT_INTERFACE_IOREAD ) + { + if ( IOReadScene() ) + { + m_interface->DeleteControl(EVENT_WINDOW5); + ChangePhase(PHASE_SIMUL); + StopSuspend(); + m_main->ChangePhase(PHASE_LOADING); + } + } + + return FALSE; + } + + if ( m_phase == PHASE_WELCOME1 ) + { + if ( event.event == EVENT_KEYDOWN || + event.event == EVENT_LBUTTONDOWN || + event.event == EVENT_RBUTTONDOWN ) + { + ChangePhase(PHASE_WELCOME2); + return TRUE; + } + } + if ( m_phase == PHASE_WELCOME2 ) + { + if ( event.event == EVENT_KEYDOWN || + event.event == EVENT_LBUTTONDOWN || + event.event == EVENT_RBUTTONDOWN ) + { + ChangePhase(PHASE_WELCOME3); + return TRUE; + } + } + if ( m_phase == PHASE_WELCOME3 ) + { + if ( event.event == EVENT_KEYDOWN || + event.event == EVENT_LBUTTONDOWN || + event.event == EVENT_RBUTTONDOWN ) + { + ChangePhase(PHASE_NAME); + return TRUE; + } + } + + if ( m_phase == PHASE_GENERIC ) + { + if ( event.event == EVENT_INTERFACE_ABORT ) + { + ChangePhase(PHASE_INIT); + } + + if ( event.event == EVENT_KEYDOWN ) + { + if ( event.param == VK_ESCAPE ) + { + ChangePhase(PHASE_INIT); + } + else + { + m_event->MakeEvent(newEvent, EVENT_QUIT); + m_event->AddEvent(newEvent); + } + } + + if ( event.event == EVENT_LBUTTONDOWN || + event.event == EVENT_RBUTTONDOWN ) + { + m_event->MakeEvent(newEvent, EVENT_QUIT); + m_event->AddEvent(newEvent); + } + } + + return TRUE; +} + + +// Moves the reflections. + +void CMainDialog::GlintMove() +{ + CWindow* pw; + CGroup* pg; + FPOINT pos, dim, zoom; + + if ( m_phase == PHASE_SIMUL ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + + if ( m_phase == PHASE_INIT ) + { + pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTl); + if ( pg != 0 ) + { + zoom.x = sinf(m_glintTime*0.23f); + zoom.y = sinf(m_glintTime*0.37f); + pos.x = 0.35f; + pos.y = 0.90f; + dim.x = 0.30f-0.10f*(zoom.x+1.0f)/2.0f; + dim.y = 0.50f-0.30f*(zoom.y+1.0f)/2.0f; + pos.y -= dim.y; + pg->SetPos(pos); + pg->SetDim(dim); + } + + pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTr); + if ( pg != 0 ) + { + zoom.x = sinf(m_glintTime*0.21f); + zoom.y = sinf(m_glintTime*0.26f); + pos.x = 0.65f; + pos.y = 0.10f; + dim.x = 0.30f-0.10f*(zoom.x+1.0f)/2.0f; + dim.y = 0.50f-0.30f*(zoom.y+1.0f)/2.0f; + pos.x -= dim.x; + pg->SetPos(pos); + pg->SetDim(dim); + } + } + + if ( m_phase == PHASE_NAME || + m_phase == PHASE_TRAINER || + m_phase == PHASE_MISSION || + m_phase == PHASE_FREE || + m_phase == PHASE_TEEN || + m_phase == PHASE_USER || + m_phase == PHASE_PROTO ) + { + pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTl); + if ( pg != 0 ) + { + zoom.x = sinf(m_glintTime*0.22f); + zoom.y = sinf(m_glintTime*0.37f); + pos.x = 0.10f; + pos.y = 0.90f; + dim.x = 0.60f+0.30f*zoom.x; + dim.y = 0.60f+0.30f*zoom.y; + pos.y -= dim.y; + pg->SetPos(pos); + pg->SetDim(dim); + } + + pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTr); + if ( pg != 0 ) + { + zoom.x = sinf(m_glintTime*0.19f); + zoom.y = sinf(m_glintTime*0.28f); + pos.x = 0.90f; + pos.y = 0.10f; + dim.x = 0.60f+0.30f*zoom.x; + dim.y = 0.60f+0.30f*zoom.y; + pos.x -= dim.x; + pg->SetPos(pos); + pg->SetDim(dim); + } + } + + if ( m_phase == PHASE_SETUPd || + m_phase == PHASE_SETUPg || + m_phase == PHASE_SETUPp || + m_phase == PHASE_SETUPc || + m_phase == PHASE_SETUPs || + m_phase == PHASE_SETUPds || + m_phase == PHASE_SETUPgs || + m_phase == PHASE_SETUPps || + m_phase == PHASE_SETUPcs || + m_phase == PHASE_SETUPss ) + { + pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTu); + if ( pg != 0 ) + { + zoom.y = sinf(m_glintTime*0.27f); + pos.x = 0.10f; + pos.y = 0.76f; + dim.x = 0.80f; + dim.y = 0.32f+0.20f*zoom.y; + pos.y -= dim.y; + pg->SetPos(pos); + pg->SetDim(dim); + } + + pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTr); + if ( pg != 0 ) + { + zoom.x = sinf(m_glintTime*0.29f); + zoom.y = sinf(m_glintTime*0.14f); + pos.x = 0.90f; + pos.y = 0.10f; + dim.x = 0.40f+0.20f*zoom.x; + dim.y = 0.40f+0.20f*zoom.y; + pos.x -= dim.x; + pg->SetPos(pos); + pg->SetDim(dim); + } + } + + if ( m_phase == PHASE_WRITE || + m_phase == PHASE_READ || + m_phase == PHASE_WRITEs || + m_phase == PHASE_READs ) + { + pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTl); + if ( pg != 0 ) + { + zoom.x = sinf(m_glintTime*0.22f); + zoom.y = sinf(m_glintTime*0.37f); + pos.x = 0.10f; + pos.y = 0.90f; + dim.x = 0.60f+0.30f*zoom.x; + dim.y = 0.60f+0.30f*zoom.y; + pos.y -= dim.y; + pg->SetPos(pos); + pg->SetDim(dim); + } + + pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTr); + if ( pg != 0 ) + { + zoom.x = sinf(m_glintTime*0.19f); + zoom.y = sinf(m_glintTime*0.28f); + pos.x = 0.90f; + pos.y = 0.10f; + dim.x = 0.60f+0.30f*zoom.x; + dim.y = 0.60f+0.30f*zoom.y; + pos.x -= dim.x; + pg->SetPos(pos); + pg->SetDim(dim); + } + } +} + + +// Returns the position for a sound. + +D3DVECTOR SoundPos(FPOINT pos) +{ + D3DVECTOR s; + + s.x = (pos.x-0.5f)*2.0f; + s.y = (pos.y-0.5f)*2.0f; + s.z = 0.0f; + + return s; +} + +// Returns a random position for a sound. + +D3DVECTOR SoundRand() +{ + D3DVECTOR s; + + s.x = (Rand()-0.5f)*2.0f; + s.y = (Rand()-0.5f)*2.0f; + s.z = 0.0f; + + return s; +} + +// Makes pretty qq particles evolve. + +void CMainDialog::FrameParticule(float rTime) +{ +#if _NEWLOOK +#else + D3DVECTOR pos, speed; + FPOINT dim; + float *pParti, *pGlint; + int nParti, nGlint; + int i, r, ii; + + static float partiPosInit[1+5*12] = + { // x x t2 t2 type + 12.0f, + 607.0f, 164.0f, 0.2f, 0.8f, 1.0f, // upper cable + 604.0f, 205.0f, 0.1f, 0.3f, 1.0f, // middle cable + 603.0f, 247.0f, 0.1f, 0.3f, 1.0f, // lower cable + 119.0f, 155.0f, 0.2f, 0.4f, 2.0f, // left pipe + 366.0f, 23.0f, 0.5f, 1.5f, 4.0f, // upper pipe + 560.0f, 414.0f, 0.1f, 0.1f, 1.0f, // button lower/right + 20.0f, 413.0f, 0.1f, 0.1f, 2.0f, // button lower/left + 39.0f, 78.0f, 0.1f, 0.2f, 1.0f, // left pot + 39.0f, 78.0f, 0.5f, 0.9f, 1.0f, // left pot + 170.0f, 229.0f, 0.5f, 0.5f, 3.0f, // left smoke + 170.0f, 229.0f, 0.5f, 0.5f, 3.0f, // left smoke + 474.0f, 229.0f, 0.5f, 0.5f, 3.0f, // right smoke + }; + + static float glintPosInit[1+2*14] = + { + 14.0f, + 15.0f, 407.0f, + 68.0f, 417.0f, + 548.0f, 36.0f, + 611.0f, 37.0f, + 611.0f, 100.0f, + 611.0f, 395.0f, + 36.0f, 35.0f, + 166.0f, 55.0f, + 166.0f, 94.0f, + 477.0f, 56.0f, + 31.0f, 190.0f, + 32.0f, 220.0f, + 65.0f, 221.0f, + 65.0f, 250.0f, + }; + + static float partiPosBig[1+5*12] = + { // x x t2 t2 type + 12.0f, + 607.0f, 164.0f, 0.2f, 0.8f, 1.0f, // upper cable + 604.0f, 205.0f, 0.1f, 0.3f, 1.0f, // middle cable + 603.0f, 247.0f, 0.1f, 0.3f, 1.0f, // lower cable + 64.0f, 444.0f, 0.2f, 0.8f, 1.0f, // down the left cable + 113.0f, 449.0f, 0.1f, 0.3f, 1.0f, // down the left cable + 340.0f, 463.0f, 0.2f, 0.8f, 1.0f, // down the middle cable + 36.0f, 155.0f, 0.2f, 0.4f, 2.0f, // left pipe + 366.0f, 23.0f, 0.5f, 1.5f, 4.0f, // upper pipe + 612.0f, 414.0f, 0.1f, 0.1f, 1.0f, // button lower/right + 20.0f, 413.0f, 0.1f, 0.1f, 2.0f, // button lower/left + 39.0f, 78.0f, 0.1f, 0.2f, 1.0f, // left pot + 39.0f, 78.0f, 0.5f, 0.9f, 1.0f, // left pot + }; + + static float glintPosBig[1+2*12] = + { + 12.0f, + 15.0f, 407.0f, + 48.0f, 399.0f, + 611.0f, 37.0f, + 611.0f, 100.0f, + 611.0f, 395.0f, + 36.0f, 35.0f, + 31.0f, 190.0f, + 32.0f, 220.0f, + 31.0f, 221.0f, + 31.0f, 189.0f, + 255.0f, 18.0f, + 279.0f, 18.0f, + }; + + if ( m_bDialog || !m_bRain ) return; + + if ( m_phase == PHASE_INIT ) + { + pParti = partiPosInit; + pGlint = glintPosInit; + } + else if ( m_phase == PHASE_NAME || + m_phase == PHASE_TRAINER || + m_phase == PHASE_DEFI || + m_phase == PHASE_MISSION || + m_phase == PHASE_FREE || + m_phase == PHASE_TEEN || + m_phase == PHASE_USER || + m_phase == PHASE_PROTO || + m_phase == PHASE_SETUPd || + m_phase == PHASE_SETUPg || + m_phase == PHASE_SETUPp || + m_phase == PHASE_SETUPc || + m_phase == PHASE_SETUPs || + m_phase == PHASE_WRITE || + m_phase == PHASE_READ ) + { + pParti = partiPosBig; + pGlint = glintPosBig; + } + else + { + return; + } + + nParti = (int)(*pParti++); + nGlint = (int)(*pGlint++); + + for ( i=0 ; i<10 ; i++ ) + { + if ( m_partiPhase[i] == 0 ) // waiting? + { + m_partiTime[i] -= rTime; + if ( m_partiTime[i] <= 0.0f ) + { + r = rand()%3; + + if ( r == 0 ) + { + ii = rand()%nParti; + m_partiPos[i].x = pParti[ii*5+0]/640.0f; + m_partiPos[i].y = (480.0f-pParti[ii*5+1])/480.0f; + m_partiTime[i] = pParti[ii*5+2]+Rand()*pParti[ii*5+3]; + m_partiPhase[i] = (int)pParti[ii*5+4]; + if ( m_partiPhase[i] == 3 ) + { + m_sound->Play(SOUND_PSHHH, SoundPos(m_partiPos[i]), 0.3f+Rand()*0.3f); + } + else + { + m_sound->Play(SOUND_GGG, SoundPos(m_partiPos[i]), 0.1f+Rand()*0.4f); + } + } + + if ( r == 1 ) + { + ii = rand()%nGlint; + pos.x = pGlint[ii*2+0]/640.0f; + pos.y = (480.0f-pGlint[ii*2+1])/480.0f; + pos.z = 0.0f; + speed.x = 0.0f; + speed.y = 0.0f; + speed.z = 0.0f; + dim.x = 0.04f+Rand()*0.04f; + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, + rand()%2?PARTIGLINT:PARTICONTROL, + Rand()*0.4f+0.4f, 0.0f, 0.0f, + SH_INTERFACE); + m_partiTime[i] = 0.5f+Rand()*0.5f; + } + + if ( r == 2 ) + { + ii = rand()%7; + if ( ii == 0 ) + { + m_sound->Play(SOUND_ENERGY, SoundRand(), 0.2f+Rand()*0.2f); + m_partiTime[i] = 1.0f+Rand()*1.0f; + } + if ( ii == 1 ) + { + m_sound->Play(SOUND_STATION, SoundRand(), 0.2f+Rand()*0.2f); + m_partiTime[i] = 1.0f+Rand()*2.0f; + } + if ( ii == 2 ) + { + m_sound->Play(SOUND_ALARM, SoundRand(), 0.1f+Rand()*0.1f); + m_partiTime[i] = 2.0f+Rand()*4.0f; + } + if ( ii == 3 ) + { + m_sound->Play(SOUND_INFO, SoundRand(), 0.1f+Rand()*0.1f); + m_partiTime[i] = 2.0f+Rand()*4.0f; + } + if ( ii == 4 ) + { + m_sound->Play(SOUND_RADAR, SoundRand(), 0.2f+Rand()*0.2f); + m_partiTime[i] = 0.5f+Rand()*1.0f; + } + if ( ii == 5 ) + { + m_sound->Play(SOUND_GFLAT, SoundRand(), 0.3f+Rand()*0.3f); + m_partiTime[i] = 2.0f+Rand()*4.0f; + } + if ( ii == 6 ) + { + m_sound->Play(SOUND_ALARMt, SoundRand(), 0.1f+Rand()*0.1f); + m_partiTime[i] = 2.0f+Rand()*4.0f; + } + } + } + } + + if ( m_partiPhase[i] != 0 ) // generates? + { + m_partiTime[i] -= rTime; + if ( m_partiTime[i] > 0.0f ) + { + if ( m_partiPhase[i] == 1 ) // sparks? + { + pos.x = m_partiPos[i].x; + pos.y = m_partiPos[i].y; + pos.z = 0.0f; + pos.x += (Rand()-0.5f)*0.01f; + pos.y += (Rand()-0.5f)*0.01f; + speed.x = (Rand()-0.5f)*0.2f; + speed.y = (Rand()-0.5f)*0.2f; + speed.z = 0.0f; + dim.x = 0.005f+Rand()*0.005f; + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, + Rand()*0.2f+0.2f, 0.0f, 0.0f, + SH_INTERFACE); + pos.x = m_partiPos[i].x; + pos.y = m_partiPos[i].y; + pos.z = 0.0f; + speed.x = (Rand()-0.5f)*0.5f; + speed.y = (0.3f+Rand()*0.3f); + speed.z = 0.0f; + dim.x = 0.01f+Rand()*0.01f; + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, + (ParticuleType)(PARTILENS1+rand()%3), + Rand()*0.5f+0.5f, 2.0f, 0.0f, + SH_INTERFACE); + } + if ( m_partiPhase[i] == 2 ) // sparks? + { + pos.x = m_partiPos[i].x; + pos.y = m_partiPos[i].y; + pos.z = 0.0f; + pos.x += (Rand()-0.5f)*0.01f; + pos.y += (Rand()-0.5f)*0.01f; + speed.x = (Rand()-0.5f)*0.2f; + speed.y = (Rand()-0.5f)*0.2f; + speed.z = 0.0f; + dim.x = 0.005f+Rand()*0.005f; + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, + Rand()*0.2f+0.2f, 0.0f, 0.0f, + SH_INTERFACE); + pos.x = m_partiPos[i].x; + pos.y = m_partiPos[i].y; + pos.z = 0.0f; + speed.x = (Rand()-0.5f)*0.5f; + speed.y = (0.3f+Rand()*0.3f); + speed.z = 0.0f; + dim.x = 0.005f+Rand()*0.005f; + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, PARTISCRAPS, + Rand()*0.5f+0.5f, 2.0f, 0.0f, + SH_INTERFACE); + } + if ( m_partiPhase[i] == 3 ) // smoke? + { + pos.x = m_partiPos[i].x; + pos.y = m_partiPos[i].y; + pos.z = 0.0f; + pos.x += (Rand()-0.5f)*0.03f; + pos.y += (Rand()-0.5f)*0.03f; + speed.x = (Rand()-0.5f)*0.2f; + speed.y = Rand()*0.5f; + speed.z = 0.0f; + dim.x = 0.03f+Rand()*0.07f; + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, + Rand()*0.4f+0.4f, 0.0f, 0.0f, + SH_INTERFACE); + } + } + else + { + m_partiPhase[i] = 0; + m_partiTime[i] = 2.0f+Rand()*4.0f; + } + } + } +#endif +} + +// Some nice particles following the mouse. + +void CMainDialog::NiceParticule(FPOINT mouse, BOOL bPress) +{ + D3DVECTOR pos, speed; + FPOINT dim; + + if ( !m_bRain ) return; + if ( (m_phase == PHASE_SIMUL || + m_phase == PHASE_WIN || + m_phase == PHASE_LOST || + m_phase == PHASE_MODEL ) && + !m_bDialog ) return; + + if ( bPress ) + { + pos.x = mouse.x; + pos.y = mouse.y; + pos.z = 0.0f; + speed.x = (Rand()-0.5f)*0.5f; + speed.y = (0.3f+Rand()*0.3f); + speed.z = 0.0f; + dim.x = 0.005f+Rand()*0.005f; + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, PARTISCRAPS, + Rand()*0.5f+0.5f, 2.0f, 0.0f, + SH_INTERFACE); + } + else + { + pos.x = mouse.x; + pos.y = mouse.y; + pos.z = 0.0f; + speed.x = (Rand()-0.5f)*0.5f; + speed.y = (0.3f+Rand()*0.3f); + speed.z = 0.0f; + dim.x = 0.01f+Rand()*0.01f; + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, + (ParticuleType)(PARTILENS1+rand()%3), + Rand()*0.5f+0.5f, 2.0f, 0.0f, + SH_INTERFACE); + } +} + + + +// Specifies the special user folder if needed. + +void CMainDialog::SetUserDir(char *base, int rank) +{ + char dir[100]; + + if ( strcmp(base, "user") == 0 && rank >= 100 ) + { + sprintf(dir, "%s\\%s", m_userDir, m_userList[rank/100-1]); + UserDir(TRUE, dir); + } + else + { + UserDir(FALSE, ""); + } +} + +// Builds the file name of a mission. + +void CMainDialog::BuildSceneName(char *filename, char *base, int rank) +{ + if ( strcmp(base, "user") == 0 ) + { + sprintf(filename, "%s\\%s\\scene%.2d.txt", m_userDir, m_userList[rank/100-1], rank%100); + } + else + { + sprintf(filename, "%s\\%s%.3d.txt", m_sceneDir, base, rank); + } +} + +// Built the default descriptive name of a mission. + +void CMainDialog::BuildResumeName(char *filename, char *base, int rank) +{ + sprintf(filename, "Scene %s %d", base, rank); +} + +// Returns the name of the file or save the files. + +char* CMainDialog::RetFilesDir() +{ + return m_filesDir; +} + + +// Updates the list of players after checking the files on disk. + +void CMainDialog::ReadNameList() +{ + CWindow* pw; + CList* pl; + long hFile; + struct _finddata_t fBuffer; + BOOL bDo; + char dir[_MAX_FNAME]; + char temp[_MAX_FNAME]; + char filenames[_MAX_FNAME][100]; + int nbFilenames, i; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); + if ( pl == 0 ) return; + pl->Flush(); + + nbFilenames = 0; + sprintf(dir, "%s\\*", m_savegameDir); + hFile = _findfirst(dir, &fBuffer); + if ( hFile != -1 ) + { + do + { + if ( (fBuffer.attrib & _A_SUBDIR) && fBuffer.name[0] != '.' ) + { + strcpy(filenames[nbFilenames++], fBuffer.name); + } + } + while ( _findnext(hFile, &fBuffer) == 0 && nbFilenames < 100 ); + } + do // sorts all names: + { + bDo = FALSE; + for ( i=0 ; i 0 ) + { + strcpy(temp, filenames[i]); + strcpy(filenames[i], filenames[i+1]); + strcpy(filenames[i+1], temp); + bDo = TRUE; + } + } + } + while ( bDo ); + + for ( i=0 ; iSetName(i, filenames[i]); + } +} + +// Updates the controls of the players. + +void CMainDialog::UpdateNameControl() +{ + CWindow* pw; + CList* pl; + CButton* pb; + CEdit* pe; + char name[100]; + char* gamer; + int total, sel; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); + if ( pl == 0 ) return; + pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_NEDIT); + if ( pe == 0 ) return; + + gamer = m_main->RetGamerName(); + total = pl->RetTotal(); + sel = pl->RetSelect(); + pe->GetText(name, 100); + + pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_NCANCEL); + if ( pb != 0 ) + { + pb->SetState(STATE_ENABLE, gamer[0]!=0); + } + + pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_NDELETE); + if ( pb != 0 ) + { + pb->SetState(STATE_ENABLE, total>0 && sel!=-1); + } + + pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_NOK); + if ( pb != 0 ) + { + pb->SetState(STATE_ENABLE, name[0]!=0 || sel!=-1); + } + + pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_PERSO); + if ( pb != 0 ) + { + pb->SetState(STATE_ENABLE, name[0]!=0 || sel!=-1); + } +} + +// Updates the list of players by name frape. + +void CMainDialog::UpdateNameList() +{ + CWindow* pw; + CList* pl; + CEdit* pe; + char name[100]; + int total, sel, i; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); + if ( pl == 0 ) return; + pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_NEDIT); + if ( pe == 0 ) return; + + pe->GetText(name, 100); + total = pl->RetTotal(); + sel = pl->RetSelect(); + + for ( i=0 ; iRetName(i)) == 0 ) + { + pl->SetSelect(i); + pl->ShowSelect(FALSE); + return; + } + } + + pl->SetSelect(-1); +} + +// Updates the player's name and function of the selected list. + +void CMainDialog::UpdateNameEdit() +{ + CWindow* pw; + CList* pl; + CEdit* pe; + char* name; + int sel; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); + if ( pl == 0 ) return; + pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_NEDIT); + if ( pe == 0 ) return; + + sel = pl->RetSelect(); + if ( sel == -1 ) + { + pe->SetText(""); + pe->SetCursor(0, 0); + } + else + { + name = pl->RetName(sel); + pe->SetText(name); + pe->SetCursor(strlen(name), 0); + } + + UpdateNameControl(); +} + +// Updates the representation of the player depending on the selected list. + +void CMainDialog::UpdateNameFace() +{ + CWindow* pw; + CList* pl; + char* name; + int sel; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); + if ( pl == 0 ) return; + + sel = pl->RetSelect(); + if ( sel == -1 ) return; + name = pl->RetName(sel); + + ReadGamerPerso(name); +} + +// Selects a player. + +void CMainDialog::NameSelect() +{ + CWindow* pw; + CList* pl; + CEdit* pe; + char name[100]; + int sel; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); + if ( pl == 0 ) return; + pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_NEDIT); + if ( pe == 0 ) return; + + pe->GetText(name, 100); + sel = pl->RetSelect(); + + if ( sel == -1 ) + { + NameCreate(); + } + else + { + m_main->SetGamerName(pl->RetName(sel)); + m_main->ChangePhase(PHASE_INIT); + } + + RetGamerFace(m_main->RetGamerName()); + + SetProfileString("Gamer", "LastName", m_main->RetGamerName()); +} + +// Creates a new player. + +void CMainDialog::NameCreate() +{ + CWindow* pw; + CEdit* pe; + char name[100]; + char dir[100]; + char c; + int len, i, j; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_NEDIT); + if ( pe == 0 ) return; + + pe->GetText(name, 100); + if ( name[0] == 0 ) + { + m_sound->Play(SOUND_TZOING); + return; + } + + len = strlen(name); + j = 0; + for ( i=0 ; i= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + c == ' ' || + c == '-' || + c == '_' || + c == '.' || + c == ',' || + c == '\'' ) + { + name[j++] = name[i]; + } + } + name[j] = 0; + if ( j == 0 ) + { + m_sound->Play(SOUND_TZOING); + return; + } + + _mkdir(m_savegameDir); // if does not exist yet! + + sprintf(dir, "%s\\%s", m_savegameDir, name); + if ( _mkdir(dir) != 0 ) + { + m_sound->Play(SOUND_TZOING); + pe->SetText(name); + pe->SetCursor(strlen(name), 0); + pe->SetFocus(TRUE); + return; + } + + SetGamerFace(name, 0); + + m_main->SetGamerName(name); + m_main->ChangePhase(PHASE_INIT); +} + +// Deletes a folder and all its offspring. + +BOOL RemoveDir(char *dirname) +{ + long hFile; + struct _finddata_t fBuffer; + char filename[100]; + + sprintf(filename, "%s\\*", dirname); + hFile = _findfirst(filename, &fBuffer); + if ( hFile != -1 ) + { + do + { + if ( fBuffer.name[0] != '.' ) + { + if ( fBuffer.attrib & _A_SUBDIR ) + { + sprintf(filename, "%s\\%s", dirname, fBuffer.name); + RemoveDir(filename); + } + else + { + sprintf(filename, "%s\\%s", dirname, fBuffer.name); + remove(filename); + } + } + } + while ( _findnext(hFile, &fBuffer) == 0 ); + } + + if ( _rmdir(dirname) != 0 ) + { + return FALSE; + } + return TRUE; +} + +// Removes a player. + +void CMainDialog::NameDelete() +{ + CWindow* pw; + CList* pl; + int sel; + char* gamer; + char dir[100]; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST); + if ( pl == 0 ) return; + + sel = pl->RetSelect(); + if ( sel == -1 ) + { + m_sound->Play(SOUND_TZOING); + return; + } + gamer = pl->RetName(sel); + + // Deletes all the contents of the file. + sprintf(dir, "%s\\%s", m_savegameDir, gamer); + if ( !RemoveDir(dir) ) + { + m_sound->Play(SOUND_TZOING); + return; + } + + m_main->SetGamerName(""); + pl->SetSelect(-1); + + ReadNameList(); + UpdateNameList(); + UpdateNameControl(); +} + + + +// ests whether two colors are equal or nearly are. + +BOOL EqColor(const D3DCOLORVALUE &c1, const D3DCOLORVALUE &c2) +{ + return (Abs(c1.r-c2.r) < 0.01f && + Abs(c1.g-c2.g) < 0.01f && + Abs(c1.b-c2.b) < 0.01f ); +} + +// Updates all the buttons for the character. + +void CMainDialog::UpdatePerso() +{ + CWindow* pw; + CLabel* pl; + CButton* pb; + CColor* pc; + CSlider* ps; + D3DCOLORVALUE color; + char name[100]; + int i; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + + pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_PHEAD); + if ( pb != 0 ) + { + pb->SetState(STATE_CHECK, m_persoTab==0); + } + pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_PBODY); + if ( pb != 0 ) + { + pb->SetState(STATE_CHECK, m_persoTab==1); + } + + pl = (CLabel*)pw->SearchControl(EVENT_LABEL11); + if ( pl != 0 ) + { + if ( m_persoTab == 0 ) + { + pl->SetState(STATE_VISIBLE); + GetResource(RES_TEXT, RT_PERSO_FACE, name); + pl->SetName(name); + } + else + { + pl->ClearState(STATE_VISIBLE); + } + } + + pl = (CLabel*)pw->SearchControl(EVENT_LABEL12); + if ( pl != 0 ) + { + if ( m_persoTab == 0 ) + { + pl->SetState(STATE_VISIBLE); + GetResource(RES_TEXT, RT_PERSO_GLASSES, name); + pl->SetName(name); + } + else + { + pl->ClearState(STATE_VISIBLE); + } + } + + pl = (CLabel*)pw->SearchControl(EVENT_LABEL13); + if ( pl != 0 ) + { + if ( m_persoTab == 0 ) GetResource(RES_TEXT, RT_PERSO_HAIR, name); + else GetResource(RES_TEXT, RT_PERSO_BAND, name); + pl->SetName(name); + } + + pl = (CLabel*)pw->SearchControl(EVENT_LABEL14); + if ( pl != 0 ) + { + if ( m_persoTab == 0 ) + { + pl->ClearState(STATE_VISIBLE); + } + else + { + pl->SetState(STATE_VISIBLE); + GetResource(RES_TEXT, RT_PERSO_COMBI, name); + pl->SetName(name); + } + } + + for ( i=0 ; i<4 ; i++ ) + { + pb = (CButton*)pw->SearchControl((EventMsg)(EVENT_INTERFACE_PFACE1+i)); + if ( pb == 0 ) break; + pb->SetState(STATE_VISIBLE, m_persoTab==0); + pb->SetState(STATE_CHECK, i==m_perso.face); + } + + for ( i=0 ; i<10 ; i++ ) + { + pb = (CButton*)pw->SearchControl((EventMsg)(EVENT_INTERFACE_PGLASS0+i)); + if ( pb == 0 ) break; + pb->SetState(STATE_VISIBLE, m_persoTab==0); + pb->SetState(STATE_CHECK, i==m_perso.glasses); + } + + for ( i=0 ; i<3*3 ; i++ ) + { + pc = (CColor*)pw->SearchControl((EventMsg)(EVENT_INTERFACE_PC0a+i)); + if ( pc == 0 ) break; + if ( m_persoTab == 0 ) + { + pc->ClearState(STATE_VISIBLE); + } + else + { + pc->SetState(STATE_VISIBLE); + color.r = perso_color[3*10*1+3*i+0]/255.0f; + color.g = perso_color[3*10*1+3*i+1]/255.0f; + color.b = perso_color[3*10*1+3*i+2]/255.0f; + color.a = 0.0f; + pc->SetColor(color); + pc->SetState(STATE_CHECK, EqColor(color, m_perso.colorCombi)); + } + + pc = (CColor*)pw->SearchControl((EventMsg)(EVENT_INTERFACE_PC0b+i)); + if ( pc == 0 ) break; + color.r = perso_color[3*10*2*m_persoTab+3*i+0]/255.0f; + color.g = perso_color[3*10*2*m_persoTab+3*i+1]/255.0f; + color.b = perso_color[3*10*2*m_persoTab+3*i+2]/255.0f; + color.a = 0.0f; + pc->SetColor(color); + pc->SetState(STATE_CHECK, EqColor(color, m_persoTab?m_perso.colorBand:m_perso.colorHair)); + } + + for ( i=0 ; i<3 ; i++ ) + { + ps = (CSlider*)pw->SearchControl((EventMsg)(EVENT_INTERFACE_PCRa+i)); + if ( ps == 0 ) break; + ps->SetState(STATE_VISIBLE, m_persoTab==1); + } + + if ( m_persoTab == 1 ) + { + color = m_perso.colorCombi; + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCRa); + if ( ps != 0 ) ps->SetVisibleValue(color.r*255.0f); + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCGa); + if ( ps != 0 ) ps->SetVisibleValue(color.g*255.0f); + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCBa); + if ( ps != 0 ) ps->SetVisibleValue(color.b*255.0f); + } + + if ( m_persoTab == 0 ) color = m_perso.colorHair; + else color = m_perso.colorBand; + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCRb); + if ( ps != 0 ) ps->SetVisibleValue(color.r*255.0f); + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCGb); + if ( ps != 0 ) ps->SetVisibleValue(color.g*255.0f); + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCBb); + if ( ps != 0 ) ps->SetVisibleValue(color.b*255.0f); +} + +// Updates the camera for the character. + +void CMainDialog::CameraPerso() +{ + if ( m_persoTab == 0 ) + { +//? m_camera->Init(D3DVECTOR(4.0f, 0.0f, 0.0f), +//? D3DVECTOR(0.0f, 0.0f, 1.0f), 0.0f); + m_camera->Init(D3DVECTOR(6.0f, 0.0f, 0.0f), + D3DVECTOR(0.0f, 0.2f, 1.5f), 0.0f); + } + else + { + m_camera->Init(D3DVECTOR(18.0f, 0.0f, 4.5f), + D3DVECTOR(0.0f, 1.6f, 4.5f), 0.0f); + } + + m_camera->SetType(CAMERA_SCRIPT); + m_camera->FixCamera(); +} + +// Sets a fixed color. + +void CMainDialog::FixPerso(int rank, int index) +{ + if ( m_persoTab == 0 ) + { + if ( index == 1 ) + { + m_perso.colorHair.r = perso_color[3*10*0+rank*3+0]/255.0f; + m_perso.colorHair.g = perso_color[3*10*0+rank*3+1]/255.0f; + m_perso.colorHair.b = perso_color[3*10*0+rank*3+2]/255.0f; + } + } + if ( m_persoTab == 1 ) + { + if ( index == 0 ) + { + m_perso.colorCombi.r = perso_color[3*10*1+rank*3+0]/255.0f; + m_perso.colorCombi.g = perso_color[3*10*1+rank*3+1]/255.0f; + m_perso.colorCombi.b = perso_color[3*10*1+rank*3+2]/255.0f; + } + if ( index == 1 ) + { + m_perso.colorBand.r = perso_color[3*10*2+rank*3+0]/255.0f; + m_perso.colorBand.g = perso_color[3*10*2+rank*3+1]/255.0f; + m_perso.colorBand.b = perso_color[3*10*2+rank*3+2]/255.0f; + } + } +} + +// Updates the color of the character. + +void CMainDialog::ColorPerso() +{ + CWindow* pw; + CSlider* ps; + D3DCOLORVALUE color; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + + color.a = 0.0f; + + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCRa); + if ( ps != 0 ) color.r = ps->RetVisibleValue()/255.0f; + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCGa); + if ( ps != 0 ) color.g = ps->RetVisibleValue()/255.0f; + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCBa); + if ( ps != 0 ) color.b = ps->RetVisibleValue()/255.0f; + if ( m_persoTab == 1 ) m_perso.colorCombi = color; + + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCRb); + if ( ps != 0 ) color.r = ps->RetVisibleValue()/255.0f; + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCGb); + if ( ps != 0 ) color.g = ps->RetVisibleValue()/255.0f; + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCBb); + if ( ps != 0 ) color.b = ps->RetVisibleValue()/255.0f; + if ( m_persoTab == 0 ) m_perso.colorHair = color; + else m_perso.colorBand = color; +} + +// Updates the default settings of the character. + +void CMainDialog::DefPerso() +{ + m_perso.colorCombi.r = 206.0f/256.0f; + m_perso.colorCombi.g = 206.0f/256.0f; + m_perso.colorCombi.b = 204.0f/256.0f; // ~white + m_perso.colorBand.r = 255.0f/256.0f; + m_perso.colorBand.g = 132.0f/256.0f; + m_perso.colorBand.b = 1.0f/256.0f; // orange + + if ( m_perso.face == 0 ) // normal ? + { + m_perso.glasses = 0; + m_perso.colorHair.r = 90.0f/256.0f; + m_perso.colorHair.g = 95.0f/256.0f; + m_perso.colorHair.b = 85.0f/256.0f; // black + } + if ( m_perso.face == 1 ) // bald ? + { + m_perso.glasses = 0; + m_perso.colorHair.r = 83.0f/256.0f; + m_perso.colorHair.g = 64.0f/256.0f; + m_perso.colorHair.b = 51.0f/256.0f; // brown + } + if ( m_perso.face == 2 ) // carlos ? + { + m_perso.glasses = 1; + m_perso.colorHair.r = 85.0f/256.0f; + m_perso.colorHair.g = 48.0f/256.0f; + m_perso.colorHair.b = 9.0f/256.0f; // brown + } + if ( m_perso.face == 3 ) // blond ? + { + m_perso.glasses = 4; + m_perso.colorHair.r = 255.0f/256.0f; + m_perso.colorHair.g = 255.0f/256.0f; + m_perso.colorHair.b = 181.0f/256.0f; // yellow + } + + m_perso.colorHair.a = 0.0f; + m_perso.colorCombi.a = 0.0f; + m_perso.colorBand.a = 0.0f; +} + + +// Indicates if there is at least one backup. + +BOOL CMainDialog::IsIOReadScene() +{ + FILE* file; + char filename[100]; + + sprintf(filename, "%s\\%s\\save%c%.3d\\data.sav", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], 0); + file = fopen(filename, "r"); + if ( file == NULL ) return FALSE; + fclose(file); + return TRUE; +} + +// Builds the file name by default. + +void CMainDialog::IOReadName() +{ + FILE* file; + CWindow* pw; + CEdit* pe; + char filename[_MAX_FNAME]; + char op[100]; + char line[500]; + char resume[100]; + char name[100]; + time_t now; + int i; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_IONAME); + if ( pe == 0 ) return; + + sprintf(resume, "%s %d", m_sceneName, m_chap[m_index]+1); + BuildSceneName(filename, m_sceneName, (m_chap[m_index]+1)*100); + file = fopen(filename, "r"); + if ( file != NULL ) + { + while ( fgets(line, 500, file) != NULL ) + { + for ( i=0 ; i<500 ; i++ ) + { + if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space + if ( line[i] == '/' && line[i+1] == '/' ) + { + line[i] = 0; + break; + } + } + + sprintf(op, "Title.%c", RetLanguageLetter()); + if ( Cmd(line, op) ) + { + OpString(line, "resume", resume); + break; + } + } + fclose(file); + } + + time(&now); + TimeToAscii(now, line); + sprintf(name, "%s %d - %s", resume, m_sel[m_index]+1, line); + pe->SetText(name); + pe->SetCursor(strlen(name), 0); + pe->SetFocus(TRUE); +} + +// Updates the list of games recorded on disk. + +void CMainDialog::IOReadList() +{ + FILE* file = NULL; + CWindow* pw; + CList* pl; + char filename[100]; + char line[500]; + char name[100]; + int i, j; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_IOLIST); + if ( pl == 0 ) return; + + pl->Flush(); + + for ( j=0 ; j<999 ; j++ ) + { + sprintf(filename, "%s\\%s\\save%c%.3d\\data.sav", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], j); + file = fopen(filename, "r"); + if ( file == NULL ) break; + + strcmp(name, filename); // default name + while ( fgets(line, 500, file) != NULL ) + { + for ( i=0 ; i<500 ; i++ ) + { + if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space + if ( line[i] == '/' && line[i+1] == '/' ) + { + line[i] = 0; + break; + } + } + + if ( Cmd(line, "Title") ) + { + OpString(line, "text", name); + break; + } + } + fclose(file); + + pl->SetName(j, name); + } + + if ( m_phase == PHASE_WRITE || + m_phase == PHASE_WRITEs ) + { + GetResource(RES_TEXT, RT_IO_NEW, name); + pl->SetName(j, name); + j ++; + } + + pl->SetSelect(j-1); + pl->ShowSelect(FALSE); // shows the selected columns +} + +// Updates the buttons according to the selected part in the list. + +void CMainDialog::IOUpdateList() +{ + FILE* file = NULL; + CWindow* pw; + CList* pl; + CButton* pb; + CImage* pi; + char filename[100]; + int sel, max; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_IOLIST); + if ( pl == 0 ) return; + pi = (CImage*)pw->SearchControl(EVENT_INTERFACE_IOIMAGE); + if ( pi == 0 ) return; + + sel = pl->RetSelect(); + max = pl->RetTotal(); + + sprintf(filename, "%s\\%s\\save%c%.3d\\screen.bmp", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); + + if ( m_phase == PHASE_WRITE || + m_phase == PHASE_WRITEs ) + { + if ( sel < max-1 ) + { + pi->SetFilenameImage(filename); + } + else + { + pi->SetFilenameImage(""); + } + + pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_IODELETE); + if ( pb != 0 ) + { + pb->SetState(STATE_ENABLE, sel < max-1); + } + } + else + { + pi->SetFilenameImage(filename); + } +} + +// Deletes the selected scene. + +void CMainDialog::IODeleteScene() +{ + CWindow* pw; + CList* pl; + char dir[100]; + char old[100]; + long hFile; + struct _finddata_t fBuffer; + int sel, max, i; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_IOLIST); + if ( pl == 0 ) return; + + sel = pl->RetSelect(); + if ( sel == -1 ) + { + m_sound->Play(SOUND_TZOING); + return; + } + + // Deletes all the contents of the file. + sprintf(dir, "%s\\%s\\save%c%.3d\\*", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); + hFile = _findfirst(dir, &fBuffer); + if ( hFile != -1 ) + { + do + { + if ( fBuffer.name[0] != '.' ) + { + sprintf(dir, "%s\\%s\\save%c%.3d\\%s", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel, fBuffer.name); + remove(dir); + } + } + while ( _findnext(hFile, &fBuffer) == 0 ); + } + + sprintf(dir, "%s\\%s\\save%c%.3d", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); + if ( _rmdir(dir) != 0 ) + { + m_sound->Play(SOUND_TZOING); + return; + } + + max = pl->RetTotal(); + for ( i=sel+1 ; iRetGamerName(), m_sceneName[0], i); + sprintf(dir, "%s\\%s\\save%c%.3d", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], i-1); + rename(old, dir); + } + IOReadList(); +} + +// Writes the scene. + +BOOL CMainDialog::IOWriteScene() +{ + CWindow* pw; + CList* pl; + CEdit* pe; + char filename[100]; + char filecbot[100]; + char info[100]; + int sel; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return FALSE; + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_IOLIST); + if ( pl == 0 ) return FALSE; + pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_IONAME); + if ( pe == 0 ) return FALSE; + + sel = pl->RetSelect(); + if ( sel == -1 ) return FALSE; + + _mkdir("Savegame"); // if doesn't exist yet! + sprintf(filename, "%s\\%s", m_savegameDir, m_main->RetGamerName()); + _mkdir(filename); + sprintf(filename, "%s\\%s\\save%c%.3d", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); + _mkdir(filename); + + sprintf(filename, "%s\\%s\\save%c%.3d\\data.sav", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); + sprintf(filecbot, "%s\\%s\\save%c%.3d\\cbot.run", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); + pe->GetText(info, 100); + m_main->IOWriteScene(filename, filecbot, info); + + m_shotDelay = 3; + sprintf(m_shotName, "%s\\%s\\save%c%.3d\\screen.bmp", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); + + return TRUE; +} + +// Reads the scene. + +BOOL CMainDialog::IOReadScene() +{ + FILE* file; + CWindow* pw; + CList* pl; + char filename[100]; + char filecbot[100]; + char line[500]; + char dir[100]; + int sel, i; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return FALSE; + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_IOLIST); + if ( pl == 0 ) return FALSE; + + sel = pl->RetSelect(); + if ( sel == -1 ) return FALSE; + + sprintf(filename, "%s\\%s\\save%c%.3d\\data.sav", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); + sprintf(filecbot, "%s\\%s\\save%c%.3d\\cbot.run", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel); + + file = fopen(filename, "r"); + if ( file == NULL ) return FALSE; + + while ( fgets(line, 500, file) != NULL ) + { + for ( i=0 ; i<500 ; i++ ) + { + if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space + if ( line[i] == '/' && line[i+1] == '/' ) + { + line[i] = 0; + break; + } + } + + if ( Cmd(line, "Mission") ) + { + OpString(line, "base", m_sceneName); + m_sceneRank = OpInt(line, "rank", 0); + + if ( strcmp(m_sceneName, "user") == 0 ) + { + m_sceneRank = m_sceneRank%100; + OpString(line, "dir", dir); + for ( i=0 ; iRetShowAll() ) return 9; + + for ( j=0 ; j<9 ; j++ ) + { + if ( !RetGamerInfoPassed((j+1)*100) ) + { + return j; + } + } + return 9; +} + +// Updates the lists according to the cheat code. + +void CMainDialog::AllMissionUpdate() +{ + if ( m_phase == PHASE_TRAINER || + m_phase == PHASE_DEFI || + m_phase == PHASE_MISSION || + m_phase == PHASE_FREE || + m_phase == PHASE_TEEN || + m_phase == PHASE_USER || + m_phase == PHASE_PROTO ) + { + UpdateSceneChap(m_chap[m_index]); + UpdateSceneList(m_chap[m_index], m_sel[m_index]); + } +} + +// Updates the chapters of exercises or missions. + +void CMainDialog::UpdateSceneChap(int &chap) +{ + FILE* file = NULL; + CWindow* pw; + CList* pl; + long hFile; + struct _finddata_t fileBuffer; + char filename[_MAX_FNAME]; + char op[100]; + char line[500]; + char name[100]; + int i, j; + BOOL bPassed, bDo; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_CHAP); + if ( pl == 0 ) return; + + pl->Flush(); + + if ( m_phase == PHASE_USER ) + { + j = 0; + hFile = _findfirst("user\\*", &fileBuffer); + if ( hFile != -1 ) + { + do + { + if ( (fileBuffer.attrib & _A_SUBDIR) != 0 && + fileBuffer.name[0] != '.' ) + { + strcpy(m_userList[j++], fileBuffer.name); + } + } + while ( _findnext(hFile, &fileBuffer) == 0 && j < 100 ); + } + m_userTotal = j; + + do // sorts all names: + { + bDo = FALSE; + for ( i=0 ; i 0 ) + { + strcpy(name, m_userList[i]); + strcpy(m_userList[i], m_userList[i+1]); + strcpy(m_userList[i+1], name); + bDo = TRUE; + } + } + } + while ( bDo ); + + for ( j=0 ; jSetName(j, name); + pl->SetEnable(j, TRUE); + } + } + else + { + for ( j=0 ; j<9 ; j++ ) + { +#if _SCHOOL + if ( m_phase == PHASE_MISSION ) break; + if ( m_phase == PHASE_FREE ) break; +#if _CEEBOTDEMO + if ( m_phase == PHASE_TRAINER && j >= 2 ) break; +#endif +#endif +#if _DEMO + if ( m_phase == PHASE_MISSION && j >= 4 ) break; + if ( m_phase == PHASE_TRAINER && j >= 1 ) break; +#endif + BuildSceneName(filename, m_sceneName, (j+1)*100); + file = fopen(filename, "r"); + if ( file == NULL ) break; + + BuildResumeName(name, m_sceneName, j+1); // default name + while ( fgets(line, 500, file) != NULL ) + { + for ( i=0 ; i<500 ; i++ ) + { + if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space + if ( line[i] == '/' && line[i+1] == '/' ) + { + line[i] = 0; + break; + } + } + + sprintf(op, "Title.%c", RetLanguageLetter()); + if ( Cmd(line, op) ) + { + OpString(line, "text", name); + break; + } + } + fclose(file); + + bPassed = RetGamerInfoPassed((j+1)*100); + sprintf(line, "%d: %s", j+1, name); + pl->SetName(j, line); + pl->SetCheck(j, bPassed); + pl->SetEnable(j, TRUE); + + if ( m_phase == PHASE_MISSION && !m_main->RetShowAll() && !bPassed ) + { + j ++; + break; + } + +#if _TEEN + if ( m_phase == PHASE_TRAINER && !m_main->RetShowAll() && !bPassed ) + { + j ++; + break; + } +#endif + + if ( m_phase == PHASE_FREE && j == m_accessChap ) + { + j ++; + break; + } + } + } + + if ( chap > j-1 ) chap = j-1; + + pl->SetSelect(chap); + pl->ShowSelect(FALSE); // shows the selected columns +} + +// Updates the list of exercises or missions. + +void CMainDialog::UpdateSceneList(int chap, int &sel) +{ + FILE* file = NULL; + CWindow* pw; + CList* pl; + char filename[_MAX_FNAME]; + char op[100]; + char line[500]; + char name[100]; + int i, j; + BOOL bPassed; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_INTERFACE_LIST); + if ( pl == 0 ) return; + + pl->Flush(); + + for ( j=0 ; j<99 ; j++ ) + { +#if _SCHOOL + if ( m_phase == PHASE_MISSION ) break; + if ( m_phase == PHASE_FREE ) break; +#if _CEEBOTDEMO +#if _TEEN + if ( m_phase == PHASE_TRAINER && j >= 5 ) break; +#else + if ( m_phase == PHASE_TRAINER && j >= 3 ) break; +#endif +#endif +#endif +#if _DEMO + if ( m_phase == PHASE_MISSION && j >= 3 ) break; + if ( m_phase == PHASE_TRAINER && j >= 5 ) break; +#endif + BuildSceneName(filename, m_sceneName, (chap+1)*100+(j+1)); + file = fopen(filename, "r"); + if ( file == NULL ) break; + + BuildResumeName(name, m_sceneName, j+1); // default name + while ( fgets(line, 500, file) != NULL ) + { + for ( i=0 ; i<500 ; i++ ) + { + if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space + if ( line[i] == '/' && line[i+1] == '/' ) + { + line[i] = 0; + break; + } + } + + sprintf(op, "Title.%c", RetLanguageLetter()); + if ( Cmd(line, op) ) + { + OpString(line, "text", name); + break; + } + } + fclose(file); + + bPassed = RetGamerInfoPassed((chap+1)*100+(j+1)); + sprintf(line, "%d: %s", j+1, name); + pl->SetName(j, line); + pl->SetCheck(j, bPassed); + pl->SetEnable(j, TRUE); + + if ( m_phase == PHASE_MISSION && !m_main->RetShowAll() && !bPassed ) + { + j ++; + break; + } + +#if _TEEN + if ( m_phase == PHASE_TRAINER && !m_main->RetShowAll() && !bPassed ) + { + j ++; + break; + } +#endif + } + + BuildSceneName(filename, m_sceneName, (chap+1)*100+(j+1)); + file = fopen(filename, "r"); + if ( file == NULL ) + { + m_maxList = j; + } + else + { + m_maxList = j+1; // this is not the last! + fclose(file); + } + + if ( sel > j-1 ) sel = j-1; + + pl->SetSelect(sel); + pl->ShowSelect(FALSE); // shows the selected columns +} + +// Updates the button "solution" according to cheat code. + +void CMainDialog::ShowSoluceUpdate() +{ + CWindow* pw; + CEdit* pe; + CCheck* pc; + + if ( m_phase == PHASE_TRAINER || + m_phase == PHASE_DEFI || + m_phase == PHASE_MISSION || + m_phase == PHASE_FREE || + m_phase == PHASE_TEEN || + m_phase == PHASE_USER || + m_phase == PHASE_PROTO ) + { + m_bSceneSoluce = FALSE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_RESUME); + if ( pe == 0 ) return; + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SOLUCE); + if ( pc == 0 ) return; + + if ( m_main->RetShowSoluce() ) + { + pc->SetState(STATE_VISIBLE); + pc->SetState(STATE_CHECK); + m_bSceneSoluce = TRUE; + } + else + { + pc->ClearState(STATE_VISIBLE); + pc->ClearState(STATE_CHECK); + m_bSceneSoluce = FALSE; + } + } +} + +// Updates a summary of exercise or mission. + +void CMainDialog::UpdateSceneResume(int rank) +{ + FILE* file = NULL; + CWindow* pw; + CEdit* pe; + CCheck* pc; + char filename[_MAX_FNAME]; + char op[100]; + char line[500]; + char name[500]; + int i, numTry; + BOOL bPassed, bVisible; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_RESUME); + if ( pe == 0 ) return; + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SOLUCE); + + if ( pc == 0 ) + { + m_bSceneSoluce = FALSE; + } + else + { + numTry = RetGamerInfoTry(rank); + bPassed = RetGamerInfoPassed(rank); + bVisible = ( numTry > 2 || bPassed || m_main->RetShowSoluce() ); + if ( !RetSoluce4() ) bVisible = FALSE; + pc->SetState(STATE_VISIBLE, bVisible); + if ( !bVisible ) + { + pc->ClearState(STATE_CHECK); + m_bSceneSoluce = FALSE; + } + } + + BuildSceneName(filename, m_sceneName, rank); + file = fopen(filename, "r"); + if ( file == NULL ) return; + + name[0] = 0; + while ( fgets(line, 500, file) != NULL ) + { + for ( i=0 ; i<500 ; i++ ) + { + if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space + if ( line[i] == '/' && line[i+1] == '/' ) + { + line[i] = 0; + break; + } + } + + sprintf(op, "Resume.%c", RetLanguageLetter()); + if ( Cmd(line, op) ) + { + OpString(line, "text", name); + break; + } + } + fclose(file); + + pe->SetText(name); +} + +// Updates the list of devices. + +void CMainDialog::UpdateDisplayDevice() +{ + CWindow* pw; + CList* pl; + char bufDevices[1000]; + char bufModes[5000]; + int i, j, totalDevices, selectDevices, totalModes, selectModes; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_LIST1); + if ( pl == 0 ) return; + pl->Flush(); + + m_engine->EnumDevices(bufDevices, 1000, + bufModes, 5000, + totalDevices, selectDevices, + totalModes, selectModes); + + i = 0; + j = 0; + while ( bufDevices[i] != 0 ) + { + pl->SetName(j++, bufDevices+i); + while ( bufDevices[i++] != 0 ); + } + + pl->SetSelect(selectDevices); + pl->ShowSelect(FALSE); + + m_setupSelDevice = selectDevices; +} + +// Updates the list of modes. + +void CMainDialog::UpdateDisplayMode() +{ + CWindow* pw; + CList* pl; + char bufDevices[1000]; + char bufModes[5000]; + int i, j, totalDevices, selectDevices, totalModes, selectModes; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_LIST2); + if ( pl == 0 ) return; + pl->Flush(); + + m_engine->EnumDevices(bufDevices, 1000, + bufModes, 5000, + totalDevices, selectDevices, + totalModes, selectModes); + + i = 0; + j = 0; + while ( bufModes[i] != 0 ) + { + pl->SetName(j++, bufModes+i); + while ( bufModes[i++] != 0 ); + } + + pl->SetSelect(selectModes); + pl->ShowSelect(FALSE); + + m_setupSelMode = selectModes; +} + +// Change the graphics mode. + +void CMainDialog::ChangeDisplay() +{ + CWindow* pw; + CList* pl; + CCheck* pc; + char* device; + char* mode; + BOOL bFull; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + + pl = (CList*)pw->SearchControl(EVENT_LIST1); + if ( pl == 0 ) return; + m_setupSelDevice = pl->RetSelect(); + device = pl->RetName(m_setupSelDevice); + + pl = (CList*)pw->SearchControl(EVENT_LIST2); + if ( pl == 0 ) return; + m_setupSelMode = pl->RetSelect(); + mode = pl->RetName(m_setupSelMode); + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_FULL); + if ( pc == 0 ) return; + bFull = pc->TestState(STATE_CHECK); + m_setupFull = bFull; + + m_engine->ChangeDevice(device, mode, bFull); + + if ( m_bSimulSetup ) + { + m_main->ChangeColor(); + m_main->UpdateMap(); + } +} + + + +// Updates the "apply" button. + +void CMainDialog::UpdateApply() +{ + CWindow* pw; + CButton* pb; + CList* pl; + CCheck* pc; + int sel1, sel2; + BOOL bFull; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + + pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_APPLY); + if ( pb == 0 ) return; + + pl = (CList*)pw->SearchControl(EVENT_LIST1); + if ( pl == 0 ) return; + sel1 = pl->RetSelect(); + + pl = (CList*)pw->SearchControl(EVENT_LIST2); + if ( pl == 0 ) return; + sel2 = pl->RetSelect(); + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_FULL); + bFull = pc->TestState(STATE_CHECK); + + if ( sel1 == m_setupSelDevice && + sel2 == m_setupSelMode && + bFull == m_setupFull ) + { + pb->ClearState(STATE_ENABLE); + } + else + { + pb->SetState(STATE_ENABLE); + } +} + +// Updates the buttons during the setup phase. + +void CMainDialog::UpdateSetupButtons() +{ + CWindow* pw; + CCheck* pc; + CEditValue* pv; + CSlider* ps; + float value; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_TOTO); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_engine->RetTotoMode()); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_TOOLTIP); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_bTooltip); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_GLINT); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_bGlint); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_RAIN); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_bRain); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_MOUSE); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_engine->RetNiceMouse()); + pc->SetState(STATE_ENABLE, m_engine->RetNiceMouseCap()); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_EDITMODE); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_engine->RetEditIndentMode()); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_EDITVALUE); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_engine->RetEditIndentValue()>2); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SOLUCE4); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_bSoluce4); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_MOVIES); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_bMovies); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_NICERST); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_bNiceReset); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_HIMSELF); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_bHimselfDamage); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SCROLL); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_bCameraScroll); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_INVERTX); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_bCameraInvertX); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_INVERTY); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_bCameraInvertY); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_EFFECT); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_bEffect); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SHADOW); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_engine->RetShadow()); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_GROUND); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_engine->RetGroundSpot()); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_DIRTY); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_engine->RetDirty()); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_FOG); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_engine->RetFog()); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_LENS); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_engine->RetLensMode()); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SKY); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_engine->RetSkyMode()); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_PLANET); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_engine->RetPlanetMode()); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_LIGHT); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_engine->RetLightMode()); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_JOYSTICK); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_engine->RetJoystick()); + } + + pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_PARTI); + if ( pv != 0 ) + { + value = m_engine->RetParticuleDensity(); + pv->SetValue(value); + } + + pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_CLIP); + if ( pv != 0 ) + { + value = m_engine->RetClippingDistance(); + pv->SetValue(value); + } + + pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_DETAIL); + if ( pv != 0 ) + { + value = m_engine->RetObjectDetail(); + pv->SetValue(value); + } + + pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_GADGET); + if ( pv != 0 ) + { + value = m_engine->RetGadgetQuantity(); + pv->SetValue(value); + } + + pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_TEXTURE); + if ( pv != 0 ) + { + value = (float)m_engine->RetTextureQuality(); + pv->SetValue(value); + } + + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_VOLSOUND); + if ( ps != 0 ) + { + value = (float)m_sound->RetAudioVolume(); + ps->SetVisibleValue(value); + } + + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_VOLMUSIC); + if ( ps != 0 ) + { + value = (float)m_sound->RetMidiVolume(); + ps->SetVisibleValue(value); + } + + pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SOUND3D); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_sound->RetSound3D()); + pc->SetState(STATE_ENABLE, m_sound->RetSound3DCap()); + } +} + +// Updates the engine function of the buttons after the setup phase. + +void CMainDialog::ChangeSetupButtons() +{ + CWindow* pw; + CEditValue* pv; + CSlider* ps; + float value; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + + pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_PARTI); + if ( pv != 0 ) + { + value = pv->RetValue(); + m_engine->SetParticuleDensity(value); + } + + pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_CLIP); + if ( pv != 0 ) + { + value = pv->RetValue(); + m_engine->SetClippingDistance(value); + } + + pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_DETAIL); + if ( pv != 0 ) + { + value = pv->RetValue(); + m_engine->SetObjectDetail(value); + } + + pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_GADGET); + if ( pv != 0 ) + { + value = pv->RetValue(); + m_engine->SetGadgetQuantity(value); + } + + pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_TEXTURE); + if ( pv != 0 ) + { + value = pv->RetValue(); + m_engine->SetTextureQuality((int)value); + } + + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_VOLSOUND); + if ( ps != 0 ) + { + value = ps->RetVisibleValue(); + m_sound->SetAudioVolume((int)value); + } + + ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_VOLMUSIC); + if ( ps != 0 ) + { + value = ps->RetVisibleValue(); + m_sound->SetMidiVolume((int)value); + } +} + + +// Memorizes all the settings. + +void CMainDialog::SetupMemorize() +{ + float fValue; + int iValue, i, j; + char key[500]; + char num[10]; + + SetProfileString("Directory", "scene", m_sceneDir); + SetProfileString("Directory", "savegame", m_savegameDir); + SetProfileString("Directory", "public", m_publicDir); + SetProfileString("Directory", "user", m_userDir); + SetProfileString("Directory", "files", m_filesDir); + + iValue = m_engine->RetTotoMode(); + SetProfileInt("Setup", "TotoMode", iValue); + + iValue = m_bTooltip; + SetProfileInt("Setup", "Tooltips", iValue); + + iValue = m_bGlint; + SetProfileInt("Setup", "InterfaceGlint", iValue); + + iValue = m_bRain; + SetProfileInt("Setup", "InterfaceGlint", iValue); + + iValue = m_engine->RetNiceMouse(); + SetProfileInt("Setup", "NiceMouse", iValue); + + iValue = m_bSoluce4; + SetProfileInt("Setup", "Soluce4", iValue); + + iValue = m_bMovies; + SetProfileInt("Setup", "Movies", iValue); + + iValue = m_bNiceReset; + SetProfileInt("Setup", "NiceReset", iValue); + + iValue = m_bHimselfDamage; + SetProfileInt("Setup", "HimselfDamage", iValue); + + iValue = m_bCameraScroll; + SetProfileInt("Setup", "CameraScroll", iValue); + + iValue = m_bCameraInvertX; + SetProfileInt("Setup", "CameraInvertX", iValue); + + iValue = m_bEffect; + SetProfileInt("Setup", "InterfaceEffect", iValue); + + iValue = m_engine->RetShadow(); + SetProfileInt("Setup", "GroundShadow", iValue); + + iValue = m_engine->RetGroundSpot(); + SetProfileInt("Setup", "GroundSpot", iValue); + + iValue = m_engine->RetDirty(); + SetProfileInt("Setup", "ObjectDirty", iValue); + + iValue = m_engine->RetFog(); + SetProfileInt("Setup", "FogMode", iValue); + + iValue = m_engine->RetLensMode(); + SetProfileInt("Setup", "LensMode", iValue); + + iValue = m_engine->RetSkyMode(); + SetProfileInt("Setup", "SkyMode", iValue); + + iValue = m_engine->RetPlanetMode(); + SetProfileInt("Setup", "PlanetMode", iValue); + + iValue = m_engine->RetLightMode(); + SetProfileInt("Setup", "LightMode", iValue); + + iValue = m_engine->RetJoystick(); + SetProfileInt("Setup", "UseJoystick", iValue); + + fValue = m_engine->RetParticuleDensity(); + SetProfileFloat("Setup", "ParticuleDensity", fValue); + + fValue = m_engine->RetClippingDistance(); + SetProfileFloat("Setup", "ClippingDistance", fValue); + + fValue = m_engine->RetObjectDetail(); + SetProfileFloat("Setup", "ObjectDetail", fValue); + + fValue = m_engine->RetGadgetQuantity(); + SetProfileFloat("Setup", "GadgetQuantity", fValue); + + iValue = m_engine->RetTextureQuality(); + SetProfileInt("Setup", "TextureQuality", iValue); + + iValue = m_sound->RetAudioVolume(); + SetProfileInt("Setup", "AudioVolume", iValue); + + iValue = m_sound->RetMidiVolume(); + SetProfileInt("Setup", "MidiVolume", iValue); + + iValue = m_sound->RetSound3D(); + SetProfileInt("Setup", "Sound3D", iValue); + + iValue = m_engine->RetEditIndentMode(); + SetProfileInt("Setup", "EditIndentMode", iValue); + + iValue = m_engine->RetEditIndentValue(); + SetProfileInt("Setup", "EditIndentValue", iValue); + + key[0] = 0; + for ( i=0 ; i<100 ; i++ ) + { + if ( m_engine->RetKey(i, 0) == 0 ) break; + + for ( j=0 ; j<2 ; j++ ) + { + iValue = m_engine->RetKey(i, j); + sprintf(num, "%d%c", iValue, j==0?'+':' '); + strcat(key, num); + } + } + SetProfileString("Setup", "KeyMap", key); + +#if _NET + if ( m_accessEnable ) + { + iValue = m_accessMission; + SetProfileInt("Setup", "AccessMission", iValue); + + iValue = m_accessUser; + SetProfileInt("Setup", "AccessUser", iValue); + } +#endif + + iValue = m_bDeleteGamer; + SetProfileInt("Setup", "DeleteGamer", iValue); + + m_engine->WriteProfile(); +} + +// Remember all the settings. + +void CMainDialog::SetupRecall() +{ + float fValue; + int iValue, i, j; + char key[500]; + char* p; + + if ( GetProfileString("Directory", "scene", key, _MAX_FNAME) ) + { + strcpy(m_sceneDir, key); + } + + if ( GetProfileString("Directory", "savegame", key, _MAX_FNAME) ) + { + strcpy(m_savegameDir, key); + } + + if ( GetProfileString("Directory", "public", key, _MAX_FNAME) ) + { + strcpy(m_publicDir, key); + } + + if ( GetProfileString("Directory", "user", key, _MAX_FNAME) ) + { + strcpy(m_userDir, key); + } + + if ( GetProfileString("Directory", "files", key, _MAX_FNAME) ) + { + strcpy(m_filesDir, key); + } + + + if ( GetProfileInt("Setup", "TotoMode", iValue) ) + { + m_engine->SetTotoMode(iValue); + } + + if ( GetProfileInt("Setup", "Tooltips", iValue) ) + { + m_bTooltip = iValue; + } + + if ( GetProfileInt("Setup", "InterfaceGlint", iValue) ) + { + m_bGlint = iValue; + } + + if ( GetProfileInt("Setup", "InterfaceGlint", iValue) ) + { + m_bRain = iValue; + } + + if ( GetProfileInt("Setup", "NiceMouse", iValue) ) + { + m_engine->SetNiceMouse(iValue); + } + + if ( GetProfileInt("Setup", "Soluce4", iValue) ) + { + m_bSoluce4 = iValue; + } + + if ( GetProfileInt("Setup", "Movies", iValue) ) + { + m_bMovies = iValue; + } + + if ( GetProfileInt("Setup", "NiceReset", iValue) ) + { + m_bNiceReset = iValue; + } + + if ( GetProfileInt("Setup", "HimselfDamage", iValue) ) + { + m_bHimselfDamage = iValue; + } + + if ( GetProfileInt("Setup", "CameraScroll", iValue) ) + { + m_bCameraScroll = iValue; + m_camera->SetCameraScroll(m_bCameraScroll); + } + + if ( GetProfileInt("Setup", "CameraInvertX", iValue) ) + { + m_bCameraInvertX = iValue; + m_camera->SetCameraInvertX(m_bCameraInvertX); + } + + if ( GetProfileInt("Setup", "CameraInvertY", iValue) ) + { + m_bCameraInvertY = iValue; + m_camera->SetCameraInvertY(m_bCameraInvertY); + } + + if ( GetProfileInt("Setup", "InterfaceEffect", iValue) ) + { + m_bEffect = iValue; + } + + if ( GetProfileInt("Setup", "GroundShadow", iValue) ) + { + m_engine->SetShadow(iValue); + } + + if ( GetProfileInt("Setup", "GroundSpot", iValue) ) + { + m_engine->SetGroundSpot(iValue); + } + + if ( GetProfileInt("Setup", "ObjectDirty", iValue) ) + { + m_engine->SetDirty(iValue); + } + + if ( GetProfileInt("Setup", "FogMode", iValue) ) + { + m_engine->SetFog(iValue); + m_camera->SetOverBaseColor(RetColor(RetColor(0.0f))); + } + + if ( GetProfileInt("Setup", "LensMode", iValue) ) + { + m_engine->SetLensMode(iValue); + } + + if ( GetProfileInt("Setup", "SkyMode", iValue) ) + { + m_engine->SetSkyMode(iValue); + } + + if ( GetProfileInt("Setup", "PlanetMode", iValue) ) + { + m_engine->SetPlanetMode(iValue); + } + + if ( GetProfileInt("Setup", "LightMode", iValue) ) + { + m_engine->SetLightMode(iValue); + } + + if ( GetProfileInt("Setup", "UseJoystick", iValue) ) + { + m_engine->SetJoystick(iValue); + } + + if ( GetProfileFloat("Setup", "ParticuleDensity", fValue) ) + { + m_engine->SetParticuleDensity(fValue); + } + + if ( GetProfileFloat("Setup", "ClippingDistance", fValue) ) + { + m_engine->SetClippingDistance(fValue); + } + + if ( GetProfileFloat("Setup", "ObjectDetail", fValue) ) + { + m_engine->SetObjectDetail(fValue); + } + + if ( GetProfileFloat("Setup", "GadgetQuantity", fValue) ) + { + m_engine->SetGadgetQuantity(fValue); + } + + if ( GetProfileInt("Setup", "TextureQuality", iValue) ) + { + m_engine->SetTextureQuality(iValue); + } + + if ( GetProfileInt("Setup", "AudioVolume", iValue) ) + { + m_sound->SetAudioVolume(iValue); + } + + if ( GetProfileInt("Setup", "MidiVolume", iValue) ) + { + m_sound->SetMidiVolume(iValue); + } + + if ( GetProfileInt("Setup", "EditIndentMode", iValue) ) + { + m_engine->SetEditIndentMode(iValue); + } + + if ( GetProfileInt("Setup", "EditIndentValue", iValue) ) + { + m_engine->SetEditIndentValue(iValue); + } + + if ( GetProfileString("Setup", "KeyMap", key, 500) ) + { + p = key; + for ( i=0 ; i<100 ; i++ ) + { + if ( p[0] == 0 ) break; + + for ( j=0 ; j<2 ; j++ ) + { + sscanf(p, "%d", &iValue); + m_engine->SetKey(i, j, iValue); + while ( *p >= '0' && *p <= '9' ) p++; + while ( *p == ' ' || *p == '+' ) p++; + } + } + } + +#if _NET + if ( m_accessEnable ) + { + if ( GetProfileInt("Setup", "AccessMission", iValue) ) + { + m_accessMission = iValue; + } + + if ( GetProfileInt("Setup", "AccessUser", iValue) ) + { + m_accessUser = iValue; + } + } +#endif + + if ( GetProfileInt("Setup", "DeleteGamer", iValue) ) + { + m_bDeleteGamer = iValue; + } +} + + +// Changes the general level of quality. + +void CMainDialog::ChangeSetupQuality(int quality) +{ + BOOL bEnable; + float value; + int iValue; + + bEnable = (quality >= 0); + m_engine->SetShadow(bEnable); + m_engine->SetGroundSpot(bEnable); + m_engine->SetDirty(bEnable); + m_engine->SetFog(bEnable); + m_engine->SetLensMode(bEnable); + m_engine->SetSkyMode(bEnable); + m_engine->SetPlanetMode(bEnable); + m_engine->SetLightMode(bEnable); + m_camera->SetOverBaseColor(RetColor(RetColor(0.0f))); + + if ( quality < 0 ) value = 0.0f; + if ( quality == 0 ) value = 1.0f; + if ( quality > 0 ) value = 2.0f; + m_engine->SetParticuleDensity(value); + + if ( quality < 0 ) value = 0.5f; + if ( quality == 0 ) value = 1.0f; + if ( quality > 0 ) value = 2.0f; + m_engine->SetClippingDistance(value); + + if ( quality < 0 ) value = 0.0f; + if ( quality == 0 ) value = 1.0f; + if ( quality > 0 ) value = 2.0f; + m_engine->SetObjectDetail(value); + + if ( quality < 0 ) value = 0.5f; + if ( quality == 0 ) value = 1.0f; + if ( quality > 0 ) value = 1.0f; + m_engine->SetGadgetQuantity(value); + + if ( quality < 0 ) iValue = 0; + if ( quality == 0 ) iValue = 1; + if ( quality > 0 ) iValue = 2; + m_engine->SetTextureQuality(iValue); + + m_engine->FirstExecuteAdapt(FALSE); +} + + +// Redefinable keys: + +static int key_table[KEY_TOTAL] = +{ +#if _SCHOOL & _TEEN + KEYRANK_LEFT, + KEYRANK_RIGHT, + KEYRANK_UP, + KEYRANK_DOWN, + KEYRANK_CAMERA, + KEYRANK_NEAR, + KEYRANK_AWAY, + KEYRANK_HELP, + KEYRANK_PROG, + KEYRANK_SPEED10, + KEYRANK_SPEED15, + KEYRANK_SPEED20, + KEYRANK_QUIT, +#else + KEYRANK_LEFT, + KEYRANK_RIGHT, + KEYRANK_UP, + KEYRANK_DOWN, + KEYRANK_GUP, + KEYRANK_GDOWN, + KEYRANK_ACTION, + KEYRANK_CAMERA, + KEYRANK_VISIT, + KEYRANK_NEXT, + KEYRANK_HUMAN, + KEYRANK_DESEL, + KEYRANK_NEAR, + KEYRANK_AWAY, + KEYRANK_HELP, + KEYRANK_PROG, + KEYRANK_CBOT, + KEYRANK_SPEED10, + KEYRANK_SPEED15, + KEYRANK_SPEED20, + KEYRANK_QUIT, +#endif +}; + +static EventMsg key_event[KEY_TOTAL] = +{ +#if _SCHOOL & _TEEN + EVENT_INTERFACE_KLEFT, + EVENT_INTERFACE_KRIGHT, + EVENT_INTERFACE_KUP, + EVENT_INTERFACE_KDOWN, + EVENT_INTERFACE_KCAMERA, + EVENT_INTERFACE_KNEAR, + EVENT_INTERFACE_KAWAY, + EVENT_INTERFACE_KHELP, + EVENT_INTERFACE_KPROG, + EVENT_INTERFACE_KSPEED10, + EVENT_INTERFACE_KSPEED15, + EVENT_INTERFACE_KSPEED20, + EVENT_INTERFACE_KQUIT, +#else + EVENT_INTERFACE_KLEFT, + EVENT_INTERFACE_KRIGHT, + EVENT_INTERFACE_KUP, + EVENT_INTERFACE_KDOWN, + EVENT_INTERFACE_KGUP, + EVENT_INTERFACE_KGDOWN, + EVENT_INTERFACE_KACTION, + EVENT_INTERFACE_KCAMERA, + EVENT_INTERFACE_KVISIT, + EVENT_INTERFACE_KNEXT, + EVENT_INTERFACE_KHUMAN, + EVENT_INTERFACE_KDESEL, + EVENT_INTERFACE_KNEAR, + EVENT_INTERFACE_KAWAY, + EVENT_INTERFACE_KHELP, + EVENT_INTERFACE_KPROG, + EVENT_INTERFACE_KCBOT, + EVENT_INTERFACE_KSPEED10, + EVENT_INTERFACE_KSPEED15, + EVENT_INTERFACE_KSPEED20, + EVENT_INTERFACE_KQUIT, +#endif +}; + +// Updates the list of keys. + +void CMainDialog::UpdateKey() +{ + CWindow* pw; + CScroll* ps; + CKey* pk; + FPOINT pos, dim; + int first, i; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + + ps = (CScroll*)pw->SearchControl(EVENT_INTERFACE_KSCROLL); + if ( ps == 0 ) return; + + first = (int)(ps->RetVisibleValue()*(KEY_TOTAL-KEY_VISIBLE)); + + for ( i=0 ; iDeleteControl(key_event[i]); + } + + dim.x = 400.0f/640.0f; + dim.y = 20.0f/480.0f; + pos.x = 110.0f/640.0f; + pos.y = 168.0f/480.0f + dim.y*(KEY_VISIBLE-1); + for ( i=0 ; iCreateKey(pos, dim, -1, key_event[first+i]); + pk = (CKey*)pw->SearchControl(key_event[first+i]); + if ( pk == 0 ) break; + pk->SetKey(0, m_engine->RetKey(key_table[first+i], 0)); + pk->SetKey(1, m_engine->RetKey(key_table[first+i], 1)); + pos.y -= dim.y; + } +} + +// Change a key. + +void CMainDialog::ChangeKey(EventMsg event) +{ + CWindow* pw; + CScroll* ps; + CKey* pk; + int i; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw == 0 ) return; + + ps = (CScroll*)pw->SearchControl(EVENT_INTERFACE_KSCROLL); + if ( ps == 0 ) return; + + for ( i=0 ; iSearchControl(key_event[i]); + if ( pk == 0 ) break; + m_engine->SetKey(key_table[i], 0, pk->RetKey(0)); + m_engine->SetKey(key_table[i], 1, pk->RetKey(1)); + } + } +} + + + +// Do you want to quit the current mission? + +void CMainDialog::StartAbort() +{ + CWindow* pw; + CButton* pb; + FPOINT pos, dim; + char name[100]; + + StartDialog(FPOINT(0.3f, 0.8f), TRUE, FALSE, FALSE); + m_bDialogDelete = FALSE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); + if ( pw == 0 ) return; + + pos.x = 0.35f; + pos.y = 0.60f; + dim.x = 0.30f; + dim.y = 0.30f; + pw->CreateGroup(pos, dim, 5, EVENT_INTERFACE_GLINTl); // orange corner + pos.x = 0.35f; + pos.y = 0.10f; + dim.x = 0.30f; + dim.y = 0.30f; + pw->CreateGroup(pos, dim, 4, EVENT_INTERFACE_GLINTr); // blue corner + + pos.x = 0.40f; + dim.x = 0.20f; +#if _POLISH + pos.x -= 7.0f/640.0f; + dim.x += 14.0f/640.0f; +#endif + dim.y = 32.0f/480.0f; + + pos.y = 0.74f; + pb = pw->CreateButton(pos, dim, -1, EVENT_DIALOG_CANCEL); + pb->SetState(STATE_SHADOW); + GetResource(RES_TEXT, RT_DIALOG_NO, name); + pb->SetName(name); + + if ( m_index == 2 || // missions ? + m_index == 3 || // free games? + m_index == 4 ) // user ? + { + pos.y = 0.62f; + pb = pw->CreateButton(pos, dim, -1, EVENT_INTERFACE_WRITE); + pb->SetState(STATE_SHADOW); + if ( m_main->IsBusy() ) // current task? + { + pb->ClearState(STATE_ENABLE); + } + + pos.y = 0.53f; + pb = pw->CreateButton(pos, dim, -1, EVENT_INTERFACE_READ); + pb->SetState(STATE_SHADOW); + if ( !IsIOReadScene() ) // no file to read? + { + pb->ClearState(STATE_ENABLE); + } + pb->SetState(STATE_WARNING); + } + + if ( m_engine->RetSetupMode() ) + { + pos.y = 0.39f; + pb = pw->CreateButton(pos, dim, -1, EVENT_INTERFACE_SETUP); + pb->SetState(STATE_SHADOW); + } + + pos.y = 0.25f; + pb = pw->CreateButton(pos, dim, -1, EVENT_INTERFACE_AGAIN); + pb->SetState(STATE_SHADOW); + pb->SetState(STATE_WARNING); + + pos.y = 0.16f; + pb = pw->CreateButton(pos, dim, -1, EVENT_DIALOG_OK); + pb->SetState(STATE_SHADOW); + pb->SetState(STATE_WARNING); + GetResource(RES_TEXT, RT_DIALOG_YES, name); + pb->SetName(name); +} + +// Do you want to destroy the building? + +void CMainDialog::StartDeleteObject() +{ + CWindow* pw; + CButton* pb; + FPOINT pos, dim; + char name[100]; + + StartDialog(FPOINT(0.7f, 0.3f), FALSE, TRUE, TRUE); + m_bDialogDelete = TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); + if ( pw == 0 ) return; + + pos.x = 0.00f; + pos.y = 0.50f; + dim.x = 1.00f; + dim.y = 0.05f; + GetResource(RES_TEXT, RT_DIALOG_DELOBJ, name); + pw->CreateLabel(pos, dim, -1, EVENT_DIALOG_LABEL, name); + + pb = (CButton*)pw->SearchControl(EVENT_DIALOG_OK); + if ( pb == 0 ) return; + GetResource(RES_TEXT, RT_DIALOG_YESDEL, name); + pb->SetName(name); + pb->SetState(STATE_WARNING); + + pb = (CButton*)pw->SearchControl(EVENT_DIALOG_CANCEL); + if ( pb == 0 ) return; + GetResource(RES_TEXT, RT_DIALOG_NODEL, name); + pb->SetName(name); +} + +// Do you want to delete the player? + +void CMainDialog::StartDeleteGame(char *gamer) +{ + CWindow* pw; + CButton* pb; + FPOINT pos, dim; + char name[100]; + char text[100]; + + StartDialog(FPOINT(0.7f, 0.3f), FALSE, TRUE, TRUE); + m_bDialogDelete = TRUE; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); + if ( pw == 0 ) return; + + pos.x = 0.00f; + pos.y = 0.50f; + dim.x = 1.00f; + dim.y = 0.05f; + GetResource(RES_TEXT, RT_DIALOG_DELGAME, name); + sprintf(text, name, gamer); + pw->CreateLabel(pos, dim, -1, EVENT_DIALOG_LABEL, text); + + pb = (CButton*)pw->SearchControl(EVENT_DIALOG_OK); + if ( pb == 0 ) return; + GetResource(RES_TEXT, RT_DIALOG_YESDEL, name); + pb->SetName(name); + pb->SetState(STATE_WARNING); + + pb = (CButton*)pw->SearchControl(EVENT_DIALOG_CANCEL); + if ( pb == 0 ) return; + GetResource(RES_TEXT, RT_DIALOG_NODEL, name); + pb->SetName(name); +} + +// Would you quit the game? + +void CMainDialog::StartQuit() +{ + CWindow* pw; + CButton* pb; + FPOINT pos, dim; + char name[100]; + + StartDialog(FPOINT(0.6f, 0.3f), FALSE, TRUE, TRUE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); + if ( pw == 0 ) return; + + pos.x = 0.00f; + pos.y = 0.50f; + dim.x = 1.00f; + dim.y = 0.05f; + GetResource(RES_TEXT, RT_DIALOG_QUIT, name); + pw->CreateLabel(pos, dim, -1, EVENT_DIALOG_LABEL, name); + + pb = (CButton*)pw->SearchControl(EVENT_DIALOG_OK); + if ( pb == 0 ) return; + GetResource(RES_TEXT, RT_DIALOG_YESQUIT, name); + pb->SetName(name); + pb->SetState(STATE_WARNING); + + pb = (CButton*)pw->SearchControl(EVENT_DIALOG_CANCEL); + if ( pb == 0 ) return; + GetResource(RES_TEXT, RT_DIALOG_NOQUIT, name); + pb->SetName(name); +} + +// Beginning of displaying a dialog. + +void CMainDialog::StartDialog(FPOINT dim, BOOL bFire, BOOL bOK, BOOL bCancel) +{ + CWindow* pw; + CButton* pb; + FPOINT pos, ddim; + char name[100]; + + StartSuspend(); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW6); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW7); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW8); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); + if ( pb != 0 ) + { + pb->ClearState(STATE_VISIBLE); + } + + m_bDialogFire = bFire; + + pos.x = (1.0f-dim.x)/2.0f; + pos.y = (1.0f-dim.y)/2.0f; + pw = m_interface->CreateWindows(pos, dim, bFire?12:8, EVENT_WINDOW9); + pw->SetState(STATE_SHADOW); + GetResource(RES_TEXT, RT_TITLE_BASE, name); + pw->SetName(name); + + m_dialogPos = pos; + m_dialogDim = dim; + m_dialogTime = 0.0f; + m_dialogParti = 999.0f; + + if ( bOK ) + { + pos.x = 0.50f-0.15f-0.02f; + pos.y = 0.50f-dim.y/2.0f+0.03f; + ddim.x = 0.15f; + ddim.y = 0.06f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_DIALOG_OK); + pb->SetState(STATE_SHADOW); + GetResource(RES_EVENT, EVENT_DIALOG_OK, name); + pb->SetName(name); + } + + if ( bCancel ) + { + pos.x = 0.50f+0.02f; + pos.y = 0.50f-dim.y/2.0f+0.03f; + ddim.x = 0.15f; + ddim.y = 0.06f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_DIALOG_CANCEL); + pb->SetState(STATE_SHADOW); + GetResource(RES_EVENT, EVENT_DIALOG_CANCEL, name); + pb->SetName(name); + } + + m_sound->Play(SOUND_TZOING); + m_bDialog = TRUE; +} + +// Animation of a dialog. + +void CMainDialog::FrameDialog(float rTime) +{ + CWindow* pw; + D3DVECTOR pos, speed; + FPOINT dim, dpos, ddim; + float zoom; + int i; + + dpos = m_dialogPos; + ddim = m_dialogDim; + + m_dialogTime += rTime; + if ( m_dialogTime < 1.0f ) + { + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); + if ( pw != 0 ) + { + if ( m_dialogTime < 0.50f ) + { + zoom = Bounce(m_dialogTime/0.50f); + } + else + { + zoom = 1.0f; + } + + dpos.x += ddim.x/2.0f; + dpos.y += ddim.y/2.0f; + + ddim.x *= zoom; +//? ddim.y *= zoom; + + dpos.x -= ddim.x/2.0f; + dpos.y -= ddim.y/2.0f; + + pw->SetPos(dpos); + pw->SetDim(ddim); + } + } + + if ( !m_bGlint ) return; + + m_dialogParti += rTime; + if ( m_dialogParti < m_engine->ParticuleAdapt(0.05f) ) return; + m_dialogParti = 0.0f; + + if ( !m_bDialogFire ) return; + + dpos = m_dialogPos; + ddim = m_dialogDim; + + pos.z = 0.0f; + speed = D3DVECTOR(0.0f, 0.0f, 0.0f); + + for ( i=0 ; i<2 ; i++ ) + { + // Bottom. + pos.x = dpos.x + ddim.x*Rand(); + pos.y = dpos.y; + pos.x += (Rand()-0.5f)*(6.0f/640.0f); + pos.y += Rand()*(16.0f/480.0f)-(10.0f/480.0f); + dim.x = 0.01f+Rand()*0.01f; + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, + (ParticuleType)(PARTILENS1+rand()%3), + 1.0f, 0.0f, 0.0f, SH_INTERFACE); + + // Top. + pos.x = dpos.x + ddim.x*Rand(); + pos.y = dpos.y + ddim.y; + pos.x += (Rand()-0.5f)*(6.0f/640.0f); + pos.y -= Rand()*(16.0f/480.0f)-(10.0f/480.0f); + dim.x = 0.01f+Rand()*0.01f; + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, + (ParticuleType)(PARTILENS1+rand()%3), + 1.0f, 0.0f, 0.0f, SH_INTERFACE); + + // Left. + pos.y = dpos.y + ddim.y*Rand(); + pos.x = dpos.x; + pos.x += Rand()*(16.0f/640.0f)-(10.0f/640.0f); + pos.y += (Rand()-0.5f)*(6.0f/480.0f); + dim.x = 0.01f+Rand()*0.01f; + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, + (ParticuleType)(PARTILENS1+rand()%3), + 1.0f, 0.0f, 0.0f, SH_INTERFACE); + + // Right. + pos.y = dpos.y + ddim.y*Rand(); + pos.x = dpos.x + ddim.x; + pos.x -= Rand()*(16.0f/640.0f)-(10.0f/640.0f); + pos.y += (Rand()-0.5f)*(6.0f/480.0f); + dim.x = 0.01f+Rand()*0.01f; + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, + (ParticuleType)(PARTILENS1+rand()%3), + 1.0f, 0.0f, 0.0f, SH_INTERFACE); + } +} + +// End of the display of a dialogue. + +void CMainDialog::StopDialog() +{ + CWindow* pw; + CButton* pb; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW6); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW7); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW8); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); + if ( pb != 0 ) + { + pb->SetState(STATE_VISIBLE); + } + + StopSuspend(); + m_interface->DeleteControl(EVENT_WINDOW9); + m_bDialog = FALSE; +} + +// Suspends the simulation for a dialog phase. + +void CMainDialog::StartSuspend() +{ + m_sound->MuteAll(TRUE); + m_main->ClearInterface(); + m_bInitPause = m_engine->RetPause(); + m_engine->SetPause(TRUE); + m_engine->SetOverFront(FALSE); // over flat behind + m_main->CreateShortcuts(); + m_main->StartSuspend(); + m_initCamera = m_camera->RetType(); + m_camera->SetType(CAMERA_DIALOG); +} + +// Resume the simulation after a period of dialog. + +void CMainDialog::StopSuspend() +{ + m_sound->MuteAll(FALSE); + m_main->ClearInterface(); + if ( !m_bInitPause ) m_engine->SetPause(FALSE); + m_engine->SetOverFront(TRUE); // over flat front + m_main->CreateShortcuts(); + m_main->StopSuspend(); + m_camera->SetType(m_initCamera); +} + + +// Whether to use tooltips. + +BOOL CMainDialog::RetTooltip() +{ + return m_bTooltip; +} + +// Specifies whether a dialog is displayed. + +BOOL CMainDialog::IsDialog() +{ + return m_bDialog; +} + + + + +// Specifies the name of the scene to read. + +void CMainDialog::SetSceneRead(char* name) +{ + strcpy(m_sceneRead, name); +} + +// Returns the name of the scene to read. + +char* CMainDialog::RetSceneRead() +{ + return m_sceneRead; +} + +// Specifies the name of the scene to read. + +void CMainDialog::SetStackRead(char* name) +{ + strcpy(m_stackRead, name); +} + +// Returns the name of the scene to read. + +char* CMainDialog::RetStackRead() +{ + return m_stackRead; +} + +// Specifies the name of the chosen to play scene. + +void CMainDialog::SetSceneName(char* name) +{ + strcpy(m_sceneName, name); +} + +// Returns the name of the chosen to play scene. + +char* CMainDialog::RetSceneName() +{ + return m_sceneName; +} + +// Specifies the rank of the chosen to play scene. + +void CMainDialog::SetSceneRank(int rank) +{ + m_sceneRank = rank; +} + +// Returns the rank of the chosen to play scene. + +int CMainDialog::RetSceneRank() +{ + return m_sceneRank; +} + +// Returns folder name of the scene that user selected to play. + +char* CMainDialog::RetSceneDir() +{ + int i; + + i = (m_sceneRank/100)-1; + + if ( i < 0 || i >= m_userTotal ) return 0; + return m_userList[i]; +} + +// Whether to show the solution. + +BOOL CMainDialog::RetSceneSoluce() +{ + return m_bSceneSoluce; +} + +// Returns the name of the folder to save. + +char* CMainDialog::RetSavegameDir() +{ + return m_savegameDir; +} + +// Returns the name of public folder. + +char* CMainDialog::RetPublicDir() +{ + return m_publicDir; +} + + +// Indicates if there are reflections on the buttons. + +BOOL CMainDialog::RetGlint() +{ + return m_bGlint; +} + +// Whether to show 4:solutions. + +BOOL CMainDialog::RetSoluce4() +{ + return m_bSoluce4; +} + +// Whether to show the cinematics. + +BOOL CMainDialog::RetMovies() +{ + return m_bMovies; +} + +// IWhether to make an animation in CTaskReset. + +BOOL CMainDialog::RetNiceReset() +{ + return m_bNiceReset; +} + +// Indicates whether the fire causes damage to its own units. + +BOOL CMainDialog::RetHimselfDamage() +{ + return m_bHimselfDamage; +} + + + +// Saves the personalized player. + +void CMainDialog::WriteGamerPerso(char *gamer) +{ + FILE* file; + char filename[100]; + char line[100]; + + sprintf(filename, "%s\\%s\\face.gam", m_savegameDir, gamer); + file = fopen(filename, "w"); + if ( file == NULL ) return; + + sprintf(line, "Head face=%d glasses=%d hair=%.2f;%.2f;%.2f;%.2f\n", + m_perso.face, m_perso.glasses, + m_perso.colorHair.r, m_perso.colorHair.g, m_perso.colorHair.b, m_perso.colorHair.a); + fputs(line, file); + + sprintf(line, "Body combi=%.2f;%.2f;%.2f;%.2f band=%.2f;%.2f;%.2f;%.2f\n", + m_perso.colorCombi.r, m_perso.colorCombi.g, m_perso.colorCombi.b, m_perso.colorCombi.a, + m_perso.colorBand.r, m_perso.colorBand.g, m_perso.colorBand.b, m_perso.colorBand.a); + fputs(line, file); + + fclose(file); +} + +// Reads the personalized player. + +void CMainDialog::ReadGamerPerso(char *gamer) +{ + FILE* file; + char filename[100]; + char line[100]; + D3DCOLORVALUE color; + + m_perso.face = 0; + DefPerso(); + + sprintf(filename, "%s\\%s\\face.gam", m_savegameDir, gamer); + file = fopen(filename, "r"); + if ( file == NULL ) return; + + while ( fgets(line, 100, file) != NULL ) + { + if ( Cmd(line, "Head") ) + { + m_perso.face = OpInt(line, "face", 0); + m_perso.glasses = OpInt(line, "glasses", 0); + + color.r = 0.0f; + color.g = 0.0f; + color.b = 0.0f; + color.a = 0.0f; + m_perso.colorHair = OpColorValue(line, "hair", color); + } + + if ( Cmd(line, "Body") ) + { + color.r = 0.0f; + color.g = 0.0f; + color.b = 0.0f; + color.a = 0.0f; + m_perso.colorCombi = OpColorValue(line, "combi", color); + + color.r = 0.0f; + color.g = 0.0f; + color.b = 0.0f; + color.a = 0.0f; + m_perso.colorBand = OpColorValue(line, "band", color); + } + } + + fclose(file); +} + +// Specifies the face of the player. + +void CMainDialog::SetGamerFace(char *gamer, int face) +{ + m_perso.face = face; + WriteGamerPerso(gamer); +} + +// Gives the face of the player. + +int CMainDialog::RetGamerFace(char *gamer) +{ + ReadGamerPerso(gamer); + return m_perso.face; +} + +// Gives the face of the player. + +int CMainDialog::RetGamerFace() +{ + return m_perso.face; +} + +int CMainDialog::RetGamerGlasses() +{ + return m_perso.glasses; +} + +BOOL CMainDialog::RetGamerOnlyHead() +{ + return (m_phase == PHASE_PERSO && m_persoTab == 0); +} + +float CMainDialog::RetPersoAngle() +{ + return m_persoAngle; +} + +D3DCOLORVALUE CMainDialog::RetGamerColorHair() +{ + return m_perso.colorHair; +} + +D3DCOLORVALUE CMainDialog::RetGamerColorCombi() +{ + return m_perso.colorCombi; +} + +D3DCOLORVALUE CMainDialog::RetGamerColorBand() +{ + return m_perso.colorBand; +} + + +// Reads the file of the player. + +BOOL CMainDialog::ReadGamerInfo() +{ + FILE* file; + char line[100]; + int chap, i, numTry, passed; + + for ( i=0 ; iRetGamerName(), m_sceneName); + file = fopen(line, "r"); + if ( file == NULL ) return FALSE; + + if ( fgets(line, 100, file) != NULL ) + { + sscanf(line, "CurrentChapter=%d CurrentSel=%d\n", &chap, &i); + m_chap[m_index] = chap-1; + m_sel[m_index] = i-1; + } + + while ( fgets(line, 100, file) != NULL ) + { + sscanf(line, "Chapter %d: Scene %d: numTry=%d passed=%d\n", + &chap, &i, &numTry, &passed); + + i += chap*100; + if ( i >= 0 && i < MAXSCENE ) + { + m_sceneInfo[i].numTry = numTry; + m_sceneInfo[i].bPassed = passed; + } + } + + fclose(file); + return TRUE; +} + +// Writes the file of the player. + +BOOL CMainDialog::WriteGamerInfo() +{ + FILE* file; + char line[100]; + int i; + + sprintf(line, "%s\\%s\\%s.gam", m_savegameDir, m_main->RetGamerName(), m_sceneName); + file = fopen(line, "w"); + if ( file == NULL ) return FALSE; + + sprintf(line, "CurrentChapter=%d CurrentSel=%d\n", + m_chap[m_index]+1, m_sel[m_index]+1); + fputs(line, file); + + for ( i=0 ; i= MAXSCENE ) return; + if ( numTry > 100 ) numTry = 100; + m_sceneInfo[rank].numTry = numTry; +} + +int CMainDialog::RetGamerInfoTry(int rank) +{ + if ( rank < 0 || rank >= MAXSCENE ) return 0; + return m_sceneInfo[rank].numTry; +} + +void CMainDialog::SetGamerInfoPassed(int rank, BOOL bPassed) +{ + int chap, i; + BOOL bAll; + + if ( rank < 0 || rank >= MAXSCENE ) return; + m_sceneInfo[rank].bPassed = bPassed; + + if ( bPassed ) + { + bAll = TRUE; + chap = rank/100; + for ( i=0 ; i= MAXSCENE ) return FALSE; + return m_sceneInfo[rank].bPassed; +} + + +// Passes to the next mission, and possibly in the next chapter. + +BOOL CMainDialog::NextMission() +{ + m_sel[m_index] ++; // next mission + + if ( m_sel[m_index] >= m_maxList ) // last mission of the chapter? + { + m_chap[m_index] ++; // next chapter + m_sel[m_index] = 0; // first mission + } + + return TRUE; +} + + diff --git a/src/ui/maindialog.h b/src/ui/maindialog.h new file mode 100644 index 0000000..21dca18 --- /dev/null +++ b/src/ui/maindialog.h @@ -0,0 +1,256 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// maindialog.h + +#ifndef _MAINDIALOG_H_ +#define _MAINDIALOG_H_ + +#include "struct.h" +#include "camera.h" +#include "robotmain.h" + + +class CInstanceManager; +class CEvent; +class CD3DEngine; +class CInterface; +class CWindow; +class CControl; +class CParticule; +class CSound; + + +#define USERLISTMAX 100 +#define MAXSCENE 1000 + +typedef struct +{ + char numTry; + char bPassed; +} +SceneInfo; + +typedef struct +{ + int face; // face + int glasses; // glasses + D3DCOLORVALUE colorHair; // hair color + D3DCOLORVALUE colorCombi; // spacesuit volor + D3DCOLORVALUE colorBand; // strips color +} +GamerPerso; + + + +class CMainDialog +{ +public: + CMainDialog(CInstanceManager* iMan); + ~CMainDialog(); + + BOOL EventProcess(const Event &event); + void ChangePhase(Phase phase); + + void SetSceneRead(char* name); + void SetStackRead(char* name); + void SetSceneName(char* name); + void SetSceneRank(int rank); + char* RetSceneRead(); + char* RetStackRead(); + char* RetSceneName(); + int RetSceneRank(); + char* RetSceneDir(); + BOOL RetSceneSoluce(); + char* RetSavegameDir(); + char* RetPublicDir(); + + BOOL RetTooltip(); + BOOL RetGlint(); + BOOL RetSoluce4(); + BOOL RetMovies(); + BOOL RetNiceReset(); + BOOL RetHimselfDamage(); + + void SetUserDir(char *base, int rank); + void BuildSceneName(char *filename, char *base, int rank); + void BuildResumeName(char *filename, char *base, int rank); + char* RetFilesDir(); + + void StartAbort(); + void StartDeleteObject(); + void StartDeleteGame(char *gamer); + void StartQuit(); + void StartDialog(FPOINT dim, BOOL bFire, BOOL bOK, BOOL bCancel); + void FrameDialog(float rTime); + void StopDialog(); + BOOL IsDialog(); + + void StartSuspend(); + void StopSuspend(); + + void SetupMemorize(); + void SetupRecall(); + + BOOL ReadGamerInfo(); + BOOL WriteGamerInfo(); + void SetGamerInfoTry(int rank, int numTry); + int RetGamerInfoTry(int rank); + void SetGamerInfoPassed(int rank, BOOL bPassed); + BOOL RetGamerInfoPassed(int rank); + BOOL NextMission(); + + void WriteGamerPerso(char *gamer); + void ReadGamerPerso(char *gamer); + void SetGamerFace(char *gamer, int face); + int RetGamerFace(char *gamer); + int RetGamerFace(); + int RetGamerGlasses(); + BOOL RetGamerOnlyHead(); + float RetPersoAngle(); + D3DCOLORVALUE RetGamerColorHair(); + D3DCOLORVALUE RetGamerColorCombi(); + D3DCOLORVALUE RetGamerColorBand(); + + void AllMissionUpdate(); + void ShowSoluceUpdate(); + +protected: + void GlintMove(); + void FrameParticule(float rTime); + void NiceParticule(FPOINT mouse, BOOL bPress); + void ReadNameList(); + void UpdateNameList(); + void UpdateNameEdit(); + void UpdateNameControl(); + void UpdateNameFace(); + void NameSelect(); + void NameCreate(); + void NameDelete(); + void UpdatePerso(); + void CameraPerso(); + void FixPerso(int rank, int index); + void ColorPerso(); + void DefPerso(); + BOOL IsIOReadScene(); + void IOReadName(); + void IOReadList(); + void IOUpdateList(); + void IODeleteScene(); + BOOL IOWriteScene(); + BOOL IOReadScene(); + int RetChapPassed(); + void UpdateSceneChap(int &chap); + void UpdateSceneList(int chap, int &sel); + void UpdateSceneResume(int rank); + void UpdateDisplayDevice(); + void UpdateDisplayMode(); + void ChangeDisplay(); + void UpdateApply(); + void UpdateSetupButtons(); + void ChangeSetupButtons(); + void ChangeSetupQuality(int quality); + void UpdateKey(); + void ChangeKey(EventMsg event); + +protected: + CInstanceManager* m_iMan; + CRobotMain* m_main; + CEvent* m_event; + CD3DEngine* m_engine; + CInterface* m_interface; + CParticule* m_particule; + CCamera* m_camera; + CSound* m_sound; + + Phase m_phase; // copy of CRobotMain + Phase m_phaseSetup; // tab selected + Phase m_phaseTerm; // phase trainer/scene/proto + float m_phaseTime; + + GamerPerso m_perso; // perso: description + GamerPerso m_persoCopy; // perso: copy for cancellation + int m_persoTab; // perso: tab selected + float m_persoAngle; // perso: angle of presentation + + char m_sceneDir[_MAX_FNAME]; // scene folder + char m_savegameDir[_MAX_FNAME]; // savegame folder + char m_publicDir[_MAX_FNAME]; // program folder + char m_userDir[_MAX_FNAME]; // user folder + char m_filesDir[_MAX_FNAME]; // case files + + int m_index; // 0..4 + int m_chap[10]; // selected chapter (0..8) + int m_sel[10]; // chosen mission (0..98) + int m_maxList; + int m_accessChap; + char m_sceneRead[100]; // name of the scene to read + char m_stackRead[100]; // name of the scene to read + char m_sceneName[20]; // name of the scene to play + int m_sceneRank; // rank of the scene to play + BOOL m_bSceneSoluce; // shows the solution + BOOL m_bSimulSetup; // adjustment during the game + BOOL m_accessEnable; + BOOL m_accessMission; + BOOL m_accessUser; + BOOL m_bDeleteGamer; + + int m_userTotal; + char m_userList[USERLISTMAX][100]; + + int m_shotDelay; // number of frames before copy + char m_shotName[100]; // generate a file name + + int m_setupSelDevice; + int m_setupSelMode; + BOOL m_setupFull; + + BOOL m_bTooltip; // tooltips to be displayed? + BOOL m_bGlint; // reflections on buttons? + BOOL m_bRain; // rain in the interface? + BOOL m_bSoluce4; // solutions in program 4? + BOOL m_bMovies; // cinematics? + BOOL m_bNiceReset; // for CTaskReset + BOOL m_bHimselfDamage; // for shots + BOOL m_bCameraScroll; // for CCamera + BOOL m_bCameraInvertX; // for CCamera + BOOL m_bCameraInvertY; // for CCamera + BOOL m_bEffect; // for CCamera + + FPOINT m_glintMouse; + float m_glintTime; + + int m_loadingCounter; + + BOOL m_bDialog; // this dialogue? + BOOL m_bDialogFire; // setting on fire? + BOOL m_bDialogDelete; + FPOINT m_dialogPos; + FPOINT m_dialogDim; + float m_dialogParti; + float m_dialogTime; + BOOL m_bInitPause; + CameraType m_initCamera; + + int m_partiPhase[10]; + float m_partiTime[10]; + FPOINT m_partiPos[10]; + + SceneInfo m_sceneInfo[MAXSCENE]; +}; + + +#endif //_MAINDIALOG_H_ diff --git a/src/ui/mainmap.cpp b/src/ui/mainmap.cpp new file mode 100644 index 0000000..c66edf2 --- /dev/null +++ b/src/ui/mainmap.cpp @@ -0,0 +1,404 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// mainmap.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "global.h" +#include "event.h" +#include "iman.h" +#include "interface.h" +#include "map.h" +#include "image.h" +#include "group.h" +#include "slider.h" +#include "scroll.h" +#include "window.h" +#include "mainmap.h" + + + +#define ZOOM_MIN 1.0f +#define ZOOM_MAX 16.0f + + + +// Constructor of the application card. + +CMainMap::CMainMap(CInstanceManager* iMan) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_MAP, this); + + m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); + m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + + m_mapMode = 1; + m_bFixImage = FALSE; +} + +// Destructor of the application card. + +CMainMap::~CMainMap() +{ +} + + +// Created the mini-map and the corresponding buttons. + +void CMainMap::CreateMap() +{ + CWindow* pw; + FPOINT pos, dim; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw == 0 ) + { + pos.x = 0.0f; + pos.y = 0.0f; + dim.x = 0.0f; + dim.y = 0.0f; + pw = m_interface->CreateWindows(pos, dim, 10, EVENT_WINDOW1); + } + + dim.x = 10.0f/640.0f; + dim.y = 10.0f/480.0f; + pos.x = 10.0f/640.0f; + pos.y = 10.0f/480.0f; + pw->CreateMap (pos, dim, 2, EVENT_OBJECT_MAP); + pw->CreateSlider(pos, dim, 0, EVENT_OBJECT_MAPZOOM); + + DimMap(); +} + +// Indicates whether the mini-map should display a still image. + +void CMainMap::SetFixImage(char *filename) +{ + CWindow* pw; + CMap* pm; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw == 0 ) return; + + pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); + if ( pm == 0 ) return; + + pw->DeleteControl(EVENT_OBJECT_MAPZOOM); + m_bFixImage = TRUE; + + pm->SetFixImage(filename); +} + +// Choosing colors of soil and water for the mini-map. + +void CMainMap::FloorColorMap(D3DCOLORVALUE floor, D3DCOLORVALUE water) +{ + CWindow* pw; + CMap* pm; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw == 0 ) return; + + pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); + if ( pm != 0 ) + { + pm->SetFloorColor(floor); + pm->SetWaterColor(water); + } +} + +// Shows or hides the minimap. + +void CMainMap::ShowMap(BOOL bShow) +{ + CWindow* pw; + CMap* pm; + CSlider* ps; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw == 0 ) return; + + if ( bShow ) + { + DimMap(); + } + else + { + pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); + if ( pm != 0 ) + { + pm->ClearState(STATE_VISIBLE); + } + + ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM); + if ( ps != 0 ) + { + ps->ClearState(STATE_VISIBLE); + } + } +} + +// Dimensions of the mini-map. + +void CMainMap::DimMap() +{ + CWindow* pw; + CMap* pm; + CSlider* ps; + FPOINT pos, dim; + float value; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw == 0 ) return; + pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); + if ( pm == 0 ) return; + + pm->SetState(STATE_VISIBLE, (m_mapMode != 0)); + + dim.x = 100.0f/640.0f; + dim.y = 100.0f/480.0f; + pos.x = 540.0f/640.0f; + pos.y = 0.0f/480.0f; + pm->SetPos(pos); + pm->SetDim(dim); + + ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM); + if ( ps != 0 ) + { + ps->SetState(STATE_VISIBLE, (m_mapMode != 0)); + + dim.x = SCROLL_WIDTH; + dim.y = 66.0f/480.0f; + pos.x = 523.0f/640.0f; + pos.y = 3.0f/480.0f; + ps->SetPos(pos); + ps->SetDim(dim); + + value = pm->RetZoom(); + value = (value-ZOOM_MIN)/(ZOOM_MAX-ZOOM_MIN); + value = powf(value, 0.5f); + ps->SetVisibleValue(value); + ps->SetArrowStep(0.2f); + } +} + +// Returns the current zoom of the minimap. + +float CMainMap::RetZoomMap() +{ + CWindow* pw; + CMap* pm; + CSlider* ps; + + pw = (CWindow*)pw->SearchControl(EVENT_WINDOW1); + if ( pw == 0 ) return ZOOM_MIN; + + pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); + if ( pm == 0 ) return ZOOM_MIN; + + ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM); + if ( ps == 0 ) return ZOOM_MIN; + + return pm->RetZoom(); +} + +// Zoom the mini-map of any factor. + +void CMainMap::ZoomMap(float zoom) +{ + CWindow* pw; + CMap* pm; + CSlider* ps; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw == 0 ) return; + pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); + if ( pm == 0 ) return; + + ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM); + if ( ps == 0 ) return; + + if ( zoom < ZOOM_MIN ) zoom = ZOOM_MIN; + if ( zoom > ZOOM_MAX ) zoom = ZOOM_MAX; + pm->SetZoom(zoom); + + DimMap(); +} + +// The mini-map zoom depending on the slider. + +void CMainMap::ZoomMap() +{ + CWindow* pw; + CMap* pm; + CSlider* ps; + float zoom; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw == 0 ) return; + pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); + if ( pm == 0 ) return; + + ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM); + if ( ps == 0 ) return; + + zoom = ps->RetVisibleValue(); + zoom = powf(zoom, 2.0f); + zoom = ZOOM_MIN+zoom*(ZOOM_MAX-ZOOM_MIN); + pm->SetZoom(zoom); + + DimMap(); +} + +// Enables or disables the card. + +void CMainMap::MapEnable(BOOL bEnable) +{ + CWindow* pw; + CMap* pm; + CSlider* ps; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw == 0 ) return; + + pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); + if ( pm != 0 ) + { + pm->SetEnable(bEnable); + } + + ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM); + if ( ps != 0 ) + { + ps->SetState(STATE_ENABLE, bEnable); + } +} + +// Specifies the type of icon for the selected object. + +void CMainMap::SetToy(BOOL bToy) +{ + CWindow* pw; + CMap* pm; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw == 0 ) return; + + pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); + if ( pm == 0 ) return; + + pm->SetToy(bToy); +} + +// Specifies the parameters when using a still image. + +void CMainMap::SetFixParam(float zoom, float ox, float oy, float angle, + int mode, BOOL bDebug) +{ + CWindow* pw; + CMap* pm; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw == 0 ) return; + + pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); + if ( pm == 0 ) return; + + pm->SetZoom(zoom); + pm->SetOffset(ox, oy); + pm->SetAngle(angle); + pm->SetMode(mode); + pm->SetDebug(bDebug); +} + +// Updates the mini-map following to a change of terrain. + +void CMainMap::UpdateMap() +{ + CWindow* pw; + CMap* pm; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw == 0 ) return; + + pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); + if ( pm != 0 ) + { + pm->UpdateTerrain(); + } +} + +// Indicates if the mini-map is visible. + +BOOL CMainMap::RetShowMap() +{ + return ( m_mapMode != 0 ); +} + +// Indicates whether the mini-map displays a still image. + +BOOL CMainMap::RetFixImage() +{ + return m_bFixImage; +} + + +// The object is detected in the mini-map. + +CObject* CMainMap::DetectMap(FPOINT pos, BOOL &bInMap) +{ + CWindow* pw; + CMap* pm; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw == 0 ) return 0; + + bInMap = FALSE; + pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); + if ( pm == 0 ) return 0; + return pm->DetectObject(pos, bInMap); +} + + +// Indicates the object with the mouse hovers over. + +void CMainMap::SetHilite(CObject* pObj) +{ + CWindow* pw; + CMap* pm; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw == 0 ) return; + + pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); + if ( pm != 0 ) + { + pm->SetHilite(pObj); + } +} + + diff --git a/src/ui/mainmap.h b/src/ui/mainmap.h new file mode 100644 index 0000000..f9fe0be --- /dev/null +++ b/src/ui/mainmap.h @@ -0,0 +1,68 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// mainmap.h + +#ifndef _MAINMAP_H_ +#define _MAINMAP_H_ + + +class CInstanceManager; +class CEvent; +class CD3DEngine; +class CInterface; +class CObject; + + + +class CMainMap +{ +public: + CMainMap(CInstanceManager* iMan); + ~CMainMap(); + + void UpdateMap(); + void CreateMap(); + void SetFixImage(char *filename); + void FloorColorMap(D3DCOLORVALUE floor, D3DCOLORVALUE water); + void ShowMap(BOOL bShow); + void DimMap(); + float RetZoomMap(); + void ZoomMap(float zoom); + void ZoomMap(); + void MapEnable(BOOL bEnable); + BOOL RetShowMap(); + BOOL RetFixImage(); + CObject* DetectMap(FPOINT pos, BOOL &bInMap); + void SetHilite(CObject* pObj); + void SetToy(BOOL bToy); + void SetFixParam(float zoom, float ox, float oy, float angle, int mode, BOOL bDebug); + +protected: + void CenterMap(); + +protected: + CInstanceManager* m_iMan; + CEvent* m_event; + CD3DEngine* m_engine; + CInterface* m_interface; + + int m_mapMode; + BOOL m_bFixImage; +}; + + +#endif //_MAINMAP_H_ diff --git a/src/ui/mainshort.cpp b/src/ui/mainshort.cpp new file mode 100644 index 0000000..4e934e5 --- /dev/null +++ b/src/ui/mainshort.cpp @@ -0,0 +1,376 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// mainshort.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "global.h" +#include "event.h" +#include "iman.h" +#include "object.h" +#include "interface.h" +#include "map.h" +#include "button.h" +#include "robotmain.h" +#include "mainshort.h" + + + + +// Constructor of the application card. + +CMainShort::CMainShort(CInstanceManager* iMan) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_SHORT, this); + + m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); + m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + + FlushShortcuts(); +} + +// Destructor of the application card. + +CMainShort::~CMainShort() +{ +} + + + +void CMainShort::SetMode(BOOL bBuilding) +{ + m_bBuilding = bBuilding; +} + + + +// Reset all shortcuts. + +void CMainShort::FlushShortcuts() +{ + int i; + + for ( i=0 ; i<20 ; i++ ) + { + m_shortcuts[i] = 0; + } +} + +static EventMsg table_sc_em[20] = +{ + EVENT_OBJECT_SHORTCUT00, + EVENT_OBJECT_SHORTCUT01, + EVENT_OBJECT_SHORTCUT02, + EVENT_OBJECT_SHORTCUT03, + EVENT_OBJECT_SHORTCUT04, + EVENT_OBJECT_SHORTCUT05, + EVENT_OBJECT_SHORTCUT06, + EVENT_OBJECT_SHORTCUT07, + EVENT_OBJECT_SHORTCUT08, + EVENT_OBJECT_SHORTCUT09, + EVENT_OBJECT_SHORTCUT10, + EVENT_OBJECT_SHORTCUT11, + EVENT_OBJECT_SHORTCUT12, + EVENT_OBJECT_SHORTCUT13, + EVENT_OBJECT_SHORTCUT14, + EVENT_OBJECT_SHORTCUT15, + EVENT_OBJECT_SHORTCUT16, + EVENT_OBJECT_SHORTCUT17, + EVENT_OBJECT_SHORTCUT18, + EVENT_OBJECT_SHORTCUT19, +}; + +// Interface creates shortcuts to the units. + +BOOL CMainShort::CreateShortcuts() +{ + CObject* pObj; + CControl* pc; + ObjectType type; + FPOINT pos, dim; + int i, rank, icon; + char name[100]; + + if ( m_main->RetFixScene() ) return FALSE; + + m_interface->DeleteControl(EVENT_OBJECT_MOVIELOCK); + m_interface->DeleteControl(EVENT_OBJECT_EDITLOCK); + for ( i=0 ; i<20 ; i++ ) + { + if ( i != 0 && m_shortcuts[i] == 0 ) continue; + + m_interface->DeleteControl(table_sc_em[i]); + m_shortcuts[i] = 0; + } + + dim.x = 28.0f/640.0f; + dim.y = 28.0f/480.0f; + pos.x = 4.0f/640.0f; + pos.y = (480.0f-32.0f)/480.0f; + + if ( m_main->RetMovieLock() && + !m_main->RetEditLock() ) // hangs during film? + { + m_interface->CreateShortcut(pos, dim, 7, EVENT_OBJECT_MOVIELOCK); + return TRUE; + } + if ( !m_main->RetFreePhoto() && + (m_main->RetEditLock() || + m_engine->RetPause()) ) // hangs during edition? + { + m_interface->CreateShortcut(pos, dim, 6, EVENT_OBJECT_EDITLOCK); + return TRUE; + } + + rank = 0; + + m_interface->CreateShortcut(pos, dim, 2, table_sc_em[rank]); + pos.x += dim.x*1.2f; + m_shortcuts[rank] = 0; + rank ++; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetActif() ) continue; + if ( !pObj->RetSelectable() ) continue; + if ( pObj->RetProxyActivate() ) continue; + + type = pObj->RetType(); + icon = -1; + if ( m_bBuilding ) + { + if ( type == OBJECT_FACTORY ) icon = 32; + if ( type == OBJECT_DERRICK ) icon = 33; + if ( type == OBJECT_CONVERT ) icon = 34; + if ( type == OBJECT_RESEARCH ) icon = 35; + if ( type == OBJECT_STATION ) icon = 36; + if ( type == OBJECT_TOWER ) icon = 37; + if ( type == OBJECT_LABO ) icon = 38; + if ( type == OBJECT_ENERGY ) icon = 39; + if ( type == OBJECT_RADAR ) icon = 40; + if ( type == OBJECT_INFO ) icon = 44; + if ( type == OBJECT_REPAIR ) icon = 41; + if ( type == OBJECT_DESTROYER) icon = 41; + if ( type == OBJECT_NUCLEAR ) icon = 42; + if ( type == OBJECT_PARA ) icon = 46; + if ( type == OBJECT_SAFE ) icon = 47; + if ( type == OBJECT_HUSTON ) icon = 48; + if ( type == OBJECT_BASE ) icon = 43; + } + else + { + if ( type == OBJECT_HUMAN ) icon = 8; + if ( type == OBJECT_MOBILEfa ) icon = 11; + if ( type == OBJECT_MOBILEta ) icon = 10; + if ( type == OBJECT_MOBILEwa ) icon = 9; + if ( type == OBJECT_MOBILEia ) icon = 22; + if ( type == OBJECT_MOBILEfc ) icon = 17; + if ( type == OBJECT_MOBILEtc ) icon = 16; + if ( type == OBJECT_MOBILEwc ) icon = 15; + if ( type == OBJECT_MOBILEic ) icon = 23; + if ( type == OBJECT_MOBILEfi ) icon = 27; + if ( type == OBJECT_MOBILEti ) icon = 26; + if ( type == OBJECT_MOBILEwi ) icon = 25; + if ( type == OBJECT_MOBILEii ) icon = 28; + if ( type == OBJECT_MOBILEfs ) icon = 14; + if ( type == OBJECT_MOBILEts ) icon = 13; + if ( type == OBJECT_MOBILEws ) icon = 12; + if ( type == OBJECT_MOBILEis ) icon = 24; + if ( type == OBJECT_MOBILErt ) icon = 18; + if ( type == OBJECT_MOBILErc ) icon = 19; + if ( type == OBJECT_MOBILErr ) icon = 20; + if ( type == OBJECT_MOBILErs ) icon = 29; + if ( type == OBJECT_MOBILEsa ) icon = 21; + if ( type == OBJECT_MOBILEft ) icon = 30; + if ( type == OBJECT_MOBILEtt ) icon = 30; + if ( type == OBJECT_MOBILEwt ) icon = 30; + if ( type == OBJECT_MOBILEit ) icon = 30; + if ( type == OBJECT_MOBILEdr ) icon = 48; + if ( type == OBJECT_APOLLO2 ) icon = 49; + } + if ( icon == -1 ) continue; + + m_interface->CreateShortcut(pos, dim, icon, table_sc_em[rank]); + pos.x += dim.x; + m_shortcuts[rank] = pObj; + + pc = m_interface->SearchControl(table_sc_em[rank]); + if ( pc != 0 ) + { + pObj->GetTooltipName(name); + pc->SetTooltip(name); + } + rank ++; + + if ( rank >= 20 ) break; + } + + UpdateShortcuts(); + return TRUE; +} + +// Updates the interface shortcuts to the units. + +BOOL CMainShort::UpdateShortcuts() +{ + CControl* pc; + int i; + + for ( i=0 ; i<20 ; i++ ) + { + if ( m_shortcuts[i] == 0 ) continue; + + pc = m_interface->SearchControl(table_sc_em[i]); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_shortcuts[i]->RetSelect()); + pc->SetState(STATE_RUN, m_shortcuts[i]->IsProgram()); + } + } + return TRUE; +} + +// Selects an object through a shortcut. + +void CMainShort::SelectShortcut(EventMsg event) +{ + int i; + + for ( i=0 ; i<20 ; i++ ) + { + if ( event == table_sc_em[i] ) + { + if ( i != 0 && m_shortcuts[i] == 0 ) continue; + + if ( i == 0 ) // buildings <-> vehicles? + { + m_bBuilding = !m_bBuilding; + CreateShortcuts(); + } + else + { + m_main->SelectObject(m_shortcuts[i]); + } + return; + } + } +} + + +// Selects the next object. + +void CMainShort::SelectNext() +{ + CObject* pPrev; + int i; + + if ( m_main->RetMovieLock() || + m_main->RetEditLock() || + m_engine->RetPause() ) return; + + pPrev = m_main->DeselectAll(); + + for ( i=1 ; i<20 ; i++ ) + { + if ( m_shortcuts[i] == pPrev ) + { + if ( m_shortcuts[++i] == 0 ) i = 1; + break; + } + } + + if ( i == 20 || m_shortcuts[i] == 0 ) + { + m_main->SelectHuman(); + } + else + { + m_main->SelectObject(m_shortcuts[i]); + } +} + + +// The object detected by the mouse hovers over. + +CObject* CMainShort::DetectShort(FPOINT pos) +{ + CControl* pc; + FPOINT cpos, cdim; + int i; + + for ( i=0 ; i<20 ; i++ ) + { + if ( m_shortcuts[i] == 0 ) continue; + + pc = m_interface->SearchControl(table_sc_em[i]); + if ( pc != 0 ) + { + cpos = pc->RetPos(); + cdim = pc->RetDim(); + + if ( pos.x >= cpos.x && + pos.x <= cpos.x+cdim.x && + pos.y >= cpos.y && + pos.y <= cpos.y+cdim.y ) + { + return m_shortcuts[i]; + } + } + } + return 0; +} + +// Reports the object with the mouse hovers over. + +void CMainShort::SetHilite(CObject* pObj) +{ + CControl* pc; + int i; + + for ( i=0 ; i<20 ; i++ ) + { + if ( m_shortcuts[i] == 0 ) continue; + + pc = m_interface->SearchControl(table_sc_em[i]); + if ( pc == 0 ) continue; + + if ( m_shortcuts[i] == pObj ) + { + pc->SetState(STATE_HILIGHT); + pc->SetState(STATE_FRAME); + } + else + { + pc->ClearState(STATE_HILIGHT); + pc->ClearState(STATE_FRAME); + } + } +} + diff --git a/src/ui/mainshort.h b/src/ui/mainshort.h new file mode 100644 index 0000000..648dbbc --- /dev/null +++ b/src/ui/mainshort.h @@ -0,0 +1,61 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// mainshort.h + +#ifndef _MAINSHORT_H_ +#define _MAINSHORT_H_ + + +class CInstanceManager; +class CEvent; +class CD3DEngine; +class CInterface; +class CRobotMain; +class CObject; + + + +class CMainShort +{ +public: + CMainShort(CInstanceManager* iMan); + ~CMainShort(); + + void SetMode(BOOL bBuilding); + void FlushShortcuts(); + BOOL CreateShortcuts(); + BOOL UpdateShortcuts(); + void SelectShortcut(EventMsg event); + void SelectNext(); + CObject* DetectShort(FPOINT pos); + void SetHilite(CObject* pObj); + +protected: + +protected: + CInstanceManager* m_iMan; + CEvent* m_event; + CD3DEngine* m_engine; + CInterface* m_interface; + CRobotMain* m_main; + + CObject* m_shortcuts[20]; + BOOL m_bBuilding; +}; + + +#endif //_MAINSHORT_H_ diff --git a/src/ui/map.cpp b/src/ui/map.cpp new file mode 100644 index 0000000..c44a218 --- /dev/null +++ b/src/ui/map.cpp @@ -0,0 +1,1342 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// map.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "event.h" +#include "math3d.h" +#include "terrain.h" +#include "water.h" +#include "object.h" +#include "event.h" +#include "misc.h" +#include "robotmain.h" +#include "iman.h" +#include "map.h" + + + + +// Object's constructor. + +CMap::CMap(CInstanceManager* iMan) : CControl(iMan) +{ + CControl::CControl(iMan); + + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); + + m_bEnable = TRUE; + m_time = 0.0f; + m_zoom = 2.0f; + m_offset.x = 0.0f; + m_offset.y = 0.0f; + m_angle = 0.0f; + + m_floorColor.r = 1.00f; + m_floorColor.g = 0.50f; + m_floorColor.b = 0.00f; // orange + + m_waterColor.r = 0.00f; + m_waterColor.g = 0.80f; + m_waterColor.b = 1.00f; // blue + + m_half = m_terrain->RetMosaic()*m_terrain->RetBrick()*m_terrain->RetSize()/2.0f; + + m_hiliteRank = -1; + FlushObject(); + + m_fixImage[0] = 0; + m_mode = 0; + m_bToy = FALSE; + m_bDebug = FALSE; +} + +// Object's destructor. + +CMap::~CMap() +{ +} + + +// Creates a new button. + +BOOL CMap::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + CControl::Create(pos, dim, icon, eventMsg); + return TRUE; +} + + +// Choice of the offset, when image is displayed. + +void CMap::SetOffset(float ox, float oy) +{ + m_offset.x = ox; + m_offset.y = oy; + m_half = m_terrain->RetMosaic()*m_terrain->RetBrick()*m_terrain->RetSize()/2.0f; +} + +// Choice of the global angle of rotation. + +void CMap::SetAngle(float angle) +{ + m_angle = angle; +} + +// Specifies the alternate mode. + +void CMap::SetMode(int mode) +{ + m_mode = mode; +} + +// Specifies the type of icon for the selected object. + +void CMap::SetToy(BOOL bToy) +{ + m_bToy = bToy; +} + +void CMap::SetDebug(BOOL bDebug) +{ + m_bDebug = bDebug; +} + + +//Choice of magnification of the map. + +void CMap::SetZoom(float value) +{ + m_zoom = value; + m_half = m_terrain->RetMosaic()*m_terrain->RetBrick()*m_terrain->RetSize()/2.0f; +} + +float CMap::RetZoom() +{ + return m_zoom; +} + +// Choosing a fixed offset. + +// Enables or disables the card. + +void CMap::SetEnable(BOOL bEnable) +{ + m_bEnable = bEnable; + SetState(STATE_DEAD, !bEnable); +} + +BOOL CMap::RetEnable() +{ + return m_bEnable; +} + + +// Choosing the color of the soil. + +void CMap::SetFloorColor(D3DCOLORVALUE color) +{ + m_floorColor = color; +} + +// Choosing the color of the water. + +void CMap::SetWaterColor(D3DCOLORVALUE color) +{ + m_waterColor = color; +} + + +// Specifies a fixed image in place of the drawing of the relief. + +void CMap::SetFixImage(char *filename) +{ + strcpy(m_fixImage, filename); +} + +// Whether to use a still image. + +BOOL CMap::RetFixImage() +{ + return (m_fixImage[0] != 0); +} + + +// Management of an event. + +BOOL CMap::EventProcess(const Event &event) +{ + BOOL bInMap; + + if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; + + CControl::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + m_time += event.rTime; + } + + if ( event.event == EVENT_MOUSEMOVE && Detect(event.pos) ) + { + m_engine->SetMouseType(D3DMOUSENORM); + if ( DetectObject(event.pos, bInMap) != 0 ) + { + m_engine->SetMouseType(D3DMOUSEHAND); + } + } + + if ( event.event == EVENT_LBUTTONDOWN ) + { + if ( CControl::Detect(event.pos) ) + { + SelectObject(event.pos); + return FALSE; + } + } + + return TRUE; +} + +// Adjusts the offset to not exceed the card. + +FPOINT CMap::AdjustOffset(FPOINT offset) +{ + float limit; + + limit = m_half - m_half/m_zoom; + if ( offset.x < -limit ) offset.x = -limit; + if ( offset.x > limit ) offset.x = limit; + if ( offset.y < -limit ) offset.y = -limit; + if ( offset.y > limit ) offset.y = limit; + + return offset; +} + +// Indicates the object with the mouse hovers over. + +void CMap::SetHilite(CObject* pObj) +{ + int i; + + m_hiliteRank = -1; + if ( m_bToy || m_fixImage[0] != 0 ) return; // card with still image? + if ( pObj == 0 ) return; + + for ( i=0 ; i m_pos.x+m_dim.x || + pos.y > m_pos.y+m_dim.y ) return 0; + + bInMap = TRUE; + + pos.x = (pos.x-m_pos.x)/m_dim.x*256.0f; + pos.y = (pos.y-m_pos.y)/m_dim.y*256.0f; // 0..256 + pos.x = (pos.x-128.0f)*m_half/(m_zoom*128.0f)+m_offset.x; + pos.y = (pos.y-128.0f)*m_half/(m_zoom*128.0f)+m_offset.y; + + min = 10000.0f; + best = -1; + for ( i=MAPMAXOBJECT-1 ; i>=0 ; i-- ) + { + if ( !m_map[i].bUsed ) continue; + if ( m_map[i].color == MAPCOLOR_BBOX && !m_bRadar ) continue; + if ( m_map[i].color == MAPCOLOR_ALIEN && !m_bRadar ) continue; + + dist = Length(m_map[i].pos.x-pos.x, m_map[i].pos.y-pos.y); + if ( dist > m_half/m_zoom*8.0f/100.0f ) continue; // too far? + if ( dist < min ) + { + min = dist; + best = i; + } + } + if ( best == -1 ) return 0; + return m_map[best].object; +} + +// Selects an object. + +void CMap::SelectObject(FPOINT pos) +{ + CObject *pObj; + BOOL bInMap; + + pObj = DetectObject(pos, bInMap); + if ( pObj != 0 ) + { + m_main->SelectObject(pObj); + } +} + + +// Draw the map. + +void CMap::Draw() +{ + FPOINT uv1, uv2; + int i; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + CControl::Draw(); // draws the bottom (button) + + if ( !m_bEnable ) return; + + if ( m_fixImage[0] == 0 && m_map[MAPMAXOBJECT-1].bUsed ) + { + m_offset = AdjustOffset(m_map[MAPMAXOBJECT-1].pos); + } + + if ( m_fixImage[0] == 0 ) // drawing of the relief? + { + m_engine->SetTexture("map.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 0.5f+(m_offset.x-(m_half/m_zoom))/(m_half*2.0f); + uv1.y = 0.5f-(m_offset.y+(m_half/m_zoom))/(m_half*2.0f); + uv2.x = 0.5f+(m_offset.x+(m_half/m_zoom))/(m_half*2.0f); + uv2.y = 0.5f-(m_offset.y-(m_half/m_zoom))/(m_half*2.0f); + DrawVertex(uv1, uv2, 0.97f); // drawing the map + } + else // still image? + { + m_engine->LoadTexture(m_fixImage); + m_engine->SetTexture(m_fixImage); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 0.0f; + uv1.y = 0.0f; + uv2.x = 1.0f; + uv2.y = 1.0f; + DrawVertex(uv1, uv2, 0.97f); // drawing the map + } + + i = MAPMAXOBJECT-1; + if ( m_map[i].bUsed ) // selection: + { + DrawFocus(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color); + } + + for ( i=0 ; im_totalMove ; i-- ) // moving objects: + { + if ( i == m_hiliteRank ) continue; + DrawObject(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color, FALSE, FALSE); + } + + i = MAPMAXOBJECT-1; + if ( m_map[i].bUsed && i != m_hiliteRank ) // selection: + { + DrawObject(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color, TRUE, FALSE); + } + + if ( m_hiliteRank != -1 && m_map[m_hiliteRank].bUsed ) + { + i = m_hiliteRank; + DrawObject(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color, FALSE, TRUE); + DrawHilite(m_map[i].pos); + } +} + +// Computing a point for drawFocus. + +FPOINT CMap::MapInter(FPOINT pos, float dir) +{ + FPOINT p1; + float limit; + + p1.x = pos.x+1.0f; + p1.y = pos.y; + p1 = RotatePoint(pos, dir, p1); + + p1.x -= pos.x; + p1.y -= pos.y; + + limit = m_mapPos.x+m_mapDim.x-pos.x; + if ( p1.x > limit ) // exceeds the right? + { + p1.y = limit*p1.y/p1.x; + p1.x = limit; + } + limit = m_mapPos.y*0.75f+m_mapDim.y*0.75f-pos.y; + if ( p1.y > limit ) // exceeds the top? + { + p1.x = limit*p1.x/p1.y; + p1.y = limit; + } + limit = m_mapPos.x-pos.x; + if ( p1.x < limit ) // exceeds the left? + { + p1.y = limit*p1.y/p1.x; + p1.x = limit; + } + limit = m_mapPos.y*0.75f-pos.y; + if ( p1.y < limit ) // exceeds the bottom? + { + p1.x = limit*p1.x/p1.y; + p1.y = limit; + } + + p1.x += pos.x; + p1.y += pos.y; + return p1; +} + +// Draw the field of vision of the selected object. + +void CMap::DrawFocus(FPOINT pos, float dir, ObjectType type, MapColor color) +{ + FPOINT p0, p1, p2, uv1, uv2, rel; + float aMin, aMax, aOct, focus, a; + float limit[5]; + BOOL bEnding; + int quart; + + if ( m_bToy || m_fixImage[0] != 0 ) return; // map with still image? + if ( color != MAPCOLOR_MOVE ) return; + + pos.x = (pos.x-m_offset.x)*(m_zoom*0.5f)/m_half+0.5f; + pos.y = (pos.y-m_offset.y)*(m_zoom*0.5f)/m_half+0.5f; + + if ( pos.x < 0.0f || pos.x > 1.0f || + pos.y < 0.0f || pos.y > 1.0f ) return; + + rel.x = pos.x*2.0f-1.0f; + rel.y = pos.y*2.0f-1.0f; // rel [-1..1] + + pos.x = m_mapPos.x+m_mapDim.x*pos.x; + pos.y = m_mapPos.y*0.75f+m_mapDim.y*pos.y*0.75f; + + focus = m_engine->RetFocus(); + dir += PI/2.0f; + aMin = NormAngle(dir-PI/4.0f*focus); + aMax = NormAngle(dir+PI/4.0f*focus); + + if ( aMin > aMax ) + { + aMax += PI*2.0f; // aMax always after aMin + } + + limit[0] = RotateAngle( 1.0f-rel.x, 1.0f-rel.y); // upper/right + limit[1] = RotateAngle(-1.0f-rel.x, 1.0f-rel.y); // upper/left + limit[2] = RotateAngle(-1.0f-rel.x, -1.0f-rel.y); // lower/left + limit[3] = RotateAngle( 1.0f-rel.x, -1.0f-rel.y); // lower/right + limit[4] = limit[0]+PI*2.0f; + + a = NormAngle(aMin); + for ( quart=0 ; quart<4 ; quart++ ) + { + if ( a >= limit[quart+0] && + a <= limit[quart+1] ) break; + } + if ( quart == 4 ) quart = -1; + + uv1.x = 113.0f/256.0f; // degrade green + uv1.y = 240.5f/256.0f; + uv2.x = 126.0f/256.0f; + uv2.y = 255.0f/256.0f; + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + + bEnding = FALSE; + do + { + quart ++; + aOct = limit[quart%4]; + if ( quart >= 4 ) aOct += PI*2.0f; + if ( aOct >= aMax-CHOUIA ) + { + aOct = aMax; + bEnding = TRUE; + } + + p0 = pos; + p1 = MapInter(pos, aMin); + p2 = MapInter(pos, aOct); + p0.y /= 0.75f; + p1.y /= 0.75f; + p2.y /= 0.75f; + DrawTriangle(p0, p2, p1, uv1, uv2); + + aMin = aOct; + } + while ( !bEnding ); +} + +// Draw an object. + +void CMap::DrawObject(FPOINT pos, float dir, ObjectType type, MapColor color, + BOOL bSelect, BOOL bHilite) +{ + FPOINT p1, p2, p3, p4, p5, dim, uv1, uv2; + BOOL bOut, bUp, bDown, bLeft, bRight; + + pos.x = (pos.x-m_offset.x)*(m_zoom*0.5f)/m_half+0.5f; + pos.y = (pos.y-m_offset.y)*(m_zoom*0.5f)/m_half+0.5f; + + bOut = bUp = bDown = bLeft = bRight = FALSE; + if ( pos.x < 0.06f ) { pos.x = 0.02f; bOut = bLeft = TRUE; } + if ( pos.y < 0.06f ) { pos.y = 0.02f; bOut = bDown = TRUE; } + if ( pos.x > 0.94f ) { pos.x = 0.98f; bOut = bRight = TRUE; } + if ( pos.y > 0.94f ) { pos.y = 0.98f; bOut = bUp = TRUE; } + + pos.x = m_mapPos.x+m_mapDim.x*pos.x; + pos.y = m_mapPos.y+m_mapDim.y*pos.y; + dim.x = 2.0f/128.0f*0.75f; + dim.y = 2.0f/128.0f; + + if ( bOut ) // outside the map? + { + if ( color == MAPCOLOR_BBOX && !m_bRadar ) return; + if ( color == MAPCOLOR_ALIEN && !m_bRadar ) return; + + if ( Mod(m_time+(pos.x+pos.y)*4.0f, 0.6f) > 0.2f ) + { + return; // flashes + } + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + if ( bUp ) + { + uv1.x = 160.5f/256.0f; // yellow triangle ^ + uv1.y = 240.5f/256.0f; + uv2.x = 175.0f/256.0f; + uv2.y = 255.0f/256.0f; + } + if ( bDown ) + { + uv1.x = 160.5f/256.0f; // yellow triangle v + uv1.y = 255.0f/256.0f; + uv2.x = 175.0f/256.0f; + uv2.y = 240.5f/256.0f; + } + if ( bRight ) + { + uv1.x = 176.5f/256.0f; // yellow triangle > + uv1.y = 240.5f/256.0f; + uv2.x = 191.0f/256.0f; + uv2.y = 255.0f/256.0f; + } + if ( bLeft ) + { + uv1.x = 191.0f/256.0f; // yellow triangle < + uv1.y = 240.5f/256.0f; + uv2.x = 176.5f/256.0f; + uv2.y = 255.0f/256.0f; + } + pos.x -= dim.x/2.0f; + pos.y -= dim.y/2.0f; + DrawIcon(pos, dim, uv1, uv2); + return; + } + + if ( bSelect ) + { + if ( m_bToy ) + { + dim.x *= 1.2f+sinf(m_time*8.0f)*0.1f; + dim.y *= 1.2f+sinf(m_time*8.0f)*0.1f; + } + else + { + dim.x *= 1.2f+sinf(m_time*8.0f)*0.3f; + dim.y *= 1.2f+sinf(m_time*8.0f)*0.3f; + } + } + if ( color == MAPCOLOR_BASE || + color == MAPCOLOR_FIX || + color == MAPCOLOR_MOVE ) + { + if ( bHilite ) + { + dim.x *= 2.2f; + dim.y *= 2.2f; + } + else + { + dim.x *= 0.6f; + dim.y *= 0.6f; + } + } + if ( color == MAPCOLOR_ALIEN ) + { + dim.x *= 1.4f; + dim.y *= 1.4f; + } + if ( type == OBJECT_TEEN28 ) // bottle? + { + dim.x *= 3.0f; + dim.y *= 3.0f; + bHilite = TRUE; + } + if ( type == OBJECT_TEEN34 ) // stone? + { + dim.x *= 2.0f; + dim.y *= 2.0f; + bHilite = TRUE; + } + + if ( color == MAPCOLOR_MOVE && bSelect ) + { + if ( m_bToy ) + { + p1.x = pos.x; + p1.y = pos.y+dim.y*1.4f; + p1 = RotatePoint(pos, dir, p1); + p1.x = pos.x+(p1.x-pos.x)*0.75f; + + p2.x = pos.x+dim.x*1.2f; + p2.y = pos.y+dim.y*0.8f; + p2 = RotatePoint(pos, dir, p2); + p2.x = pos.x+(p2.x-pos.x)*0.75f; + + p3.x = pos.x+dim.x*1.2f; + p3.y = pos.y-dim.y*1.0f; + p3 = RotatePoint(pos, dir, p3); + p3.x = pos.x+(p3.x-pos.x)*0.75f; + + p4.x = pos.x-dim.x*1.2f; + p4.y = pos.y-dim.y*1.0f; + p4 = RotatePoint(pos, dir, p4); + p4.x = pos.x+(p4.x-pos.x)*0.75f; + + p5.x = pos.x-dim.x*1.2f; + p5.y = pos.y+dim.y*0.8f; + p5 = RotatePoint(pos, dir, p5); + p5.x = pos.x+(p5.x-pos.x)*0.75f; + } + else + { + p1.x = pos.x; + p1.y = pos.y+dim.y*2.4f; + p1 = RotatePoint(pos, dir, p1); + p1.x = pos.x+(p1.x-pos.x)*0.75f; + + p2.x = pos.x+dim.x*1.0f; + p2.y = pos.y-dim.y*1.6f; + p2 = RotatePoint(pos, dir, p2); + p2.x = pos.x+(p2.x-pos.x)*0.75f; + + p3.x = pos.x-dim.x*1.0f; + p3.y = pos.y-dim.y*1.6f; + p3 = RotatePoint(pos, dir, p3); + p3.x = pos.x+(p3.x-pos.x)*0.75f; + } + } + + pos.x -= dim.x/2.0f; + pos.y -= dim.y/2.0f; + + if ( color == MAPCOLOR_BASE || + color == MAPCOLOR_FIX ) + { + DrawObjectIcon(pos, dim, color, type, bHilite); + } + + if ( color == MAPCOLOR_MOVE ) + { + if ( bSelect ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + if ( m_bToy ) + { + uv1.x = 164.5f/256.0f; // black pentagon + uv1.y = 228.5f/256.0f; + uv2.x = 172.0f/256.0f; + uv2.y = 236.0f/256.0f; + DrawPenta(p1, p2, p3, p4, p5, uv1, uv2); + } + else + { + uv1.x = 144.5f/256.0f; // red triangle + uv1.y = 240.5f/256.0f; + uv2.x = 159.0f/256.0f; + uv2.y = 255.0f/256.0f; + DrawTriangle(p1, p2, p3, uv1, uv2); + } + } + DrawObjectIcon(pos, dim, color, type, bHilite); + } + + if ( color == MAPCOLOR_BBOX ) + { + if ( m_bRadar ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + uv1.x = 64.5f/256.0f; // blue triangle + uv1.y = 240.5f/256.0f; + uv2.x = 79.0f/256.0f; + uv2.y = 255.0f/256.0f; + DrawIcon(pos, dim, uv1, uv2); + } + } + + if ( color == MAPCOLOR_ALIEN ) + { + if ( m_bRadar ) + { + DrawObjectIcon(pos, dim, color, type, TRUE); + } + } + + if ( color == MAPCOLOR_WAYPOINTb ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 192.5f/256.0f; // blue cross + uv1.y = 240.5f/256.0f; + uv2.x = 207.0f/256.0f; + uv2.y = 255.0f/256.0f; + DrawIcon(pos, dim, uv1, uv2); + } + if ( color == MAPCOLOR_WAYPOINTr ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 208.5f/256.0f; // red cross + uv1.y = 240.5f/256.0f; + uv2.x = 223.0f/256.0f; + uv2.y = 255.0f/256.0f; + DrawIcon(pos, dim, uv1, uv2); + } + if ( color == MAPCOLOR_WAYPOINTg ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 224.5f/256.0f; // green cross + uv1.y = 240.5f/256.0f; + uv2.x = 239.0f/256.0f; + uv2.y = 255.0f/256.0f; + DrawIcon(pos, dim, uv1, uv2); + } + if ( color == MAPCOLOR_WAYPOINTy ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 240.5f/256.0f; // yellow cross + uv1.y = 240.5f/256.0f; + uv2.x = 255.0f/256.0f; + uv2.y = 255.0f/256.0f; + DrawIcon(pos, dim, uv1, uv2); + } + if ( color == MAPCOLOR_WAYPOINTv ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 192.5f/256.0f; // violet cross + uv1.y = 224.5f/256.0f; + uv2.x = 207.0f/256.0f; + uv2.y = 239.0f/256.0f; + DrawIcon(pos, dim, uv1, uv2); + } +} + +// Draws the icon of an object. + +void CMap::DrawObjectIcon(FPOINT pos, FPOINT dim, MapColor color, + ObjectType type, BOOL bHilite) +{ + FPOINT ppos, ddim, uv1, uv2; + float dp; + int icon; + + dp = 0.5f/256.0f; + + m_engine->SetTexture("button3.tga"); + m_engine->SetState(D3DSTATENORMAL); + if ( color == MAPCOLOR_MOVE ) + { + uv1.x = 160.0f/256.0f; // blue + uv1.y = 224.0f/256.0f; + } + else if ( color == MAPCOLOR_ALIEN ) + { + uv1.x = 224.0f/256.0f; // green + uv1.y = 224.0f/256.0f; + } + else + { + uv1.x = 192.0f/256.0f; // yellow + uv1.y = 224.0f/256.0f; + } + uv2.x = uv1.x+32.0f/256.0f; + uv2.y = uv1.y+32.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2); // background colors + + if ( bHilite ) + { + icon = -1; + if ( type == OBJECT_FACTORY ) icon = 32; + if ( type == OBJECT_DERRICK ) icon = 33; + if ( type == OBJECT_CONVERT ) icon = 34; + if ( type == OBJECT_RESEARCH ) icon = 35; + if ( type == OBJECT_STATION ) icon = 36; + if ( type == OBJECT_TOWER ) icon = 37; + if ( type == OBJECT_LABO ) icon = 38; + if ( type == OBJECT_ENERGY ) icon = 39; + if ( type == OBJECT_RADAR ) icon = 40; + if ( type == OBJECT_INFO ) icon = 44; + if ( type == OBJECT_REPAIR ) icon = 41; + if ( type == OBJECT_DESTROYER) icon = 41; + if ( type == OBJECT_NUCLEAR ) icon = 42; + if ( type == OBJECT_PARA ) icon = 46; + if ( type == OBJECT_SAFE ) icon = 47; + if ( type == OBJECT_HUSTON ) icon = 48; + if ( type == OBJECT_TARGET1 ) icon = 45; + if ( type == OBJECT_BASE ) icon = 43; + if ( type == OBJECT_HUMAN ) icon = 8; + if ( type == OBJECT_MOBILEfa ) icon = 11; + if ( type == OBJECT_MOBILEta ) icon = 10; + if ( type == OBJECT_MOBILEwa ) icon = 9; + if ( type == OBJECT_MOBILEia ) icon = 22; + if ( type == OBJECT_MOBILEfc ) icon = 17; + if ( type == OBJECT_MOBILEtc ) icon = 16; + if ( type == OBJECT_MOBILEwc ) icon = 15; + if ( type == OBJECT_MOBILEic ) icon = 23; + if ( type == OBJECT_MOBILEfi ) icon = 27; + if ( type == OBJECT_MOBILEti ) icon = 26; + if ( type == OBJECT_MOBILEwi ) icon = 25; + if ( type == OBJECT_MOBILEii ) icon = 28; + if ( type == OBJECT_MOBILEfs ) icon = 14; + if ( type == OBJECT_MOBILEts ) icon = 13; + if ( type == OBJECT_MOBILEws ) icon = 12; + if ( type == OBJECT_MOBILEis ) icon = 24; + if ( type == OBJECT_MOBILErt ) icon = 18; + if ( type == OBJECT_MOBILErc ) icon = 19; + if ( type == OBJECT_MOBILErr ) icon = 20; + if ( type == OBJECT_MOBILErs ) icon = 29; + if ( type == OBJECT_MOBILEsa ) icon = 21; + if ( type == OBJECT_MOBILEft ) icon = 30; + if ( type == OBJECT_MOBILEtt ) icon = 30; + if ( type == OBJECT_MOBILEwt ) icon = 30; + if ( type == OBJECT_MOBILEit ) icon = 30; + if ( type == OBJECT_MOBILEtg ) icon = 45; + if ( type == OBJECT_MOBILEdr ) icon = 48; + if ( type == OBJECT_APOLLO2 ) icon = 49; + if ( type == OBJECT_MOTHER ) icon = 31; + if ( type == OBJECT_ANT ) icon = 31; + if ( type == OBJECT_SPIDER ) icon = 31; + if ( type == OBJECT_BEE ) icon = 31; + if ( type == OBJECT_WORM ) icon = 31; + if ( type == OBJECT_TEEN28 ) icon = 48; // bottle + if ( type == OBJECT_TEEN34 ) icon = 48; // stone + if ( icon == -1 ) return; + + m_engine->SetState(D3DSTATETTw); + uv1.x = (32.0f/256.0f)*(icon%8); + uv1.y = (32.0f/256.0f)*(icon/8); + uv2.x = uv1.x+32.0f/256.0f; + uv2.y = uv1.y+32.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2); // icon + } +} + +// Draw the object with the mouse hovers over. + +void CMap::DrawHilite(FPOINT pos) +{ + FPOINT dim, uv1, uv2; + BOOL bOut, bUp, bDown, bLeft, bRight; + + if ( m_bToy || m_fixImage[0] != 0 ) return; // map with still image? + + pos.x = (pos.x-m_offset.x)*(m_zoom*0.5f)/m_half+0.5f; + pos.y = (pos.y-m_offset.y)*(m_zoom*0.5f)/m_half+0.5f; + + bOut = bUp = bDown = bLeft = bRight = FALSE; + if ( pos.x < 0.06f ) { pos.x = 0.02f; bOut = bLeft = TRUE; } + if ( pos.y < 0.06f ) { pos.y = 0.02f; bOut = bDown = TRUE; } + if ( pos.x > 0.94f ) { pos.x = 0.98f; bOut = bRight = TRUE; } + if ( pos.y > 0.94f ) { pos.y = 0.98f; bOut = bUp = TRUE; } + + pos.x = m_mapPos.x+m_mapDim.x*pos.x; + pos.y = m_mapPos.y+m_mapDim.y*pos.y; + dim.x = 2.0f/128.0f*0.75f; + dim.y = 2.0f/128.0f; + dim.x *= 2.0f+cosf(m_time*8.0f)*0.5f; + dim.y *= 2.0f+cosf(m_time*8.0f)*0.5f; + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 160.5f/256.0f; // hilite + uv1.y = 224.5f/256.0f; + uv2.x = 175.0f/256.0f; + uv2.y = 239.0f/256.0f; + pos.x -= dim.x/2.0f; + pos.y -= dim.y/2.0f; + DrawIcon(pos, dim, uv1, uv2); +} + +// Draws a triangular icon. + +void CMap::DrawTriangle(FPOINT p1, FPOINT p2, FPOINT p3, FPOINT uv1, FPOINT uv2) +{ + LPDIRECT3DDEVICE7 device; + D3DVERTEX2 vertex[3]; // 1 triangle + D3DVECTOR n; + + device = m_engine->RetD3DDevice(); + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal + + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv1.y); + vertex[1] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv1.x,uv2.y); + vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv2.x,uv2.y); + + device->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_VERTEX2, vertex, 3, NULL); + m_engine->AddStatisticTriangle(1); +} + +// Draw a pentagon icon (a 5 rating, what!). + +void CMap::DrawPenta(FPOINT p1, FPOINT p2, FPOINT p3, FPOINT p4, FPOINT p5, FPOINT uv1, FPOINT uv2) +{ + LPDIRECT3DDEVICE7 device; + D3DVERTEX2 vertex[5]; // 1 pentagon + D3DVECTOR n; + + device = m_engine->RetD3DDevice(); + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal + +#if 1 + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv1.y); + vertex[1] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv1.x,uv2.y); + vertex[2] = D3DVERTEX2(D3DVECTOR(p5.x, p5.y, 0.0f), n, uv2.x,uv2.y); + vertex[3] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv2.x,uv2.y); + vertex[4] = D3DVERTEX2(D3DVECTOR(p4.x, p4.y, 0.0f), n, uv2.x,uv2.y); + + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 5, NULL); +#else + vertex[0] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv1.x,uv1.y); + vertex[1] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv1.x,uv2.y); + vertex[2] = D3DVERTEX2(D3DVECTOR(p4.x, p4.y, 0.0f), n, uv2.x,uv2.y); + + device->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_VERTEX2, vertex, 3, NULL); +#endif + m_engine->AddStatisticTriangle(3); +} + +// Draw the vertex array. + +void CMap::DrawVertex(FPOINT uv1, FPOINT uv2, float zoom) +{ + LPDIRECT3DDEVICE7 device; + D3DVERTEX2 vertex[4]; // 2 triangles + FPOINT p1, p2, c; + D3DVECTOR n; + + device = m_engine->RetD3DDevice(); + + p1.x = m_pos.x; + p1.y = m_pos.y; + p2.x = m_pos.x + m_dim.x; + p2.y = m_pos.y + m_dim.y; + + c.x = (p1.x+p2.x)/2.0f; + c.y = (p1.y+p2.y)/2.0f; // center + + p1.x = (p1.x-c.x)*zoom + c.x; + p1.y = (p1.y-c.y)*zoom + c.y; + + p2.x = (p2.x-c.x)*zoom + c.x; + p2.y = (p2.y-c.y)*zoom + c.y; + + m_mapPos = p1; + m_mapDim.x = p2.x-p1.x; + m_mapDim.y = p2.y-p1.y; + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal + + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x,uv1.y); + vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y); + vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv2.x,uv1.y); + + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); +} + + +// Updates the field in the map. + +void CMap::UpdateTerrain() +{ + D3DCOLORVALUE color; + D3DVECTOR pos; + float scale, water, level, intensity; + int x, y; + + if ( m_fixImage[0] != 0 ) return; // still image? + if ( !m_engine->OpenImage("map.tga") ) return; + + scale = m_terrain->RetScaleRelief(); + water = m_water->RetLevel(); + color.a = 0.0f; + + for ( y=0 ; y<256 ; y++ ) + { + for ( x=0 ; x<256 ; x++ ) + { + pos.x = ((float)x-128.0f)*m_half/128.0f; + pos.z = -((float)y-128.0f)*m_half/128.0f; + pos.y = 0.0f; + + if ( pos.x >= -m_half && pos.x <= m_half && + pos.z >= -m_half && pos.z <= m_half ) + { + level = m_terrain->RetFloorLevel(pos, TRUE)/scale; + } + else + { + level = 1000.0f; + } + + intensity = level/256.0f; + if ( intensity < 0.0f ) intensity = 0.0f; + if ( intensity > 1.0f ) intensity = 1.0f; + + if ( level >= water ) // on water? + { + color.r = m_floorColor.r + (intensity-0.5f); + color.g = m_floorColor.g + (intensity-0.5f); + color.b = m_floorColor.b + (intensity-0.5f); + } + else // underwater? + { + color.r = m_waterColor.r + (intensity-0.5f); + color.g = m_waterColor.g + (intensity-0.5f); + color.b = m_waterColor.b + (intensity-0.5f); + } + + m_engine->SetDot(x, y, color); + } + } + + m_engine->CopyImage(); // copy the ground drawing + m_engine->CloseImage(); +} + +// Updates the field in the map. + +void CMap::UpdateTerrain(int bx, int by, int ex, int ey) +{ + D3DCOLORVALUE color; + D3DVECTOR pos; + float scale, water, level, intensity; + int x, y; + + if ( m_fixImage[0] != 0 ) return; // still image? + if ( !m_engine->OpenImage("map.tga") ) return; + m_engine->LoadImage(); + + scale = m_terrain->RetScaleRelief(); + water = m_water->RetLevel(); + color.a = 0.0f; + + for ( y=by ; y= -m_half && pos.x <= m_half && + pos.z >= -m_half && pos.z <= m_half ) + { + level = m_terrain->RetFloorLevel(pos, TRUE)/scale; + } + else + { + level = 1000.0f; + } + + intensity = level/256.0f; + if ( intensity < 0.0f ) intensity = 0.0f; + if ( intensity > 1.0f ) intensity = 1.0f; + + if ( level > water ) // on water? + { + color.r = m_floorColor.r + (intensity-0.5f); + color.g = m_floorColor.g + (intensity-0.5f); + color.b = m_floorColor.b + (intensity-0.5f); + } + else // underwater? + { + color.r = m_waterColor.r + (intensity-0.5f); + color.g = m_waterColor.g + (intensity-0.5f); + color.b = m_waterColor.b + (intensity-0.5f); + } + + m_engine->SetDot(x, y, color); + } + } + + m_engine->CopyImage(); // copy the ground drawing + m_engine->CloseImage(); +} + + +// Empty all objects. + +void CMap::FlushObject() +{ + int i; + + m_totalFix = 0; // object index fixed + m_totalMove = MAPMAXOBJECT-2; // moving vehicles index + m_bRadar = m_main->RetCheatRadar(); // no radar + + for ( i=0 ; i= m_totalMove ) return; // full table? + + if ( !pObj->RetActif() ) return; + if ( !pObj->RetSelectable() ) return; + if ( pObj->RetProxyActivate() ) return; + if ( pObj->RetTruck() != 0 ) return; + + type = pObj->RetType(); + pos = pObj->RetPosition(0); + dir = -(pObj->RetAngleY(0)+PI/2.0f); + + if ( m_angle != 0.0f ) + { + ppos = RotatePoint(m_angle, FPOINT(pos.x, pos.z)); + pos.x = ppos.x; + pos.z = ppos.y; + dir += m_angle; + } + + if ( type == OBJECT_RADAR ) + { + m_bRadar = TRUE; // radar exists + } + + color = MAPCOLOR_NULL; + if ( type == OBJECT_BASE ) + { + color = MAPCOLOR_BASE; + } + if ( type == OBJECT_DERRICK || + type == OBJECT_FACTORY || + type == OBJECT_STATION || + type == OBJECT_CONVERT || + type == OBJECT_REPAIR || + type == OBJECT_DESTROYER|| + type == OBJECT_TOWER || + type == OBJECT_RESEARCH || + type == OBJECT_RADAR || + type == OBJECT_INFO || + type == OBJECT_ENERGY || + type == OBJECT_LABO || + type == OBJECT_NUCLEAR || + type == OBJECT_PARA || + type == OBJECT_SAFE || + type == OBJECT_HUSTON || + type == OBJECT_TARGET1 || + type == OBJECT_START || + type == OBJECT_END || // stationary object? + type == OBJECT_TEEN28 || // bottle? + type == OBJECT_TEEN34 ) // stone? + { + color = MAPCOLOR_FIX; + } + if ( type == OBJECT_BBOX || + type == OBJECT_KEYa || + type == OBJECT_KEYb || + type == OBJECT_KEYc || + type == OBJECT_KEYd ) + { + color = MAPCOLOR_BBOX; + } + if ( type == OBJECT_HUMAN || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEia || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEtg || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEtt || + type == OBJECT_MOBILEft || + type == OBJECT_MOBILEit || + type == OBJECT_MOBILEdr || + type == OBJECT_APOLLO2 ) // moving vehicle? + { + color = MAPCOLOR_MOVE; + } + if ( type == OBJECT_ANT || + type == OBJECT_BEE || + type == OBJECT_WORM || + type == OBJECT_SPIDER ) // mobile enemy? + { + color = MAPCOLOR_ALIEN; + } + if ( type == OBJECT_WAYPOINT || + type == OBJECT_FLAGb ) + { + color = MAPCOLOR_WAYPOINTb; + } + if ( type == OBJECT_FLAGr ) + { + color = MAPCOLOR_WAYPOINTr; + } + if ( type == OBJECT_FLAGg ) + { + color = MAPCOLOR_WAYPOINTg; + } + if ( type == OBJECT_FLAGy ) + { + color = MAPCOLOR_WAYPOINTy; + } + if ( type == OBJECT_FLAGv ) + { + color = MAPCOLOR_WAYPOINTv; + } + + if ( color == MAPCOLOR_NULL ) return; + + if ( m_fixImage[0] != 0 && !m_bDebug ) // map with still image? + { + if ( (type == OBJECT_TEEN28 || + type == OBJECT_TEEN34 ) && + m_mode == 0 ) return; + + if ( type != OBJECT_TEEN28 && + type != OBJECT_TEEN34 && + color != MAPCOLOR_MOVE ) return; + } + + if ( pObj->RetSelect() ) + { + m_map[MAPMAXOBJECT-1].type = type; + m_map[MAPMAXOBJECT-1].object = pObj; + m_map[MAPMAXOBJECT-1].color = color; + m_map[MAPMAXOBJECT-1].pos.x = pos.x; + m_map[MAPMAXOBJECT-1].pos.y = pos.z; + m_map[MAPMAXOBJECT-1].dir = dir; + m_map[MAPMAXOBJECT-1].bUsed = TRUE; + } + else + { + if ( color == MAPCOLOR_BASE || + color == MAPCOLOR_FIX ) + { + m_map[m_totalFix].type = type; + m_map[m_totalFix].object = pObj; + m_map[m_totalFix].color = color; + m_map[m_totalFix].pos.x = pos.x; + m_map[m_totalFix].pos.y = pos.z; + m_map[m_totalFix].dir = dir; + m_map[m_totalFix].bUsed = TRUE; + m_totalFix ++; + } + else + { + m_map[m_totalMove].type = type; + m_map[m_totalMove].object = pObj; + m_map[m_totalMove].color = color; + m_map[m_totalMove].pos.x = pos.x; + m_map[m_totalMove].pos.y = pos.z; + m_map[m_totalMove].dir = dir; + m_map[m_totalMove].bUsed = TRUE; + m_totalMove --; + } + } +} + diff --git a/src/ui/map.h b/src/ui/map.h new file mode 100644 index 0000000..4b1f793 --- /dev/null +++ b/src/ui/map.h @@ -0,0 +1,141 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// map.h + +#ifndef _MAP_H_ +#define _MAP_H_ + + +#include "control.h" +#include "struct.h" +#include "object.h" + + +class CD3DEngine; +class CTerrain; +class CWater; +class CRobotMain; + + + +#define MAPMAXOBJECT 100 + +enum MapColor +{ + MAPCOLOR_NULL, + MAPCOLOR_BASE, + MAPCOLOR_FIX, + MAPCOLOR_MOVE, + MAPCOLOR_ALIEN, + MAPCOLOR_WAYPOINTb, + MAPCOLOR_WAYPOINTr, + MAPCOLOR_WAYPOINTg, + MAPCOLOR_WAYPOINTy, + MAPCOLOR_WAYPOINTv, + MAPCOLOR_BBOX, +}; + +typedef struct +{ + char bUsed; + CObject* object; + MapColor color; + ObjectType type; + FPOINT pos; + float dir; +} +MapObject; + + + +class CMap : public CControl +{ +public: + CMap(CInstanceManager* iMan); + ~CMap(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + BOOL EventProcess(const Event &event); + void Draw(); + + void UpdateTerrain(); + void UpdateTerrain(int bx, int by, int ex, int ey); + + void SetFixImage(char *filename); + BOOL RetFixImage(); + + void SetOffset(float ox, float oy); + void SetAngle(float angle); + void SetMode(int mode); + void SetToy(BOOL bToy); + void SetDebug(BOOL bDebug); + + void SetZoom(float value); + float RetZoom(); + + void SetEnable(BOOL bEnable); + BOOL RetEnable(); + + void SetFloorColor(D3DCOLORVALUE color); + void SetWaterColor(D3DCOLORVALUE color); + + void FlushObject(); + void UpdateObject(CObject* pObj); + + CObject* DetectObject(FPOINT pos, BOOL &bInMap); + void SetHilite(CObject* pObj); + +protected: + FPOINT AdjustOffset(FPOINT offset); + void SelectObject(FPOINT pos); + FPOINT MapInter(FPOINT pos, float dir); + void DrawFocus(FPOINT pos, float dir, ObjectType type, MapColor color); + void DrawObject(FPOINT pos, float dir, ObjectType type, MapColor color, BOOL bSelect, BOOL bHilite); + void DrawObjectIcon(FPOINT pos, FPOINT dim, MapColor color, ObjectType type, BOOL bHilite); + void DrawHilite(FPOINT pos); + void DrawTriangle(FPOINT p1, FPOINT p2, FPOINT p3, FPOINT uv1, FPOINT uv2); + void DrawPenta(FPOINT p1, FPOINT p2, FPOINT p3, FPOINT p4, FPOINT p5, FPOINT uv1, FPOINT uv2); + void DrawVertex(FPOINT uv1, FPOINT uv2, float zoom); + +protected: + CTerrain* m_terrain; + CWater* m_water; + CRobotMain* m_main; + + BOOL m_bEnable; + float m_time; + float m_half; + float m_zoom; + FPOINT m_offset; + float m_angle; + D3DCOLORVALUE m_floorColor; + D3DCOLORVALUE m_waterColor; + MapObject m_map[MAPMAXOBJECT]; + int m_totalFix; + int m_totalMove; + int m_hiliteRank; + FPOINT m_mapPos; + FPOINT m_mapDim; + BOOL m_bRadar; + char m_fixImage[100]; + int m_mode; + BOOL m_bToy; + BOOL m_bDebug; +}; + + +#endif //_MAP_H_ diff --git a/src/ui/scroll.cpp b/src/ui/scroll.cpp new file mode 100644 index 0000000..1122ac5 --- /dev/null +++ b/src/ui/scroll.cpp @@ -0,0 +1,471 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// scroll.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "button.h" +#include "scroll.h" + + + + +// Object's constructor. + +CScroll::CScroll(CInstanceManager* iMan) : CControl(iMan) +{ + m_buttonUp = 0; + m_buttonDown = 0; + + m_visibleValue = 0.0f; + m_visibleRatio = 1.0f; + m_step = 0.0f; + + m_eventUp = EVENT_NULL; + m_eventDown = EVENT_NULL; + + m_bCapture = FALSE; +} + +// Object's destructor. + +CScroll::~CScroll() +{ + delete m_buttonUp; + delete m_buttonDown; +} + + +// Creates a new button. + +BOOL CScroll::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + CControl::Create(pos, dim, icon, eventMsg); + + MoveAdjust(); + return TRUE; +} + + +void CScroll::SetPos(FPOINT pos) +{ + CControl::SetPos(pos); + MoveAdjust(); +} + +void CScroll::SetDim(FPOINT dim) +{ + CControl::SetDim(dim); + MoveAdjust(); +} + +// Adjust both buttons. + +void CScroll::MoveAdjust() +{ + CButton* pc; + FPOINT pos, dim; + + if ( m_dim.y < m_dim.x*2.0f ) // very short lift? + { + delete m_buttonUp; + m_buttonUp = 0; + + delete m_buttonDown; + m_buttonDown = 0; + } + else + { + if ( m_buttonUp == 0 ) + { + m_buttonUp = new CButton(m_iMan); + pc = (CButton*)m_buttonUp; + pc->Create(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), 49, EVENT_NULL); + pc->SetRepeat(TRUE); + m_eventUp = pc->RetEventMsg(); + } + + if ( m_buttonDown == 0 ) + { + m_buttonDown = new CButton(m_iMan); + pc = (CButton*)m_buttonDown; + pc->Create(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), 50, EVENT_NULL); + pc->SetRepeat(TRUE); + m_eventDown = pc->RetEventMsg(); + } + } + + if ( m_buttonUp != 0 ) + { + pos.x = m_pos.x; + pos.y = m_pos.y+m_dim.y-m_dim.x/0.75f; + dim.x = m_dim.x; + dim.y = m_dim.x/0.75f; + m_buttonUp->SetPos(pos); + m_buttonUp->SetDim(dim); + } + + if ( m_buttonDown != 0 ) + { + pos.x = m_pos.x; + pos.y = m_pos.y; + dim.x = m_dim.x; + dim.y = m_dim.x/0.75f; + m_buttonDown->SetPos(pos); + m_buttonDown->SetDim(dim); + } + + AdjustGlint(); +} + +// Adjusts the position of reflection. + +void CScroll::AdjustGlint() +{ + FPOINT ref; + float hButton, h; + + hButton = m_buttonUp?m_dim.x/0.75f:0.0f; + h = m_dim.y-hButton*2.0f; + + ref.x = m_pos.x; + ref.y = m_pos.y+hButton+h*m_visibleRatio+0.003f; + ref.y += h*(1.0f-m_visibleRatio)*(1.0f-m_visibleValue); + + GlintCreate(ref); +} + + + +BOOL CScroll::SetState(int state, BOOL bState) +{ + if ( state & STATE_ENABLE ) + { + if ( m_buttonUp != 0 ) m_buttonUp->SetState(state, bState); + if ( m_buttonDown != 0 ) m_buttonDown->SetState(state, bState); + } + + return CControl::SetState(state, bState); +} + +BOOL CScroll::SetState(int state) +{ + if ( state & STATE_ENABLE ) + { + if ( m_buttonUp != 0 ) m_buttonUp->SetState(state); + if ( m_buttonDown != 0 ) m_buttonDown->SetState(state); + } + + return CControl::SetState(state); +} + +BOOL CScroll::ClearState(int state) +{ + if ( state & STATE_ENABLE ) + { + if ( m_buttonUp != 0 ) m_buttonUp->ClearState(state); + if ( m_buttonDown != 0 ) m_buttonDown->ClearState(state); + } + + return CControl::ClearState(state); +} + + +// Management of an event. + +BOOL CScroll::EventProcess(const Event &event) +{ + FPOINT pos, dim; + float hButton, h, value; + + CControl::EventProcess(event); + + if ( m_buttonUp != 0 && !m_bCapture ) + { + if ( !m_buttonUp->EventProcess(event) ) return FALSE; + } + if ( m_buttonDown != 0 && !m_bCapture ) + { + if ( !m_buttonDown->EventProcess(event) ) return FALSE; + } + + if ( event.event == m_eventUp && m_step > 0.0f ) + { + m_visibleValue -= m_step; + if ( m_visibleValue < 0.0f ) m_visibleValue = 0.0f; + AdjustGlint(); + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + } + + if ( event.event == m_eventDown && m_step > 0.0f ) + { + m_visibleValue += m_step; + if ( m_visibleValue > 1.0f ) m_visibleValue = 1.0f; + AdjustGlint(); + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + } + + hButton = m_buttonUp?m_dim.x/0.75f:0.0f; + + if ( event.event == EVENT_LBUTTONDOWN && + (m_state & STATE_VISIBLE) && + (m_state & STATE_ENABLE) ) + { + if ( CControl::Detect(event.pos) ) + { + pos.y = m_pos.y+hButton; + dim.y = m_dim.y-hButton*2.0f; + pos.y += dim.y*(1.0f-m_visibleRatio)*(1.0f-m_visibleValue); + dim.y *= m_visibleRatio; + if ( event.pos.y < pos.y || + event.pos.y > pos.y+dim.y ) // click outside cabin? + { + h = (m_dim.y-hButton*2.0f)*(1.0f-m_visibleRatio); + value = 1.0f-(event.pos.y-(m_pos.y+hButton+dim.y*0.5f))/h; + if ( value < 0.0f ) value = 0.0f; + if ( value > 1.0f ) value = 1.0f; + m_visibleValue = value; + AdjustGlint(); + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + } + m_bCapture = TRUE; + m_pressPos = event.pos; + m_pressValue = m_visibleValue; + } + } + + if ( event.event == EVENT_MOUSEMOVE && m_bCapture ) + { + h = (m_dim.y-hButton*2.0f)*(1.0f-m_visibleRatio); + if ( h != 0 ) + { + value = m_pressValue - (event.pos.y-m_pressPos.y)/h; + if ( value < 0.0f ) value = 0.0f; + if ( value > 1.0f ) value = 1.0f; + + if ( value != m_visibleValue ) + { + m_visibleValue = value; + AdjustGlint(); + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + } + } + } + + if ( event.event == EVENT_LBUTTONUP && m_bCapture ) + { + m_bCapture = FALSE; + } + + if ( event.event == EVENT_KEYDOWN && + event.param == VK_WHEELUP && + Detect(event.pos) && + m_buttonUp != 0 ) + { + Event newEvent = event; + newEvent.event = m_buttonUp->RetEventMsg(); + m_event->AddEvent(newEvent); + } + if ( event.event == EVENT_KEYDOWN && + event.param == VK_WHEELDOWN && + Detect(event.pos) && + m_buttonDown != 0 ) + { + Event newEvent = event; + newEvent.event = m_buttonDown->RetEventMsg(); + m_event->AddEvent(newEvent); + } + + return TRUE; +} + + +// Draws the button. + +void CScroll::Draw() +{ + FPOINT pos, dim, ppos, ddim; + float hButton; + int icon, n, i; + + hButton = m_buttonUp?m_dim.x/0.75f:0.0f; + + // Draws the bottom. + pos.x = m_pos.x; + pos.y = m_pos.y+hButton; + dim.x = m_dim.x; + dim.y = m_dim.y-hButton*2.0f; + if ( m_state & STATE_ENABLE ) icon = 0; + else icon = 1; + DrawVertex(pos, dim, icon); + + // Draws the cabin. + if ( m_visibleRatio < 1.0f && (m_state & STATE_ENABLE) ) + { + pos.x += 0.003f; // ch'tite(?) margin + pos.y += 0.003f; + dim.x -= 0.006f; + dim.y -= 0.006f; + pos.y += dim.y*(1.0f-m_visibleRatio)*(1.0f-m_visibleValue); + dim.y *= m_visibleRatio; + DrawVertex(pos, dim, 2); + + n = (int)(dim.y*0.8f/0.012f); + if ( n < 1 ) n = 1; + if ( n > 5 ) n = 5; + + ppos.x = pos.x+0.003f; + ppos.y = pos.y+(dim.y-(n-1)*0.012f-0.008f)/2.0f; + ddim.x = dim.x-0.006f; + ddim.y = 0.008f; + for ( i=0 ; iDraw(); + } + if ( m_buttonDown != 0 ) + { + m_buttonDown->Draw(); + } +} + +// Draws a rectangle. + +void CScroll::DrawVertex(FPOINT pos, FPOINT dim, int icon) +{ + FPOINT uv1, uv2; + float ex, dp; + + if ( icon == 0 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 0.0f/256.0f; // yellow rectangle + uv1.y = 32.0f/256.0f; + uv2.x = 32.0f/256.0f; + uv2.y = 64.0f/256.0f; + ex = 8.0f/256.0f; + } + else if ( icon == 1 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 128.0f/256.0f; // gray rectangle + uv1.y = 32.0f/256.0f; + uv2.x = 160.0f/256.0f; + uv2.y = 64.0f/256.0f; + ex = 8.0f/256.0f; + } + else if ( icon == 2 ) + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 64.0f/256.0f; // blue rectangle + uv1.y = 0.0f/256.0f; + uv2.x = 96.0f/256.0f; + uv2.y = 32.0f/256.0f; + ex = 8.0f/256.0f; + } + else + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 104.0f/256.0f; // blue line - + uv1.y = 32.0f/256.0f; + uv2.x = 128.0f/256.0f; + uv2.y = 40.0f/256.0f; + ex = 0.0f; + } + + dp = 0.5f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + DrawIcon(pos, dim, uv1, uv2, ex); +} + + +void CScroll::SetVisibleValue(float value) +{ + if ( value < 0.0 ) value = 0.0f; + if ( value > 1.0 ) value = 1.0f; + m_visibleValue = value; + AdjustGlint(); +} + +float CScroll::RetVisibleValue() +{ + return m_visibleValue; +} + + +void CScroll::SetVisibleRatio(float value) +{ + if ( value < 0.1 ) value = 0.1f; + if ( value > 1.0 ) value = 1.0f; + m_visibleRatio = value; + AdjustGlint(); +} + +float CScroll::RetVisibleRatio() +{ + return m_visibleRatio; +} + + +void CScroll::SetArrowStep(float step) +{ + m_step = step; +} + +float CScroll::RetArrowStep() +{ + return m_step; +} + diff --git a/src/ui/scroll.h b/src/ui/scroll.h new file mode 100644 index 0000000..6c08a19 --- /dev/null +++ b/src/ui/scroll.h @@ -0,0 +1,84 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// scroll.h + +#ifndef _SCROLL_H_ +#define _SCROLL_H_ + + +#include "control.h" +#include "struct.h" + + +class CD3DEngine; +class CButton; + + +#define SCROLL_WIDTH (15.0f/640.0f) + + + +class CScroll : public CControl +{ +public: + CScroll(CInstanceManager* iMan); + ~CScroll(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + + void SetPos(FPOINT pos); + void SetDim(FPOINT dim); + + BOOL SetState(int state, BOOL bState); + BOOL SetState(int state); + BOOL ClearState(int state); + + BOOL EventProcess(const Event &event); + void Draw(); + + void SetVisibleValue(float value); + float RetVisibleValue(); + + void SetVisibleRatio(float value); + float RetVisibleRatio(); + + void SetArrowStep(float step); + float RetArrowStep(); + +protected: + void MoveAdjust(); + void AdjustGlint(); + void DrawVertex(FPOINT pos, FPOINT dim, int icon); + +protected: + CButton* m_buttonUp; + CButton* m_buttonDown; + + float m_visibleValue; + float m_visibleRatio; + float m_step; + + BOOL m_bCapture; + FPOINT m_pressPos; + float m_pressValue; + + EventMsg m_eventUp; + EventMsg m_eventDown; +}; + + +#endif //_SCROLL_H_ diff --git a/src/ui/shortcut.cpp b/src/ui/shortcut.cpp new file mode 100644 index 0000000..21a6191 --- /dev/null +++ b/src/ui/shortcut.cpp @@ -0,0 +1,243 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// shortcut.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "shortcut.h" + + + + +// Object's constructor. + +CShortcut::CShortcut(CInstanceManager* iMan) : CControl(iMan) +{ + m_time = 0.0f; +} + +// Object's destructor. + +CShortcut::~CShortcut() +{ +} + + +// Creates a new button. + +BOOL CShortcut::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + CControl::Create(pos, dim, icon, eventMsg); + return TRUE; +} + + +// Management of an event. + +BOOL CShortcut::EventProcess(const Event &event) +{ + CControl::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + m_time += event.rTime; + } + + if ( event.event == EVENT_LBUTTONDOWN ) + { + if ( CControl::Detect(event.pos) ) + { + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + return FALSE; + } + } + + return TRUE; +} + + +// Draws the button. + +void CShortcut::Draw() +{ + float zoom; + int icon, mode; + + icon = 0; + zoom = 0.8f; + mode = D3DSTATETTw; + if ( m_state & STATE_HILIGHT ) + { + icon = 4; + zoom = 0.9f; + mode = D3DSTATENORMAL; + } + if ( m_state & STATE_CHECK ) + { + icon = 1; + zoom = 0.8f; + mode = D3DSTATENORMAL; + } + if ( m_state & STATE_PRESS ) + { + icon = 1; + zoom = 1.0f; + mode = D3DSTATENORMAL; + } + if ( m_icon == 6 || m_icon == 7 ) // pause or film? + { + icon = -1; // no bottom + zoom = 1.0f; + } + + m_engine->SetTexture("button3.tga"); + + if ( icon != -1 ) + { + m_engine->SetState(mode); + DrawVertex(icon, 0.95f); + } + + m_engine->SetState(D3DSTATETTb); + DrawVertex(m_icon, zoom); + + if ( m_state & STATE_FRAME ) + { + FPOINT p1, p2, c, uv1, uv2; + float zoom, dp; + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + + zoom = 0.9f+sinf(m_time*8.0f)*0.1f; + + p1.x = m_pos.x; + p1.y = m_pos.y; + p2.x = m_pos.x + m_dim.x; + p2.y = m_pos.y + m_dim.y; + + c.x = (p1.x+p2.x)/2.0f; + c.y = (p1.y+p2.y)/2.0f; // center + + p1.x = (p1.x-c.x)*zoom + c.x; + p1.y = (p1.y-c.y)*zoom + c.y; + p2.x = (p2.x-c.x)*zoom + c.x; + p2.y = (p2.y-c.y)*zoom + c.y; + + p2.x -= p1.x; + p2.y -= p1.y; + + uv1.x = 176.0f/256.0f; + uv1.y = 224.0f/256.0f; + uv2.x = 192.0f/256.0f; + uv2.y = 240.0f/256.0f; + + dp = 0.5f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + DrawIcon(p1, p2, uv1, uv2); + } + + if ( (m_state & STATE_RUN) && Mod(m_time, 0.7f) >= 0.3f ) + { + FPOINT uv1, uv2; + float dp; + + m_engine->SetTexture("button3.tga"); + m_engine->SetState(D3DSTATETTw); + + uv1.x = 160.0f/256.0f; + uv1.y = 0.0f/256.0f; + uv2.x = 192.0f/256.0f; + uv2.y = 32.0f/256.0f; + + dp = 0.5f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + DrawIcon(m_pos, m_dim, uv1, uv2); + } +} + +// Draw the vertex array. + +void CShortcut::DrawVertex(int icon, float zoom) +{ + LPDIRECT3DDEVICE7 device; + D3DVERTEX2 vertex[4]; // 2 triangles + FPOINT p1, p2, c; + D3DVECTOR n; + float u1, u2, v1, v2, dp; + + device = m_engine->RetD3DDevice(); + + p1.x = m_pos.x; + p1.y = m_pos.y; + p2.x = m_pos.x + m_dim.x; + p2.y = m_pos.y + m_dim.y; + + c.x = (p1.x+p2.x)/2.0f; + c.y = (p1.y+p2.y)/2.0f; // center + + p1.x = (p1.x-c.x)*zoom + c.x; + p1.y = (p1.y-c.y)*zoom + c.y; + + p2.x = (p2.x-c.x)*zoom + c.x; + p2.y = (p2.y-c.y)*zoom + c.y; + + u1 = (32.0f/256.0f)*(icon%8); + v1 = (32.0f/256.0f)*(icon/8); // u-v texture + u2 = (32.0f/256.0f)+u1; + v2 = (32.0f/256.0f)+v1; + + dp = 0.5f/256.0f; + u1 += dp; + v1 += dp; + u2 -= dp; + v2 -= dp; + + n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal + + vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2); + vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1); + vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2); + vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1); + + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); +} + diff --git a/src/ui/shortcut.h b/src/ui/shortcut.h new file mode 100644 index 0000000..e76402b --- /dev/null +++ b/src/ui/shortcut.h @@ -0,0 +1,50 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// shortcut.h + +#ifndef _SHORTCUT_H_ +#define _SHORTCUT_H_ + + +#include "control.h" + + +class CD3DEngine; + + + +class CShortcut : public CControl +{ +public: + CShortcut(CInstanceManager* iMan); + ~CShortcut(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + + BOOL EventProcess(const Event &event); + + void Draw(); + +protected: + void DrawVertex(int icon, float zoom); + +protected: + float m_time; +}; + + +#endif //_SHORTCUT_H_ diff --git a/src/ui/slider.cpp b/src/ui/slider.cpp new file mode 100644 index 0000000..95bd3a4 --- /dev/null +++ b/src/ui/slider.cpp @@ -0,0 +1,582 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// slider.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "text.h" +#include "button.h" +#include "slider.h" + + + +#define CURSOR_WIDTH (10.0f/640.0f) +#define HOLE_WIDTH (5.0f/480.0f) + + + + +// Object's constructor. + +CSlider::CSlider(CInstanceManager* iMan) : CControl(iMan) +{ + m_buttonLeft = 0; + m_buttonRight = 0; + + m_min = 0.0f; + m_max = 1.0f; + m_visibleValue = 0.0f; + m_step = 0.0f; + + m_marginButton = 0.0f; + m_bHoriz = FALSE; + + m_eventUp = EVENT_NULL; + m_eventDown = EVENT_NULL; + + m_bCapture = FALSE; +} + +// Object's destructor. + +CSlider::~CSlider() +{ + delete m_buttonLeft; + delete m_buttonRight; +} + + +// Creates a new button. + +BOOL CSlider::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + CControl::Create(pos, dim, icon, eventMsg); + + MoveAdjust(); + return TRUE; +} + + +void CSlider::SetPos(FPOINT pos) +{ + CControl::SetPos(pos); + MoveAdjust(); +} + +void CSlider::SetDim(FPOINT dim) +{ + CControl::SetDim(dim); + MoveAdjust(); +} + +void CSlider::MoveAdjust() +{ + FPOINT pos, dim; + + m_bHoriz = ( m_dim.x > m_dim.y ); + + if ( ( m_bHoriz && m_dim.x < m_dim.y*4.0f) || + (!m_bHoriz && m_dim.y < m_dim.x*4.0f) ) // very short slider? + { + delete m_buttonLeft; + m_buttonLeft = 0; + + delete m_buttonRight; + m_buttonRight = 0; + + m_marginButton = 0.0f; + } + else + { +#if 1 + if ( m_buttonLeft == 0 ) + { + m_buttonLeft = new CButton(m_iMan); + m_buttonLeft->Create(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), m_bHoriz?55:49, EVENT_NULL); // SetRepeat(TRUE); + if ( m_state & STATE_SHADOW ) m_buttonLeft->SetState(STATE_SHADOW); + m_eventUp = m_buttonLeft->RetEventMsg(); + } + + if ( m_buttonRight == 0 ) + { + m_buttonRight = new CButton(m_iMan); + m_buttonRight->Create(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), m_bHoriz?48:50, EVENT_NULL); // >/v + m_buttonRight->SetRepeat(TRUE); + if ( m_state & STATE_SHADOW ) m_buttonRight->SetState(STATE_SHADOW); + m_eventDown = m_buttonRight->RetEventMsg(); + } + + m_marginButton = m_bHoriz?(m_dim.y*0.75f):(m_dim.x/0.75f); +#endif + } + + if ( m_buttonLeft != 0 ) + { + if ( m_bHoriz ) + { + pos.x = m_pos.x; + pos.y = m_pos.y; + dim.x = m_dim.y*0.75f; + dim.y = m_dim.y; + } + else + { + pos.x = m_pos.x; + pos.y = m_pos.y+m_dim.y-m_dim.x/0.75f; + dim.x = m_dim.x; + dim.y = m_dim.x/0.75f; + } + m_buttonLeft->SetPos(pos); + m_buttonLeft->SetDim(dim); + } + + if ( m_buttonRight != 0 ) + { + if ( m_bHoriz ) + { + pos.x = m_pos.x+m_dim.x-m_dim.y*0.75f; + pos.y = m_pos.y; + dim.x = m_dim.y*0.75f; + dim.y = m_dim.y; + } + else + { + pos.x = m_pos.x; + pos.y = m_pos.y; + dim.x = m_dim.x; + dim.y = m_dim.x/0.75f; + } + m_buttonRight->SetPos(pos); + m_buttonRight->SetDim(dim); + } + + AdjustGlint(); +} + +// Adjusts the position of reflection. + +void CSlider::AdjustGlint() +{ + FPOINT ref; + float w; + + if ( m_bHoriz ) + { + w = m_dim.x-m_marginButton*0.75f; + ref.x = m_pos.x+m_marginButton; + ref.x += (w-CURSOR_WIDTH)*m_visibleValue; + ref.y = m_pos.y+m_dim.y; + } + else + { + w = m_dim.y-m_marginButton*2.0f; + ref.y = m_pos.y+m_marginButton+CURSOR_WIDTH; + ref.y += (w-CURSOR_WIDTH)*m_visibleValue; + ref.x = m_pos.x; + } + + GlintCreate(ref); +} + + +BOOL CSlider::SetState(int state, BOOL bState) +{ + if ( (state & STATE_ENABLE) || + (state & STATE_SHADOW) ) + { + if ( m_buttonLeft != 0 ) m_buttonLeft->SetState(state, bState); + if ( m_buttonRight != 0 ) m_buttonRight->SetState(state, bState); + } + + return CControl::SetState(state, bState); +} + +BOOL CSlider::SetState(int state) +{ + if ( (state & STATE_ENABLE) || + (state & STATE_SHADOW) ) + { + if ( m_buttonLeft != 0 ) m_buttonLeft->SetState(state); + if ( m_buttonRight != 0 ) m_buttonRight->SetState(state); + } + + return CControl::SetState(state); +} + +BOOL CSlider::ClearState(int state) +{ + if ( (state & STATE_ENABLE) || + (state & STATE_SHADOW) ) + { + if ( m_buttonLeft != 0 ) m_buttonLeft->ClearState(state); + if ( m_buttonRight != 0 ) m_buttonRight->ClearState(state); + } + + return CControl::ClearState(state); +} + + +// Management of an event. + +BOOL CSlider::EventProcess(const Event &event) +{ + FPOINT pos, dim; + float value; + + if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; + + CControl::EventProcess(event); + + if ( m_buttonLeft != 0 && !m_bCapture ) + { + if ( !m_buttonLeft->EventProcess(event) ) return FALSE; + } + if ( m_buttonRight != 0 && !m_bCapture ) + { + if ( !m_buttonRight->EventProcess(event) ) return FALSE; + } + + if ( event.event == m_eventUp && m_step > 0.0f ) + { + m_visibleValue -= m_bHoriz?m_step:-m_step; + if ( m_visibleValue < 0.0f ) m_visibleValue = 0.0f; + if ( m_visibleValue > 1.0f ) m_visibleValue = 1.0f; + AdjustGlint(); + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + } + + if ( event.event == m_eventDown && m_step > 0.0f ) + { + m_visibleValue += m_bHoriz?m_step:-m_step; + if ( m_visibleValue < 0.0f ) m_visibleValue = 0.0f; + if ( m_visibleValue > 1.0f ) m_visibleValue = 1.0f; + AdjustGlint(); + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + } + + if ( event.event == EVENT_LBUTTONDOWN && + (m_state & STATE_VISIBLE) && + (m_state & STATE_ENABLE) ) + { + if ( CControl::Detect(event.pos) ) + { + if ( m_bHoriz ) + { + pos.x = m_pos.x+m_marginButton; + dim.x = m_dim.x-m_marginButton*2.0f; + value = (event.pos.x-pos.x-CURSOR_WIDTH/2.0f); + value /= (dim.x-CURSOR_WIDTH); + } + else + { + pos.y = m_pos.y+m_marginButton; + dim.y = m_dim.y-m_marginButton*2.0f; + value = (event.pos.y-pos.y-CURSOR_WIDTH/2.0f); + value /= (dim.y-CURSOR_WIDTH); + } + if ( value < 0.0f ) value = 0.0f; + if ( value > 1.0f ) value = 1.0f; + m_visibleValue = value; + AdjustGlint(); + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + + m_bCapture = TRUE; + m_pressPos = event.pos; + m_pressValue = m_visibleValue; + } + } + + if ( event.event == EVENT_MOUSEMOVE && m_bCapture ) + { + if ( m_bHoriz ) + { + pos.x = m_pos.x+m_marginButton; + dim.x = m_dim.x-m_marginButton*2.0f; + value = (event.pos.x-pos.x-CURSOR_WIDTH/2.0f); + value /= (dim.x-CURSOR_WIDTH); + } + else + { + pos.y = m_pos.y+m_marginButton; + dim.y = m_dim.y-m_marginButton*2.0f; + value = (event.pos.y-pos.y-CURSOR_WIDTH/2.0f); + value /= (dim.y-CURSOR_WIDTH); + } + if ( value < 0.0f ) value = 0.0f; + if ( value > 1.0f ) value = 1.0f; + + if ( value != m_visibleValue ) + { + m_visibleValue = value; + AdjustGlint(); + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + } + } + + if ( event.event == EVENT_LBUTTONUP && m_bCapture ) + { + m_bCapture = FALSE; + } + + if ( event.event == EVENT_KEYDOWN && + event.param == VK_WHEELUP && + Detect(event.pos) && + m_buttonLeft != 0 ) + { + Event newEvent = event; + newEvent.event = m_buttonLeft->RetEventMsg(); + m_event->AddEvent(newEvent); + } + if ( event.event == EVENT_KEYDOWN && + event.param == VK_WHEELDOWN && + Detect(event.pos) && + m_buttonRight != 0 ) + { + Event newEvent = event; + newEvent.event = m_buttonRight->RetEventMsg(); + m_event->AddEvent(newEvent); + } + + return TRUE; +} + + +// Draws button. + +void CSlider::Draw() +{ + FPOINT pos, dim, ppos, ddim, spos; + int icon; + float h; + char text[100]; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + if ( m_buttonLeft != 0 ) + { + m_buttonLeft->Draw(); + } + + if ( m_bHoriz ) + { + pos.x = m_pos.x+m_marginButton; + pos.y = m_pos.y; + dim.x = m_dim.x-m_marginButton*2.0f; + dim.y = m_dim.y; + } + else + { + pos.x = m_pos.x; + pos.y = m_pos.y+m_marginButton; + dim.x = m_dim.x; + dim.y = m_dim.y-m_marginButton*2.0f; + } + + // Draws the bottom. + if ( m_bHoriz ) + { + ppos.x = pos.x + CURSOR_WIDTH/2.0f; + ppos.y = pos.y + (dim.y-HOLE_WIDTH)/2.0f; + ddim.x = dim.x - CURSOR_WIDTH; + ddim.y = HOLE_WIDTH; + } + else + { + ppos.x = pos.x + (dim.x-HOLE_WIDTH*0.75f)/2.0f; + ppos.y = pos.y + CURSOR_WIDTH/2.0f; + ddim.x = HOLE_WIDTH*0.75f; + ddim.y = dim.y - CURSOR_WIDTH; + } + + if ( m_state & STATE_SHADOW ) + { + spos = ppos; + spos.x -= 0.005f*0.75f; + spos.y += 0.005f; + DrawShadow(spos, ddim); + } + + if ( m_state & STATE_ENABLE ) icon = 0; + else icon = 1; + DrawVertex(ppos, ddim, icon); + + // Draws the cabin. + if ( m_state & STATE_ENABLE ) + { + if ( m_bHoriz ) + { + ppos.x = pos.x + (dim.x-CURSOR_WIDTH)*m_visibleValue; + ppos.y = pos.y; + ddim.x = CURSOR_WIDTH; + ddim.y = dim.y; + } + else + { + ppos.x = pos.x; + ppos.y = pos.y + (dim.y-CURSOR_WIDTH)*m_visibleValue; + ddim.x = dim.x; + ddim.y = CURSOR_WIDTH; + } + DrawShadow(ppos, ddim, 0.7f); + DrawVertex(ppos, ddim, 2); + } + + if ( m_buttonRight != 0 ) + { + m_buttonRight->Draw(); + } + + if ( m_bHoriz ) + { + sprintf(text, "%d", (int)(m_min+m_visibleValue*(m_max-m_min))); + h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType); + pos.x = m_pos.x+m_dim.x+(10.0f/640.0f); + pos.y = m_pos.y+(m_dim.y-h)/2.0f; + m_engine->RetText()->DrawText(text, pos, m_dim.x, 1, m_fontSize, m_fontStretch, m_fontType, 0); + } + else + { + if ( m_state & STATE_VALUE ) + { + pos.x = m_pos.x+m_dim.x+4.0f/640.0f; + h = m_dim.y-m_marginButton*2.0f; + pos.y = m_pos.y+m_marginButton-4.0f/480.0f; + pos.y += (h-CURSOR_WIDTH)*m_visibleValue; + dim.x = 50.0f/640.0f; + dim.y = 16.0f/480.0f; + sprintf(text, "%d", (int)(m_min+(m_visibleValue*(m_max-m_min)))); + m_engine->RetText()->DrawText(text, pos, dim.x, 1, m_fontSize, m_fontStretch, m_fontType, 0); + } + } +} + +// Draws a rectangle. + +void CSlider::DrawVertex(FPOINT pos, FPOINT dim, int icon) +{ + FPOINT uv1, uv2, corner; + float ex, dp; + + if ( icon == 0 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 0.0f/256.0f; // yellow rectangle + uv1.y = 32.0f/256.0f; + uv2.x = 32.0f/256.0f; + uv2.y = 64.0f/256.0f; + corner.x = 2.0f/640.0f; + corner.y = 2.0f/480.0f; + ex = 4.0f/256.0f; + } + else if ( icon == 1 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 128.0f/256.0f; // gray rectangle + uv1.y = 32.0f/256.0f; + uv2.x = 160.0f/256.0f; + uv2.y = 64.0f/256.0f; + corner.x = 2.0f/640.0f; + corner.y = 2.0f/480.0f; + ex = 4.0f/256.0f; + } + else + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 224.0f/256.0f; // cursor + uv1.y = 32.0f/256.0f; + uv2.x = 256.0f/256.0f; + uv2.y = 64.0f/256.0f; + if ( !m_bHoriz ) + { + uv1.y += 64.0f/256.0f; + uv2.y += 64.0f/256.0f; + } + corner.x = 2.0f/640.0f; + corner.y = 2.0f/480.0f; + ex = 4.0f/256.0f; + } + + dp = 0.5f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + DrawIcon(pos, dim, uv1, uv2, corner, ex); +} + + +void CSlider::SetLimit(float min, float max) +{ + m_min = min; + m_max = max; +} + +void CSlider::SetVisibleValue(float value) +{ + value = (value-m_min)/(m_max-m_min); + if ( value < 0.0 ) value = 0.0f; + if ( value > 1.0 ) value = 1.0f; + m_visibleValue = value; + AdjustGlint(); +} + +float CSlider::RetVisibleValue() +{ + return m_min+m_visibleValue*(m_max-m_min); +} + + +void CSlider::SetArrowStep(float step) +{ + m_step = step/(m_max-m_min); +} + +float CSlider::RetArrowStep() +{ + return m_step*(m_max-m_min); +} + + diff --git a/src/ui/slider.h b/src/ui/slider.h new file mode 100644 index 0000000..c254254 --- /dev/null +++ b/src/ui/slider.h @@ -0,0 +1,84 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// slider.h + +#ifndef _SLIDER_H_ +#define _SLIDER_H_ + + +#include "control.h" +#include "struct.h" + + +class CD3DEngine; +class CButton; + + + +class CSlider : public CControl +{ +public: + CSlider(CInstanceManager* iMan); + ~CSlider(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + + void SetPos(FPOINT pos); + void SetDim(FPOINT dim); + + BOOL SetState(int state, BOOL bState); + BOOL SetState(int state); + BOOL ClearState(int state); + + BOOL EventProcess(const Event &event); + void Draw(); + + void SetLimit(float min, float max); + + void SetVisibleValue(float value); + float RetVisibleValue(); + + void SetArrowStep(float step); + float RetArrowStep(); + +protected: + void MoveAdjust(); + void AdjustGlint(); + void DrawVertex(FPOINT pos, FPOINT dim, int icon); + +protected: + CButton* m_buttonLeft; + CButton* m_buttonRight; + + float m_min; + float m_max; + float m_visibleValue; + float m_step; + + BOOL m_bHoriz; + float m_marginButton; + + BOOL m_bCapture; + FPOINT m_pressPos; + float m_pressValue; + + EventMsg m_eventUp; + EventMsg m_eventDown; +}; + + +#endif //_SLIDER_H_ diff --git a/src/ui/studio.cpp b/src/ui/studio.cpp new file mode 100644 index 0000000..8839f31 --- /dev/null +++ b/src/ui/studio.cpp @@ -0,0 +1,1667 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// studio.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "d3dmath.h" +#include "language.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "restext.h" +#include "math3d.h" +#include "robotmain.h" +#include "object.h" +#include "camera.h" +#include "sound.h" +#include "script.h" +#include "interface.h" +#include "button.h" +#include "check.h" +#include "slider.h" +#include "edit.h" +#include "list.h" +#include "label.h" +#include "group.h" +#include "window.h" +#include "text.h" +#include "cbottoken.h" +#include "studio.h" + + + + +// Object's constructor. + +CStudio::CStudio(CInstanceManager* iMan) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_STUDIO, this); + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); + m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + + m_bEditMaximized = FALSE; + m_bEditMinimized = FALSE; + + m_time = 0.0f; + m_bRealTime = TRUE; + m_bRunning = FALSE; + m_fixInfoTextTime = 0.0f; + m_helpFilename[0] = 0; + m_dialog = SD_NULL; +} + +// Object's destructor. + +CStudio::~CStudio() +{ + m_iMan->DeleteInstance(CLASS_STUDIO, this); +} + + +// Management of an event. + +BOOL CStudio::EventProcess(const Event &event) +{ + CWindow* pw; + CEdit* edit; + CSlider* slider; + char res[100]; + + if ( m_dialog != SD_NULL ) // dialogue exists? + { + return EventDialog(event); + } + + if ( event.event == EVENT_FRAME ) + { + EventFrame(event); + } + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw == 0 ) return FALSE; + + edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); + if ( edit == 0 ) return FALSE; + + if ( event.event == pw->RetEventMsgClose() ) + { + Event newEvent = event; + newEvent.event = EVENT_STUDIO_OK; + m_event->AddEvent(newEvent); + } + + if ( event.event == EVENT_STUDIO_EDIT ) // text modifief? + { + ColorizeScript(edit); + } + + if ( event.event == EVENT_STUDIO_LIST ) // list clicked? + { + m_main->StartDisplayInfo(m_helpFilename, -1); + } + + if ( event.event == EVENT_STUDIO_NEW ) // new? + { + m_script->New(edit, ""); + } + + if ( event.event == EVENT_STUDIO_OPEN ) // open? + { + StartDialog(SD_OPEN); + } + if ( event.event == EVENT_STUDIO_SAVE ) // save? + { + StartDialog(SD_SAVE); + } + + if ( event.event == EVENT_STUDIO_UNDO ) // undo? + { + edit->Undo(); + } + if ( event.event == EVENT_STUDIO_CUT ) // cut? + { + edit->Cut(); + } + if ( event.event == EVENT_STUDIO_COPY ) // copy? + { + edit->Copy(); + } + if ( event.event == EVENT_STUDIO_PASTE ) // paste? + { + edit->Paste(); + } + + if ( event.event == EVENT_STUDIO_SIZE ) // size? + { + slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); + if ( slider == 0 ) return FALSE; + m_main->SetFontSize(9.0f+slider->RetVisibleValue()*6.0f); + ViewEditScript(); + } + + if ( event.event == EVENT_STUDIO_TOOL && // instructions? + m_dialog == SD_NULL ) + { + m_main->StartDisplayInfo(SATCOM_HUSTON, FALSE); + } + if ( event.event == EVENT_STUDIO_HELP && // help? + m_dialog == SD_NULL ) + { + m_main->StartDisplayInfo(SATCOM_PROG, FALSE); + } + + if ( event.event == EVENT_STUDIO_COMPILE ) // compile? + { + char buffer[100]; + + if ( m_script->GetScript(edit) ) // compile + { + GetResource(RES_TEXT, RT_STUDIO_COMPOK, res); + SetInfoText(res, FALSE); + } + else + { + m_script->GetError(buffer); + SetInfoText(buffer, FALSE); + } + } + + if ( event.event == EVENT_STUDIO_RUN ) // run/stop? + { + if ( m_script->IsRunning() ) + { + Event newEvent = event; + newEvent.event = EVENT_OBJECT_PROGSTOP; + m_event->AddEvent(newEvent); // stop + } + else + { + if ( m_script->GetScript(edit) ) // compile + { + SetInfoText("", FALSE); + + Event newEvent = event; + newEvent.event = EVENT_OBJECT_PROGSTART; + m_event->AddEvent(newEvent); // start + } + else + { + char buffer[100]; + m_script->GetError(buffer); + SetInfoText(buffer, FALSE); + } + } + } + + if ( event.event == EVENT_STUDIO_REALTIME ) // real time? + { + m_bRealTime = !m_bRealTime; + m_script->SetStepMode(!m_bRealTime); + UpdateFlux(); + UpdateButtons(); + } + + if ( event.event == EVENT_STUDIO_STEP ) // step? + { + m_script->Step(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { + if ( event.param == m_engine->RetKey(KEYRANK_CBOT, 0) || + event.param == m_engine->RetKey(KEYRANK_CBOT, 1) ) + { + if ( m_helpFilename[0] != 0 ) + { + m_main->StartDisplayInfo(m_helpFilename, -1); + } + } + } + + if ( event.event == EVENT_WINDOW3 ) // window is moved? + { + m_editActualPos = m_editFinalPos = pw->RetPos(); + m_editActualDim = m_editFinalDim = pw->RetDim(); + m_main->SetWindowPos(m_editActualPos); + m_main->SetWindowDim(m_editActualDim); + AdjustEditScript(); + } + if ( event.event == pw->RetEventMsgReduce() ) + { + if ( m_bEditMinimized ) + { + m_editFinalPos = m_main->RetWindowPos(); + m_editFinalDim = m_main->RetWindowDim(); + m_bEditMinimized = FALSE; + m_bEditMaximized = FALSE; + } + else + { + m_editFinalPos.x = 0.00f; + m_editFinalPos.y = -0.44f; + m_editFinalDim.x = 1.00f; + m_editFinalDim.y = 0.50f; + m_bEditMinimized = TRUE; + m_bEditMaximized = FALSE; + } + m_main->SetEditFull(m_bEditMaximized); + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw != 0 ) + { + pw->SetMaximized(m_bEditMaximized); + pw->SetMinimized(m_bEditMinimized); + } + } + if ( event.event == pw->RetEventMsgFull() ) + { + if ( m_bEditMaximized ) + { + m_editFinalPos = m_main->RetWindowPos(); + m_editFinalDim = m_main->RetWindowDim(); + m_bEditMinimized = FALSE; + m_bEditMaximized = FALSE; + } + else + { + m_editFinalPos.x = 0.00f; + m_editFinalPos.y = 0.00f; + m_editFinalDim.x = 1.00f; + m_editFinalDim.y = 1.00f; + m_bEditMinimized = FALSE; + m_bEditMaximized = TRUE; + } + m_main->SetEditFull(m_bEditMaximized); + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw != 0 ) + { + pw->SetMaximized(m_bEditMaximized); + pw->SetMinimized(m_bEditMinimized); + } + } + + return TRUE; +} + + +// Evolves value with time elapsed. + +float Evolution(float final, float actual, float time) +{ + float value; + + value = actual + (final-actual)*time; + + if ( final > actual ) + { + if ( value > final ) value = final; // does not exceed + } + else + { + if ( value < final ) value = final; // does not exceed + } + + return value; +} + +// Makes the studio evolve as time elapsed. + +BOOL CStudio::EventFrame(const Event &event) +{ + CWindow* pw; + CEdit* edit; + CList* list; + float time; + int cursor1, cursor2, iCursor1, iCursor2; + char res[100]; + + m_time += event.rTime; + m_fixInfoTextTime -= event.rTime; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw == 0 ) return FALSE; + + edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); + if ( edit == 0 ) return FALSE; + + list = (CList*)pw->SearchControl(EVENT_STUDIO_LIST); + if ( list == 0 ) return FALSE; + + if ( !m_script->IsRunning() && m_bRunning ) // stop? + { + m_bRunning = FALSE; + UpdateFlux(); // stop + AdjustEditScript(); + GetResource(RES_TEXT, RT_STUDIO_PROGSTOP, res); + SetInfoText(res, FALSE); + + Event newEvent = event; + newEvent.event = EVENT_OBJECT_PROGSTOP; + m_event->AddEvent(newEvent); // stop + } + + if ( m_script->IsRunning() && !m_bRunning ) // starting? + { + m_bRunning = TRUE; + UpdateFlux(); // run + AdjustEditScript(); + } + UpdateButtons(); + + if ( m_bRunning ) + { + m_script->GetCursor(cursor1, cursor2); + edit->GetCursor(iCursor1, iCursor2); + if ( cursor1 != iCursor1 || + cursor2 != iCursor2 ) // cursors change? + { + edit->SetCursor(cursor1, cursor2); // shows it on the execution + edit->ShowSelect(); + } + + m_script->UpdateList(list); // updates the list of variables + } + else + { + SearchToken(edit); + } + + if ( m_editFinalPos.x != m_editActualPos.x || + m_editFinalPos.y != m_editActualPos.y || + m_editFinalDim.x != m_editActualDim.x || + m_editFinalDim.y != m_editActualDim.y ) + { + time = event.rTime*20.0f; + m_editActualPos.x = Evolution(m_editFinalPos.x, m_editActualPos.x, time); + m_editActualPos.y = Evolution(m_editFinalPos.y, m_editActualPos.y, time); + m_editActualDim.x = Evolution(m_editFinalDim.x, m_editActualDim.x, time); + m_editActualDim.y = Evolution(m_editFinalDim.y, m_editActualDim.y, time); + AdjustEditScript(); + } + + return TRUE; +} + + +// Indicates whether a character is part of a word. + +BOOL IsToken(int character) +{ + char c; + + c = tolower(RetNoAccent(character)); + + return ( (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || + c == '_' ); +} + +// Seeks if the cursor is on a keyword. + +void CStudio::SearchToken(CEdit* edit) +{ + ObjectType type; + int len, cursor1, cursor2, i, character, level; + char* text; + char token[100]; + + text = edit->RetText(); + len = edit->RetTextLength(); + edit->GetCursor(cursor1, cursor2); + + i = cursor1; + if ( i > 0 ) + { + character = (unsigned char)text[i-1]; + if ( !IsToken(character) ) + { + level = 1; + while ( i > 0 ) + { + character = (unsigned char)text[i-1]; + if ( character == ')' ) + { + level ++; + } + else if ( character == '(' ) + { + level --; + if ( level == 0 ) break; + } + i --; + } + if ( level > 0 ) + { + m_helpFilename[0] = 0; + SetInfoText("", TRUE); + return; + } + while ( i > 0 ) + { + character = (unsigned char)text[i-1]; + if ( IsToken(character) ) break; + i --; + } + } + } + + while ( i > 0 ) + { + character = (unsigned char)text[i-1]; + if ( !IsToken(character) ) break; + i --; + } + cursor2 = i; + + while ( i < len ) + { + character = (unsigned char)text[i]; + if ( !IsToken(character) ) break; + i ++; + } + cursor1 = i; + len = cursor1-cursor2; + + if ( len > 100-1 ) len = 100-1; + for ( i=0 ; iColorizeScript(edit); +} + + +// Starts editing a program. + +void CStudio::StartEditScript(CScript *script, char* name, int rank) +{ + FPOINT pos, dim; + CWindow* pw; + CEdit* edit; + CButton* button; + CSlider* slider; + CList* list; + char res[100]; + + m_script = script; + m_rank = rank; + + m_main->SetEditLock(TRUE, TRUE); + m_main->SetEditFull(FALSE); + m_bInitPause = m_engine->RetPause(); + m_main->SetSpeed(1.0f); + m_editCamera = m_camera->RetType(); + m_camera->SetType(CAMERA_EDIT); + + m_bRunning = m_script->IsRunning(); + m_bRealTime = m_bRunning; + m_script->SetStepMode(!m_bRealTime); + + button = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); + if ( button != 0 ) + { + button->ClearState(STATE_VISIBLE); + } + + pos = m_editFinalPos = m_editActualPos = m_main->RetWindowPos(); + dim = m_editFinalDim = m_editActualDim = m_main->RetWindowDim(); + pw = m_interface->CreateWindows(pos, dim, 8, EVENT_WINDOW3); + if ( pw == 0 ) return; + pw->SetState(STATE_SHADOW); + pw->SetRedim(TRUE); // before SetName! + pw->SetMovable(TRUE); + pw->SetClosable(TRUE); + GetResource(RES_TEXT, RT_STUDIO_TITLE, res); + pw->SetName(res); + pw->SetMinDim(FPOINT(0.49f, 0.50f)); + pw->SetMaximized(m_bEditMaximized); + pw->SetMinimized(m_bEditMinimized); + m_main->SetEditFull(m_bEditMaximized); + + edit = pw->CreateEdit(pos, dim, 0, EVENT_STUDIO_EDIT); + if ( edit == 0 ) return; + edit->SetState(STATE_SHADOW); + edit->SetInsideScroll(FALSE); +//? if ( m_bRunning ) edit->SetEdit(FALSE); + edit->SetMaxChar(EDITSTUDIOMAX); + edit->SetFontType(FONT_COURIER); + edit->SetFontStretch(0.7f); + edit->SetDisplaySpec(TRUE); + edit->SetAutoIndent(m_engine->RetEditIndentMode()); + m_script->PutScript(edit, name); + ColorizeScript(edit); + + ViewEditScript(); + + list = pw->CreateList(pos, dim, 1, EVENT_STUDIO_LIST, 1.2f); + list->SetState(STATE_SHADOW); + list->SetFontType(FONT_COURIER); + list->SetSelectCap(FALSE); + list->SetFontSize(SMALLFONT*0.85f); +//? list->SetFontStretch(1.0f); + + button = pw->CreateButton(pos, dim, 56, EVENT_STUDIO_NEW); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 57, EVENT_STUDIO_OPEN); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 58, EVENT_STUDIO_SAVE); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 59, EVENT_STUDIO_UNDO); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 60, EVENT_STUDIO_CUT); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 61, EVENT_STUDIO_COPY); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 62, EVENT_STUDIO_PASTE); + button->SetState(STATE_SHADOW); + slider = pw->CreateSlider(pos, dim, 0, EVENT_STUDIO_SIZE); + slider->SetState(STATE_SHADOW); + slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f); + pw->CreateGroup(pos, dim, 19, EVENT_LABEL1); // SatCom logo + button = pw->CreateButton(pos, dim, 128+57, EVENT_STUDIO_TOOL); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 128+60, EVENT_STUDIO_HELP); + button->SetState(STATE_SHADOW); + + button = pw->CreateButton(pos, dim, -1, EVENT_STUDIO_OK); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, -1, EVENT_STUDIO_CANCEL); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 64+23, EVENT_STUDIO_COMPILE); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 21, EVENT_STUDIO_RUN); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 64+22, EVENT_STUDIO_REALTIME); + button->SetState(STATE_SHADOW); + button = pw->CreateButton(pos, dim, 64+29, EVENT_STUDIO_STEP); + button->SetState(STATE_SHADOW); + + UpdateFlux(); + UpdateButtons(); + AdjustEditScript(); +} + +// Repositions all the editing controls. + +void CStudio::AdjustEditScript() +{ + CWindow* pw; + CEdit* edit; + CButton* button; + CGroup* group; + CSlider* slider; + CList* list; + FPOINT wpos, wdim, pos, dim, ppos, ddim; + float hList; + + wpos = m_editActualPos; + wdim = m_editActualDim; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw != 0 ) + { + pw->SetPos(wpos); + pw->SetDim(wdim); + wdim = pw->RetDim(); + } + + if ( m_bRunning ) hList = 80.0f/480.0f; + else hList = 20.0f/480.0f; + + pos.x = wpos.x+0.01f; + pos.y = wpos.y+0.09f+hList; + dim.x = wdim.x-0.02f; + dim.y = wdim.y-0.22f-hList; + edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); + if ( edit != 0 ) + { + edit->SetPos(pos); + edit->SetDim(dim); + } + + pos.x = wpos.x+0.01f; + pos.y = wpos.y+0.09f; + dim.x = wdim.x-0.02f; + dim.y = hList; + list = (CList*)pw->SearchControl(EVENT_STUDIO_LIST); + if ( list != 0 ) + { + list->SetPos(pos); + list->SetDim(dim); + } + + dim.x = 0.04f; + dim.y = 0.04f*1.5f; + dim.y = 25.0f/480.0f; + + pos.y = wpos.y+wdim.y-dim.y-0.06f; + pos.x = wpos.x+0.01f; + button = (CButton*)pw->SearchControl(EVENT_STUDIO_NEW); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x = wpos.x+0.05f; + button = (CButton*)pw->SearchControl(EVENT_STUDIO_OPEN); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x = wpos.x+0.09f; + button = (CButton*)pw->SearchControl(EVENT_STUDIO_SAVE); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x = wpos.x+0.14f; + button = (CButton*)pw->SearchControl(EVENT_STUDIO_UNDO); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x = wpos.x+0.19f; + button = (CButton*)pw->SearchControl(EVENT_STUDIO_CUT); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x = wpos.x+0.23f; + button = (CButton*)pw->SearchControl(EVENT_STUDIO_COPY); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x = wpos.x+0.27f; + button = (CButton*)pw->SearchControl(EVENT_STUDIO_PASTE); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x = wpos.x+0.32f; + slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE); + if ( slider != 0 ) + { + ppos = pos; + ddim.x = dim.x*0.7f; + ddim.y = dim.y; + ppos.y -= 3.0f/480.0f; + ddim.y += 6.0f/480.0f; + slider->SetPos(ppos); + slider->SetDim(ddim); + } + pos.x = wpos.x+0.36f; + group = (CGroup*)pw->SearchControl(EVENT_LABEL1); + if ( group != 0 ) + { + group->SetPos(pos); + group->SetDim(dim); + } + pos.x = wpos.x+0.40f; + button = (CButton*)pw->SearchControl(EVENT_STUDIO_TOOL); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x = wpos.x+0.44f; + button = (CButton*)pw->SearchControl(EVENT_STUDIO_HELP); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + + pos.y = wpos.y+0.02f; + pos.x = wpos.x+0.01f; + dim.x = 80.0f/640.0f; + dim.y = 25.0f/480.0f; + button = (CButton*)pw->SearchControl(EVENT_STUDIO_OK); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x = wpos.x+0.14f; + button = (CButton*)pw->SearchControl(EVENT_STUDIO_CANCEL); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x = wpos.x+0.28f; + dim.x = dim.y*0.75f; + button = (CButton*)pw->SearchControl(EVENT_STUDIO_COMPILE); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x = wpos.x+0.28f+dim.x*1; + button = (CButton*)pw->SearchControl(EVENT_STUDIO_RUN); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x = wpos.x+0.28f+dim.x*2; + button = (CButton*)pw->SearchControl(EVENT_STUDIO_REALTIME); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } + pos.x = wpos.x+0.28f+dim.x*3; + button = (CButton*)pw->SearchControl(EVENT_STUDIO_STEP); + if ( button != 0 ) + { + button->SetPos(pos); + button->SetDim(dim); + } +} + +// Ends edition of a program. + +BOOL CStudio::StopEditScript(BOOL bCancel) +{ + CWindow* pw; + CEdit* edit; + CButton* button; + char buffer[100]; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw == 0 ) return FALSE; + + if ( !bCancel && !m_script->IsRunning() ) + { + edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); + if ( edit != 0 ) + { + if ( !m_script->GetScript(edit) ) // compile + { + m_script->GetError(buffer); + SetInfoText(buffer, FALSE); + return FALSE; + } + } + } + m_script->SetStepMode(FALSE); + + m_interface->DeleteControl(EVENT_WINDOW3); + + button = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); + if ( button != 0 ) + { + button->SetState(STATE_VISIBLE); + } + + if ( !m_bInitPause ) m_engine->SetPause(FALSE); + m_sound->MuteAll(FALSE); + m_main->SetEditLock(FALSE, TRUE); + m_camera->SetType(m_editCamera); + return TRUE; +} + +// Specifies the message to display. +// The messages are not clickable 8 seconds, +// even if a message was clickable poster before. + +void CStudio::SetInfoText(char *text, BOOL bClickable) +{ + CWindow* pw; + CList* list; + char res[100]; + + if ( bClickable && m_fixInfoTextTime > 0.0f ) return; + if ( !bClickable ) m_fixInfoTextTime = 8.0f; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw == 0 ) return; + + list = (CList*)pw->SearchControl(EVENT_STUDIO_LIST); + if ( list == 0 ) return; + + list->Flush(); // just text + list->SetName(0, text); + + if ( text[0] == 0 ) bClickable = FALSE; + list->SetSelectCap(bClickable); + + if ( bClickable ) + { + GetResource(RES_TEXT, RT_STUDIO_LISTTT, res); + list->SetTooltip(res); + list->SetState(STATE_ENABLE); + } + else + { + list->SetTooltip(""); +//? list->ClearState(STATE_ENABLE); + list->SetState(STATE_ENABLE, text[0] != 0); + } +} + + +// Changing the size of a editing program. + +void CStudio::ViewEditScript() +{ + CWindow* pw; + CEdit* edit; + POINT dim; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw == 0 ) return; + + edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); + if ( edit == 0 ) return; + + dim = m_engine->RetDim(); + edit->SetFontSize(m_main->RetFontSize()/(dim.x/640.0f)); +} + + +// Updates the operating mode. + +void CStudio::UpdateFlux() +{ + if ( m_bRunning ) + { +#if 1 + if ( m_bRealTime ) // run? + { + m_engine->SetPause(FALSE); + m_sound->MuteAll(FALSE); + } + else // step by step? + { + m_engine->SetPause(TRUE); + m_sound->MuteAll(TRUE); + } +#else + m_engine->SetPause(FALSE); + m_sound->MuteAll(FALSE); +#endif + } + else // stop? + { + m_engine->SetPause(TRUE); + m_sound->MuteAll(TRUE); + } +} + +// Updates the buttons. + +void CStudio::UpdateButtons() +{ + CWindow* pw; + CEdit* edit; + CButton* button; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw == 0 ) return; + + edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); + if ( edit == 0 ) return; + + if ( m_bRunning ) + { + edit->SetIcon(1); // red background + edit->SetEditCap(FALSE); // just to see + edit->SetHiliteCap(TRUE); + } + else + { + edit->SetIcon(0); // standard background + edit->SetEditCap(TRUE); + edit->SetHiliteCap(TRUE); + } + + button = (CButton*)pw->SearchControl(EVENT_STUDIO_COMPILE); + if ( button == 0 ) return; + button->SetState(STATE_ENABLE, !m_bRunning); + + button = (CButton*)pw->SearchControl(EVENT_STUDIO_RUN); + if ( button == 0 ) return; + button->SetIcon(m_bRunning?8:21); // stop/run + + button = (CButton*)pw->SearchControl(EVENT_STUDIO_REALTIME); + if ( button == 0 ) return; + button->SetIcon(m_bRealTime?64+22:64+21); + button->SetState(STATE_ENABLE, (!m_bRunning || !m_script->IsContinue())); + + button = (CButton*)pw->SearchControl(EVENT_STUDIO_STEP); + if ( button == 0 ) return; + button->SetState(STATE_ENABLE, (m_bRunning && !m_bRealTime && !m_script->IsContinue())); +} + + +// Beginning of the display of a dialogue. + +void CStudio::StartDialog(StudioDialog type) +{ + CWindow* pw; + CButton* pb; + CCheck* pc; + CLabel* pla; + CList* pli; + CEdit* pe; + FPOINT pos, dim; + char name[100]; + + m_dialog = type; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW6); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW7); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW8); + if ( pw != 0 ) pw->ClearState(STATE_ENABLE); + + if ( m_dialog == SD_OPEN || + m_dialog == SD_SAVE ) + { + pos = m_main->RetIOPos(); + dim = m_main->RetIODim(); + } +//? pw = m_interface->CreateWindows(pos, dim, 8, EVENT_WINDOW9); + pw = m_interface->CreateWindows(pos, dim, m_dialog==SD_OPEN?14:13, EVENT_WINDOW9); + pw->SetState(STATE_SHADOW); + pw->SetMovable(TRUE); + pw->SetClosable(TRUE); + pw->SetMinDim(FPOINT(320.0f/640.0f, (121.0f+18.0f*4)/480.0f)); + if ( m_dialog == SD_OPEN ) GetResource(RES_TEXT, RT_IO_OPEN, name); + if ( m_dialog == SD_SAVE ) GetResource(RES_TEXT, RT_IO_SAVE, name); + pw->SetName(name); + + pos = FPOINT(0.0f, 0.0f); + dim = FPOINT(0.0f, 0.0f); + + if ( m_dialog == SD_OPEN || + m_dialog == SD_SAVE ) + { + GetResource(RES_TEXT, RT_IO_LIST, name); + pla = pw->CreateLabel(pos, dim, 0, EVENT_DIALOG_LABEL1, name); + pla->SetJustif(1); + + pli = pw->CreateList(pos, dim, 0, EVENT_DIALOG_LIST); + pli->SetState(STATE_SHADOW); + + GetResource(RES_TEXT, RT_IO_NAME, name); + pla = pw->CreateLabel(pos, dim, 0, EVENT_DIALOG_LABEL2, name); + pla->SetJustif(1); + + pe = pw->CreateEdit(pos, dim, 0, EVENT_DIALOG_EDIT); + pe->SetState(STATE_SHADOW); + if ( m_dialog == SD_SAVE ) + { + pe->SetText(m_script->RetFilename()); + } + + GetResource(RES_TEXT, RT_IO_DIR, name); + pla = pw->CreateLabel(pos, dim, 0, EVENT_DIALOG_LABEL3, name); + pla->SetJustif(1); + + pc = pw->CreateCheck(pos, dim, 0, EVENT_DIALOG_CHECK1); + GetResource(RES_TEXT, RT_IO_PRIVATE, name); + pc->SetName(name); + pc->SetState(STATE_SHADOW); +#if _POLISH + pc->SetFontSize(8.0f); +#endif + + pc = pw->CreateCheck(pos, dim, 0, EVENT_DIALOG_CHECK2); + GetResource(RES_TEXT, RT_IO_PUBLIC, name); + pc->SetName(name); + pc->SetState(STATE_SHADOW); +#if _POLISH + pc->SetFontSize(8.0f); +#endif + + pb = pw->CreateButton(pos, dim, -1, EVENT_DIALOG_OK); + pb->SetState(STATE_SHADOW); + if ( m_dialog == SD_OPEN ) GetResource(RES_TEXT, RT_IO_OPEN, name); + if ( m_dialog == SD_SAVE ) GetResource(RES_TEXT, RT_IO_SAVE, name); + pb->SetName(name); + + pb = pw->CreateButton(pos, dim, -1, EVENT_DIALOG_CANCEL); + pb->SetState(STATE_SHADOW); + GetResource(RES_EVENT, EVENT_DIALOG_CANCEL, name); + pb->SetName(name); + + AdjustDialog(); + UpdateDialogList(); + UpdateDialogPublic(); + UpdateDialogAction(); + + pe->SetCursor(999, 0); // selects all + pe->SetFocus(TRUE); + } + + m_main->SetSatComLock(TRUE); // impossible to use the SatCom +} + +// End of the display of a dialogue. + +void CStudio::StopDialog() +{ + CWindow* pw; + + if ( m_dialog == SD_NULL ) return; + m_dialog = SD_NULL; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW6); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW7); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW8); + if ( pw != 0 ) pw->SetState(STATE_ENABLE); + + m_interface->DeleteControl(EVENT_WINDOW9); + m_main->SetSatComLock(FALSE); // possible to use the SatCom +} + +// Adjust all controls of dialogue after a change in geometry. + +void CStudio::AdjustDialog() +{ + CWindow* pw; + CButton* pb; + CCheck* pc; + CLabel* pla; + CList* pli; + CEdit* pe; + FPOINT wpos, wdim, ppos, ddim; + int nli, nch; + char name[100]; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); + if ( pw == 0 ) return; + + wpos = pw->RetPos(); + wdim = pw->RetDim(); + pw->SetPos(wpos); // to move the buttons on the titlebar + + if ( m_dialog == SD_OPEN || + m_dialog == SD_SAVE ) + { + ppos.x = wpos.x+10.0f/640.0f; + ppos.y = wpos.y+wdim.y-55.0f/480.0f; + ddim.x = wdim.x-20.0f/640.0f; + ddim.y = 20.0f/480.0f; + pla = (CLabel*)pw->SearchControl(EVENT_DIALOG_LABEL1); + if ( pla != 0 ) + { + pla->SetPos(ppos); + pla->SetDim(ddim); + } + + nli = (int)((wdim.y-120.0f/480.0f)/(18.0f/480.0f)); + ddim.y = nli*18.0f/480.0f+9.0f/480.0f; + ppos.y = wpos.y+wdim.y-48.0f/480.0f-ddim.y; + pli = (CList*)pw->SearchControl(EVENT_DIALOG_LIST); + if ( pli != 0 ) + { + pli->SetPos(ppos); + pli->SetDim(ddim); + pli->SetTabs(0, ddim.x-(50.0f+130.0f+16.0f)/640.0f); + pli->SetTabs(1, 50.0f/640.0f, -1); + pli->SetTabs(2, 130.0f/640.0f); +//? pli->ShowSelect(); + } + + ppos.y = wpos.y+30.0f/480.0f; + ddim.x = 50.0f/640.0f; + ddim.y = 20.0f/480.0f; + pla = (CLabel*)pw->SearchControl(EVENT_DIALOG_LABEL2); + if ( pla != 0 ) + { + pla->SetPos(ppos); + pla->SetDim(ddim); + } + + ppos.x += 50.0f/640.0f; + ppos.y = wpos.y+36.0f/480.0f; + ddim.x = wdim.x-170.0f/640.0f; + pe = (CEdit*)pw->SearchControl(EVENT_DIALOG_EDIT); + if ( pe != 0 ) + { + pe->SetPos(ppos); + pe->SetDim(ddim); + + nch = (int)((ddim.x*640.0f-22.0f)/8.0f); + pe->GetText(name, 100); + pe->SetMaxChar(nch); + name[nch] = 0; // truncates the text according to max + pe->SetText(name); + } + + ppos.x = wpos.x+10.0f/640.0f; + ppos.y = wpos.y+5.0f/480.0f; + ddim.x = 50.0f/640.0f; + ddim.y = 16.0f/480.0f; + pla = (CLabel*)pw->SearchControl(EVENT_DIALOG_LABEL3); + if ( pla != 0 ) + { + pla->SetPos(ppos); + pla->SetDim(ddim); + } + + ppos.x += 50.0f/640.0f; + ppos.y = wpos.y+12.0f/480.0f; + ddim.x = 70.0f/640.0f; + pc = (CCheck*)pw->SearchControl(EVENT_DIALOG_CHECK1); + if ( pc != 0 ) + { + pc->SetPos(ppos); + pc->SetDim(ddim); + } + + ppos.x += 80.0f/640.0f; + pc = (CCheck*)pw->SearchControl(EVENT_DIALOG_CHECK2); + if ( pc != 0 ) + { + pc->SetPos(ppos); + pc->SetDim(ddim); + } + + ppos.x = wpos.x+wdim.x-100.0f/640.0f; + ppos.y = wpos.y+34.0f/480.0f; + ddim.x = 90.0f/640.0f; + ddim.y = 23.0f/480.0f; + pb = (CButton*)pw->SearchControl(EVENT_DIALOG_OK); + if ( pb != 0 ) + { + pb->SetPos(ppos); + pb->SetDim(ddim); + } + + ppos.y -= 26.0f/480.0f; + pb = (CButton*)pw->SearchControl(EVENT_DIALOG_CANCEL); + if ( pb != 0 ) + { + pb->SetPos(ppos); + pb->SetDim(ddim); + } + } +} + +// Management of the event of a dialogue. + +BOOL CStudio::EventDialog(const Event &event) +{ + CWindow* pw; + FPOINT wpos, wdim; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); + if ( pw == 0 ) return FALSE; + + if ( event.event == EVENT_WINDOW9 ) // window is moved? + { + wpos = pw->RetPos(); + wdim = pw->RetDim(); + m_main->SetIOPos(wpos); + m_main->SetIODim(wdim); + AdjustDialog(); + } + + if ( m_dialog == SD_OPEN || + m_dialog == SD_SAVE ) + { + if ( event.event == EVENT_DIALOG_LIST ) + { + UpdateChangeList(); + } + if ( event.event == EVENT_DIALOG_EDIT ) + { + UpdateChangeEdit(); + } + + if ( event.event == EVENT_DIALOG_CHECK1 ) // private? + { + m_main->SetIOPublic(FALSE); + UpdateDialogPublic(); + UpdateDialogList(); + } + if ( event.event == EVENT_DIALOG_CHECK2 ) // public? + { + m_main->SetIOPublic(TRUE); + UpdateDialogPublic(); + UpdateDialogList(); + } + } + + if ( event.event == EVENT_DIALOG_OK || + (event.event == EVENT_KEYDOWN && event.param == VK_RETURN) ) + { + if ( m_dialog == SD_OPEN ) + { + if ( !ReadProgram() ) return TRUE; + } + if ( m_dialog == SD_SAVE ) + { + if ( !WriteProgram() ) return TRUE; + } + + StopDialog(); + return TRUE; + } + + if ( event.event == EVENT_DIALOG_CANCEL || + (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) || + event.event == pw->RetEventMsgClose() ) + { + StopDialog(); + return TRUE; + } + + return TRUE; +} + +// Updates the name after a click in the list. + +void CStudio::UpdateChangeList() +{ + CWindow* pw; + CList* pl; + CEdit* pe; + char name[100]; + char* p; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_DIALOG_LIST); + if ( pl == 0 ) return; + pe = (CEdit*)pw->SearchControl(EVENT_DIALOG_EDIT); + if ( pe == 0 ) return; + + strcpy(name, pl->RetName(pl->RetSelect())); + name[pe->RetMaxChar()] = 0; // truncates according lg max editable + p = strchr(name, '\t'); // seeks first tab + if ( p != 0 ) *p = 0; + pe->SetText(name); + pe->SetCursor(999, 0); // selects all + pe->SetFocus(TRUE); + + UpdateDialogAction(); +} + +// Updates the list after a change in name. + +void CStudio::UpdateChangeEdit() +{ + CWindow* pw; + CList* pl; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_DIALOG_LIST); + if ( pl == 0 ) return; + + pl->SetSelect(-1); + + UpdateDialogAction(); +} + +// Updates the action button. + +void CStudio::UpdateDialogAction() +{ + CWindow* pw; + CEdit* pe; + CButton* pb; + char name[100]; + int len, i; + BOOL bError; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); + if ( pw == 0 ) return; + pe = (CEdit*)pw->SearchControl(EVENT_DIALOG_EDIT); + if ( pe == 0 ) return; + pb = (CButton*)pw->SearchControl(EVENT_DIALOG_OK); + if ( pb == 0 ) return; + + pe->GetText(name, 100); + len = strlen(name); + if ( len == 0 ) + { + bError = TRUE; + } + else + { + bError = FALSE; + for ( i=0 ; i' || + name[i] == '"' || + name[i] == '|' || + name[i] == '/' || + name[i] == '\\' ) bError = TRUE; + } + } + + pb->SetState(STATE_ENABLE, !bError); +} + +// Updates the buttons private/public. + +void CStudio::UpdateDialogPublic() +{ + CWindow* pw; + CCheck* pc; + CLabel* pl; + char name[100]; + char dir[_MAX_FNAME]; + char text[_MAX_FNAME+100]; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); + if ( pw == 0 ) return; + + pc = (CCheck*)pw->SearchControl(EVENT_DIALOG_CHECK1); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, !m_main->RetIOPublic()); + } + + pc = (CCheck*)pw->SearchControl(EVENT_DIALOG_CHECK2); + if ( pc != 0 ) + { + pc->SetState(STATE_CHECK, m_main->RetIOPublic()); + } + + pl = (CLabel*)pw->SearchControl(EVENT_DIALOG_LABEL1); + if ( pl != 0 ) + { + GetResource(RES_TEXT, RT_IO_LIST, name); + SearchDirectory(dir, FALSE); + sprintf(text, name, dir); + pl->SetName(text, FALSE); + } +} + +// Fills the list with all programs saved. + +void CStudio::UpdateDialogList() +{ + CWindow* pw; + CList* pl; + long hFile; + struct _finddata_t fileBuffer; + struct _finddata_t* listBuffer; + BOOL bDo; + char dir[_MAX_FNAME]; + char temp[_MAX_FNAME]; + int nbFilenames, i; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); + if ( pw == 0 ) return; + pl = (CList*)pw->SearchControl(EVENT_DIALOG_LIST); + if ( pl == 0 ) return; + pl->Flush(); + + nbFilenames = 0; + listBuffer = (_finddata_t*)malloc(sizeof(_finddata_t)*1000); + + SearchDirectory(dir, FALSE); + strcat(dir, "*"); // list all + hFile = _findfirst(dir, &fileBuffer); + if ( hFile != -1 ) + { + do + { + if ( (fileBuffer.attrib & _A_SUBDIR) == 0 ) + { + listBuffer[nbFilenames++] = fileBuffer; + } + } + while ( _findnext(hFile, &fileBuffer) == 0 && nbFilenames < 1000 ); + } + do // sorts all names: + { + bDo = FALSE; + for ( i=0 ; i 0 ) + { + fileBuffer = listBuffer[i]; // exchange i and i +1 + listBuffer[i] = listBuffer[i+1]; + listBuffer[i+1] = fileBuffer; + bDo = TRUE; + } + } + } + while ( bDo ); + + for ( i=0 ; iSetName(i, temp); + } + + free(listBuffer); +} + +// Constructs the name of the folder or open/save. +// If the folder does not exist, it will be created. + +void CStudio::SearchDirectory(char *dir, BOOL bCreate) +{ + if ( m_main->RetIOPublic() ) + { + sprintf(dir, "%s\\", m_main->RetPublicDir()); + } + else + { + sprintf(dir, "%s\\%s\\Program\\", m_main->RetSavegameDir(), m_main->RetGamerName()); + } + + if ( bCreate ) + { + _mkdir(dir); // if does not exist yet! + } +} + +// Reads a new program. + +BOOL CStudio::ReadProgram() +{ + CWindow* pw; + CEdit* pe; + char filename[100]; + char dir[100]; + char* p; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); + if ( pw == 0 ) return FALSE; + + pe = (CEdit*)pw->SearchControl(EVENT_DIALOG_EDIT); + if ( pe == 0 ) return FALSE; + pe->GetText(filename, 100); + if ( filename[0] == 0 ) return FALSE; + + p = strstr(filename, ".txt"); + if ( p == 0 || p != filename+strlen(filename)-4 ) + { + strcat(filename, ".txt"); + } + SearchDirectory(dir, TRUE); + strcat(dir, filename); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw == 0 ) return FALSE; + pe = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); + if ( pe == 0 ) return FALSE; + + if ( !pe->ReadText(dir) ) return FALSE; + + m_script->SetFilename(filename); + ColorizeScript(pe); + return TRUE; +} + +// Writes the current program. + +BOOL CStudio::WriteProgram() +{ + CWindow* pw; + CEdit* pe; + char filename[100]; + char dir[100]; + char* p; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9); + if ( pw == 0 ) return FALSE; + + pe = (CEdit*)pw->SearchControl(EVENT_DIALOG_EDIT); + if ( pe == 0 ) return FALSE; + pe->GetText(filename, 100); + if ( filename[0] == 0 ) return FALSE; + + p = strstr(filename, ".txt"); + if ( p == 0 || p != filename+strlen(filename)-4 ) + { + strcat(filename, ".txt"); + } + SearchDirectory(dir, TRUE); + strcat(dir, filename); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3); + if ( pw == 0 ) return FALSE; + pe = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT); + if ( pe == 0 ) return FALSE; + + if ( !pe->WriteText(dir) ) return FALSE; + + m_script->SetFilename(filename); + return TRUE; +} + diff --git a/src/ui/studio.h b/src/ui/studio.h new file mode 100644 index 0000000..a19bedd --- /dev/null +++ b/src/ui/studio.h @@ -0,0 +1,117 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// studio.h + +#ifndef _STUDIO_H_ +#define _STUDIO_H_ + + +#include "object.h" +#include "script.h" + + +class CInstanceManager; +class CD3DEngine; +class CEvent; +class CRobotMain; +class CCamera; +class CSound; +class CInterface; +class CScript; +class CList; +class CEdit; + + + +enum StudioDialog +{ + SD_NULL, + SD_OPEN, + SD_SAVE, + SD_FIND, + SD_REPLACE, +}; + + + +class CStudio +{ +public: + CStudio(CInstanceManager* iMan); + ~CStudio(); + + BOOL EventProcess(const Event &event); + + void StartEditScript(CScript *script, char* name, int rank); + BOOL StopEditScript(BOOL bCancel); + +protected: + BOOL EventFrame(const Event &event); + void SearchToken(CEdit* edit); + void ColorizeScript(CEdit* edit); + void AdjustEditScript(); + void SetInfoText(char *text, BOOL bClickable); + void ViewEditScript(); + void UpdateFlux(); + void UpdateButtons(); + + void StartDialog(StudioDialog type); + void StopDialog(); + void AdjustDialog(); + BOOL EventDialog(const Event &event); + void UpdateChangeList(); + void UpdateChangeEdit(); + void UpdateDialogAction(); + void UpdateDialogPublic(); + void UpdateDialogList(); + void SearchDirectory(char *dir, BOOL bCreate); + BOOL ReadProgram(); + BOOL WriteProgram(); + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CEvent* m_event; + CRobotMain* m_main; + CCamera* m_camera; + CSound* m_sound; + CInterface* m_interface; + + int m_rank; + CScript* m_script; + + BOOL m_bEditMaximized; + BOOL m_bEditMinimized; + + CameraType m_editCamera; + FPOINT m_editActualPos; + FPOINT m_editActualDim; + FPOINT m_editFinalPos; + FPOINT m_editFinalDim; + + float m_time; + float m_fixInfoTextTime; + BOOL m_bRunning; + BOOL m_bRealTime; + BOOL m_bInitPause; + char m_helpFilename[100]; + + StudioDialog m_dialog; +}; + + +#endif //_STUDIO_H_ diff --git a/src/ui/target.cpp b/src/ui/target.cpp new file mode 100644 index 0000000..4a6ae43 --- /dev/null +++ b/src/ui/target.cpp @@ -0,0 +1,285 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// target.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "robotmain.h" +#include "object.h" +#include "restext.h" +#include "target.h" + + + + +// Object's constructor. + +CTarget::CTarget(CInstanceManager* iMan) : CControl(iMan) +{ +} + +// Object's destructor. + +CTarget::~CTarget() +{ +} + + +// Creates a new button. + +BOOL CTarget::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + CControl::Create(pos, dim, icon, eventMsg); + + return TRUE; +} + + +// Management of an event. + +BOOL CTarget::EventProcess(const Event &event) +{ +#if 0 + if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; + if ( m_state & STATE_DEAD ) return TRUE; + + CControl::EventProcess(event); + + if ( event.event == EVENT_MOUSEMOVE ) + { + if ( CControl::Detect(event.pos) ) + { + m_engine->SetMouseType(D3DMOUSETARGET); + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + return FALSE; + } + } + + if ( event.event == EVENT_LBUTTONDOWN && + (m_state & STATE_VISIBLE) && + (m_state & STATE_ENABLE) ) + { + if ( CControl::Detect(event.pos) ) + { + Event newEvent = event; + newEvent.event = EVENT_OBJECT_FIRE; + m_event->AddEvent(newEvent); + return FALSE; + } + } + + return TRUE; +#else + CObject* pObj; + + if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; + if ( m_state & STATE_DEAD ) return TRUE; + + CControl::EventProcess(event); + + if ( event.event == EVENT_MOUSEMOVE ) + { + m_main->SetFriendAim(FALSE); + + if ( CControl::Detect(event.pos) ) + { + pObj = DetectFriendObject(event.pos); + if ( pObj == 0 ) + { + m_engine->SetMouseType(D3DMOUSETARGET); + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + return FALSE; + } + else + { + m_main->SetFriendAim(TRUE); + m_engine->SetMouseType(D3DMOUSENORM); + } + } + } + + if ( event.event == EVENT_LBUTTONDOWN && + (m_state & STATE_VISIBLE) && + (m_state & STATE_ENABLE) ) + { + if ( CControl::Detect(event.pos) ) + { + if ( !m_main->RetFriendAim() ) + { + Event newEvent = event; + newEvent.event = EVENT_OBJECT_FIRE; + m_event->AddEvent(newEvent); + return FALSE; + } + } + } + + return TRUE; +#endif +} + + +// Draws button. + +void CTarget::Draw() +{ + // It is completely invisible! +} + + +// Returns the tooltip. + +BOOL CTarget::GetTooltip(FPOINT pos, char* name) +{ +#if 0 + if ( (m_state&STATE_VISIBLE) && Detect(pos) ) // in the window? + { + strcpy(name, m_tooltip); + return TRUE; // does not detect objects below! + } + + return FALSE; +#else +//? CObject* pObj; + + if ( (m_state & STATE_VISIBLE) == 0 ) return FALSE; + + if ( (m_state&STATE_VISIBLE) && Detect(pos) ) // in the window? + { +//? pObj = DetectFriendObject(pos); +//? if ( pObj == 0 ) + if ( !m_main->RetFriendAim() ) + { + strcpy(name, m_tooltip); + return TRUE; // does not detect objects below! + } + } + + return FALSE; +#endif +} + + +// Detects the object aimed by the mouse. + +CObject* CTarget::DetectFriendObject(FPOINT pos) +{ + ObjectType type; + CObject *pObj, *pTarget; + int objRank, i, j, rank; + + objRank = m_engine->DetectObject(pos); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetActif() ) continue; + if ( pObj->RetProxyActivate() ) continue; + if ( pObj->RetSelect() ) continue; + + pTarget = 0; + type = pObj->RetType(); + if ( type == OBJECT_DERRICK || + type == OBJECT_FACTORY || + type == OBJECT_REPAIR || + type == OBJECT_DESTROYER || + type == OBJECT_STATION || + type == OBJECT_CONVERT || + type == OBJECT_TOWER || + type == OBJECT_RESEARCH || + type == OBJECT_RADAR || + type == OBJECT_INFO || + type == OBJECT_ENERGY || + type == OBJECT_LABO || + type == OBJECT_NUCLEAR || + type == OBJECT_PARA || + type == OBJECT_SAFE || + type == OBJECT_HUSTON || + type == OBJECT_HUMAN || + type == OBJECT_TECH || + type == OBJECT_TOTO || + type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEft || + type == OBJECT_MOBILEtt || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEit || + type == OBJECT_MOBILEdr ) + { + pTarget = pObj; + } + else if ( (type == OBJECT_POWER || + type == OBJECT_ATOMIC ) && + pObj->RetTruck() != 0 ) // battery used? + { + pTarget = pObj->RetTruck(); + if ( pTarget->RetType() == OBJECT_MOBILEtg ) + { + pTarget = 0; + } + } + + for ( j=0 ; jRetObjectRank(j); + if ( rank == -1 ) continue; + if ( rank != objRank ) continue; + return pTarget; + } + } + return 0; +} + diff --git a/src/ui/target.h b/src/ui/target.h new file mode 100644 index 0000000..632e411 --- /dev/null +++ b/src/ui/target.h @@ -0,0 +1,50 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// target.h + +#ifndef _TARGET_H_ +#define _TARGET_H_ + + +#include "control.h" + + +class CD3DEngine; +class CObject; + + + +class CTarget : public CControl +{ +public: + CTarget(CInstanceManager* iMan); + ~CTarget(); + + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + + BOOL EventProcess(const Event &event); + void Draw(); + BOOL GetTooltip(FPOINT pos, char* name); + +protected: + CObject* DetectFriendObject(FPOINT pos); + +protected: +}; + + +#endif //_TARGET_H_ diff --git a/src/ui/window.cpp b/src/ui/window.cpp new file mode 100644 index 0000000..c42493a --- /dev/null +++ b/src/ui/window.cpp @@ -0,0 +1,1622 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// window.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "d3dengine.h" +#include "language.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "restext.h" +#include "iman.h" +#include "button.h" +#include "color.h" +#include "check.h" +#include "key.h" +#include "group.h" +#include "image.h" +#include "label.h" +#include "edit.h" +#include "editvalue.h" +#include "scroll.h" +#include "slider.h" +#include "list.h" +#include "shortcut.h" +#include "map.h" +#include "gauge.h" +#include "compass.h" +#include "target.h" +#include "text.h" +#include "window.h" + + + + +// Object's constructor. + +CWindow::CWindow(CInstanceManager* iMan) : CControl(iMan) +{ + int i; + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new button. + +CColor* CWindow::CreateColor(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CColor* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new button. + +CCheck* CWindow::CreateCheck(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CCheck* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new button. + +CKey* CWindow::CreateKey(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CKey* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new button. + +CGroup* CWindow::CreateGroup(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CGroup* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new button. + +CImage* CWindow::CreateImage(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CImage* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new label. + +CLabel* CWindow::CreateLabel(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, + char *name) +{ + CLabel* pc; + char* p; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + + p = strchr(name, '\\'); + if ( p == 0 ) + { + pc->SetName(name); + } + else + { + char text[100]; + strncpy(text, name, 100); + text[100-1] = 0; + if ( p-name < 100 ) + { + text[p-name] = 0; // deletes text after "\\" (tooltip) + } + pc->SetName(text); + } + return pc; + } + } + return 0; +} + +// Creates a new editable pave. + +CEdit* CWindow::CreateEdit(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CEdit* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new editable pave. + +CEditValue* CWindow::CreateEditValue(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CEditValue* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new elevator. + +CScroll* CWindow::CreateScroll(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CScroll* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new cursor. + +CSlider* CWindow::CreateSlider(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CSlider* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new list. + +CList* CWindow::CreateList(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, + float expand) +{ + CList* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg, expand); + return pc; + } + } + return 0; +} + +// Creates a new shortcut. + +CShortcut* CWindow::CreateShortcut(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CShortcut* ps; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return ps; + } + } + return 0; +} + +// Creates a new card. + +CMap* CWindow::CreateMap(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CMap* pm; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return pm; + } + } + return 0; +} + +// Creates a new gauge. + +CGauge* CWindow::CreateGauge(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CGauge* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new compass. + +CCompass* CWindow::CreateCompass(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CCompass* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Creates a new target. + +CTarget* CWindow::CreateTarget(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) +{ + CTarget* pc; + int i; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + for ( i=0 ; iCreate(pos, dim, icon, eventMsg); + return pc; + } + } + return 0; +} + +// Removes a control. + +BOOL CWindow::DeleteControl(EventMsg eventMsg) +{ + int i; + + for ( i=0 ; iRetEventMsg() ) + { + delete m_table[i]; + m_table[i] = 0; + return TRUE; + } + } + } + return FALSE; +} + +// Gives a control. + +CControl* CWindow::SearchControl(EventMsg eventMsg) +{ + int i; + + for ( i=0 ; iRetEventMsg() ) + { + return m_table[i]; + } + } + } + return 0; +} + + +// Makes the tooltip binds to the window. + +BOOL CWindow::GetTooltip(FPOINT pos, char* name) +{ + int i; + + for ( i=MAXWINDOW-1 ; i>=0 ; i-- ) + { + if ( m_table[i] != 0 ) + { + if ( m_table[i]->GetTooltip(pos, name) ) + { + return TRUE; + } + } + } + + if ( m_buttonClose != 0 && + m_buttonClose->GetTooltip(pos, name) ) + { + return TRUE; + } + if ( m_buttonFull != 0 && + m_buttonFull->GetTooltip(pos, name) ) + { + return TRUE; + } + if ( m_buttonReduce != 0 && + m_buttonReduce->GetTooltip(pos, name) ) + { + return TRUE; + } + + if ( Detect(pos) ) // in the window? + { + strcpy(name, m_tooltip); + return TRUE; + } + + return FALSE; +} + + +// Specifies the name for the title bar. + +void CWindow::SetName(char* name) +{ + CButton* pc; + BOOL bAdjust; + + CControl::SetName(name); + + if ( m_buttonReduce != 0 ) + { + delete m_buttonReduce; + m_buttonReduce = 0; + } + + if ( m_buttonFull != 0 ) + { + delete m_buttonFull; + m_buttonFull = 0; + } + + if ( m_buttonClose != 0 ) + { + delete m_buttonClose; + m_buttonClose = 0; + } + + bAdjust = FALSE; + + if ( m_name[0] != 0 && m_bRedim ) // title bar exists? + { + m_buttonReduce = new CButton(m_iMan); + pc = (CButton*)m_buttonReduce; + pc->Create(m_pos, m_dim, 0, EVENT_NULL); + + m_buttonFull = new CButton(m_iMan); + pc = (CButton*)m_buttonFull; + pc->Create(m_pos, m_dim, 0, EVENT_NULL); + + bAdjust = TRUE; + } + + if ( m_name[0] != 0 && m_bClosable ) // title bar exists? + { + m_buttonClose = new CButton(m_iMan); + pc = (CButton*)m_buttonClose; + pc->Create(m_pos, m_dim, 0, EVENT_NULL); + + bAdjust = TRUE; + } + + if ( bAdjust ) + { + AdjustButtons(); + } + + MoveAdjust(); +} + + +void CWindow::SetPos(FPOINT pos) +{ + CControl::SetPos(pos); + MoveAdjust(); +} + +void CWindow::SetDim(FPOINT dim) +{ + if ( dim.x < m_minDim.x ) dim.x = m_minDim.x; + if ( dim.x > m_maxDim.x ) dim.x = m_maxDim.x; + if ( dim.y < m_minDim.y ) dim.y = m_minDim.y; + if ( dim.y > m_maxDim.y ) dim.y = m_maxDim.y; + + CControl::SetDim(dim); + MoveAdjust(); +} + +void CWindow::MoveAdjust() +{ + FPOINT pos, dim; + float h, offset; + + h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType); + dim.y = h*1.2f; + dim.x = dim.y*0.75f; + + if ( m_buttonClose != 0 ) + { + pos.x = m_pos.x+m_dim.x-0.01f-dim.x; + pos.y = m_pos.y+m_dim.y-0.01f-h*1.2f; + m_buttonClose->SetPos(pos); + m_buttonClose->SetDim(dim); + offset = dim.x*1.0f; + } + else + { + offset = 0.0f; + } + + if ( m_buttonFull != 0 ) + { + pos.x = m_pos.x+m_dim.x-0.01f-dim.x-offset; + pos.y = m_pos.y+m_dim.y-0.01f-h*1.2f; + m_buttonFull->SetPos(pos); + m_buttonFull->SetDim(dim); + } + + if ( m_buttonReduce != 0 ) + { + pos.x = m_pos.x+m_dim.x-0.01f-dim.x*2.0f-offset; + pos.y = m_pos.y+m_dim.y-0.01f-h*1.2f; + m_buttonReduce->SetPos(pos); + m_buttonReduce->SetDim(dim); + } +} + + +void CWindow::SetMinDim(FPOINT dim) +{ + m_minDim = dim; +} + +void CWindow::SetMaxDim(FPOINT dim) +{ + m_maxDim = dim; +} + +FPOINT CWindow::RetMinDim() +{ + return m_minDim; +} + +FPOINT CWindow::RetMaxDim() +{ + return m_maxDim; +} + + +// Indicates whether the window is moved. + +void CWindow::SetMovable(BOOL bMode) +{ + m_bMovable = bMode; +} + +BOOL CWindow::RetMovable() +{ + return m_bMovable; +} + + +// Management of the presence of minimize/maximize buttons. + +void CWindow::SetRedim(BOOL bMode) +{ + m_bRedim = bMode; +} + +BOOL CWindow::RetRedim() +{ + return m_bRedim; +} + + +// Management of the presence of the close button. + +void CWindow::SetClosable(BOOL bMode) +{ + m_bClosable = bMode; +} + +BOOL CWindow::RetClosable() +{ + return m_bClosable; +} + + +void CWindow::SetMaximized(BOOL bMaxi) +{ + m_bMaximized = bMaxi; + AdjustButtons(); +} + +BOOL CWindow::RetMaximized() +{ + return m_bMaximized; +} + +void CWindow::SetMinimized(BOOL bMini) +{ + m_bMinimized = bMini; + AdjustButtons(); +} + +BOOL CWindow::RetMinimized() +{ + return m_bMinimized; +} + +void CWindow::SetFixed(BOOL bFix) +{ + m_bFixed = bFix; +} + +BOOL CWindow::RetFixed() +{ + return m_bFixed; +} + + +// Adjusts the buttons in the title bar. + +void CWindow::AdjustButtons() +{ + char res[100]; + + if ( m_buttonFull != 0 ) + { + if ( m_bMaximized ) + { + m_buttonFull->SetIcon(54); + GetResource(RES_TEXT, RT_WINDOW_STANDARD, res); + m_buttonFull->SetTooltip(res); + } + else + { + m_buttonFull->SetIcon(52); + GetResource(RES_TEXT, RT_WINDOW_MAXIMIZED, res); + m_buttonFull->SetTooltip(res); + } + } + + if ( m_buttonReduce != 0 ) + { + if ( m_bMinimized ) + { + m_buttonReduce->SetIcon(54); + GetResource(RES_TEXT, RT_WINDOW_STANDARD, res); + m_buttonReduce->SetTooltip(res); + } + else + { + m_buttonReduce->SetIcon(51); + GetResource(RES_TEXT, RT_WINDOW_MINIMIZED, res); + m_buttonReduce->SetTooltip(res); + } + } + + if ( m_buttonClose != 0 ) + { + m_buttonClose->SetIcon(11); // x + GetResource(RES_TEXT, RT_WINDOW_CLOSE, res); + m_buttonClose->SetTooltip(res); + } +} + + +void CWindow::SetTrashEvent(BOOL bTrash) +{ + m_bTrashEvent = bTrash; +} + +BOOL CWindow::RetTrashEvent() +{ + return m_bTrashEvent; +} + + +// Returns the message from the button "reduce". + +EventMsg CWindow::RetEventMsgReduce() +{ + if ( m_buttonReduce == 0 ) return EVENT_NULL; + return m_buttonReduce->RetEventMsg(); +} + +// Returns the message from the button "full". + +EventMsg CWindow::RetEventMsgFull() +{ + if ( m_buttonFull == 0 ) return EVENT_NULL; + return m_buttonFull->RetEventMsg(); +} + +// Returns the message from the button "close". + +EventMsg CWindow::RetEventMsgClose() +{ + if ( m_buttonClose == 0 ) return EVENT_NULL; + return m_buttonClose->RetEventMsg(); +} + + +// Detects whether the mouse is in an edge of the window, to resize it. +// Bit returns: 0 = left, 1 = down, 2 = right, 3 = up, 1 = all. + +int CWindow::BorderDetect(FPOINT pos) +{ + FPOINT dim; + float h; + int flags; + + if ( m_bMaximized || m_bMinimized || m_bFixed ) return 0; + + flags = 0; + if ( pos.x < m_pos.x+0.030f ) + { + flags |= (1<<0); + } + if ( pos.y < m_pos.y+0.020f ) + { + flags |= (1<<1); + } + if ( pos.x > m_pos.x+m_dim.x-0.030f ) + { + flags |= (1<<2); + } + if ( pos.y > m_pos.y+m_dim.y-0.020f ) + { + flags |= (1<<3); + } + + if ( pos.x > m_pos.x+ 0.015f && + pos.x < m_pos.x+m_dim.x-0.015f && + pos.y > m_pos.y+ 0.010f && + pos.y < m_pos.y+m_dim.y-0.010f ) + { + flags = 0; + } + + if ( flags == 0 ) + { + h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType); + dim.y = h*1.2f; + dim.x = dim.y*0.75f; + if ( pos.x < m_pos.x+m_dim.x-0.01f-dim.x*3.0f && + pos.y >= m_pos.y+m_dim.y-0.01f-h*1.2f ) + { + flags = -1; + } + } + + return flags; +} + +// Management of an event. + +BOOL CWindow::EventProcess(const Event &event) +{ + FPOINT pos; + int i, flags; + + if ( event.event == EVENT_MOUSEMOVE ) + { + if ( m_bCapture ) + { + m_engine->SetMouseType(m_pressMouse); + } + else + { + m_pressMouse = D3DMOUSENORM; + + if ( m_name[0] != 0 && m_bMovable && // title bar? + Detect(event.pos) ) + { + flags = BorderDetect(event.pos); + if ( flags == -1 ) + { + m_pressMouse = D3DMOUSEMOVE; // + + } + else if ( ((flags & (1<<0)) && (flags & (1<<3))) || + ((flags & (1<<1)) && (flags & (1<<2))) ) + { + m_pressMouse = D3DMOUSEMOVEI; // \ // + } + else if ( ((flags & (1<<0)) && (flags & (1<<1))) || + ((flags & (1<<2)) && (flags & (1<<3))) ) + { + m_pressMouse = D3DMOUSEMOVED; // / + } + else if ( (flags & (1<<0)) || (flags & (1<<2)) ) + { + m_pressMouse = D3DMOUSEMOVEH; // - + } + else if ( (flags & (1<<1)) || (flags & (1<<3)) ) + { + m_pressMouse = D3DMOUSEMOVEV; // | + } + } + + if ( m_pressMouse != D3DMOUSENORM ) + { + m_engine->SetMouseType(m_pressMouse); + } + } + } + + if ( !m_bCapture ) + { + for ( i=MAXWINDOW-1 ; i>=0 ; i-- ) + { + if ( m_table[i] != 0 ) + { + if ( !m_table[i]->EventProcess(event) ) + { + return FALSE; + } + } + } + + if ( m_buttonReduce != 0 ) + { + m_buttonReduce->EventProcess(event); + } + if ( m_buttonFull != 0 ) + { + m_buttonFull->EventProcess(event); + } + if ( m_buttonClose != 0 ) + { + m_buttonClose->EventProcess(event); + } + } + + if ( m_bTrashEvent && event.event == EVENT_LBUTTONDOWN ) + { + if ( Detect(event.pos) ) + { + if ( m_name[0] != 0 && m_bMovable ) // title bar? + { + m_pressFlags = BorderDetect(event.pos); + if ( m_pressFlags != 0 ) + { + m_bCapture = TRUE; + m_pressPos = event.pos; + } + } + return FALSE; + } + } + + if ( event.event == EVENT_MOUSEMOVE && m_bCapture ) + { + pos = event.pos; + if ( m_pressFlags == -1 ) // all moves? + { + m_pos.x += pos.x-m_pressPos.x; + m_pos.y += pos.y-m_pressPos.y; + } + else + { + if ( m_pressFlags & (1<<0) ) // left edge? + { + if ( pos.x > m_pressPos.x+m_dim.x-m_minDim.x ) + { + pos.x = m_pressPos.x+m_dim.x-m_minDim.x; + } + m_pos.x += pos.x-m_pressPos.x; + m_dim.x -= pos.x-m_pressPos.x; + } + if ( m_pressFlags & (1<<1) ) // bottom edge? + { + if ( pos.y > m_pressPos.y+m_dim.y-m_minDim.y ) + { + pos.y = m_pressPos.y+m_dim.y-m_minDim.y; + } + m_pos.y += pos.y-m_pressPos.y; + m_dim.y -= pos.y-m_pressPos.y; + } + if ( m_pressFlags & (1<<2) ) // right edge? + { + if ( pos.x < m_pressPos.x-m_dim.x+m_minDim.x ) + { + pos.x = m_pressPos.x-m_dim.x+m_minDim.x; + } + m_dim.x += pos.x-m_pressPos.x; + } + if ( m_pressFlags & (1<<3) ) // top edge? + { + if ( pos.y < m_pressPos.y-m_dim.y+m_minDim.y ) + { + pos.y = m_pressPos.y-m_dim.y+m_minDim.y; + } + m_dim.y += pos.y-m_pressPos.y; + } + } + m_pressPos = pos; + AdjustButtons(); + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); + } + + if ( event.event == EVENT_LBUTTONUP && m_bCapture ) + { + m_bCapture = FALSE; + } + + return TRUE; +} + + +// Draws the window. + +void CWindow::Draw() +{ + FPOINT pos, dim; + float width, h, sw; + int i; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + if ( m_state & STATE_SHADOW ) + { + DrawShadow(m_pos, m_dim); + } + + DrawVertex(m_pos, m_dim, m_icon); // draws the background + + if ( m_name[0] != 0 ) // title bar? + { + h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType); + + // Draws the shadow under the title bar. + { + FPOINT sPos, sDim; + + pos.x = m_pos.x+0.01f; + dim.x = m_dim.x-0.02f; + pos.y = m_pos.y+m_dim.y-0.01f-h*1.2f; + dim.y = h*1.2f; + DrawShadow(pos, dim); + } + + width = m_dim.x; + if ( m_bRedim ) width -= h*1.2f*0.75f*2.0f; + if ( m_bClosable ) width -= h*1.2f*0.75f; + + pos.x = m_pos.x+0.01f; + dim.x = width-0.02f; + pos.y = m_pos.y+m_dim.y-0.01f-h*1.2f; + dim.y = h*1.2f; + DrawVertex(pos, dim, (m_state&STATE_ENABLE)?2:9); + + sw = m_engine->RetText()->RetStringWidth(m_name, strlen(m_name), m_fontSize, m_fontStretch, m_fontType); + + if ( m_state&STATE_ENABLE ) + { + pos.x = m_pos.x+0.015f; + dim.x = (width-sw-0.06f)/2.0f; + pos.y = m_pos.y+m_dim.y-0.01f-h*1.0f; + dim.y = h*0.8f; + DrawHach(pos, dim); // left hatch + pos.x = m_pos.x+width-dim.x-0.015f; + DrawHach(pos, dim); // right hatch + } + + pos.x = m_pos.x+width/2.0f; + pos.y = m_pos.y+m_dim.y-0.01f-h*1.10f; + m_engine->RetText()->DrawText(m_name, pos, width, 0, m_fontSize, m_fontStretch, m_fontType, 0); + + if ( m_buttonReduce != 0 ) + { + m_buttonReduce->Draw(); + } + + if ( m_buttonFull != 0 ) + { + m_buttonFull->Draw(); + } + + if ( m_buttonClose != 0 ) + { + m_buttonClose->Draw(); + } + } + + for ( i=0 ; iDraw(); + } + } +} + +// Draws a rectangle. + +void CWindow::DrawVertex(FPOINT pos, FPOINT dim, int icon) +{ + FPOINT p1, p2, uv1, uv2, corner; + float dp; + int i; + + dp = 0.5f/256.0f; + + if ( icon == 0 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + uv1.x = 64.0f/256.0f; // dark blue transparent + uv1.y = 64.0f/256.0f; + uv2.x = 128.0f/256.0f; + uv2.y = 128.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 14.0f/640.0f; + corner.y = 14.0f/480.0f; + DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); + } + else if ( icon == 1 ) + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 128.0f/256.0f; // yellow tooltip + uv1.y = 0.0f/256.0f; + uv2.x = 224.0f/256.0f; + uv2.y = 16.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); + } + else if ( icon == 2 ) + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 128.0f/256.0f; // yellow + uv1.y = 16.0f/256.0f; + uv2.x = 224.0f/256.0f; + uv2.y = 32.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); + } + else if ( icon == 3 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 0.0f/256.0f; // transparent blue bar with yellow upper + uv1.y = 64.0f/256.0f; + uv2.x = 64.0f/256.0f; + uv2.y = 128.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); + } + else if ( icon == 4 ) // SatCom ? + { + pos.x -= 50.0f/640.0f; + pos.y -= 30.0f/480.0f; + dim.x += 100.0f/640.0f; + dim.y += 60.0f/480.0f; + + m_engine->SetTexture("human.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 140.0f/256.0f; + uv1.y = 32.0f/256.0f; + uv2.x = 182.0f/256.0f; + uv2.y = 64.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2); // clothing + + pos.x += 20.0f/640.0f; + pos.y -= 10.0f/480.0f; + dim.x -= 20.0f/640.0f; + dim.y += 0.0f/480.0f; + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + uv1.x = 192.0f/256.0f; + uv1.y = 32.0f/256.0f; + uv2.x = 224.0f/256.0f; + uv2.y = 64.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 30.0f/640.0f; + corner.y = 30.0f/480.0f; + DrawIcon(pos, dim, uv1, uv2, corner, 5.0f/256.0f); // shadow + + pos.x += 0.0f/640.0f; + pos.y += 20.0f/480.0f; + dim.x -= 20.0f/640.0f; + dim.y -= 20.0f/480.0f; + + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 64.0f/256.0f; + uv1.y = 0.0f/256.0f; + uv2.x = 96.0f/256.0f; + uv2.y = 32.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 14.0f/640.0f; + corner.y = 14.0f/480.0f; + DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); // outside blue + + pos.x += 20.0f/640.0f; + pos.y += 10.0f/480.0f; + dim.x -= 40.0f/640.0f; + dim.y -= 20.0f/480.0f; + + uv1.x = 96.0f/256.0f; + uv1.y = 0.0f/256.0f; + uv2.x = 128.0f/256.0f; + uv2.y = 32.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 14.0f/640.0f; + corner.y = 14.0f/480.0f; + DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); // inside blue + + pos.x += 10.0f/640.0f; + pos.y += 10.0f/480.0f; + dim.x -= 20.0f/640.0f; + dim.y -= 20.0f/480.0f; + + m_engine->SetTexture("button3.tga"); + uv1.x = 0.0f/256.0f; + uv1.y = 224.0f/256.0f; + uv2.x = 32.0f/256.0f; + uv2.y = 256.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2); // dark blue background + + m_engine->SetTexture("button2.tga"); + uv1.x = 224.0f/256.0f; + uv1.y = 224.0f/256.0f; + uv2.x = 249.0f/256.0f; + uv2.y = 235.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + pos.x = 20.0f/640.0f; + pos.y = 70.0f/480.0f; + dim.x = 25.0f/640.0f; + dim.y = 11.0f/480.0f; + for ( i=0 ; i<5 ; i++ ) + { + DrawIcon(pos, dim, uv1, uv2); // = bottom/left + pos.y += 15.0f/480.0f; + } + pos.y = (480.0f-70.0f-11.0f)/480.0f; + for ( i=0 ; i<5 ; i++ ) + { + DrawIcon(pos, dim, uv1, uv2); // = top/left + pos.y -= 15.0f/480.0f; + } + pos.x = (640.0f-25.0f-20.0f)/640.0f; + pos.y = 70.0f/480.0f; + for ( i=0 ; i<5 ; i++ ) + { + DrawIcon(pos, dim, uv1, uv2); // = bottom/right + pos.y += 15.0f/480.0f; + } + pos.y = (480.0f-70.0f-11.0f)/480.0f; + for ( i=0 ; i<5 ; i++ ) + { + DrawIcon(pos, dim, uv1, uv2); // = top/right + pos.y -= 15.0f/480.0f; + } + + uv1.x = 208.0f/256.0f; + uv1.y = 224.0f/256.0f; + uv2.x = 224.0f/256.0f; + uv2.y = 240.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + dim.x = 10.0f/640.0f; + dim.y = 10.0f/480.0f; + pos.x = 534.0f/640.0f; + pos.y = 430.0f/480.0f; + for ( i=0 ; i<3 ; i++ ) + { + DrawIcon(pos, dim, uv1, uv2); // micro + pos.x += 12.0f/640.0f; + } + pos.x = 528.0f/640.0f; + pos.y -= 12.0f/480.0f; + for ( i=0 ; i<4 ; i++ ) + { + DrawIcon(pos, dim, uv1, uv2); // micro + pos.x += 12.0f/640.0f; + } + pos.x = 534.0f/640.0f; + pos.y -= 12.0f/480.0f; + for ( i=0 ; i<3 ; i++ ) + { + DrawIcon(pos, dim, uv1, uv2); // micro + pos.x += 12.0f/640.0f; + } + } + else if ( icon == 5 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 64.0f/256.0f; // transparent green + uv1.y = 160.0f/256.0f; + uv2.x = 160.0f/256.0f; + uv2.y = 176.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); + } + else if ( icon == 6 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 64.0f/256.0f; // transparent red + uv1.y = 176.0f/256.0f; + uv2.x = 160.0f/256.0f; + uv2.y = 192.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); + } + else if ( icon == 7 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 64.0f/256.0f; // transparent blue + uv1.y = 192.0f/256.0f; + uv2.x = 160.0f/256.0f; + uv2.y = 208.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); + } + else if ( icon == 8 ) + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 0.0f/256.0f; // opaque orange + uv1.y = 0.0f/256.0f; + uv2.x = 32.0f/256.0f; + uv2.y = 32.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 14.0f/640.0f; + corner.y = 14.0f/480.0f; + DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); + } + else if ( icon == 9 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 32.0f/256.0f; // opaque gray + uv1.y = 32.0f/256.0f; + uv2.x = 64.0f/256.0f; + uv2.y = 64.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 14.0f/640.0f; + corner.y = 14.0f/480.0f; + DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); + } + else if ( icon == 10 ) + { + // nothing (in the background image)! + } + else if ( icon == 11 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTb); + uv1.x = 64.0f/256.0f; // transparent yellow + uv1.y = 224.0f/256.0f; + uv2.x = 160.0f/256.0f; + uv2.y = 240.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); + } + else if ( icon == 12 ) + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 128.0f/256.0f; // dirty opaque gray + uv1.y = 128.0f/256.0f; + uv2.x = 160.0f/256.0f; + uv2.y = 160.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 6.0f/640.0f; + corner.y = 6.0f/480.0f; + DrawIcon(pos, dim, uv1, uv2, corner, 5.0f/256.0f); + } + else if ( icon == 13 ) + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 192.0f/256.0f; // dirty opaque blue + uv1.y = 128.0f/256.0f; + uv2.x = 224.0f/256.0f; + uv2.y = 160.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 6.0f/640.0f; + corner.y = 6.0f/480.0f; + DrawIcon(pos, dim, uv1, uv2, corner, 5.0f/256.0f); + } + else if ( icon == 14 ) + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 160.0f/256.0f; // dirty opaque red + uv1.y = 128.0f/256.0f; + uv2.x = 192.0f/256.0f; + uv2.y = 160.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + corner.x = 6.0f/640.0f; + corner.y = 6.0f/480.0f; + DrawIcon(pos, dim, uv1, uv2, corner, 5.0f/256.0f); + } +} + +// Draws hatching. + +void CWindow::DrawHach(FPOINT pos, FPOINT dim) +{ +#if _NEWLOOK +#else + FPOINT ppos, ddim, uv1, uv2; + float dp, max, ndim; + BOOL bStop; + + dp = 0.5f/256.0f; + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 64.0f/256.0f; // hatching + uv1.y = 208.0f/256.0f; + uv2.x = 145.0f/256.0f; + uv2.y = 224.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + max = dim.y*(uv2.x-uv1.x)/(uv2.y-uv1.y); + + ppos = pos; + ddim = dim; + bStop = FALSE; + do + { + ddim.x = max; + if ( ppos.x+ddim.x > pos.x+dim.x ) + { + ndim = pos.x+dim.x-ppos.x; + uv2.x = uv1.x+(uv2.x-uv1.x)*(ndim/ddim.x); + ddim.x = ndim; + bStop = TRUE; + } + DrawIcon(ppos, ddim, uv1, uv2); + + ppos.x += ddim.x; + } + while ( !bStop ); +#endif +} + diff --git a/src/ui/window.h b/src/ui/window.h new file mode 100644 index 0000000..61506d1 --- /dev/null +++ b/src/ui/window.h @@ -0,0 +1,148 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// window.h + +#ifndef _WINDOW_H_ +#define _WINDOW_H_ + + +#include "control.h" + + +class CD3DEngine; +class CButton; +class CColor; +class CCheck; +class CKey; +class CGroup; +class CImage; +class CLabel; +class CEdit; +class CEditValue; +class CScroll; +class CSlider; +class CList; +class CShortcut; +class CMap; +class CGauge; +class CCompass; +class CTarget; + + +#define MAXWINDOW 100 + + +class CWindow : public CControl +{ +public: + CWindow(CInstanceManager* iMan); + ~CWindow(); + + void Flush(); + BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CButton* CreateButton(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CColor* CreateColor(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CCheck* CreateCheck(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CKey* CreateKey(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CGroup* CreateGroup(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CImage* CreateImage(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CLabel* CreateLabel(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, char *name); + CEdit* CreateEdit(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CEditValue* CreateEditValue(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CScroll* CreateScroll(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CSlider* CreateSlider(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CList* CreateList(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, float expand=1.2f); + CShortcut* CreateShortcut(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CMap* CreateMap(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CGauge* CreateGauge(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CCompass* CreateCompass(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + CTarget* CreateTarget(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); + BOOL DeleteControl(EventMsg eventMsg); + CControl* SearchControl(EventMsg eventMsg); + + EventMsg RetEventMsgReduce(); + EventMsg RetEventMsgFull(); + EventMsg RetEventMsgClose(); + + void SetName(char* name); + + void SetTrashEvent(BOOL bTrash); + BOOL RetTrashEvent(); + + void SetPos(FPOINT pos); + void SetDim(FPOINT dim); + + void SetMinDim(FPOINT dim); + void SetMaxDim(FPOINT dim); + FPOINT RetMinDim(); + FPOINT RetMaxDim(); + + void SetMovable(BOOL bMode); + BOOL RetMovable(); + + void SetRedim(BOOL bMode); + BOOL RetRedim(); + + void SetClosable(BOOL bMode); + BOOL RetClosable(); + + void SetMaximized(BOOL bMaxi); + BOOL RetMaximized(); + void SetMinimized(BOOL bMini); + BOOL RetMinimized(); + void SetFixed(BOOL bFix); + BOOL RetFixed(); + + BOOL GetTooltip(FPOINT pos, char* name); + + BOOL EventProcess(const Event &event); + + void Draw(); + +protected: + int BorderDetect(FPOINT pos); + void AdjustButtons(); + void MoveAdjust(); + void DrawVertex(FPOINT pos, FPOINT dim, int icon); + void DrawHach(FPOINT pos, FPOINT dim); + +protected: + CControl* m_table[MAXWINDOW]; + + BOOL m_bTrashEvent; + BOOL m_bMaximized; + BOOL m_bMinimized; + BOOL m_bFixed; + + FPOINT m_minDim; + FPOINT m_maxDim; + + CButton* m_buttonReduce; + CButton* m_buttonFull; + CButton* m_buttonClose; + + BOOL m_bMovable; + BOOL m_bRedim; + BOOL m_bClosable; + BOOL m_bCapture; + FPOINT m_pressPos; + int m_pressFlags; + D3DMouse m_pressMouse; +}; + + +#endif //_WINDOW_H_ diff --git a/src/version.txt b/src/version.txt deleted file mode 100644 index da31287..0000000 --- a/src/version.txt +++ /dev/null @@ -1,108 +0,0 @@ -1.18 (24.01.08) -- Ne vérifie plus la présence des pistes audio. - -1.17 (08.01.08) -- Sound.cpp:InitAudioTrackVolume:mixerGetLineControls ne devrait plus planter - sous Vista, grace à l'abandon de MIXER_GETLINECONTROLSF_ALL. -- CoLoBoT ne joue plus les pistes audio, et le réglage du volume a disparu -- CoLoBoT n'affiche plus Alsyd -- Texte "www.colobot.com" remplacé par "www.ceebot.com" - -1.16 (10.11.03) -- Options: si "accès aux solutions" décoché -> Lancer défi, - éditer programme, Esc, Abandonner: plus de bouton "accès à la solution" - -1.15 (02.09.03) -- EVENT_INTERFACE_KGUP: plus si CeeBot-Teen ! -- EVENT_INTERFACE_KGDOWN: plus si CeeBot-Teen ! -- EVENT_INTERFACE_KACTION: plus si CeeBot-Teen ! -- EVENT_INTERFACE_KVISIT: plus si CeeBot-Teen ! -- EVENT_INTERFACE_KNEXT: plus si CeeBot-Teen ! -- EVENT_INTERFACE_KHUMAN: plus si CeeBot-Teen ! -- EVENT_INTERFACE_KDESEL: plus si CeeBot-Teen ! -- EVENT_INTERFACE_KCBOT: plus si CeeBot-Teen ! - -1.14 (28.07.03) -- Switch -nosetup -> plus de bouton "Options" pendant jeu - -1.8 () -- instruction shield(1, radius) ok avec radius 10..25 -- instruction shield(1, radius) possible si bouclier déjà déployé - -1.8 BETA (05.10.01) -- CBOT: public, static, synchronized, private, protected -- CBOT: strlen, strleft, strright, strmid, strval, strfind, strupper, strlower -- CBOT: file, open, close, writeln, readln, eof, deletefile -- extern/public: aide en cliquant dans la ligne d'info de l'éditeur -- ExchangePost: UpdateList si infos reçues -- ok si lien d'un seul caractère: \l;x\u file; -- colobot.ini: [Setup] DeleteGamer=1 -- colobot.ini: [Directory] files=files -- studio: nb max de caractères: 10000 -> 20000 -- script antt41 (scene904): AlienMother -> AlienQueen -- load: recompilation ok si procédures "public" dans d'autres robots -- si le volume CD est nul, la piste n'est pas du tout jouée -- goto ResearchCenter toujours possible -- meilleure gestion des touches Ctrl et Shift dans l'éditeur -- object.temperature=12 impossible (PR_READ) -- studio: ne plante plus si on tape plus de 100 car. sans espace -- studio: "enregistrer" se rappelle du nom de fichier dans la mission -- studio: Ctrl+A sélectionne tout -- studio: run: si liste < 5 variables -> fond gris - -1.7 (13.09.01) -- object.lifeTime -- object.range Winged* idem si camera OnBoard/Back -- float flatground(center, rmax); -- float abstime(); -- float receive(name, power); -- void send(name, value, power); -- void deleteinfo(name, power); -- bool testinfo(name, power); -- Le cosmonaute peut construire une borne d'information - -1.6 (06.09.01) -- niveaux supplémentaires avec %user% -- fonction "send" plus coloriée -- english help: EnergyPack -> EnergyCell -- english help: energyPack -> energyCell -- english help: FinishArea -> GoalArea - -1.5 (24.08.01) -- first execute: prefered first non-T&L, second T&L -- fondus welcome: D3DSTATETTb/w -> D3DSTATETCb/w - -1.4 (02.08.01) -- n'importe quelle touche/clic passe les écrans welcome1, 2 et 3 -- icône associée au CD dans autorun.inf -- SatCom: icône "Aide à la programmation" présente dans exercices -- welcome: phase "Alsyd" plus longue (8s) -- SaveOneScript quand on quitte le studio par ok, cancel ou run - -1.3 (27.07.01) -- goto BotFactory toujours possible -- documentation errmode(0) -- petites corrections anglaises par MW -- enlever pile pendant recherche ne bloque plus -- si human porte qq chose et vaisseau décole -> ne reste plus sur place -- robot sur vaisseau puis sauvegarder-reprendre -> impossible gravir pentes - -GoldMaster 1.3 /e envoyé à CD PRESS pour 1000x - -1.2 -- bouton de fermeture (en haut à droite) supprimé en mode fenêtré -- suppression du réglage "nice reset" - -1.1 (20.07.01) -- volume du son non nul après installation -- images logo au démarrage du jeu -- image generic != si français ou anglais -- install: nouvelle clé pour uninstall depuis autorun - -GoldMaster 1.1 /f envoyé à Alsyd - -1.0 -- commande "reset" (exercices) tjrs ok (fichier rechargé) -- nom sauvegarde avec date/heure au format anglais -- ScriptName.F et .E - diff --git a/src/water.cpp b/src/water.cpp deleted file mode 100644 index 59963cc..0000000 --- a/src/water.cpp +++ /dev/null @@ -1,835 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// water.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "d3dmath.h" -#include "d3dutil.h" -#include "event.h" -#include "misc.h" -#include "iman.h" -#include "math3d.h" -#include "particule.h" -#include "terrain.h" -#include "object.h" -#include "sound.h" -#include "water.h" - - - - -// Constructor of the terrain. - -CWater::CWater(CInstanceManager* iMan, CD3DEngine* engine) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_WATER, this); - - m_engine = engine; - m_terrain = 0; - m_particule = 0; - m_sound = 0; - - m_type[0] = WATER_NULL; - m_type[1] = WATER_NULL; - m_level = 0.0f; - m_bDraw = TRUE; - m_bLava = FALSE; - m_color = 0xffffffff; - m_subdiv = 4; - m_filename[0] = 0; -} - -// Destructor of the terrain. - -CWater::~CWater() -{ -} - - -BOOL CWater::EventProcess(const Event &event) -{ - if ( event.event == EVENT_FRAME ) - { - return EventFrame(event); - } - - if ( event.event == EVENT_KEYDOWN ) - { -#if 0 - if ( event.param == 'S' ) - { - if ( m_subdiv == 1 ) m_subdiv = 2; - else if ( m_subdiv == 2 ) m_subdiv = 4; - else if ( m_subdiv == 4 ) m_subdiv = 8; - else if ( m_subdiv == 8 ) m_subdiv = 1; - SetLevel(m_level); - } - if ( event.param == 'M' ) - { - SetLevel(m_level+1.0f); - } - if ( event.param == 'D' ) - { - SetLevel(m_level-1.0f); - } - if ( event.param == 'H' ) - { - m_bDraw = !m_bDraw; - } - if ( event.param == 'C' ) - { - if ( m_color == 0xffffffff ) m_color = 0xcccccccc; - else if ( m_color == 0xcccccccc ) m_color = 0x88888888; - else if ( m_color == 0x88888888 ) m_color = 0x44444444; - else if ( m_color == 0x44444444 ) m_color = 0x00000000; - else if ( m_color == 0x00000000 ) m_color = 0xffffffff; - } - if ( event.param == 'Q' ) - { - int i; - i = (m_color>>24); - i += 0x44; - i &= 0xff; - i = (i<<24); - m_color &= 0x00ffffff; - m_color |= i; - } - if ( event.param == 'W' ) - { - int i; - i = (m_color>>16); - i += 0x44; - i &= 0xff; - i = (i<<16); - m_color &= 0xff00ffff; - m_color |= i; - } - if ( event.param == 'E' ) - { - int i; - i = (m_color>>8); - i += 0x44; - i &= 0xff; - i = (i<<8); - m_color &= 0xffff00ff; - m_color |= i; - } - if ( event.param == 'R' ) - { - int i; - i = m_color; - i += 0x44; - i &= 0xff; - m_color &= 0xffffff00; - m_color |= i; - } -#endif - } - return TRUE; -} - -// Makes water evolve. - -BOOL CWater::EventFrame(const Event &event) -{ - if ( m_engine->RetPause() ) return TRUE; - - m_time += event.rTime; - - if ( m_type[0] == WATER_NULL ) return TRUE; - - if ( m_bLava ) - { - LavaFrame(event.rTime); - } - return TRUE; -} - -// Makes evolve the steam jets on the lava. - -void CWater::LavaFrame(float rTime) -{ - D3DVECTOR eye, lookat, dir, perp, pos; - float distance, shift, level; - int i; - - if ( m_particule == 0 ) - { - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - } - - for ( i=0 ; i= 0.1f ) - { - eye = m_engine->RetEyePt(); - lookat = m_engine->RetLookatPt(); - - distance = Rand()*200.0f; - shift = (Rand()-0.5f)*200.0f; - - dir = Normalize(lookat-eye); - pos = eye + dir*distance; - - perp.x = -dir.z; - perp.y = dir.y; - perp.z = dir.x; - pos = pos + perp*shift; - - level = m_terrain->RetFloorLevel(pos, TRUE); - if ( level < m_level ) - { - pos.y = m_level; - - level = Rand(); - if ( level < 0.8f ) - { - if ( VaporCreate(PARTIFIRE, pos, 0.02f+Rand()*0.06f) ) - { - m_lastLava = m_time; - } - } - else if ( level < 0.9f ) - { - if ( VaporCreate(PARTIFLAME, pos, 0.5f+Rand()*3.0f) ) - { - m_lastLava = m_time; - } - } - else - { - if ( VaporCreate(PARTIVAPOR, pos, 0.2f+Rand()*2.0f) ) - { - m_lastLava = m_time; - } - } - } - } -} - -// Removes all the steam jets. - -void CWater::VaporFlush() -{ - int i; - - for ( i=0 ; iPlay(SOUND_BLUP, pos, 1.0f, 1.0f-Rand()*0.5f); - } - if ( m_vapor[i].type == PARTIFLAME ) - { -//? m_sound->Play(SOUND_SWIM, pos, 1.0f, 1.0f-Rand()*0.5f); - } - if ( m_vapor[i].type == PARTIVAPOR ) - { - m_sound->Play(SOUND_PSHHH, pos, 0.3f, 2.0f); - } - - return TRUE; - } - } - return FALSE; -} - -// Makes evolve a steam jet, - -void CWater::VaporFrame(int i, float rTime) -{ - D3DVECTOR pos, speed; - FPOINT dim; - int j; - - m_vapor[i].time += rTime; - - if ( m_sound == 0 ) - { - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - } - - if ( m_vapor[i].time <= m_vapor[i].delay ) - { - if ( m_time-m_vapor[i].last >= m_engine->ParticuleAdapt(0.02f) ) - { - m_vapor[i].last = m_time; - - if ( m_vapor[i].type == PARTIFIRE ) - { - for ( j=0 ; j<10 ; j++ ) - { - pos = m_vapor[i].pos; - pos.x += (Rand()-0.5f)*2.0f; - pos.z += (Rand()-0.5f)*2.0f; - pos.y -= 1.0f; - speed.x = (Rand()-0.5f)*6.0f; - speed.z = (Rand()-0.5f)*6.0f; - speed.y = 8.0f+Rand()*5.0f; - dim.x = Rand()*1.5f+1.5f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIERROR, 2.0f, 10.0f); - } - } - else if ( m_vapor[i].type == PARTIFLAME ) - { - pos = m_vapor[i].pos; - pos.x += (Rand()-0.5f)*8.0f; - pos.z += (Rand()-0.5f)*8.0f; - pos.y -= 2.0f; - speed.x = (Rand()-0.5f)*2.0f; - speed.z = (Rand()-0.5f)*2.0f; - speed.y = 4.0f+Rand()*4.0f; - dim.x = Rand()*2.0f+2.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFLAME); - } - else - { - pos = m_vapor[i].pos; - pos.x += (Rand()-0.5f)*4.0f; - pos.z += (Rand()-0.5f)*4.0f; - pos.y -= 2.0f; - speed.x = (Rand()-0.5f)*2.0f; - speed.z = (Rand()-0.5f)*2.0f; - speed.y = 8.0f+Rand()*8.0f; - dim.x = Rand()*1.0f+1.0f; - dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIVAPOR); - } - } - } - else - { - m_vapor[i].bUsed = FALSE; - } -} - - -// Adjusts the position to normal, to imitate reflections on an expanse of water at rest. - -void CWater::AdjustLevel(D3DVECTOR &pos, D3DVECTOR &norm, - FPOINT &uv1, FPOINT &uv2) -{ -#if 0 - float t1, t2; - - uv1.x = (pos.x+10000.0f)/40.0f; - uv1.y = (pos.z+10000.0f)/40.0f; - - t1 = m_time*1.5f + pos.x*0.1f * pos.z*0.2f; - pos.y += sinf(t1)*m_eddy.y; - - t1 = m_time*0.6f + pos.x*0.1f * pos.z*0.2f; - t2 = m_time*0.7f + pos.x*0.3f * pos.z*0.4f; - pos.x += sinf(t1)*m_eddy.x; - pos.z += sinf(t2)*m_eddy.z; - -//? uv2.x = (pos.x+10000.0f)/40.0f+0.3f; -//? uv2.y = (pos.z+10000.0f)/40.0f+0.4f; - uv2.x = (pos.x+10000.0f)/20.0f; - uv2.y = (pos.z+10000.0f)/20.0f; - - t1 = m_time*0.7f + pos.x*5.5f + pos.z*5.6f; - t2 = m_time*0.8f + pos.x*5.7f + pos.z*5.8f; - norm = D3DVECTOR(sinf(t1)*m_glint, 1.0f, sinf(t2)*m_glint); -#else - float t1, t2; - - t1 = m_time*1.5f + pos.x*0.1f * pos.z*0.2f; - pos.y += sinf(t1)*m_eddy.y; - - t1 = m_time*1.5f; - uv1.x = (pos.x+10000.0f)/40.0f+sinf(t1)*m_eddy.x*0.02f; - uv1.y = (pos.z+10000.0f)/40.0f-cosf(t1)*m_eddy.z*0.02f; - uv2.x = (pos.x+10010.0f)/20.0f+cosf(-t1)*m_eddy.x*0.02f; - uv2.y = (pos.z+10010.0f)/20.0f-sinf(-t1)*m_eddy.z*0.02f; - - t1 = m_time*0.50f + pos.x*2.1f + pos.z*1.1f; - t2 = m_time*0.75f + pos.x*2.0f + pos.z*1.0f; - norm = D3DVECTOR(sinf(t1)*m_glint, 1.0f, sinf(t2)*m_glint); -#endif -} - -// Draw the back surface of the water. -// This surface prevents to see the sky (background) underwater! - -void CWater::DrawBack() -{ - LPDIRECT3DDEVICE7 device; - D3DVERTEX2 vertex[4]; // 2 triangles - D3DMATERIAL7 material; - D3DMATRIX matrix; - D3DVECTOR eye, lookat, n, p, p1, p2; - FPOINT uv1, uv2; - float deep, dist; - - if ( !m_bDraw ) return; - if ( m_type[0] == WATER_NULL ) return; - if ( m_lineUsed == 0 ) return; - - eye = m_engine->RetEyePt(); - lookat = m_engine->RetLookatPt(); - - ZeroMemory( &material, sizeof(D3DMATERIAL7) ); - material.diffuse = m_diffuse; - material.ambient = m_ambient; - m_engine->SetMaterial(material); - - m_engine->SetTexture("", 0); - - device = m_engine->RetD3DDevice(); - device->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE); - device->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); - device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - m_engine->SetState(D3DSTATENORMAL); - - deep = m_engine->RetDeepView(0); - m_engine->SetDeepView(deep*2.0f, 0); - m_engine->SetFocus(m_engine->RetFocus()); - m_engine->UpdateMatProj(); // twice the depth of view - - D3DUtil_SetIdentityMatrix(matrix); - device->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); - - p.x = eye.x; - p.z = eye.z; - dist = Length2d(eye, lookat); - p.x = (lookat.x-eye.x)*deep*1.0f/dist + eye.x; - p.z = (lookat.z-eye.z)*deep*1.0f/dist + eye.z; - - p1.x = (lookat.z-eye.z)*deep*2.0f/dist + p.x; - p1.z = -(lookat.x-eye.x)*deep*2.0f/dist + p.z; - p2.x = -(lookat.z-eye.z)*deep*2.0f/dist + p.x; - p2.z = (lookat.x-eye.x)*deep*2.0f/dist + p.z; - - p1.y = -50.0f; - p2.y = m_level; - - n.x = (lookat.x-eye.x)/dist; - n.z = (lookat.z-eye.z)/dist; - n.y = 0.0f; - - uv1.x = uv1.y = 0.0f; - uv2.x = uv2.y = 0.0f; - - vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, p1.z), n, uv1.x,uv2.y); - vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, p1.z), n, uv1.x,uv1.y); - vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, p2.z), n, uv2.x,uv2.y); - vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, p2.z), n, uv2.x,uv1.y); - - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - m_engine->AddStatisticTriangle(2); - - m_engine->SetDeepView(deep, 0); - m_engine->SetFocus(m_engine->RetFocus()); - m_engine->UpdateMatProj(); // gives the initial depth of view - - device->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE); - device->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE); - device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); -} - -// Draws the flat surface of the water. - -void CWater::DrawSurf() -{ - LPDIRECT3DDEVICE7 device; - D3DVERTEX2* vertex; // triangles - D3DMATERIAL7 material; - D3DMATRIX matrix; - D3DVECTOR eye, lookat, n, pos, p; - FPOINT uv1, uv2; - BOOL bUnder; - DWORD flags; - float deep, size, sizez, radius; - int rankview, i, j, u; - - if ( !m_bDraw ) return; - if ( m_type[0] == WATER_NULL ) return; - if ( m_lineUsed == 0 ) return; - - vertex = (D3DVERTEX2*)malloc(sizeof(D3DVERTEX2)*(m_brick+2)*2); - - eye = m_engine->RetEyePt(); - lookat = m_engine->RetLookatPt(); - - rankview = m_engine->RetRankView(); - bUnder = ( rankview == 1); - - device = m_engine->RetD3DDevice(); -//? device->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); -//? device->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE); -//? device->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); - device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - - D3DUtil_SetIdentityMatrix(matrix); - device->SetTransform(D3DTRANSFORMSTATE_WORLD, &matrix); - - ZeroMemory( &material, sizeof(D3DMATERIAL7) ); - material.diffuse = m_diffuse; - material.ambient = m_ambient; - m_engine->SetMaterial(material); - - m_engine->SetTexture(m_filename, 0); - m_engine->SetTexture(m_filename, 1); - - if ( m_type[rankview] == WATER_TT ) - { - m_engine->SetState(D3DSTATETTb|D3DSTATEDUALw|D3DSTATEWRAP, m_color); - } - if ( m_type[rankview] == WATER_TO ) - { - m_engine->SetState(D3DSTATENORMAL|D3DSTATEDUALw|D3DSTATEWRAP); - } - if ( m_type[rankview] == WATER_CT ) - { - m_engine->SetState(D3DSTATETTb); - } - if ( m_type[rankview] == WATER_CO ) - { - m_engine->SetState(D3DSTATENORMAL); - } - device->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE); - - size = m_size/2.0f; - if ( bUnder ) sizez = -size; - else sizez = size; - - // Draws all the lines. - deep = m_engine->RetDeepView(0)*1.5f; - - for ( i=0 ; i deep+radius ) continue; - device->ComputeSphereVisibility(&p, &radius, 1, 0, &flags); - if ( flags & D3DSTATUS_CLIPINTERSECTIONALL ) continue; - - u = 0; - p.x = pos.x-size; - p.z = pos.z-sizez; - p.y = pos.y; - AdjustLevel(p, n, uv1, uv2); - if ( bUnder ) n.y = -n.y; - vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y); - - p.x = pos.x-size; - p.z = pos.z+sizez; - p.y = pos.y; - AdjustLevel(p, n, uv1, uv2); - if ( bUnder ) n.y = -n.y; - vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y); - - for ( j=0 ; jDrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, u, NULL); - m_engine->AddStatisticTriangle(u-2); - } - - free(vertex); -} - - -// Indicates if there is water in a given position. - -BOOL CWater::RetWater(int x, int y) -{ - D3DVECTOR pos; - float size, offset, level; - int dx, dy; - - x *= m_subdiv; - y *= m_subdiv; - - size = m_size/m_subdiv; - offset = m_brick*m_size/2.0f; - - for ( dy=0 ; dy<=m_subdiv ; dy++ ) - { - for ( dx=0 ; dx<=m_subdiv ; dx++ ) - { - pos.x = (x+dx)*size - offset; - pos.z = (y+dy)*size - offset; - pos.y = 0.0f; - level = m_terrain->RetFloorLevel(pos, TRUE); - if ( level < m_level+m_eddy.y ) return TRUE; - } - } - return FALSE; -} - -// Updates the positions, relative to the ground. - -BOOL CWater::CreateLine(int x, int y, int len) -{ - float offset; - - m_line[m_lineUsed].x = x; - m_line[m_lineUsed].y = y; - m_line[m_lineUsed].len = len; - - offset = m_brick*m_size/2.0f - m_size/2.0f; - - m_line[m_lineUsed].px1 = m_size* m_line[m_lineUsed].x - offset; - m_line[m_lineUsed].px2 = m_size*(m_line[m_lineUsed].x+m_line[m_lineUsed].len) - offset; - m_line[m_lineUsed].pz = m_size* m_line[m_lineUsed].y - offset; - - m_lineUsed ++; - - return ( m_lineUsed < MAXWATERLINE ); -} - -// Creates all expanses of water. - -BOOL CWater::Create(WaterType type1, WaterType type2, const char *filename, - D3DCOLORVALUE diffuse, D3DCOLORVALUE ambient, - float level, float glint, D3DVECTOR eddy) -{ - int x, y, len; - - m_type[0] = type1; - m_type[1] = type2; - m_diffuse = diffuse; - m_ambient = ambient; - m_level = level; - m_glint = glint; - m_eddy = eddy; - m_time = 0.0f; - m_lastLava = 0.0f; - strcpy(m_filename, filename); - - VaporFlush(); - - if ( m_filename[0] != 0 ) - { - m_engine->LoadTexture(m_filename, 0); - m_engine->LoadTexture(m_filename, 1); - } - - if ( m_terrain == 0 ) - { - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - } - m_brick = m_terrain->RetBrick()*m_terrain->RetMosaic(); - m_size = m_terrain->RetSize(); - - m_brick /= m_subdiv; - m_size *= m_subdiv; - - if ( m_type[0] == WATER_NULL ) return TRUE; - - m_lineUsed = 0; - for ( y=0 ; y= 5 ) - { - if ( !CreateLine(x-len+1, y, len) ) return FALSE; - len = 0; - } - } - else // dry? - { - if ( len != 0 ) - { - if ( !CreateLine(x-len, y, len) ) return FALSE; - len = 0; - } - } - } - if ( len != 0 ) - { - if ( !CreateLine(x-len, y, len) ) return FALSE; - } - } - return TRUE; -} - -// Removes all the water. - -void CWater::Flush() -{ - m_type[0] = WATER_NULL; - m_type[1] = WATER_NULL; - m_level = 0.0f; - m_bLava = FALSE; -} - - -// Changes the level of the water. - -BOOL CWater::SetLevel(float level) -{ - m_level = level; - - return Create(m_type[0], m_type[1], m_filename, m_diffuse, m_ambient, - m_level, m_glint, m_eddy); -} - -// Returns the current level of water. - -float CWater::RetLevel() -{ - return m_level; -} - -// Returns the current level of water for a given object. - -float CWater::RetLevel(CObject* object) -{ - ObjectType type; - - type = object->RetType(); - - if ( type == OBJECT_HUMAN || - type == OBJECT_TECH ) - { - return m_level-3.0f; - } - - if ( type == OBJECT_MOBILEfa || - type == OBJECT_MOBILEta || - type == OBJECT_MOBILEwa || - type == OBJECT_MOBILEia || - type == OBJECT_MOBILEfc || - type == OBJECT_MOBILEtc || - type == OBJECT_MOBILEwc || - type == OBJECT_MOBILEic || - type == OBJECT_MOBILEfi || - type == OBJECT_MOBILEti || - type == OBJECT_MOBILEwi || - type == OBJECT_MOBILEii || - type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEts || - type == OBJECT_MOBILEws || - type == OBJECT_MOBILEis || - type == OBJECT_MOBILErt || - type == OBJECT_MOBILErc || - type == OBJECT_MOBILErr || - type == OBJECT_MOBILErs || - type == OBJECT_MOBILEsa || - type == OBJECT_MOBILEtg || - type == OBJECT_MOBILEft || - type == OBJECT_MOBILEtt || - type == OBJECT_MOBILEwt || - type == OBJECT_MOBILEit || - type == OBJECT_MOBILEdr ) - { - return m_level-2.0f; - } - - return m_level; -} - - -// Management of the mode of lava/water. - -void CWater::SetLava(BOOL bLava) -{ - m_bLava = bLava; -} - -BOOL CWater::RetLava() -{ - return m_bLava; -} - - -// Adjusts the eye of the camera, not to be in the water. - -void CWater::AdjustEye(D3DVECTOR &eye) -{ - if ( m_bLava ) - { - if ( eye.y < m_level+2.0f ) - { - eye.y = m_level+2.0f; // never under the lava - } - } - else - { - if ( eye.y >= m_level-2.0f && - eye.y <= m_level+2.0f ) // close to the surface? - { - eye.y = m_level+2.0f; // bam, well above - } - } -} - diff --git a/src/water.h b/src/water.h deleted file mode 100644 index dc9384d..0000000 --- a/src/water.h +++ /dev/null @@ -1,134 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// water.h - -#ifndef _WATER_H_ -#define _WATER_H_ - - -#include "d3dengine.h" -#include "particule.h" - - -class CInstanceManager; -class CTerrain; -class CSound; - - - -#define MAXWATERLINE 500 - -typedef struct -{ - short x, y; // beginning - short len; // length by x - float px1, px2, pz; -} -WaterLine; - - -#define MAXWATVAPOR 10 - -typedef struct -{ - BOOL bUsed; - ParticuleType type; - D3DVECTOR pos; - float delay; - float time; - float last; -} -WaterVapor; - - -enum WaterType -{ - WATER_NULL = 0, // no water - WATER_TT = 1, // transparent texture - WATER_TO = 2, // opaque texture - WATER_CT = 3, // transparent color - WATER_CO = 4, // opaque color -}; - - -class CWater -{ -public: - CWater(CInstanceManager* iMan, CD3DEngine* engine); - ~CWater(); - - void SetD3DDevice(LPDIRECT3DDEVICE7 device); - BOOL EventProcess(const Event &event); - void Flush(); - BOOL Create(WaterType type1, WaterType type2, const char *filename, D3DCOLORVALUE diffuse, D3DCOLORVALUE ambient, float level, float glint, D3DVECTOR eddy); - void DrawBack(); - void DrawSurf(); - - BOOL SetLevel(float level); - float RetLevel(); - float RetLevel(CObject* object); - - void SetLava(BOOL bLava); - BOOL RetLava(); - - void AdjustEye(D3DVECTOR &eye); - -protected: - BOOL EventFrame(const Event &event); - void LavaFrame(float rTime); - void AdjustLevel(D3DVECTOR &pos, D3DVECTOR &norm, FPOINT &uv1, FPOINT &uv2); - BOOL RetWater(int x, int y); - BOOL CreateLine(int x, int y, int len); - - void VaporFlush(); - BOOL VaporCreate(ParticuleType type, D3DVECTOR pos, float delay); - void VaporFrame(int i, float rTime); - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - LPDIRECT3DDEVICE7 m_pD3DDevice; - CTerrain* m_terrain; - CParticule* m_particule; - CSound* m_sound; - - WaterType m_type[2]; - char m_filename[100]; - float m_level; // overall level - float m_glint; // amplitude of reflections - D3DVECTOR m_eddy; // amplitude of swirls - D3DCOLORVALUE m_diffuse; // diffuse color - D3DCOLORVALUE m_ambient; // ambient color - float m_time; - float m_lastLava; - int m_subdiv; - - int m_brick; // number of brick*mosaics - float m_size; // size of a item in an brick - - int m_lineUsed; - WaterLine m_line[MAXWATERLINE]; - - WaterVapor m_vapor[MAXWATVAPOR]; - - BOOL m_bDraw; - BOOL m_bLava; - D3DCOLOR m_color; -}; - - -#endif //_WATER_H_ diff --git a/src/window.cpp b/src/window.cpp deleted file mode 100644 index c42493a..0000000 --- a/src/window.cpp +++ /dev/null @@ -1,1622 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// window.cpp - -#define STRICT -#define D3D_OVERLOADS - -#include -#include -#include - -#include "struct.h" -#include "d3dengine.h" -#include "language.h" -#include "math3d.h" -#include "event.h" -#include "misc.h" -#include "restext.h" -#include "iman.h" -#include "button.h" -#include "color.h" -#include "check.h" -#include "key.h" -#include "group.h" -#include "image.h" -#include "label.h" -#include "edit.h" -#include "editvalue.h" -#include "scroll.h" -#include "slider.h" -#include "list.h" -#include "shortcut.h" -#include "map.h" -#include "gauge.h" -#include "compass.h" -#include "target.h" -#include "text.h" -#include "window.h" - - - - -// Object's constructor. - -CWindow::CWindow(CInstanceManager* iMan) : CControl(iMan) -{ - int i; - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new button. - -CColor* CWindow::CreateColor(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CColor* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new button. - -CCheck* CWindow::CreateCheck(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CCheck* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new button. - -CKey* CWindow::CreateKey(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CKey* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new button. - -CGroup* CWindow::CreateGroup(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CGroup* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new button. - -CImage* CWindow::CreateImage(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CImage* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new label. - -CLabel* CWindow::CreateLabel(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, - char *name) -{ - CLabel* pc; - char* p; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - - p = strchr(name, '\\'); - if ( p == 0 ) - { - pc->SetName(name); - } - else - { - char text[100]; - strncpy(text, name, 100); - text[100-1] = 0; - if ( p-name < 100 ) - { - text[p-name] = 0; // deletes text after "\\" (tooltip) - } - pc->SetName(text); - } - return pc; - } - } - return 0; -} - -// Creates a new editable pave. - -CEdit* CWindow::CreateEdit(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CEdit* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new editable pave. - -CEditValue* CWindow::CreateEditValue(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CEditValue* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new elevator. - -CScroll* CWindow::CreateScroll(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CScroll* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new cursor. - -CSlider* CWindow::CreateSlider(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CSlider* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new list. - -CList* CWindow::CreateList(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, - float expand) -{ - CList* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg, expand); - return pc; - } - } - return 0; -} - -// Creates a new shortcut. - -CShortcut* CWindow::CreateShortcut(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CShortcut* ps; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return ps; - } - } - return 0; -} - -// Creates a new card. - -CMap* CWindow::CreateMap(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CMap* pm; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return pm; - } - } - return 0; -} - -// Creates a new gauge. - -CGauge* CWindow::CreateGauge(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CGauge* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new compass. - -CCompass* CWindow::CreateCompass(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CCompass* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Creates a new target. - -CTarget* CWindow::CreateTarget(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg) -{ - CTarget* pc; - int i; - - if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); - - for ( i=0 ; iCreate(pos, dim, icon, eventMsg); - return pc; - } - } - return 0; -} - -// Removes a control. - -BOOL CWindow::DeleteControl(EventMsg eventMsg) -{ - int i; - - for ( i=0 ; iRetEventMsg() ) - { - delete m_table[i]; - m_table[i] = 0; - return TRUE; - } - } - } - return FALSE; -} - -// Gives a control. - -CControl* CWindow::SearchControl(EventMsg eventMsg) -{ - int i; - - for ( i=0 ; iRetEventMsg() ) - { - return m_table[i]; - } - } - } - return 0; -} - - -// Makes the tooltip binds to the window. - -BOOL CWindow::GetTooltip(FPOINT pos, char* name) -{ - int i; - - for ( i=MAXWINDOW-1 ; i>=0 ; i-- ) - { - if ( m_table[i] != 0 ) - { - if ( m_table[i]->GetTooltip(pos, name) ) - { - return TRUE; - } - } - } - - if ( m_buttonClose != 0 && - m_buttonClose->GetTooltip(pos, name) ) - { - return TRUE; - } - if ( m_buttonFull != 0 && - m_buttonFull->GetTooltip(pos, name) ) - { - return TRUE; - } - if ( m_buttonReduce != 0 && - m_buttonReduce->GetTooltip(pos, name) ) - { - return TRUE; - } - - if ( Detect(pos) ) // in the window? - { - strcpy(name, m_tooltip); - return TRUE; - } - - return FALSE; -} - - -// Specifies the name for the title bar. - -void CWindow::SetName(char* name) -{ - CButton* pc; - BOOL bAdjust; - - CControl::SetName(name); - - if ( m_buttonReduce != 0 ) - { - delete m_buttonReduce; - m_buttonReduce = 0; - } - - if ( m_buttonFull != 0 ) - { - delete m_buttonFull; - m_buttonFull = 0; - } - - if ( m_buttonClose != 0 ) - { - delete m_buttonClose; - m_buttonClose = 0; - } - - bAdjust = FALSE; - - if ( m_name[0] != 0 && m_bRedim ) // title bar exists? - { - m_buttonReduce = new CButton(m_iMan); - pc = (CButton*)m_buttonReduce; - pc->Create(m_pos, m_dim, 0, EVENT_NULL); - - m_buttonFull = new CButton(m_iMan); - pc = (CButton*)m_buttonFull; - pc->Create(m_pos, m_dim, 0, EVENT_NULL); - - bAdjust = TRUE; - } - - if ( m_name[0] != 0 && m_bClosable ) // title bar exists? - { - m_buttonClose = new CButton(m_iMan); - pc = (CButton*)m_buttonClose; - pc->Create(m_pos, m_dim, 0, EVENT_NULL); - - bAdjust = TRUE; - } - - if ( bAdjust ) - { - AdjustButtons(); - } - - MoveAdjust(); -} - - -void CWindow::SetPos(FPOINT pos) -{ - CControl::SetPos(pos); - MoveAdjust(); -} - -void CWindow::SetDim(FPOINT dim) -{ - if ( dim.x < m_minDim.x ) dim.x = m_minDim.x; - if ( dim.x > m_maxDim.x ) dim.x = m_maxDim.x; - if ( dim.y < m_minDim.y ) dim.y = m_minDim.y; - if ( dim.y > m_maxDim.y ) dim.y = m_maxDim.y; - - CControl::SetDim(dim); - MoveAdjust(); -} - -void CWindow::MoveAdjust() -{ - FPOINT pos, dim; - float h, offset; - - h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType); - dim.y = h*1.2f; - dim.x = dim.y*0.75f; - - if ( m_buttonClose != 0 ) - { - pos.x = m_pos.x+m_dim.x-0.01f-dim.x; - pos.y = m_pos.y+m_dim.y-0.01f-h*1.2f; - m_buttonClose->SetPos(pos); - m_buttonClose->SetDim(dim); - offset = dim.x*1.0f; - } - else - { - offset = 0.0f; - } - - if ( m_buttonFull != 0 ) - { - pos.x = m_pos.x+m_dim.x-0.01f-dim.x-offset; - pos.y = m_pos.y+m_dim.y-0.01f-h*1.2f; - m_buttonFull->SetPos(pos); - m_buttonFull->SetDim(dim); - } - - if ( m_buttonReduce != 0 ) - { - pos.x = m_pos.x+m_dim.x-0.01f-dim.x*2.0f-offset; - pos.y = m_pos.y+m_dim.y-0.01f-h*1.2f; - m_buttonReduce->SetPos(pos); - m_buttonReduce->SetDim(dim); - } -} - - -void CWindow::SetMinDim(FPOINT dim) -{ - m_minDim = dim; -} - -void CWindow::SetMaxDim(FPOINT dim) -{ - m_maxDim = dim; -} - -FPOINT CWindow::RetMinDim() -{ - return m_minDim; -} - -FPOINT CWindow::RetMaxDim() -{ - return m_maxDim; -} - - -// Indicates whether the window is moved. - -void CWindow::SetMovable(BOOL bMode) -{ - m_bMovable = bMode; -} - -BOOL CWindow::RetMovable() -{ - return m_bMovable; -} - - -// Management of the presence of minimize/maximize buttons. - -void CWindow::SetRedim(BOOL bMode) -{ - m_bRedim = bMode; -} - -BOOL CWindow::RetRedim() -{ - return m_bRedim; -} - - -// Management of the presence of the close button. - -void CWindow::SetClosable(BOOL bMode) -{ - m_bClosable = bMode; -} - -BOOL CWindow::RetClosable() -{ - return m_bClosable; -} - - -void CWindow::SetMaximized(BOOL bMaxi) -{ - m_bMaximized = bMaxi; - AdjustButtons(); -} - -BOOL CWindow::RetMaximized() -{ - return m_bMaximized; -} - -void CWindow::SetMinimized(BOOL bMini) -{ - m_bMinimized = bMini; - AdjustButtons(); -} - -BOOL CWindow::RetMinimized() -{ - return m_bMinimized; -} - -void CWindow::SetFixed(BOOL bFix) -{ - m_bFixed = bFix; -} - -BOOL CWindow::RetFixed() -{ - return m_bFixed; -} - - -// Adjusts the buttons in the title bar. - -void CWindow::AdjustButtons() -{ - char res[100]; - - if ( m_buttonFull != 0 ) - { - if ( m_bMaximized ) - { - m_buttonFull->SetIcon(54); - GetResource(RES_TEXT, RT_WINDOW_STANDARD, res); - m_buttonFull->SetTooltip(res); - } - else - { - m_buttonFull->SetIcon(52); - GetResource(RES_TEXT, RT_WINDOW_MAXIMIZED, res); - m_buttonFull->SetTooltip(res); - } - } - - if ( m_buttonReduce != 0 ) - { - if ( m_bMinimized ) - { - m_buttonReduce->SetIcon(54); - GetResource(RES_TEXT, RT_WINDOW_STANDARD, res); - m_buttonReduce->SetTooltip(res); - } - else - { - m_buttonReduce->SetIcon(51); - GetResource(RES_TEXT, RT_WINDOW_MINIMIZED, res); - m_buttonReduce->SetTooltip(res); - } - } - - if ( m_buttonClose != 0 ) - { - m_buttonClose->SetIcon(11); // x - GetResource(RES_TEXT, RT_WINDOW_CLOSE, res); - m_buttonClose->SetTooltip(res); - } -} - - -void CWindow::SetTrashEvent(BOOL bTrash) -{ - m_bTrashEvent = bTrash; -} - -BOOL CWindow::RetTrashEvent() -{ - return m_bTrashEvent; -} - - -// Returns the message from the button "reduce". - -EventMsg CWindow::RetEventMsgReduce() -{ - if ( m_buttonReduce == 0 ) return EVENT_NULL; - return m_buttonReduce->RetEventMsg(); -} - -// Returns the message from the button "full". - -EventMsg CWindow::RetEventMsgFull() -{ - if ( m_buttonFull == 0 ) return EVENT_NULL; - return m_buttonFull->RetEventMsg(); -} - -// Returns the message from the button "close". - -EventMsg CWindow::RetEventMsgClose() -{ - if ( m_buttonClose == 0 ) return EVENT_NULL; - return m_buttonClose->RetEventMsg(); -} - - -// Detects whether the mouse is in an edge of the window, to resize it. -// Bit returns: 0 = left, 1 = down, 2 = right, 3 = up, 1 = all. - -int CWindow::BorderDetect(FPOINT pos) -{ - FPOINT dim; - float h; - int flags; - - if ( m_bMaximized || m_bMinimized || m_bFixed ) return 0; - - flags = 0; - if ( pos.x < m_pos.x+0.030f ) - { - flags |= (1<<0); - } - if ( pos.y < m_pos.y+0.020f ) - { - flags |= (1<<1); - } - if ( pos.x > m_pos.x+m_dim.x-0.030f ) - { - flags |= (1<<2); - } - if ( pos.y > m_pos.y+m_dim.y-0.020f ) - { - flags |= (1<<3); - } - - if ( pos.x > m_pos.x+ 0.015f && - pos.x < m_pos.x+m_dim.x-0.015f && - pos.y > m_pos.y+ 0.010f && - pos.y < m_pos.y+m_dim.y-0.010f ) - { - flags = 0; - } - - if ( flags == 0 ) - { - h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType); - dim.y = h*1.2f; - dim.x = dim.y*0.75f; - if ( pos.x < m_pos.x+m_dim.x-0.01f-dim.x*3.0f && - pos.y >= m_pos.y+m_dim.y-0.01f-h*1.2f ) - { - flags = -1; - } - } - - return flags; -} - -// Management of an event. - -BOOL CWindow::EventProcess(const Event &event) -{ - FPOINT pos; - int i, flags; - - if ( event.event == EVENT_MOUSEMOVE ) - { - if ( m_bCapture ) - { - m_engine->SetMouseType(m_pressMouse); - } - else - { - m_pressMouse = D3DMOUSENORM; - - if ( m_name[0] != 0 && m_bMovable && // title bar? - Detect(event.pos) ) - { - flags = BorderDetect(event.pos); - if ( flags == -1 ) - { - m_pressMouse = D3DMOUSEMOVE; // + - } - else if ( ((flags & (1<<0)) && (flags & (1<<3))) || - ((flags & (1<<1)) && (flags & (1<<2))) ) - { - m_pressMouse = D3DMOUSEMOVEI; // \ // - } - else if ( ((flags & (1<<0)) && (flags & (1<<1))) || - ((flags & (1<<2)) && (flags & (1<<3))) ) - { - m_pressMouse = D3DMOUSEMOVED; // / - } - else if ( (flags & (1<<0)) || (flags & (1<<2)) ) - { - m_pressMouse = D3DMOUSEMOVEH; // - - } - else if ( (flags & (1<<1)) || (flags & (1<<3)) ) - { - m_pressMouse = D3DMOUSEMOVEV; // | - } - } - - if ( m_pressMouse != D3DMOUSENORM ) - { - m_engine->SetMouseType(m_pressMouse); - } - } - } - - if ( !m_bCapture ) - { - for ( i=MAXWINDOW-1 ; i>=0 ; i-- ) - { - if ( m_table[i] != 0 ) - { - if ( !m_table[i]->EventProcess(event) ) - { - return FALSE; - } - } - } - - if ( m_buttonReduce != 0 ) - { - m_buttonReduce->EventProcess(event); - } - if ( m_buttonFull != 0 ) - { - m_buttonFull->EventProcess(event); - } - if ( m_buttonClose != 0 ) - { - m_buttonClose->EventProcess(event); - } - } - - if ( m_bTrashEvent && event.event == EVENT_LBUTTONDOWN ) - { - if ( Detect(event.pos) ) - { - if ( m_name[0] != 0 && m_bMovable ) // title bar? - { - m_pressFlags = BorderDetect(event.pos); - if ( m_pressFlags != 0 ) - { - m_bCapture = TRUE; - m_pressPos = event.pos; - } - } - return FALSE; - } - } - - if ( event.event == EVENT_MOUSEMOVE && m_bCapture ) - { - pos = event.pos; - if ( m_pressFlags == -1 ) // all moves? - { - m_pos.x += pos.x-m_pressPos.x; - m_pos.y += pos.y-m_pressPos.y; - } - else - { - if ( m_pressFlags & (1<<0) ) // left edge? - { - if ( pos.x > m_pressPos.x+m_dim.x-m_minDim.x ) - { - pos.x = m_pressPos.x+m_dim.x-m_minDim.x; - } - m_pos.x += pos.x-m_pressPos.x; - m_dim.x -= pos.x-m_pressPos.x; - } - if ( m_pressFlags & (1<<1) ) // bottom edge? - { - if ( pos.y > m_pressPos.y+m_dim.y-m_minDim.y ) - { - pos.y = m_pressPos.y+m_dim.y-m_minDim.y; - } - m_pos.y += pos.y-m_pressPos.y; - m_dim.y -= pos.y-m_pressPos.y; - } - if ( m_pressFlags & (1<<2) ) // right edge? - { - if ( pos.x < m_pressPos.x-m_dim.x+m_minDim.x ) - { - pos.x = m_pressPos.x-m_dim.x+m_minDim.x; - } - m_dim.x += pos.x-m_pressPos.x; - } - if ( m_pressFlags & (1<<3) ) // top edge? - { - if ( pos.y < m_pressPos.y-m_dim.y+m_minDim.y ) - { - pos.y = m_pressPos.y-m_dim.y+m_minDim.y; - } - m_dim.y += pos.y-m_pressPos.y; - } - } - m_pressPos = pos; - AdjustButtons(); - - Event newEvent = event; - newEvent.event = m_eventMsg; - m_event->AddEvent(newEvent); - } - - if ( event.event == EVENT_LBUTTONUP && m_bCapture ) - { - m_bCapture = FALSE; - } - - return TRUE; -} - - -// Draws the window. - -void CWindow::Draw() -{ - FPOINT pos, dim; - float width, h, sw; - int i; - - if ( (m_state & STATE_VISIBLE) == 0 ) return; - - if ( m_state & STATE_SHADOW ) - { - DrawShadow(m_pos, m_dim); - } - - DrawVertex(m_pos, m_dim, m_icon); // draws the background - - if ( m_name[0] != 0 ) // title bar? - { - h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType); - - // Draws the shadow under the title bar. - { - FPOINT sPos, sDim; - - pos.x = m_pos.x+0.01f; - dim.x = m_dim.x-0.02f; - pos.y = m_pos.y+m_dim.y-0.01f-h*1.2f; - dim.y = h*1.2f; - DrawShadow(pos, dim); - } - - width = m_dim.x; - if ( m_bRedim ) width -= h*1.2f*0.75f*2.0f; - if ( m_bClosable ) width -= h*1.2f*0.75f; - - pos.x = m_pos.x+0.01f; - dim.x = width-0.02f; - pos.y = m_pos.y+m_dim.y-0.01f-h*1.2f; - dim.y = h*1.2f; - DrawVertex(pos, dim, (m_state&STATE_ENABLE)?2:9); - - sw = m_engine->RetText()->RetStringWidth(m_name, strlen(m_name), m_fontSize, m_fontStretch, m_fontType); - - if ( m_state&STATE_ENABLE ) - { - pos.x = m_pos.x+0.015f; - dim.x = (width-sw-0.06f)/2.0f; - pos.y = m_pos.y+m_dim.y-0.01f-h*1.0f; - dim.y = h*0.8f; - DrawHach(pos, dim); // left hatch - pos.x = m_pos.x+width-dim.x-0.015f; - DrawHach(pos, dim); // right hatch - } - - pos.x = m_pos.x+width/2.0f; - pos.y = m_pos.y+m_dim.y-0.01f-h*1.10f; - m_engine->RetText()->DrawText(m_name, pos, width, 0, m_fontSize, m_fontStretch, m_fontType, 0); - - if ( m_buttonReduce != 0 ) - { - m_buttonReduce->Draw(); - } - - if ( m_buttonFull != 0 ) - { - m_buttonFull->Draw(); - } - - if ( m_buttonClose != 0 ) - { - m_buttonClose->Draw(); - } - } - - for ( i=0 ; iDraw(); - } - } -} - -// Draws a rectangle. - -void CWindow::DrawVertex(FPOINT pos, FPOINT dim, int icon) -{ - FPOINT p1, p2, uv1, uv2, corner; - float dp; - int i; - - dp = 0.5f/256.0f; - - if ( icon == 0 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTw); - uv1.x = 64.0f/256.0f; // dark blue transparent - uv1.y = 64.0f/256.0f; - uv2.x = 128.0f/256.0f; - uv2.y = 128.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 14.0f/640.0f; - corner.y = 14.0f/480.0f; - DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); - } - else if ( icon == 1 ) - { - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 128.0f/256.0f; // yellow tooltip - uv1.y = 0.0f/256.0f; - uv2.x = 224.0f/256.0f; - uv2.y = 16.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); - } - else if ( icon == 2 ) - { - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 128.0f/256.0f; // yellow - uv1.y = 16.0f/256.0f; - uv2.x = 224.0f/256.0f; - uv2.y = 32.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); - } - else if ( icon == 3 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 0.0f/256.0f; // transparent blue bar with yellow upper - uv1.y = 64.0f/256.0f; - uv2.x = 64.0f/256.0f; - uv2.y = 128.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); - } - else if ( icon == 4 ) // SatCom ? - { - pos.x -= 50.0f/640.0f; - pos.y -= 30.0f/480.0f; - dim.x += 100.0f/640.0f; - dim.y += 60.0f/480.0f; - - m_engine->SetTexture("human.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 140.0f/256.0f; - uv1.y = 32.0f/256.0f; - uv2.x = 182.0f/256.0f; - uv2.y = 64.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2); // clothing - - pos.x += 20.0f/640.0f; - pos.y -= 10.0f/480.0f; - dim.x -= 20.0f/640.0f; - dim.y += 0.0f/480.0f; - - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTw); - uv1.x = 192.0f/256.0f; - uv1.y = 32.0f/256.0f; - uv2.x = 224.0f/256.0f; - uv2.y = 64.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 30.0f/640.0f; - corner.y = 30.0f/480.0f; - DrawIcon(pos, dim, uv1, uv2, corner, 5.0f/256.0f); // shadow - - pos.x += 0.0f/640.0f; - pos.y += 20.0f/480.0f; - dim.x -= 20.0f/640.0f; - dim.y -= 20.0f/480.0f; - - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 64.0f/256.0f; - uv1.y = 0.0f/256.0f; - uv2.x = 96.0f/256.0f; - uv2.y = 32.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 14.0f/640.0f; - corner.y = 14.0f/480.0f; - DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); // outside blue - - pos.x += 20.0f/640.0f; - pos.y += 10.0f/480.0f; - dim.x -= 40.0f/640.0f; - dim.y -= 20.0f/480.0f; - - uv1.x = 96.0f/256.0f; - uv1.y = 0.0f/256.0f; - uv2.x = 128.0f/256.0f; - uv2.y = 32.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 14.0f/640.0f; - corner.y = 14.0f/480.0f; - DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); // inside blue - - pos.x += 10.0f/640.0f; - pos.y += 10.0f/480.0f; - dim.x -= 20.0f/640.0f; - dim.y -= 20.0f/480.0f; - - m_engine->SetTexture("button3.tga"); - uv1.x = 0.0f/256.0f; - uv1.y = 224.0f/256.0f; - uv2.x = 32.0f/256.0f; - uv2.y = 256.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2); // dark blue background - - m_engine->SetTexture("button2.tga"); - uv1.x = 224.0f/256.0f; - uv1.y = 224.0f/256.0f; - uv2.x = 249.0f/256.0f; - uv2.y = 235.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - pos.x = 20.0f/640.0f; - pos.y = 70.0f/480.0f; - dim.x = 25.0f/640.0f; - dim.y = 11.0f/480.0f; - for ( i=0 ; i<5 ; i++ ) - { - DrawIcon(pos, dim, uv1, uv2); // = bottom/left - pos.y += 15.0f/480.0f; - } - pos.y = (480.0f-70.0f-11.0f)/480.0f; - for ( i=0 ; i<5 ; i++ ) - { - DrawIcon(pos, dim, uv1, uv2); // = top/left - pos.y -= 15.0f/480.0f; - } - pos.x = (640.0f-25.0f-20.0f)/640.0f; - pos.y = 70.0f/480.0f; - for ( i=0 ; i<5 ; i++ ) - { - DrawIcon(pos, dim, uv1, uv2); // = bottom/right - pos.y += 15.0f/480.0f; - } - pos.y = (480.0f-70.0f-11.0f)/480.0f; - for ( i=0 ; i<5 ; i++ ) - { - DrawIcon(pos, dim, uv1, uv2); // = top/right - pos.y -= 15.0f/480.0f; - } - - uv1.x = 208.0f/256.0f; - uv1.y = 224.0f/256.0f; - uv2.x = 224.0f/256.0f; - uv2.y = 240.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - dim.x = 10.0f/640.0f; - dim.y = 10.0f/480.0f; - pos.x = 534.0f/640.0f; - pos.y = 430.0f/480.0f; - for ( i=0 ; i<3 ; i++ ) - { - DrawIcon(pos, dim, uv1, uv2); // micro - pos.x += 12.0f/640.0f; - } - pos.x = 528.0f/640.0f; - pos.y -= 12.0f/480.0f; - for ( i=0 ; i<4 ; i++ ) - { - DrawIcon(pos, dim, uv1, uv2); // micro - pos.x += 12.0f/640.0f; - } - pos.x = 534.0f/640.0f; - pos.y -= 12.0f/480.0f; - for ( i=0 ; i<3 ; i++ ) - { - DrawIcon(pos, dim, uv1, uv2); // micro - pos.x += 12.0f/640.0f; - } - } - else if ( icon == 5 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 64.0f/256.0f; // transparent green - uv1.y = 160.0f/256.0f; - uv2.x = 160.0f/256.0f; - uv2.y = 176.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); - } - else if ( icon == 6 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 64.0f/256.0f; // transparent red - uv1.y = 176.0f/256.0f; - uv2.x = 160.0f/256.0f; - uv2.y = 192.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); - } - else if ( icon == 7 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 64.0f/256.0f; // transparent blue - uv1.y = 192.0f/256.0f; - uv2.x = 160.0f/256.0f; - uv2.y = 208.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); - } - else if ( icon == 8 ) - { - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 0.0f/256.0f; // opaque orange - uv1.y = 0.0f/256.0f; - uv2.x = 32.0f/256.0f; - uv2.y = 32.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 14.0f/640.0f; - corner.y = 14.0f/480.0f; - DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); - } - else if ( icon == 9 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 32.0f/256.0f; // opaque gray - uv1.y = 32.0f/256.0f; - uv2.x = 64.0f/256.0f; - uv2.y = 64.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 14.0f/640.0f; - corner.y = 14.0f/480.0f; - DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); - } - else if ( icon == 10 ) - { - // nothing (in the background image)! - } - else if ( icon == 11 ) - { - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATETTb); - uv1.x = 64.0f/256.0f; // transparent yellow - uv1.y = 224.0f/256.0f; - uv2.x = 160.0f/256.0f; - uv2.y = 240.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f); - } - else if ( icon == 12 ) - { - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 128.0f/256.0f; // dirty opaque gray - uv1.y = 128.0f/256.0f; - uv2.x = 160.0f/256.0f; - uv2.y = 160.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 6.0f/640.0f; - corner.y = 6.0f/480.0f; - DrawIcon(pos, dim, uv1, uv2, corner, 5.0f/256.0f); - } - else if ( icon == 13 ) - { - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 192.0f/256.0f; // dirty opaque blue - uv1.y = 128.0f/256.0f; - uv2.x = 224.0f/256.0f; - uv2.y = 160.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 6.0f/640.0f; - corner.y = 6.0f/480.0f; - DrawIcon(pos, dim, uv1, uv2, corner, 5.0f/256.0f); - } - else if ( icon == 14 ) - { - m_engine->SetTexture("button1.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 160.0f/256.0f; // dirty opaque red - uv1.y = 128.0f/256.0f; - uv2.x = 192.0f/256.0f; - uv2.y = 160.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - corner.x = 6.0f/640.0f; - corner.y = 6.0f/480.0f; - DrawIcon(pos, dim, uv1, uv2, corner, 5.0f/256.0f); - } -} - -// Draws hatching. - -void CWindow::DrawHach(FPOINT pos, FPOINT dim) -{ -#if _NEWLOOK -#else - FPOINT ppos, ddim, uv1, uv2; - float dp, max, ndim; - BOOL bStop; - - dp = 0.5f/256.0f; - - m_engine->SetTexture("button2.tga"); - m_engine->SetState(D3DSTATENORMAL); - uv1.x = 64.0f/256.0f; // hatching - uv1.y = 208.0f/256.0f; - uv2.x = 145.0f/256.0f; - uv2.y = 224.0f/256.0f; - uv1.x += dp; - uv1.y += dp; - uv2.x -= dp; - uv2.y -= dp; - - max = dim.y*(uv2.x-uv1.x)/(uv2.y-uv1.y); - - ppos = pos; - ddim = dim; - bStop = FALSE; - do - { - ddim.x = max; - if ( ppos.x+ddim.x > pos.x+dim.x ) - { - ndim = pos.x+dim.x-ppos.x; - uv2.x = uv1.x+(uv2.x-uv1.x)*(ndim/ddim.x); - ddim.x = ndim; - bStop = TRUE; - } - DrawIcon(ppos, ddim, uv1, uv2); - - ppos.x += ddim.x; - } - while ( !bStop ); -#endif -} - diff --git a/src/window.h b/src/window.h deleted file mode 100644 index 61506d1..0000000 --- a/src/window.h +++ /dev/null @@ -1,148 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// window.h - -#ifndef _WINDOW_H_ -#define _WINDOW_H_ - - -#include "control.h" - - -class CD3DEngine; -class CButton; -class CColor; -class CCheck; -class CKey; -class CGroup; -class CImage; -class CLabel; -class CEdit; -class CEditValue; -class CScroll; -class CSlider; -class CList; -class CShortcut; -class CMap; -class CGauge; -class CCompass; -class CTarget; - - -#define MAXWINDOW 100 - - -class CWindow : public CControl -{ -public: - CWindow(CInstanceManager* iMan); - ~CWindow(); - - void Flush(); - BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CButton* CreateButton(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CColor* CreateColor(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CCheck* CreateCheck(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CKey* CreateKey(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CGroup* CreateGroup(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CImage* CreateImage(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CLabel* CreateLabel(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, char *name); - CEdit* CreateEdit(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CEditValue* CreateEditValue(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CScroll* CreateScroll(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CSlider* CreateSlider(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CList* CreateList(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, float expand=1.2f); - CShortcut* CreateShortcut(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CMap* CreateMap(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CGauge* CreateGauge(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CCompass* CreateCompass(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - CTarget* CreateTarget(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg); - BOOL DeleteControl(EventMsg eventMsg); - CControl* SearchControl(EventMsg eventMsg); - - EventMsg RetEventMsgReduce(); - EventMsg RetEventMsgFull(); - EventMsg RetEventMsgClose(); - - void SetName(char* name); - - void SetTrashEvent(BOOL bTrash); - BOOL RetTrashEvent(); - - void SetPos(FPOINT pos); - void SetDim(FPOINT dim); - - void SetMinDim(FPOINT dim); - void SetMaxDim(FPOINT dim); - FPOINT RetMinDim(); - FPOINT RetMaxDim(); - - void SetMovable(BOOL bMode); - BOOL RetMovable(); - - void SetRedim(BOOL bMode); - BOOL RetRedim(); - - void SetClosable(BOOL bMode); - BOOL RetClosable(); - - void SetMaximized(BOOL bMaxi); - BOOL RetMaximized(); - void SetMinimized(BOOL bMini); - BOOL RetMinimized(); - void SetFixed(BOOL bFix); - BOOL RetFixed(); - - BOOL GetTooltip(FPOINT pos, char* name); - - BOOL EventProcess(const Event &event); - - void Draw(); - -protected: - int BorderDetect(FPOINT pos); - void AdjustButtons(); - void MoveAdjust(); - void DrawVertex(FPOINT pos, FPOINT dim, int icon); - void DrawHach(FPOINT pos, FPOINT dim); - -protected: - CControl* m_table[MAXWINDOW]; - - BOOL m_bTrashEvent; - BOOL m_bMaximized; - BOOL m_bMinimized; - BOOL m_bFixed; - - FPOINT m_minDim; - FPOINT m_maxDim; - - CButton* m_buttonReduce; - CButton* m_buttonFull; - CButton* m_buttonClose; - - BOOL m_bMovable; - BOOL m_bRedim; - BOOL m_bClosable; - BOOL m_bCapture; - FPOINT m_pressPos; - int m_pressFlags; - D3DMouse m_pressMouse; -}; - - -#endif //_WINDOW_H_ diff --git a/src/winmain.aps b/src/winmain.aps deleted file mode 100644 index 6a1e0df..0000000 Binary files a/src/winmain.aps and /dev/null differ diff --git a/src/winmain.rc b/src/winmain.rc deleted file mode 100644 index 547d4c2..0000000 --- a/src/winmain.rc +++ /dev/null @@ -1,265 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#define IDC_STATIC -1 -#include - - - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_MAIN_ICON ICON DISCARDABLE "DirectX.ico" - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - "#define IDC_STATIC -1\r\n" - "#include \r\n" - "\r\n" - "\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Accelerator -// - -IDR_MAIN_ACCEL ACCELERATORS DISCARDABLE -BEGIN - VK_F12, IDM_CHANGEDEVICE, VIRTKEY, SHIFT, NOINVERT -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE -BEGIN - IDD_ABOUT, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 165 - TOPMARGIN, 7 - BOTTOMMARGIN, 117 - END - - IDD_CHANGEDEVICE, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 174 - TOPMARGIN, 7 - BOTTOMMARGIN, 83 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_ABOUT DIALOG DISCARDABLE 0, 0, 172, 124 -STYLE DS_SYSMODAL | DS_MODALFRAME | DS_NOIDLEMSG | DS_SETFOREGROUND | - DS_3DLOOK | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "About" -FONT 8, "MS Sans Serif" -BEGIN - DEFPUSHBUTTON "OK",IDOK,115,103,50,14 - ICON IDI_MAIN_ICON,IDC_STATIC,5,5,20,20 - LTEXT "Robot Sample",IDC_STATIC,35,5,46,8 - LTEXT "Copyright (c) 1999-2000 EPSITEC SA",IDC_STATIC,35,15, - 120,8 - LTEXT "About",IDC_STATIC,62,52,20,8 - LTEXT "Select Driver / Device / Mode",IDC_STATIC,62,62,97,8 - CTEXT "",IDC_STATIC,12,72,45,8 - LTEXT "Toggle Fullscreen / Windowed",IDC_STATIC,62,72,98,8 - LTEXT "Exit",IDC_STATIC,62,82,12,8 - CTEXT "",IDC_STATIC,12,52,45,8 - CTEXT "",IDC_STATIC,12,62,45,8 - CTEXT "",IDC_STATIC,12,82,45,8 - GROUPBOX "Usage",IDC_STATIC,7,42,160,55 - LTEXT "Daniel Roux, version 0.1 Janvier 2000",IDC_STATIC,35,26, - 121,8 -END - -IDD_CHANGEDEVICE DIALOG DISCARDABLE 0, 0, 182, 90 -STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Change device" -FONT 8, "MS Sans Serif" -BEGIN - GROUPBOX "&Device selection",-1,5,5,115,40 - COMBOBOX IDC_DEVICE_COMBO,10,15,105,100,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - CONTROL "Use desktop &window",IDC_WINDOWED_CHECKBOX,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,10,30,85,10 - GROUPBOX "Fullscreen &modes",IDC_FULLSCREEN_TEXT,5,45,115,40 - COMBOBOX IDC_MODE_COMBO,10,55,105,100,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - CONTROL "&Stereoscopic viewing",IDC_STEREO_CHECKBOX,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,10,70,85,9 - DEFPUSHBUTTON "OK",IDOK,125,5,50,14 - PUSHBUTTON "Cancel",IDCANCEL,125,25,50,14 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDR_MENU MENU DISCARDABLE -BEGIN - POPUP "&File" - BEGIN - MENUITEM "&Go/stop\tEnter", IDM_TOGGLESTART - MENUITEM "&Single step\tSpace", IDM_SINGLESTEP - MENUITEM SEPARATOR - MENUITEM "&About...\tF1", IDM_ABOUT - MENUITEM "&Change device...\tF2", IDM_CHANGEDEVICE - MENUITEM SEPARATOR - MENUITEM "E&xit\tESC", IDM_EXIT - END -END - -IDR_POPUP MENU DISCARDABLE -BEGIN - POPUP "Popup" - BEGIN - MENUITEM "&Go/stop", IDM_TOGGLESTART - MENUITEM "&Single step", IDM_SINGLESTEP - MENUITEM SEPARATOR - MENUITEM "&About...", IDM_ABOUT - MENUITEM "&Change device...", IDM_CHANGEDEVICE - MENUITEM SEPARATOR - MENUITEM "E&xit", IDM_EXIT - END -END - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// French (Switzerland) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRS) -#ifdef _WIN32 -LANGUAGE LANG_FRENCH, SUBLANG_FRENCH_SWISS -#pragma code_page(1252) -#endif //_WIN32 - -#ifndef _MAC -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,0 - PRODUCTVERSION 1,0,0,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "100c04b0" - BEGIN - VALUE "CompanyName", "www.epsitec.com\0" - VALUE "FileDescription", "CeeBot\0" - VALUE "FileVersion", "Version 1.0\0" - VALUE "InternalName", "CeeBot\0" - VALUE "LegalCopyright", "Copyright © 2001 by EPSITEC SA\0" - VALUE "OriginalFilename", "ceebot.exe\0" - VALUE "ProductName", "EPSITEC CeeBot\0" - VALUE "ProductVersion", "Version 1.0\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x100c, 1200 - END -END - -#endif // !_MAC - - -///////////////////////////////////////////////////////////////////////////// -// -// Cursor -// - -IDC_CURSORHAND CURSOR DISCARDABLE "cursor1.cur" -IDC_CURSORSCROLLL CURSOR DISCARDABLE "cursorha.cur" -IDC_CURSORSCROLLR CURSOR DISCARDABLE "cursorsc.cur" -IDC_CURSORSCROLLU CURSOR DISCARDABLE "cur00001.cur" -IDC_CURSORSCROLLD CURSOR DISCARDABLE "cur00002.cur" -IDC_CURSORTARGET CURSOR DISCARDABLE "cur00003.cur" -#endif // French (Switzerland) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - -- cgit v1.2.3-1-g7c22